1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! # tracing-actix-web-mozlog
//!
//! Support for [tracing] in [actix-web](https://actix.rs/) apps that target [MozLog][].
//!
//! [MozLog]: https://wiki.mozilla.org/Firefox/Services/Logging
//!
//! This crate provides a Tracing subscriber as well as an Actix web middleware.
//! Both can be used independently, but using them together implements the full
//! recommended format for MozLog.
//!
//! ## Subscriber
//!
//! To use the subscriber, register it and a [`JsonStorageLayer`] with a
//! [`tracing_subscriber::Registry`]:
//!
//! ```
//! use tracing_actix_web_mozlog::{JsonStorageLayer, MozLogFormatLayer};
//! use tracing_subscriber::layer::SubscriberExt;
//!
//! let subscriber = tracing_subscriber::registry()
//!     .with(JsonStorageLayer)
//!     .with(MozLogFormatLayer::new("service-name", std::io::stdout));
//! ```
//!
//! This subscriber can then be registered with tracing using
//! [`tracing::subscriber::set_global_default`], or any other registration
//! method. It will manage formatting any events logged in MozLog JSON format.
//!
//! Fields defined on the enclosing spans of an event will be included when
//! logging an event. The event overrides the spans, and inner spans override
//! outer spans.
//!
//! ## Middleware
//!
//! To make sure that the correct Tracing context is captured, it is important to
//! create the MozLog middleware outside of the `HttpServer::new` closure:
//!
//! ```
//! use tracing_actix_web_mozlog::MozLog;
//! use actix_web::{HttpServer, App};
//!
//! let moz_log = MozLog::default();
//!
//! let server = HttpServer::new(move || {
//!     App::new()
//!         .wrap(moz_log.clone())
//! });
//! ```
//!
//! This middleware will emit `request.summary` events for each request as it is
//! completed, including timing information.
//!
//! ## Message Types
//!
//! MozLog expects all messages to have a type that defines the schema of their
//! fields. This can be specified with the `type` field while logging events.
//! Since `type` is a Rust reserved keyword, this can also be specified using a
//! raw-string-inspired format: `r#type = value`.
//!
//! ```rust
//! let format_error = "...";
//! tracing::warn!(
//!     r#type = "auth.login.invalid-email",
//!     %format_error,
//!     "A user attempted to register using an email in an invalid format"
//! );
//! ```
//!
//! Messages that don't include a `type` field will be assigned a type of
//! `<unknown>`. If a message contains both a `type` field and a `r#type` field,
//! the `type` field will take precedence.
//!
//! Notably, use of the standard `log` facade's macros will have an unknown type,
//! as well as most other logging that originates from libraries.
//!
//! ## MozLog extensions
//!
//! In addition to all standard MozLog fields, this crate always adds a `spans`
//! field to messages. This contains a comma-separated list of the names of the
//! spans enclosing the event, with the outermost span coming first. Top-level
//! events will have an empty string for this value.

#![warn(missing_crate_level_docs)]
#![warn(missing_docs)]

mod middleware;
mod subscriber;

pub use crate::middleware::MozLog;
pub use crate::subscriber::{MozLogFormatLayer, MozLogMessage};

/// A layer to collect information about Tracing spans and provide it to other layers.
///
/// This is a re-exported entry from [`tracing_bunyan_formatter`].
pub use tracing_bunyan_formatter::JsonStorageLayer;