#![doc = include_str!("../README.md")]
mod event;
#[expect(
dead_code,
reason = "consumed by the pipeline (`Telemetry`, `Exporter`), not in place yet"
)]
mod store;
#[expect(
dead_code,
reason = "consumed by the pipeline (`Telemetry`, `Exporter`), not in place yet"
)]
mod stats;
#[cfg_attr(
not(test),
expect(
dead_code,
reason = "consumed by the pipeline (`Telemetry`, `Exporter`), not in place yet"
)
)]
mod device;
#[cfg_attr(
not(test),
expect(
dead_code,
reason = "consumed by the pipeline (`Telemetry`, `Exporter`), not in place yet"
)
)]
mod rtc;
#[expect(
dead_code,
reason = "consumed by the pipeline (`Telemetry`, `Exporter`), not in place yet"
)]
mod scope;
#[expect(
dead_code,
reason = "consumed by the pipeline (`Telemetry`, `Exporter`), not in place yet"
)]
mod span;
#[expect(
dead_code,
reason = "consumed by the pipeline (`Telemetry`, `Exporter`), not in place yet"
)]
mod otlp;
mod cache;
mod proto;
#[cfg_attr(
not(test),
expect(
dead_code,
reason = "consumed by the pipeline (`Telemetry`, `Exporter`), not in place yet"
)
)]
mod transport;
#[expect(
dead_code,
reason = "consumed by the pipeline (`Telemetry`, `Exporter`), not in place yet"
)]
mod destination;
pub use cache::{BatchCache, FileCache, MemoryCache};
pub use destination::ENDPOINT_OVERRIDE_ENV;
pub use device::*;
pub use event::*;
pub use rtc::{RtcStat, RtcStatsSample, StreamDirection, TrackKind};
pub use span::SpanOutcome;
pub use stats::{TelemetryStats, TelemetryStatus};
#[cfg(feature = "net")]
pub use transport::NetTransport;
pub use transport::{ExportError, ExportRequest, ExportResponse, TelemetryTransport};
#[cfg(feature = "uniffi")]
uniffi::setup_scaffolding!();
#[cfg(test)]
pub(crate) mod test_log {
use std::cell::RefCell;
use std::sync::{Mutex, Once};
use std::thread::{self, ThreadId};
static LINES: Mutex<Vec<(ThreadId, String)>> = Mutex::new(Vec::new());
thread_local! {
static HELD: RefCell<Option<Box<dyn Fn() -> bool>>> = const { RefCell::new(None) };
}
struct Capture;
impl log::Log for Capture {
fn enabled(&self, metadata: &log::Metadata) -> bool {
metadata.level() <= log::Level::Warn
}
fn log(&self, record: &log::Record) {
if self.enabled(record.metadata()) {
let held = HELD.with(|held| held.borrow().as_ref().is_some_and(|held| held()));
let line = format!("{}{}", if held { "held: " } else { "" }, record.args());
let line = (thread::current().id(), line);
LINES.lock().unwrap_or_else(|e| e.into_inner()).push(line);
}
}
fn flush(&self) {}
}
pub fn capture() {
static INSTALL: Once = Once::new();
INSTALL.call_once(|| {
log::set_logger(&Capture).expect("the only logger in tests");
log::set_max_level(log::LevelFilter::Warn);
});
}
pub fn mark_while(held: impl Fn() -> bool + 'static) {
HELD.with(|slot| *slot.borrow_mut() = Some(Box::new(held)));
}
pub fn take() -> Vec<String> {
let me = thread::current().id();
let mut lines = LINES.lock().unwrap_or_else(|e| e.into_inner());
let (mine, others): (Vec<_>, Vec<_>) =
std::mem::take(&mut *lines).into_iter().partition(|(id, _)| *id == me);
*lines = others;
mine.into_iter().map(|(_, line)| line).collect()
}
}