Added logging infrastructure

+ Using log and simple_logger libs
+ Added a command line argument to set the log level
main
Joey Hines 2021-10-17 13:09:50 -06:00
parent 9224edca65
commit f6b797b6c1
No known key found for this signature in database
GPG Key ID: 80F567B5C968F91B
8 changed files with 116 additions and 6 deletions

30
Cargo.lock generated
View File

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.15"
@ -119,6 +121,17 @@ dependencies = [
"vec_map",
]
[[package]]
name = "colored"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59"
dependencies = [
"atty",
"lazy_static",
"winapi",
]
[[package]]
name = "config"
version = "0.11.0"
@ -297,8 +310,10 @@ dependencies = [
"config",
"geoffrey_db",
"geoffrey_models",
"log",
"serde 1.0.124",
"serde_json",
"simple_logger",
"structopt",
"tokio",
"warp",
@ -311,8 +326,10 @@ dependencies = [
"byteorder",
"geoffrey_models",
"lazy_static",
"log",
"serde 1.0.124",
"serde_json",
"simple_logger",
"sled",
]
@ -1060,6 +1077,19 @@ dependencies = [
"libc",
]
[[package]]
name = "simple_logger"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7de33c687404ec3045d4a0d437580455257c0436f858d702f244e7d652f9f07"
dependencies = [
"atty",
"chrono",
"colored",
"log",
"winapi",
]
[[package]]
name = "slab"
version = "0.4.2"

View File

@ -14,4 +14,6 @@ serde_json = "1.0.64"
geoffrey_models = { path = "../geoffrey_models" }
geoffrey_db = { path = "../geoffrey_db" }
config = "0.11.0"
structopt = "0.3.21"
structopt = "0.3.21"
log = "0.4.14"
simple_logger = "1.13.0"

View File

@ -10,6 +10,7 @@ use serde::Serialize;
use std::sync::Arc;
use warp::filters::BoxedFilter;
use warp::Filter;
use std::fmt::Debug;
pub mod add_location;
pub mod find;
@ -23,7 +24,7 @@ pub enum RequestType {
}
pub trait Command {
type Req: Serialize + DeserializeOwned + Send + 'static;
type Req: Serialize + DeserializeOwned + Send + 'static + Debug;
type Resp: Serialize + DeserializeOwned + Send;
fn command_name() -> String;
@ -38,11 +39,18 @@ pub fn create_command_filter<T: Command>(ctx: Arc<Context>) -> BoxedFilter<(impl
.and(warp::any().map(move || ctx.clone()))
.and(warp::body::json())
.map(|ctx: Arc<Context>, req: T::Req| {
log::info!("Running command {}", T::command_name());
log::debug!("Request: {:?}", req);
let reply = T::run_command(ctx, req);
if let Ok(reply) = reply {
log::debug!("Successfully processed command");
warp::reply::json(&APIResponse::Response::<T::Resp>(reply))
} else {
warp::reply::json(&APIResponse::<T::Resp>::Error(reply.err().unwrap()))
let e = reply.err().unwrap();
log::warn!("Got error when processing command: {:?}", e);
warp::reply::json(&APIResponse::<T::Resp>::Error(e))
}
});

View File

@ -0,0 +1,41 @@
use serde::{Deserialize, Serialize};
use log::{LevelFilter, SetLoggerError};
use simple_logger::SimpleLogger;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum LogLevel {
None,
Warn,
Info,
Debug
}
impl From<&str> for LogLevel {
fn from(s: &str) -> Self {
match s {
"warn" | "w" => LogLevel::Warn,
"info" | "i" => LogLevel::Info,
"debug" | "d" => LogLevel::Debug,
"none" | _ => LogLevel::None,
}
}
}
impl From<LogLevel> for LevelFilter {
fn from(l: LogLevel) -> Self {
match l {
LogLevel::None => LevelFilter::Off,
LogLevel::Warn => LevelFilter::Warn,
LogLevel::Info => LevelFilter::Info,
LogLevel::Debug => LevelFilter::Debug
}
}
}
pub fn init_logging(log_level: LogLevel) -> Result<(), SetLoggerError> {
SimpleLogger::new()
.with_level(log_level.into())
.with_module_level("hyper", LevelFilter::Info)
.with_module_level("sled", LevelFilter::Info)
.init()
}

View File

@ -2,6 +2,7 @@ mod commands;
mod config;
mod context;
mod helper;
mod logging;
use crate::commands::command_filter;
use crate::config::GeoffreyAPIConfig;
@ -11,6 +12,7 @@ use std::net::SocketAddr;
use std::path::PathBuf;
use std::str::FromStr;
use structopt::StructOpt;
use crate::logging::{init_logging, LogLevel};
pub type Result<T> = std::result::Result<T, GeoffreyAPIError>;
@ -19,19 +21,41 @@ pub type Result<T> = std::result::Result<T, GeoffreyAPIError>;
struct Args {
#[structopt(env = "GEOFFREY_CONFIG", parse(from_os_str))]
config: PathBuf,
#[structopt(short, long, env = "GEOFFREY_LOG_LEVEL", parse(from_str), default_value="Info")]
log_level: LogLevel,
}
#[tokio::main]
async fn main() {
let args: Args = Args::from_args();
let cfg = GeoffreyAPIConfig::new(args.config.as_path()).unwrap();
if let Err(e) = init_logging(args.log_level) {
println!("Unable to initialize logger: {}", e);
return;
}
let cfg = match GeoffreyAPIConfig::new(args.config.as_path()) {
Ok(cfg) => cfg,
Err(e) => {
log::warn!("Error opening config: {}", e);
return;
}
};
let socket_addr = match SocketAddr::from_str(cfg.host.as_str()) {
Ok(socket_addr) => socket_addr,
Err(e) => {
log::warn!("Error parsing {} as address: {}", cfg.host, e);
return;
}
};
let ctx = Context::new(cfg).unwrap();
let api = command_filter(ctx.clone());
warp::serve(api)
.run(SocketAddr::from_str(ctx.cfg.host.as_str()).unwrap())
.run(socket_addr)
.await;
}

View File

@ -12,6 +12,8 @@ serde = "1.0"
serde_json = "1.0"
geoffrey_models = { path = "../geoffrey_models" }
byteorder = "1.4.2"
log = "0.4.14"
simple_logger = "1.13.0"
[dev-dependencies]
lazy_static = "1.4.0"

View File

@ -37,6 +37,7 @@ impl Database {
let match_count = self.filter(|_, o: &T| !o.check_unique(&model))?.count();
if match_count > 0 {
log::debug!("{} is not unique: {:?}", T::tree(), model);
return Err(GeoffreyDBError::NotUnique);
}
@ -58,6 +59,7 @@ impl Database {
if let Some(bytes) = tree.get(id_bytes)? {
Ok(T::try_from_bytes(&bytes)?)
} else {
log::debug!("{} of id {} was not found in the database", T::tree(), id);
Err(GeoffreyDBError::NotFound)
}
}

View File

@ -1,12 +1,13 @@
#![allow(dead_code)]
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::fmt::Debug;
pub mod models;
const DB_VERSION: u64 = 1;
pub trait GeoffreyDatabaseModel: Serialize + DeserializeOwned {
pub trait GeoffreyDatabaseModel: Serialize + DeserializeOwned + Debug {
fn id(&self) -> Option<u64>;
fn set_id(&mut self, id: u64);
fn tree() -> String;