kanidm/server/core/src/https/trace.rs
James Hodgkinson 60e5935faa
Moving daemon tracing to OpenTelemetry ()
* sally forth into the great otel unknown
* make the build env identification slightly more durable
* docs updates
* wasm recompile
2023-11-09 05:15:12 +00:00

100 lines
2.7 KiB
Rust

//! Reimplementation of tower-http's DefaultMakeSpan that only runs at "INFO" level for our own needs.
use http::Request;
use kanidm_proto::constants::KOPID;
use sketching::event_dynamic_lvl;
use tower_http::LatencyUnit;
use tracing::{Level, Span};
/// The default way Spans will be created for Trace.
///
#[derive(Debug, Clone)]
pub struct DefaultMakeSpanKanidmd {}
impl DefaultMakeSpanKanidmd {
/// Create a new `DefaultMakeSpanKanidmd`.
pub fn new() -> Self {
Self {}
}
}
impl Default for DefaultMakeSpanKanidmd {
fn default() -> Self {
Self::new()
}
}
impl<B> tower_http::trace::MakeSpan<B> for DefaultMakeSpanKanidmd {
#[instrument(name = "handle_request", skip_all, fields(latency, status_code))]
fn make_span(&mut self, request: &Request<B>) -> Span {
tracing::span!(
Level::INFO,
"request",
method = %request.method(),
uri = %request.uri(),
version = ?request.version(),
)
}
}
#[derive(Clone, Debug)]
pub(crate) struct DefaultOnResponseKanidmd {
#[allow(dead_code)]
level: Level,
#[allow(dead_code)]
latency_unit: LatencyUnit,
#[allow(dead_code)]
include_headers: bool,
}
impl DefaultOnResponseKanidmd {
#[allow(dead_code)]
pub fn new() -> Self {
Self::default()
}
}
impl Default for DefaultOnResponseKanidmd {
fn default() -> Self {
Self {
level: Level::INFO,
latency_unit: LatencyUnit::Millis,
include_headers: false,
}
}
}
impl<B> tower_http::trace::OnResponse<B> for DefaultOnResponseKanidmd {
fn on_response(
self,
response: &axum::response::Response<B>,
latency: std::time::Duration,
_span: &Span,
) {
let kopid = match response.headers().get(KOPID) {
Some(val) => val.to_str().unwrap_or("<invalid kopid>"),
None => "<unknown>",
};
let (level, msg) =
match response.status().is_success() || response.status().is_informational() {
true => (Level::INFO, "response sent"),
false => {
if response.status().is_redirection() {
(Level::INFO, "client redirection sent")
} else if response.status().is_client_error() {
(Level::WARN, "client error") // it worked, but there was an input error
} else {
(Level::ERROR, "error handling request") // oh no the server failed
}
}
};
event_dynamic_lvl!(
level,
?latency,
status_code = response.status().as_u16(),
kopid = kopid,
msg
);
}
}