feat: add logging

This commit is contained in:
Sandro Eiler 2023-10-17 14:12:08 +02:00
parent 0f0f7f3961
commit ed4322b8e9
5 changed files with 254 additions and 6 deletions

180
Cargo.lock generated
View file

@ -26,6 +26,21 @@ dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anyhow"
version = "1.0.71"
@ -155,6 +170,19 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
dependencies = [
"android-tzdata",
"iana-time-zone",
"num-traits",
"serde",
"windows-targets",
]
[[package]]
name = "cookie"
version = "0.16.2"
@ -227,6 +255,41 @@ version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]]
name = "darling"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]]
name = "encoding_rs"
version = "0.8.32"
@ -236,6 +299,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.1"
@ -377,7 +446,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http",
"indexmap",
"indexmap 1.9.3",
"slab",
"tokio",
"tokio-util",
@ -390,6 +459,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
[[package]]
name = "heck"
version = "0.4.1"
@ -402,6 +477,12 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "http"
version = "0.2.9"
@ -495,6 +576,35 @@ dependencies = [
"tokio-native-tls",
]
[[package]]
name = "iana-time-zone"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.2.3"
@ -533,7 +643,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown",
"hashbrown 0.12.3",
"serde",
]
[[package]]
name = "indexmap"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
dependencies = [
"equivalent",
"hashbrown 0.14.1",
"serde",
]
[[package]]
@ -617,6 +739,7 @@ dependencies = [
"lazy-regex",
"serde",
"serde_json",
"serde_with",
"strum_macros",
"tokio",
"tower-cookies",
@ -724,6 +847,15 @@ dependencies = [
"tempfile",
]
[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.16.0"
@ -1142,6 +1274,35 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_with"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237"
dependencies = [
"base64",
"chrono",
"hex",
"indexmap 1.9.3",
"indexmap 2.0.2",
"serde",
"serde_json",
"serde_with_macros",
"time",
]
[[package]]
name = "serde_with_macros"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.1"
@ -1186,6 +1347,12 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "strum_macros"
version = "0.25.3"
@ -1619,6 +1786,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.42.0"

View file

@ -10,6 +10,7 @@ tokio = { version = "1.32.0", features = ["full"] }
# Serde / json
serde = { version = "1.0", features = ["derive"] }
serde_json = "1"
serde_with = "3"
# Axum
axum = { version = "0.6.20" }
tower-http = { version = "0.4.4", features = ["fs"] }

View file

@ -1,9 +1,11 @@
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use serde::Serialize;
pub type Result<T> = core::result::Result<T, Error>;
#[derive(Clone, Debug, strum_macros::AsRefStr)]
#[derive(Clone, Debug, Serialize, strum_macros::AsRefStr)]
#[serde(tag = "type", content = "data")]
pub enum Error {
LoginFail,

65
src/log.rs Normal file
View file

@ -0,0 +1,65 @@
use std::time::SystemTime;
use crate::{Error, Result};
use crate::ctx::Ctx;
use crate::error::ClientError;
use axum::http::{Method, Uri};
use serde::Serialize;
use serde_json::{json, Value};
use serde_with::skip_serializing_none;
use uuid::Uuid;
pub async fn log_request(
uuid: Uuid,
req_method: Method,
uri: Uri,
ctx: Option<Ctx>,
service_error: Option<&Error>,
client_error: Option<ClientError>,
) -> Result<()> {
let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis();
let error_type = service_error.map(|se| se.as_ref().to_string());
let error_data = serde_json::to_value(service_error).ok().and_then(|mut v| v.get_mut("data").map(|v| v.take()));
// Create the RequestLogLine.
let log_line = RequestLogLine {
uuid: uuid.to_string(),
timestamp: timestamp.to_string(),
req_path: uri.path().to_string(),
req_method: req_method.to_string(),
user_id: ctx.map(|ctx| ctx.user_id()),
client_error_type: client_error.map(|e| e.as_ref().to_string()),
error_type,
error_data,
};
println!(" ->> log request: \n{}", json!(log_line));
// TODO: Send to cloud-watch or something.
Ok(())
}
#[skip_serializing_none]
#[derive(Serialize)]
struct RequestLogLine {
uuid: String, // uuid string formatted
timestamp: String, // (should be iso8601)
// -- User and context attributes.
user_id: Option<u64>,
// -- http request attributes.
req_path: String,
req_method: String,
// -- Errors attributes.
client_error_type: Option<String>,
error_type: Option<String>,
error_data: Option<Value>,
}

View file

@ -3,6 +3,8 @@
use crate::model::ModelController;
pub use self::error::{Error, Result};
use self::ctx::Ctx;
use self::log::log_request;
use std::net::SocketAddr;
@ -20,6 +22,7 @@ use uuid::Uuid;
mod ctx;
mod error;
mod log;
mod web;
mod model;
@ -57,7 +60,7 @@ async fn main() -> Result<()>{
/// Map the response to add headers, etc.
///
/// * `res`: the response to map
async fn main_response_mapper(res: Response) -> Response {
async fn main_response_mapper(ctx: Option<Ctx>, uri: Uri, req_method: Method, res: Response) -> Response {
println!("->> {:<12} - main_response_mapper", "RES_MAPPER");
let uuid = Uuid::new_v4();
@ -82,8 +85,9 @@ async fn main_response_mapper(res: Response) -> Response {
(*status_code, Json(client_error_body)).into_response()
});
// -- TODO: Build and log the server log line.
println!(" ->> server log line - {uuid} - Error: {service_error:?}");
// -- Build and log the server log line.
let client_error = client_status_error.unzip().1;
log_request(uuid, req_method, uri, ctx, service_error, client_error).await;
println!();
error_response.unwrap_or(res)