opentelemetry/logs/
record.rs

1use crate::{Array, Key, StringValue, Value};
2use std::{borrow::Cow, collections::HashMap, time::SystemTime};
3
4/// SDK implemented trait for managing log records
5pub trait LogRecord {
6    /// Sets the `event_name` of a record
7    fn set_event_name<T>(&mut self, _name: T)
8    where
9        T: Into<Cow<'static, str>>,
10    {
11    }
12
13    /// Sets the `target` of a record.
14    /// Currently, both `opentelemetry-appender-tracing` and `opentelemetry-appender-log` create a single logger
15    /// with a scope that doesn't accurately reflect the component emitting the logs.
16    /// Exporters MAY use this field to override the `instrumentation_scope.name`.
17    fn set_target<T>(&mut self, _target: T)
18    where
19        T: Into<Cow<'static, str>>;
20
21    /// Sets the time when the event occurred measured by the origin clock, i.e. the time at the source.
22    fn set_timestamp(&mut self, timestamp: SystemTime);
23
24    /// Sets the observed event timestamp.
25    fn set_observed_timestamp(&mut self, timestamp: SystemTime);
26
27    /// Sets severity as text.
28    fn set_severity_text(&mut self, text: Cow<'static, str>);
29
30    /// Sets severity as a numeric value.
31    fn set_severity_number(&mut self, number: Severity);
32
33    /// Sets the message body of the log.
34    fn set_body(&mut self, body: AnyValue);
35
36    /// Adds multiple attributes.
37    fn add_attributes<I, K, V>(&mut self, attributes: I)
38    where
39        I: IntoIterator<Item = (K, V)>,
40        K: Into<Key>,
41        V: Into<AnyValue>;
42
43    /// Adds a single attribute.
44    fn add_attribute<K, V>(&mut self, key: K, value: V)
45    where
46        K: Into<Key>,
47        V: Into<AnyValue>;
48}
49
50/// Value types for representing arbitrary values in a log record.
51#[derive(Debug, Clone, PartialEq)]
52pub enum AnyValue {
53    /// An integer value
54    Int(i64),
55    /// A double value
56    Double(f64),
57    /// A string value
58    String(StringValue),
59    /// A boolean value
60    Boolean(bool),
61    /// A byte array
62    Bytes(Vec<u8>),
63    /// An array of `Any` values
64    ListAny(Vec<AnyValue>),
65    /// A map of string keys to `Any` values, arbitrarily nested.
66    Map(HashMap<Key, AnyValue>),
67}
68
69macro_rules! impl_trivial_from {
70    ($t:ty, $variant:path) => {
71        impl From<$t> for AnyValue {
72            fn from(val: $t) -> AnyValue {
73                $variant(val.into())
74            }
75        }
76    };
77}
78
79impl_trivial_from!(i8, AnyValue::Int);
80impl_trivial_from!(i16, AnyValue::Int);
81impl_trivial_from!(i32, AnyValue::Int);
82impl_trivial_from!(i64, AnyValue::Int);
83
84impl_trivial_from!(u8, AnyValue::Int);
85impl_trivial_from!(u16, AnyValue::Int);
86impl_trivial_from!(u32, AnyValue::Int);
87
88impl_trivial_from!(f64, AnyValue::Double);
89impl_trivial_from!(f32, AnyValue::Double);
90
91impl_trivial_from!(String, AnyValue::String);
92impl_trivial_from!(Cow<'static, str>, AnyValue::String);
93impl_trivial_from!(&'static str, AnyValue::String);
94impl_trivial_from!(StringValue, AnyValue::String);
95
96impl_trivial_from!(bool, AnyValue::Boolean);
97
98impl<T: Into<AnyValue>> FromIterator<T> for AnyValue {
99    /// Creates an [`AnyValue::ListAny`] value from a sequence of `Into<AnyValue>` values.
100    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
101        AnyValue::ListAny(iter.into_iter().map(Into::into).collect())
102    }
103}
104
105impl<K: Into<Key>, V: Into<AnyValue>> FromIterator<(K, V)> for AnyValue {
106    /// Creates an [`AnyValue::Map`] value from a sequence of key-value pairs
107    /// that can be converted into a `Key` and `AnyValue` respectively.
108    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
109        AnyValue::Map(HashMap::from_iter(
110            iter.into_iter().map(|(k, v)| (k.into(), v.into())),
111        ))
112    }
113}
114
115impl From<Value> for AnyValue {
116    fn from(value: Value) -> Self {
117        match value {
118            Value::Bool(b) => b.into(),
119            Value::I64(i) => i.into(),
120            Value::F64(f) => f.into(),
121            Value::String(s) => s.into(),
122            Value::Array(a) => match a {
123                Array::Bool(b) => AnyValue::from_iter(b),
124                Array::F64(f) => AnyValue::from_iter(f),
125                Array::I64(i) => AnyValue::from_iter(i),
126                Array::String(s) => AnyValue::from_iter(s),
127            },
128        }
129    }
130}
131
132/// A normalized severity value.
133#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd)]
134pub enum Severity {
135    /// TRACE
136    Trace = 1,
137    /// TRACE2
138    Trace2 = 2,
139    /// TRACE3
140    Trace3 = 3,
141    /// TRACE4
142    Trace4 = 4,
143    /// DEBUG
144    Debug = 5,
145    /// DEBUG2
146    Debug2 = 6,
147    /// DEBUG3
148    Debug3 = 7,
149    /// DEBUG4
150    Debug4 = 8,
151    /// INFO
152    Info = 9,
153    /// INFO2
154    Info2 = 10,
155    /// INFO3
156    Info3 = 11,
157    /// INFO4
158    Info4 = 12,
159    /// WARN
160    Warn = 13,
161    /// WARN2
162    Warn2 = 14,
163    /// WARN3
164    Warn3 = 15,
165    /// WARN4
166    Warn4 = 16,
167    /// ERROR
168    Error = 17,
169    /// ERROR2
170    Error2 = 18,
171    /// ERROR3
172    Error3 = 19,
173    /// ERROR4
174    Error4 = 20,
175    /// FATAL
176    Fatal = 21,
177    /// FATAL2
178    Fatal2 = 22,
179    /// FATAL3
180    Fatal3 = 23,
181    /// FATAL4
182    Fatal4 = 24,
183}
184
185impl Severity {
186    /// Return the string representing the short name for the `Severity`
187    /// value as specified by the OpenTelemetry logs data model.
188    pub const fn name(&self) -> &'static str {
189        match &self {
190            Severity::Trace => "TRACE",
191            Severity::Trace2 => "TRACE2",
192            Severity::Trace3 => "TRACE3",
193            Severity::Trace4 => "TRACE4",
194
195            Severity::Debug => "DEBUG",
196            Severity::Debug2 => "DEBUG2",
197            Severity::Debug3 => "DEBUG3",
198            Severity::Debug4 => "DEBUG4",
199
200            Severity::Info => "INFO",
201            Severity::Info2 => "INFO2",
202            Severity::Info3 => "INFO3",
203            Severity::Info4 => "INFO4",
204
205            Severity::Warn => "WARN",
206            Severity::Warn2 => "WARN2",
207            Severity::Warn3 => "WARN3",
208            Severity::Warn4 => "WARN4",
209
210            Severity::Error => "ERROR",
211            Severity::Error2 => "ERROR2",
212            Severity::Error3 => "ERROR3",
213            Severity::Error4 => "ERROR4",
214
215            Severity::Fatal => "FATAL",
216            Severity::Fatal2 => "FATAL2",
217            Severity::Fatal3 => "FATAL3",
218            Severity::Fatal4 => "FATAL4",
219        }
220    }
221}