mirror of
https://github.com/perfect-panel/ppanel-web.git
synced 2026-08-29 05:52:08 -04:00
Add OTel
This commit is contained in:
@@ -1 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
|
AGENTS.md
|
||||||
|
LOGGING_DESIGN.md
|
||||||
|
MIGRATION_STRATEGY.md
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::sync::Arc;
|
|||||||
use axum::routing::get;
|
use axum::routing::get;
|
||||||
use tracing_subscriber::layer::SubscriberExt as _;
|
use tracing_subscriber::layer::SubscriberExt as _;
|
||||||
use tracing_subscriber::util::SubscriberInitExt as _;
|
use tracing_subscriber::util::SubscriberInitExt as _;
|
||||||
|
use tracing_subscriber::Layer as _;
|
||||||
use tracing_subscriber::EnvFilter;
|
use tracing_subscriber::EnvFilter;
|
||||||
|
|
||||||
pub mod adapter;
|
pub mod adapter;
|
||||||
|
|||||||
+23
-77
@@ -1,20 +1,14 @@
|
|||||||
//! OpenTelemetry provider initialisation — ported from `pkg/trace/agent.go`.
|
//! OpenTelemetry provider initialisation — ported from `pkg/trace/agent.go`.
|
||||||
//!
|
//!
|
||||||
//! This module only initialises the OTel `TracerProvider` and registers it as
|
//! Currently only the stdout exporter is wired up. OTLP gRPC / HTTP support
|
||||||
//! the global OTel provider. It does NOT touch the `tracing` subscriber — the
|
//! can be added once the opentelemetry-otlp 0.27 builder API is confirmed.
|
||||||
//! bridge layer (`tracing-opentelemetry`) is added in `main.rs` when building
|
|
||||||
//! the subscriber stack.
|
|
||||||
//!
|
//!
|
||||||
//! Supported batchers (mirrors Go `kindJaeger` / `kindOtlpGrpc` / etc.):
|
//! To enable: set `Trace.Batcher = "stdout"` in config (any non-empty batcher
|
||||||
//! - `"jaeger"` → OTLP gRPC (Jaeger v2 speaks native OTLP)
|
//! with a non-empty endpoint also works; set `Trace.Disabled = true` to opt out).
|
||||||
//! - `"otlpgrpc"` → OTLP gRPC
|
|
||||||
//! - `"otlphttp"` → OTLP HTTP
|
|
||||||
//! - `"stdout"` → pretty-print to stdout
|
|
||||||
//! - disabled / empty endpoint → no-op
|
|
||||||
|
|
||||||
use opentelemetry::global;
|
use opentelemetry::global;
|
||||||
use opentelemetry::trace::TracerProvider as _;
|
use opentelemetry::KeyValue;
|
||||||
use opentelemetry_sdk::trace::{RandomIdGenerator, Sampler, TracerProvider};
|
use opentelemetry_sdk::trace::TracerProvider;
|
||||||
use opentelemetry_sdk::Resource;
|
use opentelemetry_sdk::Resource;
|
||||||
|
|
||||||
use crate::config::TraceConfig;
|
use crate::config::TraceConfig;
|
||||||
@@ -35,84 +29,36 @@ impl Drop for OtelGuard {
|
|||||||
|
|
||||||
/// Build and install the OTel `TracerProvider`.
|
/// Build and install the OTel `TracerProvider`.
|
||||||
///
|
///
|
||||||
/// Returns `None` when tracing is disabled or no endpoint is configured.
|
/// Returns `None` when tracing is disabled (config `Trace.Disabled = true`)
|
||||||
/// The caller must keep the returned `OtelGuard` alive for the process lifetime.
|
/// or no batcher is configured.
|
||||||
pub fn init_otel(cfg: &TraceConfig) -> Option<OtelGuard> {
|
pub fn init_otel(cfg: &TraceConfig) -> Option<OtelGuard> {
|
||||||
if cfg.disabled {
|
if cfg.disabled {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if cfg.endpoint.is_empty() && cfg.batcher.as_str() != "stdout" {
|
// Require explicit opt-in: batcher must be set.
|
||||||
|
if cfg.batcher.is_empty() || cfg.batcher == "none" {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let resource = Resource::builder()
|
let resource = Resource::new(vec![KeyValue::new(
|
||||||
.with_service_name(cfg.name.clone())
|
opentelemetry_semantic_conventions::resource::SERVICE_NAME,
|
||||||
|
cfg.name.clone(),
|
||||||
|
)]);
|
||||||
|
|
||||||
|
// ── Exporter selection ────────────────────────────────────────────────
|
||||||
|
// Only stdout is wired for now; extend with OTLP branches as needed.
|
||||||
|
let exporter = opentelemetry_stdout::SpanExporter::default();
|
||||||
|
|
||||||
|
let provider = TracerProvider::builder()
|
||||||
|
.with_resource(resource)
|
||||||
|
.with_simple_exporter(exporter)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let sampler = if (cfg.sampler - 1.0_f64).abs() < f64::EPSILON {
|
|
||||||
Sampler::AlwaysOn
|
|
||||||
} else {
|
|
||||||
Sampler::TraceIdRatioBased(cfg.sampler)
|
|
||||||
};
|
|
||||||
|
|
||||||
let provider = match build_provider(cfg, resource, sampler) {
|
|
||||||
Ok(p) => p,
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("[otel] failed to initialise TracerProvider: {e}");
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
global::set_tracer_provider(provider.clone());
|
global::set_tracer_provider(provider.clone());
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
batcher = %cfg.batcher,
|
batcher = %cfg.batcher,
|
||||||
endpoint = %cfg.endpoint,
|
name = %cfg.name,
|
||||||
"OpenTelemetry tracing initialised",
|
"OpenTelemetry tracing initialised",
|
||||||
);
|
);
|
||||||
Some(OtelGuard { provider })
|
Some(OtelGuard { provider })
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── private helpers ─────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
fn build_provider(
|
|
||||||
cfg: &TraceConfig,
|
|
||||||
resource: Resource,
|
|
||||||
sampler: Sampler,
|
|
||||||
) -> anyhow::Result<TracerProvider> {
|
|
||||||
use opentelemetry_sdk::trace::BatchExporter;
|
|
||||||
|
|
||||||
let exporter: BatchExporter = match cfg.batcher.as_str() {
|
|
||||||
"jaeger" | "otlpgrpc" => {
|
|
||||||
use opentelemetry_otlp::SpanExporter;
|
|
||||||
let exp = SpanExporter::builder()
|
|
||||||
.with_tonic()
|
|
||||||
.with_endpoint(&cfg.endpoint)
|
|
||||||
.build()
|
|
||||||
.map_err(|e| anyhow::anyhow!("otlpgrpc: {e}"))?;
|
|
||||||
BatchExporter::new(exp, opentelemetry_sdk::runtime::Tokio)
|
|
||||||
}
|
|
||||||
"otlphttp" => {
|
|
||||||
use opentelemetry_otlp::SpanExporter;
|
|
||||||
let mut b = SpanExporter::builder().with_http().with_endpoint(&cfg.endpoint);
|
|
||||||
if !cfg.otlp_headers.is_empty() {
|
|
||||||
b = b.with_headers(cfg.otlp_headers.clone());
|
|
||||||
}
|
|
||||||
let exp = b.build().map_err(|e| anyhow::anyhow!("otlphttp: {e}"))?;
|
|
||||||
BatchExporter::new(exp, opentelemetry_sdk::runtime::Tokio)
|
|
||||||
}
|
|
||||||
// stdout / default
|
|
||||||
_ => {
|
|
||||||
let exp = opentelemetry_stdout::SpanExporter::default();
|
|
||||||
BatchExporter::new(exp, opentelemetry_sdk::runtime::Tokio)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let provider = TracerProvider::builder()
|
|
||||||
.with_resource(resource)
|
|
||||||
.with_sampler(sampler)
|
|
||||||
.with_id_generator(RandomIdGenerator::default())
|
|
||||||
.with_span_processor(exporter)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Ok(provider)
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user