I’ve written a High level view of Opentelemetry, and visualising Opentelemetry data in Jaeger.
This blog post is about the Opentelemetry aggregated data, and displaying it in Grafana.
Prometheus accepts metric data from sources like Opentelemetry, but it does not take the raw Opentelemetry “log” data from application directly into Prometheus. There is a component System Performance Measuring(SPM) which takes the OTEL log data and creates metrics. It runs in Opentelemetry collector, or the Jaeger program. (I think running it in Opentelemetry collector is better, because running it in Jaeger did not immediatelygive me all of the records)
The SPM code takes each record
- extracts hinformation from the OTEL logs. For example the service name, the span name, and others fields that have been configured in the configuration file
Conceptually the SPM code takes all the records received in a time interval – say 10 seconds, and creates two records
- traces_span_metrics_duration_milliseconds_count
- traces_span_metrics_duration_milliseconds_sum
and copies in the default dimensions (meta data) and which additional dimensions have been configured to be included. My simplistic view would have had one record with both the sum and the count, but this is not how it is done. There is a lot of additional data for each of the generated records, but I cannot find how to use it.
See here for information
The span metrics processor works by inspecting every received span and computing the total count and the duration of spans for every unique combination of dimensions. Dimensions can be the service name, the operation, the span kind, the status code and any attribute present in the span.
You can display the data in Prometheus, but you can do so much more with Grafana. I did Unit Testing with Grafana, and my System Testing using Grafana, because Grafana can save queries and dashboards.
It will help if you are familiar with the Prometheus data model.
First query
The values traces_span_metrics_duration_milliseconds_sum and traces_span_metrics_duration_milliseconds_count are ever increasing.
To find the average value over 1 minute intervals use (see here for an explanation)
increase(traces_span_metrics_duration_milliseconds_sum[1m])/ increase(traces_span_metrics_duration_milliseconds_count[1m])
If you move the mouse over a colour, it gives you information about that point (see the purple data below). The pop-up shows it is for an MQPUT to CSERVER for queue manager (=service name) CSQ9, with a duration of 1.52 ms.
Below the chart is all the data for the items.
There is data on the chart for every combination of dimensions/parameters/meta data. These items include information like
service.name: CSQ9
span.name: MQPUT CSERVER
span.kind: SPAN_KIND_PRODUCER
status.code: STATUS_CODE_UNSET
collector.instance.id: 2e1c51fc-7f54-4da5-aa9f-9c3cac190103
w3.tracestate: rojo=MODEL – this is what I passed on the trace data.
I had some data with service.name MQPA, and different span.names

This is for all resources
You can select which records are displayed, for example
rate(traces_span_metrics_duration_milliseconds_sum{w3_tracestate= "rojo=MODEL"}[$__rate_interval])
Selects those with the property w3.tracestate = “rojo=MODEL”. I specified this by setting the MQ message propery
tracestate=rojo=MODEL
You can control which parameters are passed from the original records into the aggregated records. See the dimensions parameter in the span_metrics: definitions.
Set up data source
You can set up different data sources. I have one for Prometheus, and one or Jaeger. Once you have configured them you can use explore to look at the data.
Set up dashboards
You can set up dashboard to display the data in different ways.
You specify the data source, and then how you want the data formatted, typically I use a timeline.
You can use Builder |code to define your query. With builder you define the query through a GUI. With code you specify the query.
You can define multiple queries which display on the same windows. You can hide/unhide the data from each query, by selecting/unselecting the query.
You could define one query for w3_tracestate= “appl=OnlineBanking”, and another for w3_tracestate= “appl=OfflineBanking”.
Time ranges
From a pull down you can select “last 5 minutes”, “last 15 minutes”, or you can specify a date and time range. This means you can go back to a previous days data.
I have it refreshing the data every 5 seconds, and the graph data gradually creeps left, until the data falls out of the displayed time range.
Data links
On each page you can set up data links. If you hover your graphic cursor over a data item, it shows the data item’s attributes in a pop up window. You can also configure data links, which appear on in the pop up window, so you can link to another URL, passing data from the data items.
In the figure below, I graphed the top 4 span_names with the highest average value. It has a data link called colins jaeger2

By clicking on the “colins jaeger2” it invoked the URL, and passed the __from and __to times, in the URL.
