How to monitor MongoDB using Prometheus and Grafana on Docker? (Part-1)

Nihar Zanwar
4 min readJul 21, 2020

This is my first Medium post ever, so please excuse me if make any mistakes. I will try to put up steps and code snippets after testing so that you don't have to invest time in debugging it.

This post will explain how you can monitor your MongoDB instance and generate really cool graphs using drag and drop interface.

Prerequisites

  1. Docker installed on your system. Steps are given here.
  2. I will be working on Linux Environment(Ubuntu 20.04) but since we are working with docker I think anyone with docker installed on windows will not face many issues.

Components

  1. MongoDB — is a NoSQL document-based database.
  2. Prometheus — open-source monitoring and alarming tool used to collect metrics from various systems
  3. Grafana — multi-platform open-source analytics and interactive visualization tool. It provides charts, graphs, and alerts for the web when connected to supported data sources.
  4. mongodb_exporter — will be used to convert MongoDB parameters into a format understandable by Prometheus.

System Diagram

Steps

  1. We first create a docker network and name it mynetwork using the command on the terminal and give it a subnet of 172.29.0.0/24 so that we can add all our containers on the same network so that they can communicate with each other.
$ docker network create --subnet 172.29.0.0/24 mynetwork

to check if the network has been created you can type $ docker network ls and check in the list if you can find mynetwork .

2. We first make the MongoDB container using the below command

docker run \
-d \
--restart unless-stopped \
-p 27017:27017 \
-v `pwd`/data:/data/db \
--name mongodb \
-e "MONGO_INITDB_ROOT_USERNAME=root" \
-e "MONGO_INITDB_ROOT_PASSWORD=root" \
--network mynetwork \
--ip=172.29.0.2 \
mongo:latest

we have set username and pass as root:root but you should change it as per your preference. To check if the container is running run $ docker ps

We now need to create a user in the database for our mongodb_exporter to do this run docker exec -it mongodb mongo -u root -p then type the password(=root).

You will get MongoDB CLI. Now execute this query -

> use admin
> db.createUser(
{
user: "exporter",
pwd: "password",
roles: [
{ role: "clusterMonitor", db: "admin" },
{ role: "read", db: "local" }
]
}
)

3. Now we create the mongodb_exporter which will help Prometheus scrape data from MongoDB. To do this first we clone

$ git clone https://github.com/percona/mongodb_exporter
$ cd mongodb_exporter
$ docker build -t mongodb-exporter .

This will build the MongoDB-exporter image for us. To check if the image has been built docker image ls and find MongoDB-exporter listed there.

Now to run this image

docker run \
-d \
--name mongo_exporter_prometheus \
-e "MONGODB_URI=mongodb://exporter:password@172.29.0.2:27017" \
--network mynetwork \
--ip=172.29.0.3 \
mongodb-exporter

to confirm whether the exporter is working properly run docker logs mongo_exporter_prometheus this should be the output —

4. Now we have to setup Prometheus. Again we can run the docker command

docker run \
-it \
--name prometheus \
-p 9090:9090 \
--restart unless-stopped \
-v `pwd`/prometheus.yml:/etc/prometheus/prometheus.yml \
--network mynetwork \
--ip=172.29.0.4 \
prom/prometheus

open the prometheus.yml file created on your host directory and make change the contents is

global:
scrape_interval: 15s # By default, scrape targets every 15 seconds.
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: 'codelab-monitor'
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s
static_configs:
- targets: ['localhost:9090']

- job_name: 'mongodb'
# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s
static_configs:
- targets: ['172.29.0.3:9216']

this is YAML format file so please use an editor to ensure the correct format. Prometheus scrapes targets using the using HTTP GET, so by default, it scrapes /metrics endpoint but we can specify otherwise. Once you have saved this prometheus.yaml you can restart your Prometheus container by docker container prometheus restart

To verify that Prometheus is working you can go to your web browser to and type localhost:9090 .

Assuming Prometheus is working you can check status of your MongoDB on the browser page by clicking on Status ->Targets. You can query the different metrics of MongoDB using the PromQL language, documentation for which you can find here.

5. Now to set up Grafana we can again execute the command

docker run \
-d \
--restart unless-stopped \
--name grafana \
-p 3000:3000 \
--network mynetwork \
--ip=172.29.0.5 \
grafana/grafana:latest

To check if the container is running go to localhost:3000 on your browser window. If it is working a login page will come up the default username:password to this isadmin:admin .

After this, you have to add Prometheus data-source

Do not change any other settings. Click on Save & Test. Hopefully, it should be able to connect to the Prometheus.

All that is left to do now is to create your dashboard using Prometheus as your data source.

In the next part, I will show how to make different graphs on Grafana

As this is my first technical blog I would love to know your views and criticisms.

--

--

Nihar Zanwar

I am a final year Undergrad studying at BITS Pilani, India. OSS and system design enthusiast.