opentelemetry_log/lib.rs
1//! # OpenTelemetry Log Integration
2//!
3//! This crate provides integration with OpenTelemetry for logging purposes. It allows you to
4//! initialize and manage loggers that are compatible with the OpenTelemetry SDK.
5//!
6//! ## Features
7//!
8//! - Initialize loggers with specific tags, levels, and exporter endpoints.
9//! - Automatically manage the lifecycle of loggers, ensuring proper shutdown.
10//!
11//! ## Usage
12//!
13//! Add this crate to your `Cargo.toml`:
14//!
15//! ```toml
16//! [dependencies]
17//! opentelemetry-log = "0.1"
18//! ```
19//!
20//! Import and use the `Opentelemetry` struct to manage your loggers:
21//!
22//! ```rust
23//! use opentelemetry_log::Opentelemetry;
24//!
25//! #[tokio::main]
26//! async fn main() {
27//! let mut otel = Opentelemetry::new();
28//! otel.init_log("my_app", "info", "http://localhost:4317").unwrap(); // Please do not unwrap in production code
29//! // Your application logic here
30//! }
31//! ```
32//!
33//! ## Modules
34//!
35//! - `log`: Contains the log initialization logic.
36//!
37//! ## Structs
38//!
39//! - `Opentelemetry`: Main struct for managing OpenTelemetry loggers.
40//!
41//! ## Traits
42//!
43//! - `Default`: Provides a default implementation for `Opentelemetry`.
44//! - `Drop`: Ensures proper shutdown of loggers when `Opentelemetry` instances are dropped.
45//!
46//! ## Errors
47//!
48//! This crate uses the `anyhow` crate for error handling. Ensure you handle errors appropriately
49//! when initializing and using loggers.
50pub mod log;
51pub use anyhow;
52
53use std::sync::Arc;
54
55use opentelemetry_sdk::logs as sdklogs;
56
57/// Main struct for managing OpenTelemetry loggers, when you init the logger
58/// remember to keep this alive for all the lifetime of the application.
59///
60/// An example can be found in the `examples` directory.
61#[derive(Debug, Clone)]
62pub struct Opentelemetry {
63 pub(crate) logger: Option<Arc<sdklogs::LoggerProvider>>,
64}
65
66impl Default for Opentelemetry {
67 fn default() -> Self {
68 Self::new()
69 }
70}
71
72impl Opentelemetry {
73 pub fn new() -> Self {
74 Opentelemetry { logger: None }
75 }
76
77 /// Initialize a new logger with the provided tag, level, and exporter endpoint.
78 /// this is assuming tat your application is using `log` crate
79 pub fn init_log(
80 &mut self,
81 tag: &str,
82 level: &str,
83 exporter_endpoint: &str,
84 ) -> anyhow::Result<()> {
85 log::init(self, tag.to_owned(), level, exporter_endpoint)?;
86 Ok(())
87 }
88}
89
90impl Drop for Opentelemetry {
91 fn drop(&mut self) {
92 let Some(Err(err)) = self.logger.as_ref().map(|log| log.shutdown()) else {
93 return;
94 };
95 eprintln!("Failed to shutdown logger: {:?}", err);
96 }
97}