Add OTLP logs layer (#5386)

This commit is contained in:
dorien-koelemeijer
2025-10-30 08:06:41 +10:00
committed by GitHub
parent 3654a48000
commit d25372c7e2
5 changed files with 69 additions and 4 deletions
Generated
+13
View File
@@ -2646,6 +2646,7 @@ dependencies = [
"oauth2",
"once_cell",
"opentelemetry",
"opentelemetry-appender-tracing",
"opentelemetry-otlp",
"opentelemetry_sdk",
"paste",
@@ -4561,6 +4562,18 @@ dependencies = [
"tracing",
]
[[package]]
name = "opentelemetry-appender-tracing"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5feffc321035ad94088a7e5333abb4d84a8726e54a802e736ce9dd7237e85b"
dependencies = [
"opentelemetry",
"tracing",
"tracing-core",
"tracing-subscriber",
]
[[package]]
name = "opentelemetry-http"
version = "0.27.0"
+8 -1
View File
@@ -102,7 +102,9 @@ fn setup_logging_internal(
}
if !force {
if let Ok((otlp_tracing_layer, otlp_metrics_layer)) = otlp_layer::init_otlp() {
if let Ok((otlp_tracing_layer, otlp_metrics_layer, otlp_logs_layer)) =
otlp_layer::init_otlp()
{
layers.push(
otlp_tracing_layer
.with_filter(otlp_layer::create_otlp_tracing_filter())
@@ -113,6 +115,11 @@ fn setup_logging_internal(
.with_filter(otlp_layer::create_otlp_metrics_filter())
.boxed(),
);
layers.push(
otlp_logs_layer
.with_filter(otlp_layer::create_otlp_logs_filter())
.boxed(),
);
}
}
+6 -1
View File
@@ -74,7 +74,7 @@ pub fn setup_logging(name: Option<&str>) -> Result<()> {
console_layer.with_filter(LevelFilter::INFO).boxed(),
];
if let Ok((otlp_tracing_layer, otlp_metrics_layer)) = otlp_layer::init_otlp() {
if let Ok((otlp_tracing_layer, otlp_metrics_layer, otlp_logs_layer)) = otlp_layer::init_otlp() {
layers.push(
otlp_tracing_layer
.with_filter(otlp_layer::create_otlp_tracing_filter())
@@ -85,6 +85,11 @@ pub fn setup_logging(name: Option<&str>) -> Result<()> {
.with_filter(otlp_layer::create_otlp_metrics_filter())
.boxed(),
);
layers.push(
otlp_logs_layer
.with_filter(otlp_layer::create_otlp_logs_filter())
.boxed(),
);
}
if let Some(langfuse) = langfuse_layer::create_langfuse_observer() {
+1
View File
@@ -67,6 +67,7 @@ tracing = "0.1"
tracing-subscriber = "0.3"
tracing-opentelemetry = "0.28"
opentelemetry = "0.27"
opentelemetry-appender-tracing = "0.27"
opentelemetry_sdk = { version = "0.27", features = ["rt-tokio", "metrics"] }
opentelemetry-otlp = { version = "0.27", features = ["grpc-tonic", "http-proto", "reqwest-client"] }
tonic = "0.12"
+41 -2
View File
@@ -1,6 +1,8 @@
use opentelemetry::trace::TracerProvider;
use opentelemetry::{global, KeyValue};
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
use opentelemetry_otlp::WithExportConfig;
use opentelemetry_sdk::logs::{Logger, LoggerProvider};
use opentelemetry_sdk::trace::{self, RandomIdGenerator, Sampler};
use opentelemetry_sdk::{runtime, Resource};
use std::time::Duration;
@@ -11,7 +13,8 @@ use tracing_subscriber::filter::FilterFn;
pub type OtlpTracingLayer =
OpenTelemetryLayer<tracing_subscriber::Registry, opentelemetry_sdk::trace::Tracer>;
pub type OtlpMetricsLayer = MetricsLayer<tracing_subscriber::Registry>;
pub type OtlpLayers = (OtlpTracingLayer, OtlpMetricsLayer);
pub type OtlpLogsLayer = OpenTelemetryTracingBridge<LoggerProvider, Logger>;
pub type OtlpLayers = (OtlpTracingLayer, OtlpMetricsLayer, OtlpLogsLayer);
pub type OtlpResult<T> = Result<T, Box<dyn std::error::Error + Send + Sync>>;
#[derive(Debug, Clone)]
@@ -163,10 +166,34 @@ pub fn create_otlp_metrics_layer() -> OtlpResult<OtlpMetricsLayer> {
Ok(tracing_opentelemetry::MetricsLayer::new(meter_provider))
}
pub fn create_otlp_logs_layer() -> OtlpResult<OpenTelemetryTracingBridge<LoggerProvider, Logger>> {
let config = OtlpConfig::from_config().ok_or("OTEL_EXPORTER_OTLP_ENDPOINT not configured")?;
let resource = Resource::new(vec![
KeyValue::new("service.name", "goose"),
KeyValue::new("service.version", env!("CARGO_PKG_VERSION")),
KeyValue::new("service.namespace", "goose"),
]);
let exporter = opentelemetry_otlp::LogExporter::builder()
.with_http()
.with_endpoint(&config.endpoint)
.with_timeout(config.timeout)
.build()?;
let logger_provider = LoggerProvider::builder()
.with_batch_exporter(exporter, runtime::Tokio)
.with_resource(resource)
.build();
Ok(OpenTelemetryTracingBridge::new(&logger_provider))
}
pub fn init_otlp() -> OtlpResult<OtlpLayers> {
let tracing_layer = create_otlp_tracing_layer()?;
let metrics_layer = create_otlp_metrics_layer()?;
Ok((tracing_layer, metrics_layer))
let logs_layer = create_otlp_logs_layer()?;
Ok((tracing_layer, metrics_layer, logs_layer))
}
pub fn init_otlp_tracing_only() -> OtlpResult<OtlpTracingLayer> {
@@ -221,6 +248,18 @@ pub fn create_otlp_metrics_filter() -> FilterFn<impl Fn(&Metadata<'_>) -> bool>
})
}
/// Creates a custom filter for OTLP metrics that captures:
/// - All events at WARN level and above
pub fn create_otlp_logs_filter() -> FilterFn<impl Fn(&Metadata<'_>) -> bool> {
FilterFn::new(|metadata: &Metadata<'_>| {
if metadata.level() <= &Level::WARN {
return true;
}
false
})
}
/// Shutdown OTLP providers gracefully
pub fn shutdown_otlp() {
// Shutdown the tracer provider and flush any pending spans