use actix_web::body::MessageBody;
use actix_web::dev::{ServiceRequest, ServiceResponse};
use tracing::Span;
use tracing_actix_web::{DefaultRootSpanBuilder, RootSpanBuilder, TracingLogger};
use crate::correlation::{DEFAULT_HEADER_CHAIN, extract_from_headers};
pub struct EnrichedRootSpanBuilder;
impl RootSpanBuilder for EnrichedRootSpanBuilder {
fn on_request_start(request: &ServiceRequest) -> Span {
let correlation_id = extract_from_headers(request.headers(), DEFAULT_HEADER_CHAIN, |h, n| {
h.get(n).and_then(|v| v.to_str().ok()).map(str::to_owned)
});
let span = tracing_actix_web::root_span!(request, correlation_id = tracing::field::Empty);
if let Some(id) = correlation_id {
span.record("correlation_id", tracing::field::display(&id));
}
span
}
fn on_request_end<B: MessageBody>(span: Span, outcome: &Result<ServiceResponse<B>, actix_web::Error>) {
DefaultRootSpanBuilder::on_request_end(span, outcome);
}
}
#[must_use]
pub fn get_actix_web_logger() -> TracingLogger<EnrichedRootSpanBuilder> {
TracingLogger::<EnrichedRootSpanBuilder>::new()
}
#[must_use]
pub fn get_actix_web_logger_with<RSB: RootSpanBuilder>() -> TracingLogger<RSB> {
TracingLogger::<RSB>::new()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn constructors_build_middleware() {
let _enriched = get_actix_web_logger();
let _default = get_actix_web_logger_with::<DefaultRootSpanBuilder>();
let _explicit = get_actix_web_logger_with::<EnrichedRootSpanBuilder>();
}
}