Skip to main content

rs_zero/core/logging/
fields.rs

1/// Stable low-cardinality fields that can be attached to request logs.
2#[derive(Debug, Clone, PartialEq, Eq)]
3pub struct LogFields {
4    service: String,
5    transport: Option<String>,
6    route: Option<String>,
7    method: Option<String>,
8    request_id: Option<String>,
9    trace_id: Option<String>,
10    span_id: Option<String>,
11    status: Option<String>,
12}
13
14impl LogFields {
15    /// Creates fields for a logical service.
16    pub fn new(service: impl Into<String>) -> Self {
17        Self {
18            service: service.into(),
19            transport: None,
20            route: None,
21            method: None,
22            request_id: None,
23            trace_id: None,
24            span_id: None,
25            status: None,
26        }
27    }
28
29    /// Sets the transport label.
30    pub fn with_transport(mut self, value: impl Into<String>) -> Self {
31        self.transport = Some(value.into());
32        self
33    }
34
35    /// Sets the route or RPC method pattern.
36    pub fn with_route(mut self, value: impl Into<String>) -> Self {
37        self.route = Some(value.into());
38        self
39    }
40
41    /// Sets the operation method.
42    pub fn with_method(mut self, value: impl Into<String>) -> Self {
43        self.method = Some(value.into());
44        self
45    }
46
47    /// Sets the request id.
48    pub fn with_request_id(mut self, value: impl Into<String>) -> Self {
49        self.request_id = Some(value.into());
50        self
51    }
52
53    /// Sets the trace id.
54    pub fn with_trace_id(mut self, value: impl Into<String>) -> Self {
55        self.trace_id = Some(value.into());
56        self
57    }
58
59    /// Sets the span id.
60    pub fn with_span_id(mut self, value: impl Into<String>) -> Self {
61        self.span_id = Some(value.into());
62        self
63    }
64
65    /// Sets the status or code label.
66    pub fn with_status(mut self, value: impl Into<String>) -> Self {
67        self.status = Some(value.into());
68        self
69    }
70
71    /// Returns all populated fields as key/value pairs.
72    pub fn as_pairs(&self) -> Vec<(String, String)> {
73        let mut pairs = vec![("service".to_string(), self.service.clone())];
74        push_optional(&mut pairs, "transport", &self.transport);
75        push_optional(&mut pairs, "route", &self.route);
76        push_optional(&mut pairs, "method", &self.method);
77        push_optional(&mut pairs, "request_id", &self.request_id);
78        push_optional(&mut pairs, "trace_id", &self.trace_id);
79        push_optional(&mut pairs, "span_id", &self.span_id);
80        push_optional(&mut pairs, "status", &self.status);
81        pairs
82    }
83}
84
85fn push_optional(pairs: &mut Vec<(String, String)>, key: &str, value: &Option<String>) {
86    if let Some(value) = value
87        && !value.is_empty()
88    {
89        pairs.push((key.to_string(), value.clone()));
90    }
91}