diff --git a/.changesets/feat_metric_temporality.md b/.changesets/feat_metric_temporality.md new file mode 100644 index 00000000..770f3a68 --- /dev/null +++ b/.changesets/feat_metric_temporality.md @@ -0,0 +1,8 @@ +### feat: Add configuration option for metric temporality - @swcollard PR #413 + +Creates a new configuration option for telemetry to set the Metric temporality to either Cumulative (default) or Delta. + +* Cumulative - The metric value will be the overall value since the start of the measurement. +* Delta - The metric will be the difference in the measurement since the last time it was reported. + +Some observability vendors require that one is used over the other so we want to support the configuration in the MCP Server. \ No newline at end of file diff --git a/crates/apollo-mcp-server/src/runtime/telemetry.rs b/crates/apollo-mcp-server/src/runtime/telemetry.rs index d5d0688b..565b15d3 100644 --- a/crates/apollo-mcp-server/src/runtime/telemetry.rs +++ b/crates/apollo-mcp-server/src/runtime/telemetry.rs @@ -7,7 +7,7 @@ use crate::runtime::telemetry::sampler::SamplerOption; use apollo_mcp_server::generated::telemetry::TelemetryAttribute; use opentelemetry::{Key, KeyValue, global, trace::TracerProvider as _}; use opentelemetry_otlp::WithExportConfig; -use opentelemetry_sdk::metrics::{Instrument, Stream}; +use opentelemetry_sdk::metrics::{Instrument, Stream, Temporality}; use opentelemetry_sdk::{ Resource, metrics::{MeterProviderBuilder, PeriodicReader, SdkMeterProvider}, @@ -44,10 +44,30 @@ pub struct MetricsExporters { omitted_attributes: Option>, } +#[derive(Debug, Deserialize, JsonSchema)] +pub enum MetricTemporality { + Cumulative, + Delta, +} + +impl OTLPMetricExporter { + pub fn to_temporality(&self) -> Temporality { + match self + .temporality + .as_ref() + .unwrap_or(&MetricTemporality::Cumulative) + { + MetricTemporality::Cumulative => Temporality::Cumulative, + MetricTemporality::Delta => Temporality::Delta, + } + } +} + #[derive(Debug, Deserialize, JsonSchema)] pub struct OTLPMetricExporter { endpoint: String, protocol: String, + temporality: Option, } impl Default for OTLPMetricExporter { @@ -55,6 +75,7 @@ impl Default for OTLPMetricExporter { Self { endpoint: "http://localhost:4317".into(), protocol: "grpc".into(), + temporality: Some(MetricTemporality::Cumulative), } } } @@ -122,10 +143,12 @@ fn init_meter_provider(telemetry: &Telemetry) -> Result opentelemetry_otlp::MetricExporter::builder() .with_tonic() .with_endpoint(otlp.endpoint.clone()) + .with_temporality(otlp.to_temporality()) .build()?, "http/protobuf" => opentelemetry_otlp::MetricExporter::builder() .with_http() .with_endpoint(otlp.endpoint.clone()) + .with_temporality(otlp.to_temporality()) .build()?, other => { return Err(anyhow::anyhow!( @@ -331,6 +354,7 @@ mod tests { otlp: Some(OTLPMetricExporter { protocol: "bogus".to_string(), endpoint: "http://localhost:4317".to_string(), + temporality: None, }), omitted_attributes: None, }), @@ -354,6 +378,7 @@ mod tests { otlp: Some(OTLPMetricExporter { protocol: "http/protobuf".to_string(), endpoint: "http://localhost:4318/v1/metrics".to_string(), + temporality: Some(MetricTemporality::Delta), }), omitted_attributes: None, }), diff --git a/docs/source/config-file.mdx b/docs/source/config-file.mdx index a65a7cc4..20b492d4 100644 --- a/docs/source/config-file.mdx +++ b/docs/source/config-file.mdx @@ -244,20 +244,29 @@ transport: #### Metrics -| Option | Type | Default | Description | -| :-------------------- | :--------------- | :-------------------------- | :--------------------------------------------- | -| `otlp` | `OTLP Exporter` | `null` (Exporting disabled) | Configuration for exporting metrics via OTLP. | -| `omitted_attributes` | `List` | | List of attributes to be omitted from metrics. | +| Option | Type | Default | Description | +| :-------------------- | :---------------------- | :-------------------------- | :--------------------------------------------- | +| `otlp` | `OTLP Metric Exporter` | `null` (Exporting disabled) | Configuration for exporting metrics via OTLP. | +| `omitted_attributes` | `List` | | List of attributes to be omitted from metrics. | + + +#### OTLP Metrics Exporter + +| Option | Type | Default | Description | +| :--------- | :--------------------------------------- | :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `endpoint` | `URL` | `http://localhost:4317` | URL to export data to. Requires full path. | +| `protocol` | `string` | `grpc` | Protocol for export. Only `grpc` and `http/protobuf` are supported. | +| `temporality` | `MetricTemporality` | `Cumulative` | Optional OTel property that refers to the way additive quantities are expressed, in relation to time, indicating whether reported values incorporate previous measurements (Cumulative) or not (Delta). | #### Traces -| Option | Type | Default | Description | -| :-------------------- | :--------------- | :-------------------------- | :--------------------------------------------- | -| `otlp` | `OTLP Exporter` | `null` (Exporting disabled) | Configuration for exporting traces via OTLP. | -| `sampler` | `SamplerOption` | `ALWAYS_ON` | Configuration to control sampling of traces. | -| `omitted_attributes` | `List` | | List of attributes to be omitted from traces. | +| Option | Type | Default | Description | +| :-------------------- | :--------------------- | :-------------------------- | :--------------------------------------------- | +| `otlp` | `OTLP Trace Exporter` | `null` (Exporting disabled) | Configuration for exporting traces via OTLP. | +| `sampler` | `SamplerOption` | `ALWAYS_ON` | Configuration to control sampling of traces. | +| `omitted_attributes` | `List` | | List of attributes to be omitted from traces. | -#### OTLP Exporter +#### OTLP Trace Exporter | Option | Type | Default | Description | | :--------- | :-------- | :-------------------------- | :--------------------------------------------------------------- |