Added logger

This commit is contained in:
Franklin 2022-08-30 13:32:22 -04:00
parent 54272767f5
commit 18b94e9e19
6 changed files with 89 additions and 8 deletions

View File

@ -14,5 +14,7 @@ chrono = { version = "0.4", features = [ "serde" ] }
ring = "0.16.20" ring = "0.16.20"
data-encoding = "2.3.2" data-encoding = "2.3.2"
futures-util = "0.3" futures-util = "0.3"
actix-web-utils = "0.2"
log = { version = "0.4", features = ["serde"] }
dev-dtos = { git = "https://backend:Eo1n1TPsyWV7wwo9uFwgUJGKKheMM6paM2mDkVPA4zqkh5dt6Q6XPkbtojzYQudQsM84vSwKmhHHTPjyn535d6NLBmA3meeGj0Gb8if4sceAwvySdmzedg5mN2P5zzQt@gitea.blancoinfante.com/blancoinfante_backend/dev-dtos-rust.git" } dev-dtos = { git = "https://backend:Eo1n1TPsyWV7wwo9uFwgUJGKKheMM6paM2mDkVPA4zqkh5dt6Q6XPkbtojzYQudQsM84vSwKmhHHTPjyn535d6NLBmA3meeGj0Gb8if4sceAwvySdmzedg5mN2P5zzQt@gitea.blancoinfante.com/blancoinfante_backend/dev-dtos-rust.git" }

View File

@ -1,6 +1,7 @@
use std::collections::HashMap; use std::{collections::HashMap, str::FromStr, time::Duration};
use sqlx::{MySqlPool}; use log::{LevelFilter, info};
use sqlx::{MySqlPool, mysql::{MySqlConnectOptions, MySqlPoolOptions}, ConnectOptions};
pub async fn start_database_connection(env_vars: &HashMap<String, String>) -> Result<MySqlPool, sqlx::Error>{ pub async fn start_database_connection(env_vars: &HashMap<String, String>) -> Result<MySqlPool, sqlx::Error>{
let db_url = match env_vars.get("DATABASE_URL") { let db_url = match env_vars.get("DATABASE_URL") {
@ -8,11 +9,14 @@ pub async fn start_database_connection(env_vars: &HashMap<String, String>) -> Re
None => panic!("DATABASE_URL env var not found") None => panic!("DATABASE_URL env var not found")
}; };
let formatted_db_url = &db_url; let formatted_db_url = &db_url;
sqlx::MySqlPool::connect(&formatted_db_url).await let mut options = MySqlConnectOptions::from_str(formatted_db_url)?;
options.log_slow_statements(LevelFilter::Warn, Duration::from_secs(1))
.log_statements(LevelFilter::Trace);
MySqlPoolOptions::new().connect_with(options).await
} }
pub async fn run_all_migrations(conn: &MySqlPool){ pub async fn run_all_migrations(conn: &MySqlPool){
match sqlx::migrate!("./migrations").run(conn).await { match sqlx::migrate!("./migrations").run(conn).await {
Ok(()) => {println!("{}", "Successfully ran migrations.")}, Ok(()) => {info!("Successfully ran migrations.")},
Err(error) => {panic!("{error}")} Err(error) => {panic!("{error}")}
} }
} }

67
src/do/loggers.rs Normal file
View File

@ -0,0 +1,67 @@
use std::{future::{ready, Ready}, rc::Rc, io::Read};
use actix_web::{
dev::{self, Service, ServiceRequest, ServiceResponse, Transform},
Error, HttpMessage, web::BytesMut,
};
use futures_util::{future::LocalBoxFuture, StreamExt, Stream};
// There are two steps in middleware processing.
// 1. Middleware initialization, middleware factory gets called with
// next service in chain as parameter.
// 2. Middleware's call method gets called with normal request.
pub struct BodyLogger;
// Middleware factory is `Transform` trait from actix-service crate
// `S` - type of the next service
// `B` - type of response's body
impl<S: 'static, B> Transform<S, ServiceRequest> for BodyLogger
where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
S::Future: 'static,
B: 'static,
{
type Response = ServiceResponse<B>;
type Error = Error;
type InitError = ();
type Transform = BodyLoggerMiddleware<S>;
type Future = Ready<Result<Self::Transform, Self::InitError>>;
fn new_transform(&self, service: S) -> Self::Future {
ready(Ok(BodyLoggerMiddleware { service: Rc::new(service) }))
}
}
pub struct BodyLoggerMiddleware<S> {
service: Rc<S>,
}
impl<S, B> Service<ServiceRequest> for BodyLoggerMiddleware<S>
where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
S::Future: 'static,
B: 'static,
{
type Response = ServiceResponse<B>;
type Error = Error;
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
dev::forward_ready!(service);
fn call(&self, mut req: ServiceRequest) -> Self::Future {
let svc = self.service.clone();
Box::pin(async move {
let mut body = BytesMut::new();
let mut stream = req.take_payload();
while let Some(chunk) = stream.next().await {
body.extend_from_slice(&chunk?);
}
println!("request body: {body:?}");
let res = svc.call(req).await?;
println!("response: {:?}", res.headers());
Ok(res)
})
}
}

View File

@ -1 +1,2 @@
pub mod shared_state; pub mod shared_state;
//pub mod loggers;

View File

@ -4,6 +4,7 @@ mod routes; mod service;
mod util; mod dto; mod util; mod dto;
mod validation; mod resources; mod validation; mod resources;
use actix_web_utils::utils::logger_util::{self};
use r#do::shared_state::SharedStateObj; use r#do::shared_state::SharedStateObj;
use util::env_util; use util::env_util;
use routes::main_router::{start_all_routes, after_startup_fn}; use routes::main_router::{start_all_routes, after_startup_fn};
@ -13,6 +14,8 @@ use dao::{main_dao::{self, run_all_migrations}};
#[tokio::main] #[tokio::main]
async fn main(){ async fn main(){
logger_util::init_logger_custom(2).expect("LOGGER FAILED TO LOAD");
// Retrieve env variables and send to services that need them. // Retrieve env variables and send to services that need them.
let env_vars = env_util::get_dot_env_map(); let env_vars = env_util::get_dot_env_map();

View File

@ -1,11 +1,13 @@
use std::sync::{Mutex, Arc}; use std::sync::{Mutex, Arc};
use actix_web::{HttpServer, App, web}; use actix_web::{HttpServer, App, web, middleware::Logger};
use crate::r#do::shared_state::SharedStateObj; use log::info;
use crate::{r#do::shared_state::SharedStateObj};
use super::user_routes; use super::user_routes;
// This function is to be used in case code is meant to be run after server startup // This function is to be used in case code is meant to be run after server startup
pub fn after_startup_fn() { pub fn after_startup_fn() {
println!("{}", "Started server."); info!("Started server.")
} }
pub async fn start_all_routes(after_startup_fn_call: &dyn Fn(), state: SharedStateObj) pub async fn start_all_routes(after_startup_fn_call: &dyn Fn(), state: SharedStateObj)
@ -34,6 +36,8 @@ pub async fn start_all_routes(after_startup_fn_call: &dyn Fn(), state: SharedSta
let server_future = HttpServer::new( move || { let server_future = HttpServer::new( move || {
App::new() App::new()
// Define routes & pass in shared state // Define routes & pass in shared state
//.wrap(loggers::BodyLogger) This is how you add middleware
.wrap(Logger::default())
.app_data(db_conn_state.clone()) .app_data(db_conn_state.clone())
.app_data(env_vars_state.clone()) .app_data(env_vars_state.clone())
.service(user_routes::create_user) .service(user_routes::create_user)