labs

This lab has been modernised but not yet verified end to end. Tell us if something breaks.

Visualizing Metrics with Grafana

40 dkdockerView on GitHub
On this page

Grafana

Grafana is a web-based UI for visualizing data. It can consume data from many different sources, and it's particularly well matched with Prometheus. You might use the Prometheus UI to fine-tune your queries, and then you'd take the PromQL and use it in Grafana.

The screenshots and the written steps in this lab were both taken on Grafana 13.2.4, the version the containers run. Menu labels do move between Grafana releases - if something has shifted again, the Grafana docs are authoritative.

Reference

Run Grafana

Grafana is a cross-platform app, written in Go. You can download Grafana for different platforms - but we'll run in a Docker container:

  • grafana.yml - specifies containers for Prometheus and Grafana
  • prometheus.yml - the Prometheus config we'll be using; sets up scraping for various apps, and adds the tier label

Run the metrics components:

docker compose -f labs/grafana/grafana.yml up -d

Check the Prometheus status at http://localhost:9090/targets

You'll see all the targets are down, but the tier label is set along with instance and job. You can add to target labels like this to include infrastructure-specific details; you might include the region for cloud services, or the operating system and CPU architecture.

Browse to Grafana at http://localhost:3000

Sign in with the default credentials - you'll be asked to create a new password, but you can skip that step:

  • username: admin
  • password: admin

In current Grafana you add a data source from Connections > Data sources:

Grafana home screen

📋 Add a Prometheus data source, with the URL http://prometheus:9090 and test it.

Need some help?

Open Connections > Data sources from the left nav and click Add new data source (or browse straight to http://localhost:3000/connections/datasources/new).

  • Select Prometheus as the data source type
  • Enter http://prometheus:9090 in the Prometheus server URL field
  • Leave all other fields as they are

Click Save & test and you'll see the message Data source is working.


That's all the setup you need - now you can create a dashboard with panels to query Prometheus.

Create an uptime panel

Open Dashboards from the left nav, then New > New dashboard. You'll see an empty dashboard like this:

Empty dashboard

Every visualization is a panel within a dashboard.

📋 Add a new panel to show the uptime of Prometheus targets using the up metric.

Need some help?

The empty dashboard asks you to Select layout - pick either Auto grid or Custom grid, then click Add and choose Panel. (Grafana 13 replaced the old + Add visualization button with this layout picker.) The panel editor opens on your default data source; enter up in the query editor. You'll see a preview of the visualization, which is not quite what we want:

Default time series preview of the up metric


The panel designer is in three sections:

  • visualization preview at the top
  • data on the bottom, including the query and transforms
  • display options on the right, including visualization type

The defaults are to use a Time series visualization, representing a range vector from Prometheus.

Now it's time to find your way around 🙂

📋 Change the panel setup so Grafana treats this as a table showing an instant vector, using a table visualization. Set up the table so the instance name and status are the only fields, showing ok for instances which are up and OFFLINE for others.

Here's what you're aiming for:

Target uptime as a table with ok/OFFLINE value mappings

Need some help?

In the Query panel:

  • set Format to Table
  • set Type to Instant

In Grafana 13 these live under Options in the query row. Instant used to be a checkbox; it is now one of the two Type choices (Range or Instant).

In the display options:

  • change type to Table

In the Transformations tab (next to Query):

  • Select Organize fields by name
    • hide all except instance and value
    • rename value to Status

Back in display options:

  • Add a title
  • scroll to Value mappings and click Add value mappings (the button reads

    Edit value mappings once you have some)

    • add a mapping for value=0 to display OFFLINE
    • add a mapping for value=1 to display ok
    • click Apply

Click Back at the top-right to return to the dashboard, then Save to keep it. (Both buttons were named Back to dashboard and Save dashboard in older Grafana.)


Grafana dashboards can be set to auto-refresh. Select to refresh every 5 seconds (top-right of the dashboard), so when we start the apps you'll see the table update as they come online.

Visualization Types

Start the apps, so Prometheus will have some metrics to collect:

  • apps.yml - specifies the node exporter, document API and three document processors; one of the processors is configured to keep exiting and restarting.

Run the apps:

docker compose -f labs/grafana/apps.yml up -d

Switch back to Grafana - you'll see the table update as instances come online.

If you watch long enough you'll see processor instance 1 flicks between ok and OFFLINE. The table we have shows the current status, and it would also be useful to see the history of each component's uptime.

Click Add in the top menu and choose Panel to add a second panel.

Last time we used a transform to hide labels, but we can do that in the query too:

  • set the query to be sum without(job, tier) (up)
  • change the visualization type to State timeline
  • add the same value mapping to show 0 as OFFLINE and 1 as ok
  • change the time range to (e.g.) last 15 minutes

We're getting there, just some tidying up to do.

📋 Edit the query and display options so the legend on the y-axis is more useful, hide the x-axis legend, and show OFFLINE as a red bar and ok as green.

This is the goal:

Target uptime as a state timeline, green for ok and red for OFFLINE

Need some help?

In the display options:

  • add a panel title
  • scroll to Legend
    • set Legend mode to Hidden
  • scroll to Thresholds
    • set the base value to the colour red
    • set the next threshold to 1 and the colour green

In the query panel:

  • set the legend format to {{instance}}

Click Back.


That's better - the dashboard now shows current and historical status for all the instances. We can see there's a recurring problem with processor 1, which isn't clear from the table alone.

A Real Dashboard

Grafana can be fiddly to work with - but once you have your dashboard designed, you can load it into any Grafana server.

In the lab we'll carry on with a custom dashboard, but so you can see what a real dashboard looks like, there's one stored in the file labs/grafana/dashboards/app.json you can load:

  • open Dashboards from the left nav, then New > Import
  • click Upload dashboard JSON file and navigate to the path for the

    app.json file

  • select your Prometheus data source if you are prompted, then click Import

These visualizations are all powered by the metrics from the container apps you have running. You can reduce the timescale from the dropdown in the top-right and show metrics from the last 30 minutes to see how Grafana shows trends.

Lab

You'll have several dashboards for your apps, showing information at different levels.

For this lab we'll stick with instance uptime, but your job is to split the dashboard into multiple rows, one for each tier of the application:

  • an infrastructure row with the node exporter instance
  • a web row with the document API instance
  • a backend row with the processor instances

Each row should have a current status table and an timeline for the instances in that tier, something like this:

Uptime dashboard split into infrastructure, web and backend rows

Save your dashboard as JSON so you can load it into another Grafana instance later.

Stuck? Try hints or check the solution.


Cleanup

Clean up by removing this lab's containers:

docker compose -f labs/grafana/grafana.yml down
docker compose -f labs/grafana/apps.yml down

This removes only the containers this lab started. If you want a clean slate, docker ps will show anything still running.