tracing_ecs/
attribute_mapper.rs

1use std::{borrow::Cow, collections::HashMap, ops::Deref};
2
3/// This span_name is used when calling the current `AttributeMapper` while
4/// processing event attributes.
5pub const EVENT_SPAN_NAME: &str = "__EVENT__";
6
7/// Map span attributes name to ECS field name
8///
9/// # Trait implementations
10///
11/// This trait is implemented on `HashMap<String, String>` and `HashMap<&'static str, &'static str>`
12/// to allow a direct mapping from a map.
13///
14/// Example
15///
16/// ```rust
17/// use tracing_ecs::ECSLayerBuilder;
18/// use maplit::hashmap;
19///
20/// ECSLayerBuilder::default()
21///     .with_attribute_mapper(hashmap!(
22///         "txid" => "transaction.id",
23///         "request_ip" => "source.ip",
24///     )).stdout().install().unwrap();
25/// ```
26///
27/// It is also implemented on `HashMap<String, HashMap<String, String>>` and
28/// `HashMap<&'static str, HashMap<&'static str, &'static str>>`. In this case, the first map level
29/// maps span names and the second attribute names.
30///
31/// Example
32///
33/// ```rust
34/// use tracing_ecs::ECSLayerBuilder;
35/// use maplit::hashmap;
36///
37/// ECSLayerBuilder::default()
38///     .with_attribute_mapper(hashmap!(
39///         "request" => hashmap!(
40///             "method" => "http.request.method",
41///             "request_ip" => "source.ip",
42///         ),
43///         "cron" => hashmap!(
44///             "request_ip" => "cron.source.ip",
45///         ),
46///     )).stdout().install().unwrap();
47/// ```
48///
49///
50pub trait AttributeMapper: Send + Sync + 'static {
51    /// Given a span name and the name of an attribute,
52    /// return the mapped attribute name
53    fn map(&self, span_name: &str, name: Cow<'static, str>) -> Cow<'static, str>;
54}
55
56impl<F> AttributeMapper for F
57where
58    F: for<'a> Fn(&'a str, Cow<'static, str>) -> Cow<'static, str> + Send + Sync + 'static,
59{
60    fn map(&self, span_name: &str, name: Cow<'static, str>) -> Cow<'static, str> {
61        self(span_name, name)
62    }
63}
64
65impl AttributeMapper for HashMap<String, String> {
66    fn map(&self, _span_name: &str, name: Cow<'static, str>) -> Cow<'static, str> {
67        self.get(name.deref())
68            .cloned()
69            .map(Cow::from)
70            .unwrap_or(name)
71    }
72}
73
74impl AttributeMapper for HashMap<&'static str, &'static str> {
75    fn map(&self, _span_name: &str, name: Cow<'static, str>) -> Cow<'static, str> {
76        self.get(name.deref())
77            .copied()
78            .map(Cow::from)
79            .unwrap_or(name)
80    }
81}
82
83impl AttributeMapper for HashMap<String, HashMap<String, String>> {
84    fn map(&self, span_name: &str, name: Cow<'static, str>) -> Cow<'static, str> {
85        self.get(span_name)
86            .and_then(|span_map| span_map.get(name.deref()).cloned().map(Cow::from))
87            .unwrap_or(name)
88    }
89}
90
91impl AttributeMapper for HashMap<&'static str, HashMap<&'static str, &'static str>> {
92    fn map(&self, span_name: &str, name: Cow<'static, str>) -> Cow<'static, str> {
93        self.get(span_name)
94            .and_then(|span_map| span_map.get(name.deref()).copied().map(Cow::from))
95            .unwrap_or(name)
96    }
97}