context_logger/context.rs
1//! Context builder for structured logging.
2
3use std::borrow::Cow;
4
5use crate::{LogValue, records::LogRecords};
6
7/// A set of records that can be attached to a logging scope.
8///
9/// Records are split into two categories:
10///
11/// - **local** - records belonging only to the current scope.
12/// They do not propagate to child scopes.
13/// - **inherited** - records that automatically flow into all child scopes created within the current scope.
14///
15/// Nested scopes resolution rules:
16///
17/// - child `inherited` overwrites parent `inherited` by key
18/// - inherited are emitted before local, so "last write wins" consumers see local shadowing
19#[derive(Debug, Default, Clone)]
20pub struct LogContext {
21 /// Records belonging only to the current scope.
22 pub local: LogRecords,
23 /// Records that automatically flow into all child scopes created within the current scope.
24 pub inherited: LogRecords,
25}
26
27impl LogContext {
28 /// Creates a new, empty context.
29 #[must_use]
30 pub fn new() -> Self {
31 Self::default()
32 }
33
34 /// Adds a key-value record to the local records of this context.
35 ///
36 /// See [`LogRecords`] for more details about log records.
37 #[must_use]
38 pub fn with_local_record(
39 mut self,
40 key: impl Into<Cow<'static, str>>,
41 value: impl Into<LogValue>,
42 ) -> Self {
43 self.local = self.local.field(key, value);
44 self
45 }
46
47 /// Adds a key-value record to the inherited records of this context.
48 ///
49 /// See [`LogRecords`] for more details about log records.
50 #[must_use]
51 pub fn with_inherited_record(
52 mut self,
53 key: impl Into<Cow<'static, str>>,
54 value: impl Into<LogValue>,
55 ) -> Self {
56 self.inherited = self.inherited.field(key, value);
57 self
58 }
59
60 /// Returns `true` if both local and inherited records are empty.
61 #[must_use]
62 pub fn is_empty(&self) -> bool {
63 self.local.is_empty() && self.inherited.is_empty()
64 }
65}