1use ::tracing::{
2 field::{Field, Visit},
3 span,
4};
5use serde::{Deserialize, Serialize};
6
7use crate::attribute::OwnedMetadata;
8
9type FieldName = String;
10
11#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
12#[serde(untagged)]
13pub enum RecordValue {
14 Error(String),
15 Value(serde_json::Value),
16 Debug(String),
17}
18
19#[derive(Default, Clone, Debug)]
20pub(crate) struct RecordEverything(Vec<Record>);
21
22impl RecordEverything {
23 pub fn contents(&self) -> impl Iterator<Item = &Record> {
24 self.0.iter()
25 }
26}
27
28impl Visit for RecordEverything {
29 fn record_f64(&mut self, field: &Field, value: f64) {
31 self.0
32 .push((field.name().to_string(), RecordValue::Value(value.into())));
33 }
34
35 fn record_i64(&mut self, field: &Field, value: i64) {
37 self.0
38 .push((field.name().to_string(), RecordValue::Value(value.into())));
39 }
40
41 fn record_u64(&mut self, field: &Field, value: u64) {
43 self.0
44 .push((field.name().to_string(), RecordValue::Value(value.into())));
45 }
46
47 fn record_bool(&mut self, field: &Field, value: bool) {
49 self.0
50 .push((field.name().to_string(), RecordValue::Value(value.into())));
51 }
52
53 fn record_str(&mut self, field: &Field, value: &str) {
55 self.0
56 .push((field.name().to_string(), RecordValue::Value(value.into())));
57 }
58
59 #[cfg(feature = "std")]
67 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
68 fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) {
69 self.0.push((
70 field.name().to_string(),
71 RecordValue::Error(&format_args!("{}", value).into()),
72 ));
73 }
74
75 fn record_debug(&mut self, field: &Field, value: &dyn std::fmt::Debug) {
76 self.0.push((
77 field.name().to_string(),
78 RecordValue::Debug(format!("{:?}", value)),
79 ));
80 }
81}
82
83pub type Record = (FieldName, RecordValue);
84
85#[derive(Clone, Debug, Default)]
86pub struct Recorder {
87 metadata: Option<OwnedMetadata>,
88 visitor: RecordEverything,
89}
90
91impl Recorder {
92 pub fn attributes(&mut self, span_id: tracing::Id, attributes: &span::Attributes<'_>) {
93 let mut owned_metadata: OwnedMetadata = attributes.metadata().into();
94 owned_metadata.span_id = Some(span_id.into_u64());
95 self.metadata = Some(owned_metadata);
96 attributes.record(&mut self.visitor)
97 }
98
99 pub fn metadata(&self) -> Option<&OwnedMetadata> {
100 self.metadata.as_ref()
101 }
102
103 pub fn record(&mut self, record: &span::Record<'_>) {
104 record.record(&mut self.visitor)
105 }
106
107 pub fn contents(&self, filter: &crate::Filter) -> RecordWithMetadata {
108 let mut r = RecordWithMetadata::new(self.metadata.clone().unwrap());
109
110 if filter.is_enabled(&r.metadata) {
111 r.append(self.visitor.0.clone());
112 }
113 r
114 }
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
118pub struct RecordWithMetadata {
119 entries: Vec<Record>,
120 metadata: OwnedMetadata,
121}
122
123impl RecordWithMetadata {
124 pub fn new(metadata: OwnedMetadata) -> Self {
125 Self {
126 entries: Default::default(),
127 metadata,
128 }
129 }
130
131 pub fn metadata(&self) -> OwnedMetadata {
132 self.metadata.clone()
133 }
134
135 pub fn for_root() -> Self {
136 Self {
137 entries: Vec::new(),
138 metadata: OwnedMetadata {
139 name: "root".to_string(),
140 ..Default::default()
141 },
142 }
143 }
144
145 pub fn entries(&self) -> impl Iterator<Item = &Record> {
146 self.entries.iter()
147 }
148
149 pub fn push(&mut self, entry: Record) {
150 self.entries.push(entry)
151 }
152
153 pub fn append(&mut self, mut entries: Vec<Record>) {
154 self.entries.append(&mut entries)
155 }
156}