diff --git a/.changesets/fix_bnjjj_fix_telemetry_prom_resource.md b/.changesets/fix_bnjjj_fix_telemetry_prom_resource.md new file mode 100644 index 0000000000..1c8fb8d235 --- /dev/null +++ b/.changesets/fix_bnjjj_fix_telemetry_prom_resource.md @@ -0,0 +1,19 @@ +### Telemetry: export properly resources on metrics configured on prometheus ([PR #7394](https://github.com/apollographql/router/pull/7394)) + +When configuring `telemetry.exporters.metrics.common.resource` to globally add labels on metrics, these labels were not exported to every metrics on prometheus. This can now be done if you set `resource_selector` to `all` (default is `none`). + +```yaml +telemetry: + exporters: + metrics: + common: + resource: + "test-resource": "test" + prometheus: + enabled: true + resource_selector: all # This will add resources on every metrics +``` + +This only occurred with Prometheus and not OTLP. + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/7394 diff --git a/apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__schema_generation.snap b/apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__schema_generation.snap index 37f70fc2d8..baa5e990fc 100644 --- a/apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__schema_generation.snap +++ b/apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__schema_generation.snap @@ -1813,6 +1813,10 @@ expression: "&schema" "description": "The optional output name", "nullable": true, "type": "string" + }, + "resource_selector": { + "$ref": "#/definitions/ResourceSelectorConfig", + "description": "#/definitions/ResourceSelectorConfig" } }, "required": [ @@ -4664,6 +4668,24 @@ expression: "&schema" ], "type": "object" }, + "ResourceSelectorConfig": { + "oneOf": [ + { + "description": "Export all resource attributes with every metrics.", + "enum": [ + "all" + ], + "type": "string" + }, + { + "description": "Do not export any resource attributes with every metrics.", + "enum": [ + "none" + ], + "type": "string" + } + ] + }, "ResponseStatus": { "oneOf": [ { diff --git a/apollo-router/src/plugins/telemetry/metrics/prometheus.rs b/apollo-router/src/plugins/telemetry/metrics/prometheus.rs index f5d0801f5b..01e64786dc 100644 --- a/apollo-router/src/plugins/telemetry/metrics/prometheus.rs +++ b/apollo-router/src/plugins/telemetry/metrics/prometheus.rs @@ -5,9 +5,17 @@ use std::task::Poll; use futures::future::BoxFuture; use http::StatusCode; use once_cell::sync::Lazy; +<<<<<<< HEAD use opentelemetry::sdk::Resource; use opentelemetry::sdk::metrics::MeterProvider; use opentelemetry::sdk::metrics::View; +======= +use opentelemetry_prometheus::ResourceSelector; +use opentelemetry_sdk::Resource; +use opentelemetry_sdk::metrics::SdkMeterProvider; +use opentelemetry_sdk::metrics::View; +use parking_lot::Mutex; +>>>>>>> 731fd23c (fix(telemetry): export properly resources configured on prometheus (#7394)) use prometheus::Encoder; use prometheus::Registry; use prometheus::TextEncoder; @@ -33,16 +41,38 @@ use crate::services::router::Body; pub(crate) struct Config { /// Set to true to enable pub(crate) enabled: bool, + /// resource_selector is used to select which resource to export with every metrics. + pub(crate) resource_selector: ResourceSelectorConfig, /// The listen address pub(crate) listen: ListenAddr, /// The path where prometheus will be exposed pub(crate) path: String, } +#[derive(Debug, Clone, Copy, Deserialize, JsonSchema, Default)] +#[serde(rename_all = "snake_case")] +pub(crate) enum ResourceSelectorConfig { + /// Export all resource attributes with every metrics. + All, + #[default] + /// Do not export any resource attributes with every metrics. + None, +} + +impl From for ResourceSelector { + fn from(value: ResourceSelectorConfig) -> Self { + match value { + ResourceSelectorConfig::All => ResourceSelector::All, + ResourceSelectorConfig::None => ResourceSelector::None, + } + } +} + impl Default for Config { fn default() -> Self { Self { enabled: false, + resource_selector: ResourceSelectorConfig::default(), listen: ListenAddr::SocketAddr("127.0.0.1:9090".parse().expect("valid listenAddr")), path: "/metrics".to_string(), } @@ -133,6 +163,7 @@ impl MetricsConfigurator for Config { .record_min_max(true) .build(), ) + .with_resource_selector(self.resource_selector) .with_registry(registry.clone()) .build()?; diff --git a/apollo-router/src/plugins/telemetry/mod.rs b/apollo-router/src/plugins/telemetry/mod.rs index ebd7b5d501..6e6a7b82b3 100644 --- a/apollo-router/src/plugins/telemetry/mod.rs +++ b/apollo-router/src/plugins/telemetry/mod.rs @@ -2109,6 +2109,7 @@ struct MetricsAttributes(HashMap); struct SubgraphMetricsAttributes(HashMap); struct EnableSubgraphFtv1; + // // Please ensure that any tests added to the tests module use the tokio multi-threaded test executor. // @@ -2185,10 +2186,31 @@ mod tests { use crate::services::SupergraphResponse; use crate::services::router::body::get_body_bytes; +<<<<<<< HEAD async fn create_plugin_with_config(config: &str) -> Box { let prometheus_support = config.contains("prometheus"); let config: Value = serde_yaml::from_str(config).expect("yaml must be valid"); let telemetry_config = config +======= + macro_rules! assert_prometheus_metrics { + ($plugin:expr) => {{ + let prometheus_metrics = get_prometheus_metrics($plugin.as_ref()).await; + let regexp = regex::Regex::new( + r#"process_executable_name="(?P[^"]+)",?|service_name="(?P[^"]+)",?"#, + ) + .unwrap(); + let prometheus_metrics = regexp.replace_all(&prometheus_metrics, "").to_owned(); + assert_snapshot!(prometheus_metrics.replace( + &format!(r#"service_version="{}""#, std::env!("CARGO_PKG_VERSION")), + r#"service_version="X""# + )); + }}; + } + + async fn create_plugin_with_config(full_config: &str) -> Box { + let full_config = serde_yaml::from_str::(full_config).expect("yaml must be valid"); + let telemetry_config = full_config +>>>>>>> 731fd23c (fix(telemetry): export properly resources configured on prometheus (#7394)) .as_object() .expect("must be an object") .get("telemetry") @@ -3099,8 +3121,7 @@ mod tests { let plugin = create_plugin_with_config(include_str!("testdata/prometheus.router.yaml")).await; make_supergraph_request(plugin.as_ref()).await; - let prometheus_metrics = get_prometheus_metrics(plugin.as_ref()).await; - assert_snapshot!(prometheus_metrics); + assert_prometheus_metrics!(plugin); } .with_metrics() .await; @@ -3114,9 +3135,7 @@ mod tests { )) .await; make_supergraph_request(plugin.as_ref()).await; - let prometheus_metrics = get_prometheus_metrics(plugin.as_ref()).await; - - assert_snapshot!(prometheus_metrics); + assert_prometheus_metrics!(plugin); } .with_metrics() .await; @@ -3130,9 +3149,14 @@ mod tests { )) .await; make_supergraph_request(plugin.as_ref()).await; +<<<<<<< HEAD let prometheus_metrics = get_prometheus_metrics(plugin.as_ref()).await; assert_snapshot!(prometheus_metrics); +======= + u64_histogram!("apollo.test.histo", "it's a test", 1u64); + assert_prometheus_metrics!(plugin); +>>>>>>> 731fd23c (fix(telemetry): export properly resources configured on prometheus (#7394)) } .with_metrics() .await; @@ -3146,14 +3170,30 @@ mod tests { )) .await; make_supergraph_request(plugin.as_ref()).await; - let prometheus_metrics = get_prometheus_metrics(plugin.as_ref()).await; + assert_prometheus_metrics!(plugin); + } + .with_metrics() + .await; + } - assert!(prometheus_metrics.is_empty()); +<<<<<<< HEAD +======= + #[tokio::test(flavor = "multi_thread")] + async fn it_test_prometheus_metrics_units_are_included() { + async { + let plugin = + create_plugin_with_config(include_str!("testdata/prometheus.router.yaml")).await; + u64_histogram_with_unit!("apollo.test.histo1", "no unit", "{request}", 1u64); + f64_histogram_with_unit!("apollo.test.histo2", "unit", "s", 1f64); + + make_supergraph_request(plugin.as_ref()).await; + assert_prometheus_metrics!(plugin); } .with_metrics() .await; } +>>>>>>> 731fd23c (fix(telemetry): export properly resources configured on prometheus (#7394)) #[test] fn it_test_send_headers_to_studio() { let fw_headers = ForwardHeaders::Only(vec![ diff --git a/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics.snap b/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics.snap index eae5de460a..fda5aedfb9 100644 --- a/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics.snap +++ b/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics.snap @@ -1,7 +1,8 @@ --- source: apollo-router/src/plugins/telemetry/mod.rs -expression: prometheus_metrics +expression: "prometheus_metrics.replace(& format!\n(r#\"service_version=\"{}\"\"#, std :: env! (\"CARGO_PKG_VERSION\")),\nr#\"service_version=\"X\"\"#)" --- +<<<<<<< HEAD apollo_router_http_request_duration_seconds_bucket{status="200",otel_scope_name="apollo/router",le="+Inf"} 1 apollo_router_http_request_duration_seconds_bucket{status="200",otel_scope_name="apollo/router",le="0.001"} 1 apollo_router_http_request_duration_seconds_bucket{status="200",otel_scope_name="apollo/router",le="0.005"} 1 @@ -15,3 +16,18 @@ apollo_router_http_request_duration_seconds_bucket{status="200",otel_scope_name= apollo_router_http_request_duration_seconds_bucket{status="200",otel_scope_name="apollo/router",le="1"} 1 apollo_router_http_request_duration_seconds_bucket{status="200",otel_scope_name="apollo/router",le="10"} 1 apollo_router_http_request_duration_seconds_bucket{status="200",otel_scope_name="apollo/router",le="5"} 1 +======= +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="+Inf"} 1 +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.001"} 0 +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.005"} 0 +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.015"} 0 +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.05"} 0 +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.1"} 0 +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.2"} 0 +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.3"} 0 +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.4"} 0 +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.5"} 0 +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="1"} 1 +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="10"} 1 +apollo_test_histo_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="5"} 1 +>>>>>>> 731fd23c (fix(telemetry): export properly resources configured on prometheus (#7394)) diff --git a/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_custom_buckets.snap b/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_custom_buckets.snap index 3f346c2ad6..36ec479c30 100644 --- a/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_custom_buckets.snap +++ b/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_custom_buckets.snap @@ -1,6 +1,6 @@ --- source: apollo-router/src/plugins/telemetry/mod.rs -expression: prometheus_metrics +expression: "prometheus_metrics.replace(& format!\n(r#\"service_version=\"{}\"\"#, std :: env! (\"CARGO_PKG_VERSION\")),\nr#\"service_version=\"X\"\"#)" --- apollo_router_http_request_duration_seconds_bucket{status="200",otel_scope_name="apollo/router",le="+Inf"} 1 apollo_router_http_request_duration_seconds_bucket{status="200",otel_scope_name="apollo/router",le="10"} 1 diff --git a/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_custom_buckets_for_specific_metrics.snap b/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_custom_buckets_for_specific_metrics.snap index 49dfbd2b76..6f59420cd1 100644 --- a/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_custom_buckets_for_specific_metrics.snap +++ b/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_custom_buckets_for_specific_metrics.snap @@ -1,6 +1,6 @@ --- source: apollo-router/src/plugins/telemetry/mod.rs -expression: prometheus_metrics +expression: "prometheus_metrics.replace(& format!\n(r#\"service_version=\"{}\"\"#, std :: env! (\"CARGO_PKG_VERSION\")),\nr#\"service_version=\"X\"\"#)" --- apollo_router_http_request_duration_seconds_bucket{otel_scope_name="apollo/router",le="+Inf"} 1 apollo_router_http_request_duration_seconds_bucket{otel_scope_name="apollo/router",le="1"} 1 diff --git a/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_custom_view_drop.snap b/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_custom_view_drop.snap new file mode 100644 index 0000000000..e615546e4a --- /dev/null +++ b/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_custom_view_drop.snap @@ -0,0 +1,5 @@ +--- +source: apollo-router/src/plugins/telemetry/mod.rs +expression: "prometheus_metrics.replace(& format!\n(r#\"service_version=\"{}\"\"#, std :: env! (\"CARGO_PKG_VERSION\")),\nr#\"service_version=\"X\"\"#)" +--- + diff --git a/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_units_are_included.snap b/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_units_are_included.snap new file mode 100644 index 0000000000..b6cf273ce5 --- /dev/null +++ b/apollo-router/src/plugins/telemetry/snapshots/apollo_router__plugins__telemetry__tests__it_test_prometheus_metrics_units_are_included.snap @@ -0,0 +1,30 @@ +--- +source: apollo-router/src/plugins/telemetry/mod.rs +expression: "prometheus_metrics.replace(& format!\n(r#\"service_version=\"{}\"\"#, std :: env! (\"CARGO_PKG_VERSION\")),\nr#\"service_version=\"X\"\"#)" +--- +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="+Inf"} 1 +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.001"} 0 +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.005"} 0 +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.015"} 0 +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.05"} 0 +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.1"} 0 +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.2"} 0 +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.3"} 0 +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.4"} 0 +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.5"} 0 +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="1"} 1 +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="10"} 1 +apollo_test_histo1_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="5"} 1 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="+Inf"} 1 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.001"} 0 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.005"} 0 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.015"} 0 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.05"} 0 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.1"} 0 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.2"} 0 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.3"} 0 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.4"} 0 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="0.5"} 0 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="1"} 1 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="10"} 1 +apollo_test_histo2_seconds_bucket{otel_scope_name="apollo/router",service_version="X",test_resource="test",le="5"} 1 diff --git a/apollo-router/src/plugins/telemetry/testdata/prometheus.router.yaml b/apollo-router/src/plugins/telemetry/testdata/prometheus.router.yaml index 6273bcf4b2..238694e24e 100644 --- a/apollo-router/src/plugins/telemetry/testdata/prometheus.router.yaml +++ b/apollo-router/src/plugins/telemetry/testdata/prometheus.router.yaml @@ -4,5 +4,9 @@ telemetry: client_version_header: version_header exporters: metrics: + common: + resource: + "test-resource": "test" prometheus: enabled: true + resource_selector: all diff --git a/apollo-router/tests/integration/telemetry/metrics.rs b/apollo-router/tests/integration/telemetry/metrics.rs index 16febaa9b8..7239a436a1 100644 --- a/apollo-router/tests/integration/telemetry/metrics.rs +++ b/apollo-router/tests/integration/telemetry/metrics.rs @@ -73,10 +73,10 @@ async fn test_metrics_reloading() { if std::env::var("TEST_APOLLO_KEY").is_ok() && std::env::var("TEST_APOLLO_GRAPH_REF").is_ok() { router.assert_metrics_contains_multiple(vec![ - r#"apollo_router_telemetry_studio_reports_total{report_type="metrics",otel_scope_name="apollo/router"} 2"#, - r#"apollo_router_telemetry_studio_reports_total{report_type="traces",otel_scope_name="apollo/router"} 2"#, - r#"apollo_router_uplink_fetch_duration_seconds_count{kind="unchanged",query="License",url="https://uplink.api.apollographql.com/",otel_scope_name="apollo/router"}"#, - r#"apollo_router_uplink_fetch_count_total{query="License",status="success",otel_scope_name="apollo/router"}"# + r#"apollo_router_telemetry_studio_reports_total{report_type="metrics",otel_scope_name="apollo/router"} 2"#, + r#"apollo_router_telemetry_studio_reports_total{report_type="traces",otel_scope_name="apollo/router"} 2"#, + r#"apollo_router_uplink_fetch_duration_seconds_count{kind="unchanged",query="License",url="https://uplink.api.apollographql.com/",otel_scope_name="apollo/router"}"#, + r#"apollo_router_uplink_fetch_count_total{query="License",status="success",otel_scope_name="apollo/router"}"# ], Some(Duration::from_secs(10))) .await; } @@ -184,7 +184,11 @@ async fn test_bad_queries() { .await; router .assert_metrics_contains( +<<<<<<< HEAD r#"apollo_router_http_requests_total{error="Request body payload too large",status="413",otel_scope_name="apollo/router"} 1"#, +======= + r#"http_server_request_duration_seconds_count{error_type="Payload Too Large",http_request_method="POST",status="413",otel_scope_name="apollo/router"} 1"#, +>>>>>>> 731fd23c (fix(telemetry): export properly resources configured on prometheus (#7394)) None, ) .await; @@ -230,23 +234,23 @@ async fn test_graphql_metrics() { ) .await; router - .assert_metrics_contains(r#"graphql_field_list_length_sum{graphql_field_name="topProducts",graphql_field_type="Product",graphql_type_name="Query",otel_scope_name="apollo/router"} 3"#, None) - .await; + .assert_metrics_contains(r#"graphql_field_list_length_sum{graphql_field_name="topProducts",graphql_field_type="Product",graphql_type_name="Query",otel_scope_name="apollo/router"} 3"#, None) + .await; router - .assert_metrics_contains(r#"graphql_field_list_length_bucket{graphql_field_name="topProducts",graphql_field_type="Product",graphql_type_name="Query",otel_scope_name="apollo/router",le="5"} 1"#, None) - .await; + .assert_metrics_contains(r#"graphql_field_list_length_bucket{graphql_field_name="topProducts",graphql_field_type="Product",graphql_type_name="Query",otel_scope_name="apollo/router",le="5"} 1"#, None) + .await; router - .assert_metrics_contains(r#"graphql_field_execution_total{graphql_field_name="name",graphql_field_type="String",graphql_type_name="Product",otel_scope_name="apollo/router"} 3"#, None) - .await; + .assert_metrics_contains(r#"graphql_field_execution_total{graphql_field_name="name",graphql_field_type="String",graphql_type_name="Product",otel_scope_name="apollo/router"} 3"#, None) + .await; router - .assert_metrics_contains(r#"graphql_field_execution_total{graphql_field_name="topProducts",graphql_field_type="Product",graphql_type_name="Query",otel_scope_name="apollo/router"} 1"#, None) - .await; + .assert_metrics_contains(r#"graphql_field_execution_total{graphql_field_name="topProducts",graphql_field_type="Product",graphql_type_name="Query",otel_scope_name="apollo/router"} 1"#, None) + .await; router - .assert_metrics_contains(r#"custom_counter_total{graphql_field_name="name",graphql_field_type="String",graphql_type_name="Product",otel_scope_name="apollo/router"} 3"#, None) - .await; + .assert_metrics_contains(r#"custom_counter_total{graphql_field_name="name",graphql_field_type="String",graphql_type_name="Product",otel_scope_name="apollo/router"} 3"#, None) + .await; router - .assert_metrics_contains(r#"custom_histogram_sum{graphql_field_name="topProducts",graphql_field_type="Product",graphql_type_name="Query",otel_scope_name="apollo/router"} 3"#, None) - .await; + .assert_metrics_contains(r#"custom_histogram_sum{graphql_field_name="topProducts",graphql_field_type="Product",graphql_type_name="Query",otel_scope_name="apollo/router"} 3"#, None) + .await; router .assert_metrics_contains(r#"apollo_router_compute_jobs_duration_count{job_outcome="executed_ok",job_type="query_parsing",otel_scope_name="apollo/router"} 1"#, None) .await; diff --git a/docs/source/routing/observability/telemetry/metrics-exporters/prometheus.mdx b/docs/source/routing/observability/telemetry/metrics-exporters/prometheus.mdx index 8eec897f3f..daf76140db 100644 --- a/docs/source/routing/observability/telemetry/metrics-exporters/prometheus.mdx +++ b/docs/source/routing/observability/telemetry/metrics-exporters/prometheus.mdx @@ -24,11 +24,20 @@ To export metrics to Prometheus, enable the Prometheus endpoint and set its addr ```yaml title="router.yaml" telemetry: exporters: +<<<<<<< HEAD metrics: prometheus: enabled: true listen: 127.0.0.1:9090 path: /metrics +======= + metrics: + prometheus: + enabled: true + resource_selector: all # default: none + listen: 127.0.0.1:9090 + path: /metrics +>>>>>>> 731fd23c (fix(telemetry): export properly resources configured on prometheus (#7394)) ``` Once enabled, you will be able to access the Prometheus endpoint at `http://localhost:9090/metrics`. @@ -47,6 +56,10 @@ The address and port to listen on for Prometheus metrics. Defaults to `127.0.0.1 The path to expose the Prometheus metrics. Defaults to `/metrics`. +### `resource_selector` + +Resource selector is used to select which resource to export with every metrics. If it's set to `all`, it will export all resource attributes with every metrics. Defaults to `none`. + ## Prometheus configuration reference | Attribute | Default | Description |