From bc8b90c6ff71a35452615b05876b7ad861f8f8f7 Mon Sep 17 00:00:00 2001 From: danielsanchezq Date: Tue, 28 Jul 2020 16:23:24 +0200 Subject: [PATCH] Include metadata into LogMessage. Added default log metadata, message and builder. --- Cargo.lock | 1 + logging-lib/src/messages.rs | 57 +++++++++++++++++++------ logging-lib/src/methods.rs | 6 ++- vit-servicing-station-lib/Cargo.toml | 1 + vit-servicing-station-lib/src/v0/mod.rs | 12 ++++++ 5 files changed, 63 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3e44f647..82d7c8f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3249,6 +3249,7 @@ dependencies = [ "itertools", "libsqlite3-sys", "log 0.4.11", + "logging-lib", "serde", "serde_json", "simplelog", diff --git a/logging-lib/src/messages.rs b/logging-lib/src/messages.rs index 21ead8c8..41ec4bc9 100644 --- a/logging-lib/src/messages.rs +++ b/logging-lib/src/messages.rs @@ -1,26 +1,34 @@ -use serde::{Deserialize, Serialize}; +use serde::Serialize; +use std::collections::HashMap; -#[derive(Serialize, Deserialize)] +pub type DefaultMetadata = HashMap; +pub type DefaultLogMessage = LogMessage; +pub type DefaultLogMessageBuilder = LogMessageBuilder; + +#[derive(Serialize)] pub enum LogMessageId { None, Other(String), } -#[derive(Serialize, Deserialize)] -pub struct LogMessage { +#[derive(Serialize)] +pub struct LogMessage { id: LogMessageId, level: log::Level, #[serde(skip_serializing_if = "Vec::is_empty")] tags: Vec, message: String, timestamp: i64, + #[serde(skip_serializing_if = "Option::is_none")] + metadata: Option, } -pub struct LogMessageBuilder { +pub struct LogMessageBuilder { id: LogMessageId, level: log::Level, tags: Vec, message: Option, + metadata: Option, } impl std::fmt::Display for LogMessageId { @@ -29,13 +37,14 @@ impl std::fmt::Display for LogMessageId { } } -impl LogMessageBuilder { +impl LogMessageBuilder { pub fn new() -> Self { Self { id: LogMessageId::None, level: log::Level::max(), tags: vec![], message: None, + metadata: None, } } @@ -45,6 +54,7 @@ impl LogMessageBuilder { level: self.level, tags: self.tags, message: self.message, + metadata: self.metadata, } } @@ -54,15 +64,17 @@ impl LogMessageBuilder { level, tags: self.tags, message: self.message, + metadata: self.metadata, } } - pub fn with_tags(self, tags: Vec) -> Self { + pub fn with_tags(self, tags: Vec<&str>) -> Self { Self { id: self.id, level: self.level, - tags, + tags: tags.iter().map(|s| s.to_string()).collect(), message: self.message, + metadata: self.metadata, } } @@ -72,34 +84,53 @@ impl LogMessageBuilder { level: self.level, tags: self.tags, message: Some(message), + metadata: self.metadata, + } + } + + pub fn with_metadata(self, metadata: Metadata) -> Self { + Self { + id: self.id, + level: self.level, + tags: self.tags, + message: self.message, + metadata: Some(metadata), } } - pub fn build(self) -> LogMessage { + pub fn build(self) -> LogMessage { LogMessage { id: self.id, level: self.level, tags: self.tags, message: self.message.unwrap_or_default(), timestamp: chrono::Utc::now().timestamp(), + metadata: self.metadata, } } } -impl Default for LogMessageBuilder { +impl Default for LogMessageBuilder { fn default() -> Self { Self::new() } } -impl LogMessage { - pub fn new(id: LogMessageId, level: log::Level, message: String, tags: Vec) -> Self { +impl LogMessage { + pub fn new( + id: LogMessageId, + level: log::Level, + message: String, + tags: Vec, + metadata: Metadata, + ) -> Self { Self { id, level, tags, message, timestamp: chrono::Utc::now().timestamp(), + metadata: Some(metadata), } } @@ -108,7 +139,7 @@ impl LogMessage { } } -impl std::fmt::Display for LogMessage { +impl std::fmt::Display for LogMessage { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", serde_json::to_string(self).unwrap()) } diff --git a/logging-lib/src/methods.rs b/logging-lib/src/methods.rs index 8ca3839a..ef047304 100644 --- a/logging-lib/src/methods.rs +++ b/logging-lib/src/methods.rs @@ -3,7 +3,11 @@ macro_rules! log { ($lvl:expr, $($arg:tt)+) => ( let formatted_message = format_args!($($arg)+).to_string(); let level = $lvl; - $crate::messages::LogMessageBuilder::default().with_level(level).with_message(formatted_message).build().log(); + $crate::messages::DefaultLogMessageBuilder::default() + .with_level(level) + .with_message(formatted_message) + .build() + .log(); ) } diff --git a/vit-servicing-station-lib/Cargo.toml b/vit-servicing-station-lib/Cargo.toml index 2cfb76b3..12c1c6f6 100644 --- a/vit-servicing-station-lib/Cargo.toml +++ b/vit-servicing-station-lib/Cargo.toml @@ -17,6 +17,7 @@ diesel = { version = "1.4.4", features = ["sqlite", "r2d2"] } dotenv = "0.9.0" itertools = "0.9.0" log = { version = "0.4.11", features = ["serde"] } +logging-lib = { path = "../logging-lib" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.53" simplelog = "0.8.0" diff --git a/vit-servicing-station-lib/src/v0/mod.rs b/vit-servicing-station-lib/src/v0/mod.rs index 476c8960..8dabc7af 100644 --- a/vit-servicing-station-lib/src/v0/mod.rs +++ b/vit-servicing-station-lib/src/v0/mod.rs @@ -4,6 +4,7 @@ pub mod endpoints; pub mod errors; pub mod result; +use logging_lib::messages::LogMessageId; use warp::{Filter, Rejection, Reply}; pub async fn filter( @@ -11,7 +12,18 @@ pub async fn filter( ) -> impl Filter + Clone { let root = warp::path!("api" / "v0" / ..); + let log = warp::log::custom(|info| { + logging_lib::messages::DefaultLogMessageBuilder::new() + .with_level(log::Level::Info) + .with_tags(vec!["request", "elapsed"]) + .with_message(format!("{}ns", info.elapsed().as_nanos())) + .with_id(LogMessageId::Other("request_average".into())) + .build() + .log(); + }); + endpoints::filter(root.boxed(), ctx) .await .recover(errors::handle_rejection) + .with(log) }