opentelemetry_stdout/logs/
exporter.rs

1use chrono::{DateTime, Utc};
2use core::fmt;
3use opentelemetry_sdk::error::{OTelSdkError, OTelSdkResult};
4use opentelemetry_sdk::logs::LogBatch;
5use opentelemetry_sdk::Resource;
6use std::sync::atomic;
7use std::sync::atomic::Ordering;
8
9/// An OpenTelemetry exporter that writes Logs to stdout on export.
10pub struct LogExporter {
11    resource: Resource,
12    is_shutdown: atomic::AtomicBool,
13    resource_emitted: atomic::AtomicBool,
14}
15
16impl Default for LogExporter {
17    fn default() -> Self {
18        LogExporter {
19            resource: Resource::builder().build(),
20            is_shutdown: atomic::AtomicBool::new(false),
21            resource_emitted: atomic::AtomicBool::new(false),
22        }
23    }
24}
25
26impl fmt::Debug for LogExporter {
27    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28        f.write_str("LogExporter")
29    }
30}
31
32impl opentelemetry_sdk::logs::LogExporter for LogExporter {
33    /// Export logs to stdout
34    async fn export(&self, batch: LogBatch<'_>) -> OTelSdkResult {
35        if self.is_shutdown.load(atomic::Ordering::SeqCst) {
36            Err(OTelSdkError::AlreadyShutdown)
37        } else {
38            println!("Logs");
39            if self
40                .resource_emitted
41                .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
42                .is_err()
43            {
44                print_logs(batch);
45            } else {
46                println!("Resource");
47                if let Some(schema_url) = self.resource.schema_url() {
48                    println!("\t Resource SchemaUrl: {:?}", schema_url);
49                }
50                self.resource.iter().for_each(|(k, v)| {
51                    println!("\t ->  {}={:?}", k, v);
52                });
53                print_logs(batch);
54            }
55
56            Ok(())
57        }
58    }
59
60    fn shutdown(&self) -> OTelSdkResult {
61        self.is_shutdown.store(true, atomic::Ordering::SeqCst);
62        Ok(())
63    }
64
65    fn set_resource(&mut self, res: &opentelemetry_sdk::Resource) {
66        self.resource = res.clone();
67    }
68}
69
70fn print_logs(batch: LogBatch<'_>) {
71    for (i, log) in batch.iter().enumerate() {
72        println!("Log #{}", i);
73        let (record, library) = log;
74
75        println!("\t Instrumentation Scope: {:?}", library);
76
77        if let Some(event_name) = record.event_name() {
78            println!("\t EventName: {:?}", event_name);
79        }
80        if let Some(target) = record.target() {
81            println!("\t Target (Scope): {:?}", target);
82        }
83        if let Some(trace_context) = record.trace_context() {
84            println!("\t TraceId: {:?}", trace_context.trace_id);
85            println!("\t SpanId: {:?}", trace_context.span_id);
86            if let Some(trace_flags) = trace_context.trace_flags {
87                println!("\t TraceFlags: {:?}", trace_flags);
88            }
89        }
90        if let Some(timestamp) = record.timestamp() {
91            let datetime: DateTime<Utc> = timestamp.into();
92            println!("\t Timestamp: {}", datetime.format("%Y-%m-%d %H:%M:%S%.6f"));
93        }
94        if let Some(timestamp) = record.observed_timestamp() {
95            let datetime: DateTime<Utc> = timestamp.into();
96            println!(
97                "\t Observed Timestamp: {}",
98                datetime.format("%Y-%m-%d %H:%M:%S%.6f")
99            );
100        }
101        if let Some(severity) = record.severity_text() {
102            println!("\t SeverityText: {:?}", severity);
103        }
104        if let Some(severity) = record.severity_number() {
105            println!("\t SeverityNumber: {:?}", severity);
106        }
107        if let Some(body) = record.body() {
108            println!("\t Body: {:?}", body);
109        }
110
111        println!("\t Attributes:");
112        for (k, v) in record.attributes_iter() {
113            println!("\t\t ->  {}: {:?}", k, v);
114        }
115    }
116}