Collecting metrics in the Apollo Router
The Apollo Router provides built-in support for metrics collection via Prometheus and OpenTelemetry Collector.
Using Prometheus
You can use Prometheus and Grafana to collect metrics and visualize the router metrics.
telemetry:metrics:prometheus:# By setting this endpoint you enable the prometheus exporter# All our endpoints exposed by plugins are namespaced by the name of the plugin# Then to access to this prometheus endpoint, the full url path will be `/plugins/apollo.telemetry/prometheus`enabled: true
Assuming you are running locally:
- Run a query against the router.
- Navigate to http://localhost:4000/plugins/apollo.telemetry/prometheus to see something like:
# HELP http_request_duration_seconds Total number of HTTP requests made.# TYPE http_request_duration_seconds histogramhttp_request_duration_seconds_bucket{le="0.5"} 1http_request_duration_seconds_bucket{le="0.9"} 1---SNIP---
Note that if you have not run a query against the router you will see a blank page as no metrics will have been generated yet!
Here is the list of available metrics you'll have using Prometheus:
- HTTP router request duration (
http_request_duration_seconds_bucket
) - HTTP request duration by subgraph (
http_request_duration_seconds_bucket
with attributesubgraph
) - Total number of HTTP requests by HTTP Status (
http_requests_total
) - Total number of HTTP requests in error (
http_requests_error_total
)
Using OpenTelemetry Collector
You may send metrics to OpenTelemetry Collector for processing and reporting metrics.
telemetry:metrics:otlp:# Either 'default' or a URLendpoint: default# Optional protocol. Only grpc is supported currently.# Setting to http will result in configuration failure.protocol: grpc# Optional Grpc configurationgrpc:domain_name: "my.domain"key:file: ""# env: ""ca:file: ""# env: ""cert:file: ""# env: ""metadata:foo: bar# Optional timeout in humatime formtimeout: 2s
Add custom attributes/labels
If you need to add attributes/labels on your generated metrics, for example add a custom attributes/labels coming from a specific header in the original HTTP router request, or insert custom attributes/labels on every metrics. You also have access to the body of subgraph/router request/response. And be able to add a custom attribute coming from the context filled in the plugins chain.
telemetry:metrics:common:attributes:router:static:- name: "version"value: "v1.0.0"request:header:- named: "content-type"rename: "payload_type"default: "application/json"- named: "x-custom-header-to-add"response:body:# Take element from the response body of the router located at this path- path: .errors[0].extensions.statusname: error_from_bodycontext:# Take element from context in plugin chains and add it in attributes- named: my_keysubgraph:all:static:# Always insert on all metrics for all subgraphs- name: kindvalue: subgraph_requestsubgraphs:my_subgraph_name: # Apply these rules only for the subgraph named `my_subgraph_name`request:header:- named: "x-custom-header"body:# Take element from the request body of the router located at this path (here it's the query)- path: .queryname: querydefault: UNKNOWN
Example of JSON Query to extract data from the body
If you have this data:
{"items": [{"unwanted": 7,"wanted": { "x": 3, "y": 7 },"array": [3, 2, 1]},{"whatever": true}]}
And want to fetch the field whatever
here is the syntax .items[1].whatever
. You can also try to fetch the field x
by using this query .items[0].wanted.x
. A JSON Query is always starting with a dot.