From 16727298ea5e1f8bc300dc0f987d0ff852dab527 Mon Sep 17 00:00:00 2001 From: tison Date: Fri, 2 Aug 2024 19:00:40 +0800 Subject: [PATCH] feat: opentelemetry appender for HTTP protocols (#27) Signed-off-by: tison --- Cargo.toml | 34 +++++++++++++++++++---------- README.md | 5 ++++- src/append/opentelemetry.rs | 43 ++++++++++++++++++++++++++----------- src/layout/json.rs | 2 +- src/layout/text.rs | 2 +- 5 files changed, 60 insertions(+), 26 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f99db40..5ee4b67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ license = "Apache-2.0" readme = "README.md" repository = "https://github.com/tisonkun/logforth" rust-version = "1.71.0" -version = "0.6.0" +version = "0.7.0" [package.metadata.docs.rs] all-features = true @@ -44,18 +44,8 @@ rolling_file = ["dep:crossbeam-channel", "dep:parking_lot", "dep:time"] anyhow = { version = "1.0" } colored = { version = "2.1" } crossbeam-channel = { version = "0.5", optional = true } -fastrace = { version = "0.6", optional = true } humantime = { version = "2.1" } log = { version = "0.4", features = ["std", "kv_unstable"] } -opentelemetry = { version = "0.24", features = ["logs"], optional = true } -opentelemetry-otlp = { version = "0.17", features = [ - "logs", - "grpc-tonic", -], optional = true } -opentelemetry_sdk = { version = "0.24", features = [ - "logs", - "rt-tokio", -], optional = true } parking_lot = { version = "0.12", optional = true } paste = { version = "1.0" } serde = { version = "1.0", features = ["derive"], optional = true } @@ -65,6 +55,28 @@ time = { version = "0.3", features = [ "parsing", ], optional = true } +## Fastrace dependencies +[dependencies.fastrace] +optional = true +version = "0.6" + +## Opentelemetry dependencies +[dependencies.opentelemetry] +features = ["logs"] +optional = true +version = "0.24" + +[dependencies.opentelemetry-otlp] +features = ["logs", "grpc-tonic", "http-json", "http-proto"] +optional = true +version = "0.17" + +[dependencies.opentelemetry_sdk] +features = ["logs", "rt-tokio"] +optional = true +version = "0.24" + +## Examples [[example]] name = "fn_layout_filter" path = "examples/fn_layout_filter.rs" diff --git a/README.md b/README.md index 07df37a..0155e97 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,15 @@ A versatile and extensible logging implementation. ## Usage -Add the dependency to your `Cargo.toml` with: +Add the dependencies to your `Cargo.toml` with: ```shell +cargo add log cargo add logforth ``` +... where [log](https://crates.io/crates/log) is the logging facade and [logforth](https://crates.io/crates/logforth) is the logging implementation. + Then, you can use the logger with: ```rust diff --git a/src/append/opentelemetry.rs b/src/append/opentelemetry.rs index 9a162a8..7c55da2 100644 --- a/src/append/opentelemetry.rs +++ b/src/append/opentelemetry.rs @@ -22,6 +22,7 @@ use opentelemetry::logs::Logger; use opentelemetry::logs::LoggerProvider as ILoggerProvider; use opentelemetry::logs::Severity; use opentelemetry::InstrumentationLibrary; +use opentelemetry_otlp::Protocol; use opentelemetry_otlp::WithExportConfig; use opentelemetry_sdk::logs::LoggerProvider; @@ -40,20 +41,38 @@ impl OpentelemetryLog { name: impl Into, category: impl Into, otlp_endpoint: impl Into, - ) -> Self { + protocol: Protocol, + ) -> Result { let name = name.into(); let category = category.into(); let otlp_endpoint = otlp_endpoint.into(); - let exporter = opentelemetry_otlp::new_exporter() - .tonic() - .with_endpoint(otlp_endpoint) - .with_protocol(opentelemetry_otlp::Protocol::Grpc) - .with_timeout(Duration::from_secs( - opentelemetry_otlp::OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT, - )) - .build_log_exporter() - .expect("failed to initialize oltp exporter"); + let exporter = match protocol { + Protocol::Grpc => opentelemetry_otlp::new_exporter() + .tonic() + .with_endpoint(otlp_endpoint) + .with_protocol(Protocol::Grpc) + .with_timeout(Duration::from_secs( + opentelemetry_otlp::OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT, + )) + .build_log_exporter(), + Protocol::HttpBinary => opentelemetry_otlp::new_exporter() + .http() + .with_endpoint(otlp_endpoint) + .with_protocol(Protocol::HttpBinary) + .with_timeout(Duration::from_secs( + opentelemetry_otlp::OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT, + )) + .build_log_exporter(), + Protocol::HttpJson => opentelemetry_otlp::new_exporter() + .http() + .with_endpoint(otlp_endpoint) + .with_protocol(Protocol::HttpJson) + .with_timeout(Duration::from_secs( + opentelemetry_otlp::OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT, + )) + .build_log_exporter(), + }?; let provider = LoggerProvider::builder() .with_batch_exporter(exporter, opentelemetry_sdk::runtime::Tokio) @@ -61,12 +80,12 @@ impl OpentelemetryLog { let library = Arc::new(InstrumentationLibrary::builder(name.clone()).build()); - Self { + Ok(Self { name, category, library, provider, - } + }) } } diff --git a/src/layout/json.rs b/src/layout/json.rs index 30d716b..3298965 100644 --- a/src/layout/json.rs +++ b/src/layout/json.rs @@ -84,7 +84,7 @@ impl JsonLayout { level: record.level().as_str(), module_path: record.module_path().unwrap_or_default(), file: record.file().unwrap_or_default(), - line: record.line().unwrap_or(0), + line: record.line().unwrap_or_default(), message: record.args(), kvs, }; diff --git a/src/layout/text.rs b/src/layout/text.rs index 5fcc57a..6de907d 100644 --- a/src/layout/text.rs +++ b/src/layout/text.rs @@ -66,7 +66,7 @@ impl TextLayout { let level = ColoredString::from(record.level().to_string()).color(color); let module = record.module_path().unwrap_or_default(); let file = record.file().unwrap_or_default(); - let line = record.line().unwrap_or(0); + let line = record.line().unwrap_or_default(); let message = record.args(); let kvs = KvDisplay::new(record.key_values());