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