opentelemetry_sdk/logs/export.rs
1//! Log exporters
2use crate::error::OTelSdkResult;
3use crate::logs::SdkLogRecord;
4use crate::Resource;
5use opentelemetry::logs::Severity;
6use opentelemetry::InstrumentationScope;
7use std::fmt::Debug;
8use std::time;
9
10/// A batch of log records to be exported by a `LogExporter`.
11///
12/// The `LogBatch` struct holds a collection of log records along with their associated
13/// instrumentation scopes. This structure is used to group log records together for efficient
14/// export operations.
15///
16/// # Type Parameters
17/// - `'a`: The lifetime of the references to the log records and instrumentation scopes.
18///
19#[derive(Debug)]
20pub struct LogBatch<'a> {
21 data: LogBatchData<'a>,
22}
23
24/// The `LogBatchData` enum represents the data field of a `LogBatch`.
25/// It can either be:
26/// - A shared reference to a slice of boxed tuples, where each tuple consists of an owned `LogRecord` and an owned `InstrumentationScope`.
27/// - Or it can be a shared reference to a slice of tuples, where each tuple consists of a reference to a `LogRecord` and a reference to an `InstrumentationScope`.
28#[derive(Debug)]
29enum LogBatchData<'a> {
30 SliceOfOwnedData(&'a [Box<(SdkLogRecord, InstrumentationScope)>]), // Used by BatchProcessor which clones the LogRecords for its own use.
31 SliceOfBorrowedData(&'a [(&'a SdkLogRecord, &'a InstrumentationScope)]),
32}
33
34impl<'a> LogBatch<'a> {
35 /// Creates a new instance of `LogBatch`.
36 ///
37 /// # Arguments
38 ///
39 /// * `data` - A slice of tuples, where each tuple consists of a reference to a `LogRecord`
40 /// and a reference to an `InstrumentationScope`. These tuples represent the log records
41 /// and their associated instrumentation scopes to be exported.
42 ///
43 /// # Returns
44 ///
45 /// A `LogBatch` instance containing the provided log records and instrumentation scopes.
46 ///
47 /// Note - this is not a public function, and should not be used directly. This would be
48 /// made private in the future.
49 pub fn new(data: &'a [(&'a SdkLogRecord, &'a InstrumentationScope)]) -> LogBatch<'a> {
50 LogBatch {
51 data: LogBatchData::SliceOfBorrowedData(data),
52 }
53 }
54
55 pub(crate) fn new_with_owned_data(
56 data: &'a [Box<(SdkLogRecord, InstrumentationScope)>],
57 ) -> LogBatch<'a> {
58 LogBatch {
59 data: LogBatchData::SliceOfOwnedData(data),
60 }
61 }
62}
63
64impl LogBatch<'_> {
65 /// Returns the number of log records in the batch.
66 #[cfg(test)]
67 pub(crate) fn len(&self) -> usize {
68 match &self.data {
69 LogBatchData::SliceOfOwnedData(data) => data.len(),
70 LogBatchData::SliceOfBorrowedData(data) => data.len(),
71 }
72 }
73
74 /// Returns an iterator over the log records and instrumentation scopes in the batch.
75 ///
76 /// Each item yielded by the iterator is a tuple containing references to a `LogRecord`
77 /// and an `InstrumentationScope`.
78 ///
79 /// # Returns
80 ///
81 /// An iterator that yields references to the `LogRecord` and `InstrumentationScope` in the batch.
82 ///
83 pub fn iter(&self) -> impl Iterator<Item = (&SdkLogRecord, &InstrumentationScope)> {
84 LogBatchDataIter {
85 data: &self.data,
86 index: 0,
87 }
88 }
89}
90
91struct LogBatchDataIter<'a> {
92 data: &'a LogBatchData<'a>,
93 index: usize,
94}
95
96impl<'a> Iterator for LogBatchDataIter<'a> {
97 type Item = (&'a SdkLogRecord, &'a InstrumentationScope);
98
99 fn next(&mut self) -> Option<Self::Item> {
100 match self.data {
101 LogBatchData::SliceOfOwnedData(data) => {
102 if self.index < data.len() {
103 let record = &*data[self.index];
104 self.index += 1;
105 Some((&record.0, &record.1))
106 } else {
107 None
108 }
109 }
110 LogBatchData::SliceOfBorrowedData(data) => {
111 if self.index < data.len() {
112 let record = &data[self.index];
113 self.index += 1;
114 Some((record.0, record.1))
115 } else {
116 None
117 }
118 }
119 }
120 }
121}
122
123/// `LogExporter` defines the interface that log exporters should implement.
124pub trait LogExporter: Send + Sync + Debug {
125 /// Exports a batch of log records and their associated instrumentation scopes.
126 ///
127 /// The `export` method is responsible for sending a batch of log records to an external
128 /// destination. It takes a `LogBatch` as an argument, which contains references to the
129 /// log records and their corresponding instrumentation scopes. The method returns
130 /// a `LogResult` indicating the success or failure of the export operation.
131 ///
132 /// # Arguments
133 ///
134 /// * `batch` - A `LogBatch` containing the log records and instrumentation scopes
135 /// to be exported.
136 ///
137 /// # Returns
138 ///
139 /// A `LogResult<()>`, which is a result type indicating either a successful export (with
140 /// `Ok(())`) or an error (`Err(LogError)`) if the export operation failed.
141 ///
142 fn export(
143 &self,
144 batch: LogBatch<'_>,
145 ) -> impl std::future::Future<Output = OTelSdkResult> + Send;
146 /// Shuts down the exporter.
147 fn shutdown_with_timeout(&self, _timeout: time::Duration) -> OTelSdkResult {
148 Ok(())
149 }
150 /// Shuts down the exporter with a default timeout.
151 fn shutdown(&self) -> OTelSdkResult {
152 self.shutdown_with_timeout(time::Duration::from_secs(5))
153 }
154
155 /// Check if logs are enabled.
156 fn event_enabled(&self, _level: Severity, _target: &str, _name: Option<&str>) -> bool {
157 // By default, all logs are enabled
158 true
159 }
160 /// Set the resource for the exporter.
161 fn set_resource(&mut self, _resource: &Resource) {}
162}