A Comprehensive Guide to Prometheus Exporters
Prometheus' ability to collect and analyze metrics from a wide range of sources is essential for ensuring the health and performance of your applications and infrastructure.
But what happens when the systems you want to monitor don't speak Prometheus's language? That's where exporters come in.
They act as translators, converting metrics from diverse systems into a format compatible with Prometheus. With Exporters, your monitoring capabilities become virtually limitless. Regardless of the system or technology, there's likely an exporter available to integrate it into your observability stack.
This article is your comprehensive guide to Prometheus exporters. We'll explore what they are, how they work, how to customize them, and even how to build your own if needed.
Let's get started!
What are Prometheus Exporters?
Many applications and systems are not inherently designed to expose metrics in a format that Prometheus can directly consume.
Exporters bridge this gap by acting as intermediaries, translating diverse data formats into the standardized Prometheus format.
This allows Prometheus to monitor a broad array of targets, including those without native Prometheus support.
Here's how it works:
- Metric collection: An exporter gathers data from a specific source, which could be anything from a database like PostgreSQL to a hardware device like a network switch.
- Metric transformation: The collected data is then converted into the Prometheus exposition format, making it compatible with Prometheus' scraping mechanism.
- Metric exposition: The transformed metrics are exposed via an HTTP endpoint, allowing Prometheus to retrieve them at regular intervals.
A vast ecosystem of exporters exists, ranging from official Prometheus-maintained exporters to community-contributed ones. Below are some popular examples:
- Node Exporter: Collects system metrics on Linux/Unix.
- PostgreSQL Exporter: Provides insights into the query execution times and other related statistics for PostgreSQL instances.
- MySQL Exporter: The MySQL equivalent of the PostgreSQL exporter.
- Blackbox Exporter: Allows blackbox probing of endpoints over HTTP, HTTPS, DNS, TCP, and gRPC.
- JMX Exporter: Collects metrics from a wide variety of JVM-based applications such as Apache Kafka and Cassandra.
When no existing exporter is available for a specific system, you can create a custom exporter to collect and expose its metrics. We'll delve into how to write your own exporter later on in this article.
Let's look at how to use exporters next.
How to use Prometheus Exporters
Using Prometheus exporters involves identifying the systems you want to monitor and selecting the appropriate exporter if the system doesn't natively expose Prometheus-compatible metrics.
Prometheus has a well-established presence in the monitoring space, resulting in a vast ecosystem of exporters for various systems and applications. In most cases, you won't need to build your own exporter, as the Prometheus community and vendors have likely already created and maintained one for your needs.
For example, if you want to monitor your Nginx servers with Prometheus, you can use the official NGINX Prometheus exporter provided by the Nginx team.
Once you've selected the relevant exporter, you'll need to install it. Usually, a static binary and a Docker image will be provided, but you should confirm the specific options available from the exporter's documentation.
Once the exporter is installed, you must connect it to your system or application. Most exporters only require minimal configuration to start working.
Next, you'll need to update your Prometheus configuration file to include the exporter's HTTP endpoint as a scrape target. If Prometheus can successfully scrape your metrics, you've set it up correctly.
Let's set up the Nginx Prometheus Exporter to monitor Nginx metrics to see this process in action. You only need to have Docker installed to follow along.
Scraping Nginx metrics with Prometheus
Nginx exposes a handful of basic server metrics via the stub_status page page which looks like this:
This page provides a snapshot of server activity, showing the number of active connections, total accepted and handled connections, processed requests, and the current state of connections: those reading client requests, writing responses, and waiting for new requests.
Our task is to set up an Nginx exporter to collect these metrics, transform them to the Prometheus format, and expose them for scraping by the Prometheus server.
To get started, let's use Docker Compose to configure and deploy the following services:
nginx: The web server exposing metrics via the/stub_statusendpoint.nginx-exporter: Collects metrics from the Nginx/stub_statusendpoint and transforms them to the Prometheus format.prometheus: Scrapes and stores the metrics exposed by thenginx-exporter.
Here's the docker-compose.yml file to set up the environment:
In this file, the nginx service is configured to listen at port 80, the
nginx-exporter is configured to listen at port 9113, while the prometheus
service is set up to listen at port 9090.
Looking at the nginx-exporter configuration, you'll see that it is configured
to scrape the status page at http://nginx:80/stub_status so that it can
access the raw Nginx metrics.
For this to work, you need to ensure your Nginx server exposes this page
accordingly. You can do this by extracting the Nginx configuration file from the
nginx image with:
Then open the resulting nginx.conf file and modify it as follows:
With this in place, the /stub_status endpoint will now be exposed and
accessible by the nginx-exporter service.
You'll also need to set up Prometheus to scrape the nginx-exporter by creating
a configuration file as follows:
With this in place, you're all set to launch the services with:
Once the services are started, make a request to http://localhost/stub_status
to see the raw Nginx metrics:
Let's confirm that the Nginx exporter is able to scrape the metrics by heading
to http://localhost:9113/metrics. Look for metrics with the nginx_ prefix,
such as:
If you're running Nginx plus, the exporter can scrape a lot more metrics. You can see the full list in its GitHub repository.
Finally, head over to http://localhost:9090/targets in your browser. You
should see the Nginx exporter listed and actively scraped:
With this setup complete, you can use Prometheus or an observability tool like Better Stack to query and visualize metrics.
Preventing metrics explosion in Prometheus
Exporters often expose more metrics than you need, including metrics for the monitored system or application, as well as the exporter itself.
Monitoring a large number of services without managing these metrics can lead to a metrics explosion that could significantly increase storage costs and query execution times.
To avoid this, it's necessary to drop unneeded metrics whenever possible. Here are some strategies to achieve this:
1. Disabling unnecessary metrics in the exporter
Exporters often expose their own internal metrics, typically prefixed with
promhttp_, process_, or go_. For example:
With the Node exporter, you can use
the --web.disable-exporter-metrics flag to drop such metrics.
You can also disable certain collectors with:
Or you can use an allowlist by combining the following flags:
Ensure to check the documentation of the exporter you're using to see if similar flags are available.
2. Using Prometheus metric relabeling
If the exporter does not support disabling metrics, Prometheus allows you to drop unwanted metrics during scraping using metric relabeling.
For example, to drop metrics prefixed with go_, add the following to your
Prometheus configuration:
With this in place, you'll no longer see the go_ prefixed metrics in
Prometheus.
Currently, the Nginx exporter does not support disabling specific metrics, although there's an open issue tracking this feature. For now, you can use the metric relabeling technique to drop unused metrics.
Writing custom exporters
When monitoring a system that doesn't have an existing Prometheus exporter, you may need to create a custom exporter.
To see how this works, let's recreate some functionality of the official Nginx
Prometheus Exporter by creating a custom exporter for Nginx metrics through its
stub_status module.
To get started, clone the custom-nginx-exporter repository to your machine and navigate into the created directory:
This repository contains an implementation of a custom exporter written in Go. You can also create custom exporters with any language that has a working Prometheus client library such as Python, Java, Rust, and others.
To examine the code, open up the main.go file in your text editor.
Here's the part that scrapes the raw Nginx metrics into structured data:
The templateMetrics variable is a format string that represents the structure
of the NGINX /stub_status output. It matches the metrics exposed by the
endpoint, and each placeholder (%d) corresponds to a metric to be extracted.
The GetStubStats() function fetches the raw data from the /stub_status
endpoint and parses it into the StubStats struct by calling the
parseSubStats() function.
The second part of the code is what translates the Nginx stub_status metrics
into a format Prometheus can scrape. It uses the
Prometheus Go client library
to define, describe, and collect metrics dynamically:
The metrics struct holds prometheus.Desc descriptions for Nginx-related
metrics. Each field in the struct corresponds to a specific Nginx metric, and it
is initialized by calling NewMetrics().
The CollectMetrics struct implements the
prometheus.Collector
interface, which defines how metrics are described and collected dynamically.
In the Describe() method, metric descriptors are sent to a Prometheus-provided
channel, while the Collect() method dynamically collects Nginx metrics with
GetStubStats() and converts the collected data into Prometheus-compatible
metrics using prometheus.MustNewConstMetric().
The main() function ties everything together by initializing the
CollectMetrics struct, creating an HTTP server listening on port 9113, and
exposing the metrics on the /metrics endpoint for Prometheus scraping:
To see this in action, ensure that you don't have an existing nginx,
nginx-exporter or prometheus instance running. Then execute the following
command from the custom-nginx-exporter directory root:
Once the services are running, visit http://localhost:9113/metrics to verify
the metrics are exposed:
You can then query the metrics in Prometheus as follows:
To see a production-grade implementation, check out the nginx-prometheus-exporter GitHub repository or any of the other exporters available.
Prometheus also provides some guidelines and best practices for writing custom exporters so be sure to read through them accordingly.
Final thoughts
Prometheus exporters play a crucial role in extending its monitoring capabilities to systems and applications that do not natively expose metrics in its format.
However, managing exporters efficiently is just as important as setting them up in the first place.
By dropping unused metrics and using Prometheus' metric relabeling features, you can optimize resource usage and keep metric collection and storage costs under control.
Thanks for reading, and happy monitoring!