MongoDB Exporter

Review
Exporters
Helm Charts
Rules
Dashboards
Discussion

The MongoDB exporter is required to expose metrics from the NoSQL database MongoDB, a critical resource so downtown can cause significant losses. Find out all about the exporter in this article.

About MongoDB

Unlike PostgreSQL and MySQL, MongoDB is a NoSQL database. This means it is non-relational, document-oriented with a dynamic schema database. Instead of using tables and rows like in traditional relational databases, MongoDB makes use of collections and documents. Documents consist of key-value pairs, which is the basic unit of data in MongoDB. Collections contain sets of documents and functions, which are the equivalent of relational database tables.

Since databases are a critical resource and downtime can cause significant financial and reputation losses, monitoring is a must. A MongoDB exporter is required to monitor and expose MongoDB metrics. It queries MongoDB, scraps the data, and exposes the metrics to a Kubernetes service endpoint that can further be scrapped by Prometheus to ingest the time series data. 

For monitoring of MongoDB, an external Prometheus exporter can be used, which is maintained by the Prometheus Community. On deployment, this exporter collects and exports oplog, replica set, server status, sharding, and storage engine metrics. It handles all metrics exposed by MongoDB monitoring commands. It loops over all the fields exposed in diagnostic commands and tries to get data from them. This way, the MongoDB exporter helps users get crucial and continuous information about the database which is difficult to get from the DB directly.

How do you set up an exporter for Prometheus?

With the latest version of Prometheus (2.33 as of February 2022), these are the ways to set up a Prometheus exporter: 

Method 1 - Native

Supported by Prometheus since the beginning
To set up an exporter in native way a Prometheus config needs to be updated to add the target.
A sample configuration:

# scrape_config job - job_name: mongodb-staging scrape_interval: 45s scrape_timeout: 30s metrics_path: "/metrics" static_configs: - targets: - <mongodb exporter endpoint>
Code language: PHP (php)
Method 2 - Pod Discovery

This method is applicable for Kubernetes deployment only
With this, a default scrap config can be added to the prometheus.yaml file and an annotation can be added to the exporter service. With this, Prometheus will automatically start scrapping the data from the services with the mentioned path.

Prometheus.yaml

- job_name: "kubernetes-pods" kubernetes_sd_configs: - role: pod
Code language: JavaScript (javascript)

Exporter service:

 annotations:     prometheus.io/path: /metrics     prometheus.io/scrape: "true"
Code language: PHP (php)
Method 3 - Prometheus Operator

Setting up a service monitor
The Prometheus operator supports an automated way of scraping data from the exporters by setting up a service monitor Kubernetes object. A sample service monitor for MongoDB can be found here.
These are the necessary steps:

Step 1

Add/update Prometheus operator’s selectors. By default, the Prometheus operator comes with empty selectors which will select every service monitor available in the cluster for scrapping the data.

To check your Prometheus configuration:

Kubectl get prometheus -n <namespace> -o yaml
Code language: HTML, XML (xml)

A sample output will look like this.

ruleNamespaceSelector: {} ruleSelector: matchLabels: app: kube-prometheus-stack release: kps scrapeInterval: 1m scrapeTimeout: 10s securityContext: fsGroup: 2000 runAsGroup: 2000 runAsNonRoot: true runAsUser: 1000 serviceAccountName: kps-kube-prometheus-stack-prometheus serviceMonitorNamespaceSelector: {} serviceMonitorSelector: matchLabels: release: kps
Code language: CSS (css)

Here you can see that this Prometheus configuration is selecting all the service monitors with the label release = kps

So with this, if you are modifying the default Prometheus operator configuration for service monitor scrapping, make sure you use the right labels in your service monitor as well.

Step 2

Add a service monitor and make sure it has a matching label and namespace for the Prometheus service monitor selectors (serviceMonitorNamespaceSelector & serviceMonitorSelector).

To enable service monitor run:

helm install <RELEASE_NAME> prometheus-community/prometheus-mongodb-exporter --set serviceMonitor.enabled=true
Code language: HTML, XML (xml)

Sample configuration:

apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: annotations: meta.helm.sh/release-name: mongodb-exporter meta.helm.sh/release-namespace: monitor generation: 1 labels: app: prometheus-mongodb-exporter app.kubernetes.io/managed-by: Helm heritage: Helm release: kps name: mongodb-exporter-prometheus-mongodb-exporter namespace: monitor spec: endpoints: - interval: 15s port: mongodb-exporter selector: matchLabels: app: prometheus-mongodb-exporter release: mongodb-exporter

Here you can see we have a matching label on the service monitor release = kps that we are specifying in the Prometheus operator scrapping configuration.

How do you set up an exporter: MongoDB with sidecar exporter

There is another way of scrapping metrics from MongoDB is using the Bitnami images. With the Bitnami Helm charts, the MongoDB exporter can be deployed as a sidecar container in the same pod.
To enable the side car:

helm upgrade --install my-release bitnami/mongodb --set architecture=replicaset --set metrics.enabled=true --set metrics.extraFlags="--compatible-mode"
Code language: JavaScript (javascript)

More details can be found here.

After enabling, sidecar Prometheus metrics are exported by the built-in container on the “/metrics” endpoint that can be scrapped by Prometheus. Once metrics are enabled, Helm will automatically add the annotation to the mongodb pods.
Annotation:

annotations: prometheus.io/path: /metrics prometheus.io/scrape: "true"
Code language: PHP (php)

Now Prometheus will automatically start scraping the data if the pod discovery is enabled.
Prometheus configuration for pod discovery:

- job_name: "kubernetes-pods" kubernetes_sd_configs: - role: pod
Code language: JavaScript (javascript)

Metrics

The following ones are handpicked metrics that will provide insights into MongoDB. Metrics keys will be different based on the type of exporter that is deployed, but the functionality is the same for all exporters.

  1. MongoDB is up
    This shows whether the last scrape of metrics from MongoDB was able to connect to the server.
    ➡ The key of the exporter metric is “mogodb_up”
    ➡ The value of the metric is a boolean -  1 or 0 which symbolizes if MongoDB is up or down respectively (1 for yes, 0 for no) 
  1. Too many connections
    MongoDB connections depend on the resources available on the system. Unless constrained by system-wide limits, the maximum number of incoming connections supported by MongoDB is configured with the maxIncomingConnections setting. The number of connections between the applications and the database can overwhelm the ability of the server to handle requests. Therefore, it is important to monitor the number of connections.
    ➡ The metric “mongodb_connections{state="current"}” gives the total current connections on MongoDB
    ➡ The number can be calculated based on “mongodb_connections{state="available"}” which shows the maximum connection availability of the database server
  1.  MongoDB replication lag
    Replication lag is a delay between an operation on the primary, and the application of that operation from the oplog to the secondary. Replication lag can be a significant issue and can seriously affect MongoDB replica set deployments. Excessive replication lag makes "lagged" members ineligible to quickly become primary and increases the possibility that distributed read operations will be inconsistent.
    ➡ The metric key is “mongodb_mongodb_replset_member_optime_date” (Promentheus community) or “mongodb_replset_member_optime_date”(bitnami) based on the exporter used
    ➡ The lag can be calculated by comparing the optime date between primary and secondary
  1. MongoDB replica set status
    Each member of a replica set has a state represented by a number. The numbers 1 and 2 represent primary and secondary, and any other value indicates an issue. You can find the list of states here.
    ➡ The metric “mongodb_mongodb_replset_member_state”  shows the member state
  1. MongoDB memory
    This metric will give us insight into the target system architecture of MongoDB and current memory usage.
    ➡ The metric  “mongodb_memory” includes 4 types of memory: mapped, mapped_with_journal, resident, and virtual
  • percona/mongodb_exporter
  • percona/mongodb_exporter

    MongoDB exporter

    Release
    Build Status
    codecov.io Code Coverage
    Go Report Card
    CLA assistant
    Discord

    This is the new MongoDB exporter implementation that handles ALL metrics exposed by MongoDB monitoring commands.
    This new implementation loops over all the fields exposed in diagnostic commands and tries to get data from them.

    Currently, these metric sources are implemented:

    • $collStats
    • $indexStats
    • getDiagnosticData
    • replSetGetStatus
    • serverStatus

    Info on Percona MongoDB exporter versions

    The old 0.1x.y version (ex master branch) has been moved to the release-0.1x branch.

    A flag, --compatible-mode, which exposes metrics with 0.1x compatible metric
    names has been implemented which simplifies migration from the old version to
    the current version.

    Build the exporter

    The build process uses the dockerized version of goreleaser so you don't need to install Go.
    Just run make release and the new binaries will be generated under the build directory.

    ├── build
    │ ├── config.yaml
    │ ├── mongodb_exporter_7c73946_checksums.txt
    │ ├── mongodb_exporter-7c73946.darwin-amd64.tar.gz
    │ ├── mongodb_exporter-7c73946.linux-amd64.tar.gz
    │ ├── mongodb_exporter_darwin_amd64
    │ │ └── mongodb_exporter <--- MacOS binary
    │ └── mongodb_exporter_linux_amd64
    │ └── mongodb_exporter <--- Linux binary

    Running the exporter

    If you built the exporter using the method mentioned in the previous section, the generated binaries are in mongodb_exporter_linux_amd64/mongodb_exporter or mongodb_exporter_darwin_amd64/mongodb_exporter

    Docker

    A docker image is available on the official percona repository.

    Examples
    # with podman
    podman run -d -p 9216:9216 -p 17001:17001 percona/mongodb_exporter:0.20 --mongodb.uri=mongodb://127.0.0.1:17001
    
    # with docker
    docker run -d -p 9216:9216 -p 17001:17001 percona/mongodb_exporter:0.20 --mongodb.uri=mongodb://127.0.0.1:17001

    Permissions

    Connecting user should have sufficient rights to query needed stats:

          {
             "role":"clusterMonitor",
             "db":"admin"
          },
          {
             "role":"read",
             "db":"local"
          }

    More info about roles in MongoDB documentation.

    Example

    mongodb_exporter_linux_amd64/mongodb_exporter --mongodb.uri=mongodb://127.0.0.1:17001

    Enabling collstats metrics gathering

    --mongodb.collstats-colls receives a list of databases and collections to monitor using collstats.
    Usage example: --mongodb.collstats-colls=database1.collection1,database2.collection2

    mongodb_exporter_linux_amd64/mongodb_exporter --mongodb.uri=mongodb://127.0.0.1:17001 --mongodb.collstats-colls=db1.c1,db2.c2

    Enabling compatibility mode.

    When compatibility mode is enabled by the --compatible-mode, the exporter will expose all new metrics with the new naming and labeling schema and at the same time will expose metrics in the version 1 compatible way.
    For example, if compatibility mode is enabled, the metric mongodb_ss_wt_log_log_bytes_written (new format)

    # HELP mongodb_ss_wt_log_log_bytes_written serverStatus.wiredTiger.log.
    # TYPE mongodb_ss_wt_log_log_bytes_written untyped
    mongodb_ss_wt_log_log_bytes_written 2.6208e+06

    will be also exposed as mongodb_mongod_wiredtiger_log_bytes_total with the unwritten label.

    HELP mongodb_mongod_wiredtiger_log_bytes_total mongodb_mongod_wiredtiger_log_bytes_total
    # TYPE mongodb_mongod_wiredtiger_log_bytes_total untyped
    mongodb_mongod_wiredtiger_log_bytes_total{type="unwritten"} 2.6208e+06

    Cluster role labels

    The exporter sets some topology labels in all metrics.
    The labels are:

    • cl_role: Cluster role according to this table:
    Server typeLabel
    mongosmongos
    regular instance (primary or secondary)shardsvr
    arbitershardsvr
    standalone(empty string)
    • cl_id: Cluster ID
    • rs_nm: Replicaset name
    • rs_state: Replicaset state is an integer from getDiagnosticData() -> replSetGetStatus.myState.
      Check the official documentation for details on replicaset status values.

    Usage Reference

    See the Reference Guide for details on using the exporter.

    Bug Reports / Feature PR

    Refer to the Contribution Guide.

  • MongoDB Exporter Helm Chart
  • MongoDB Exporter Helm Chart

    Helm chart to install MySQL

    If your MongoDB is not up and ready yet, you can start the MongoDB cluster using Helm:

    $ helm repo add bitnami https://charts.bitnami.com/bitnami
    $ helm upgrade --install my-release bitnami/mongodb --set architecture=replicaset --set metrics.enabled=true --set metrics.extraFlags="--compatible-mode"

    With these commands, MongoDB will be up and running with a sidecar container to expose Prometheus metrics.

    Please note:  “--compatible-mode” is enabled explicitly to expose all kinds of metrics (new and old format), so that most of the community dashboards can be used without alterations.

    In the case of an existing MongoDB or a MongoDB running outside of Kubernetes, we need to deploy an explicit exporter to get the metrics. For this, follow the steps below:

    Installing MongoDB Exporter

    The MongoDB exporter can be deployed in Kubernetes using the Helm chart. The Helm chart used for deployment is from the Prometheus community and can be found here. To deploy this Helm chart, users can either follow the steps in the above link or refer to the ones outlined below:

    $ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
    $ helm repo update
    $ helm install [RELEASE_NAME] prometheus-community/prometheus-mongodb-exporter

    Some of the common parameters that should be changed in the values file include: 

    mongodb.uri: <[mongodb[+srv]://][user:pass@]host1[:port1][,host2[:port2],...][/database][?options]>
    
    Ex:
    
    mongodb.uri:  “mongodb://root:password@mongodb.default.svc.cluster.local:27017/admin?authSource=admin”
    

    In case the user wants to pass the credentials as secrets, they can create a secret and pass the secret name in the following value file.

    existingSecret.name: <Secret name>

    Additional parameters can be changed based on the individual needs - such as enabling and disabling collectors, parameters, and so on. All these parameters can be tuned via values.yaml file here.

    In addition to the native way of setting up Prometheus monitoring, a service monitor can be deployed (if the Prometheus operator is being used) to scrap the data from MongoDB. Prometheus then scraps the data from the service monitor. With this approach, multiple MongoDB can be scrapped without altering the Prometheus configuration. Every MongoDB exporter comes with its own service monitor.

    In the above-mentioned chart, a service monitor can be deployed by turning it on from the values.yaml file here. By default, it is set to true.

    serviceMonitor:
      enabled: true
      interval: 30s
      scrapeTimeout: 10s
      namespace:
      additionalLabels: {}
      targetLabels: []
      metricRelabelings: []

    Another way of scraping metrics while having the pod discovery enabled in Prometheus is by updating the annotation section here with the following:

     ​​podAnnotations:
        prometheus.io/path: /metrics
        prometheus.io/scrape: "true"

    Here is a sample values file:

    mongodb:
      uri: ""
    
    # Name of an externally managed secret (in the same namespace) containing the connection uri as key `mongodb-uri`.
    # If this is provided, the value mongodb.uri is ignored.
    existingSecret:
      name: ""
      key: "mongodb-uri"
    
    nameOverride: ""
    
    nodeSelector: {}
    
    podAnnotations: {}
    #  prometheus.io/scrape: "true"
    #  prometheus.io/port: "metrics"
    
    port: "9216"
    
    priorityClassName: ""
    
    service:
      labels: {}
      annotations: {}
      port: 9216
      type: ClusterIP
    
    serviceAccount:
      create: true
      # If create is true and name is not set, then a name is generated using the
      # fullname template.
      name:
    
    serviceMonitor:
      enabled: true
      interval: 30s
      scrapeTimeout: 10s
      namespace:
      additionalLabels: {}
      targetLabels: []
      metricRelabelings: []

    This concludes our review of the exporter for MongoDB. Please feel free to reach out to us via support@nexclipper.io in case you have any questions. As always, stay tuned for more exporter reviews and tips coming soon!

  • MongoDB Exporter Alerts
  • MongoDB Exporter Alerts

    After digging into all the valuable metrics, this section explains in detail how we can get critical alerts.

    PromQL is a query language for the Prometheus monitoring system. It is designed for building powerful yet simple queries for graphs, alerts, or derived time series (aka recording rules). PromQL is designed from scratch and has zero common grounds with other query languages used in time series databases, such as SQL in TimescaleDB, InfluxQL, or Flux. More details can be found here.

    Prometheus comes with a built-in Alert Manager that is responsible for sending alerts (could be email, Slack, or any other supported channel) when any of the trigger conditions is met. Alerting rules allow users to define alerts based on Prometheus query expressions. They are defined based on the available metrics scraped by the exporter. Click here for a good source for community-defined alerts.

    A general alert looks as follows:

    - alert:(Alert Name)
    expr: (Metric exported from exporter) >/</==/<=/=> (Value)
    for: (wait for a certain duration between first encountering a new expression output vector element and counting an alert as firing for this element)
    labels: (allows specifying a set of additional labels to be attached to the alert)
    annotation: (specifies a set of informational labels that can be used to store longer additional information)

    Some of the recommended MongoDB alerts are:

    1. Alert - MongoDB is Down
    - alert: MongodbDown
      expr: mongodb_up == 0
      for: 0m
      labels:
        severity: critical
      annotations:
        summary: MongoDB Down (instance {{ $labels.instance }})
        description: "MongoDB instance is down\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
    1. Alert - MongoDB has too many connections
    - alert: MongodbTooManyConnections
      expr: avg by(instance) (rate(mongodb_connections{state="current"}[1m])) / avg by(instance) (sum (mongodb_connections) by (instance)) * 100 > 80
      for: 2m
      labels:
        severity: warning
      annotations:
        summary: MongoDB too many connections (instance {{ $labels.instance }})
        description: "Too many connections (> 80%)\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
    1.  Alert - MongoDB replication lag
    • Prometheus community:
     - alert: MongodbReplicationLag
       expr: mongodb_mongod_replset_member_optime_date{state="PRIMARY"}   - ON (set) mongodb_mongod_replset_member_optime_date{state="SECONDARY"} > 10
       for: 0m
       labels:
         severity: critical
       annotations:
         summary: MongoDB replication lag (instance {{ $labels.instance }})
         description: "Mongodb replication lag is more than 10s\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
    • Bitnami:
      - alert: MongodbReplicationLag
        expr: avg(mongodb_replset_member_optime_date{state="PRIMARY"}) - avg(mongodb_replset_member_optime_date{state="SECONDARY"}) > 10
        for: 0m
        labels:
          severity: critical
        annotations:
          summary: MongoDB replication lag (instance {{ $labels.instance }})
          description: "Mongodb replication lag is more than 10s\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
    1.   Alert -  MongoDB replication status (for Prometheus community exporter)
      - alert: MongodbReplicationStatus8
        expr: mongodb_mongod_replset_member_state == 8
        for: 0m
        labels:
          severity: critical
        annotations:
          summary: MongoDB replication Status 8 (instance {{ $labels.instance }})
          description: "MongoDB Replication set member as seen from another member of the set, is unreachable\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
    1.  Alert - High memory usage
     - alert: MongodbVirtualMemoryUsage
       expr: (sum(mongodb_memory{type="virtual"}) BY (instance) / sum(mongodb_memory{type="mapped"}) BY (instance)) > 3
       for: 2m
       labels:
         severity: warning
       annotations:
         summary: MongoDB virtual memory usage (instance {{ $labels.instance }})
         description: "High memory usage\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"

    Additionally, here are some other useful alerts:

    1. Alert - MongoDB curser time out - happens when too many operations are happening on MongoDB
    • With Prometheus community exporter:
      - alert: MongodbCursorsTimeouts
        expr: increase(mongodb_metrics_cursor_timed_out_total[1m]) > 100
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: MongoDB cursors timeouts (instance {{ $labels.instance }})
          description: "Too many cursors are timing out\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
    • With Bitnami:
      - alert: MongodbCursorsTimeouts
        expr: increase(mongodb_mongod_metrics_cursor_timed_out_total[1m]) > 100
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: MongoDB cursors timeouts (instance {{ $labels.instance }})
          description: "Too many cursors are timing out\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
    1. Alert - Too many cursor open for clients
    • For the Prometheus community exporter:
      - alert: MongodbNumberCursorsOpen
        expr: mongodb_mongod_metrics_cursor_open{state="total"} > 10 * 1000
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: MongoDB number cursors open (instance {{ $labels.instance }})
          description: "Too many cursors opened by MongoDB for clients (> 10k)\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
    • For Bitnami:
      - alert: MongodbNumberCursorsOpen
        expr: mongodb_metrics_cursor_open{state="total_open"} > 10000
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: MongoDB number cursors open (instance {{ $labels.instance }})
          description: "Too many cursors opened by MongoDB for clients (> 10k)\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
  • MongoDB Exporter Grafana
  • MongoDB Exporter Grafana

    Graphs are easier to understand and more user-friendly than a row of numbers. For this purpose, users can plot their time series data in visualized format using Grafana.

    Grafana is an open-source dashboarding tool used for visualizing metrics with the help of customizable and illustrative charts and graphs. It connects very well with Prometheus and makes monitoring easy and informative. Dashboards in Grafana are made up of panels, with each panel running a PromQL query to fetch metrics from Prometheus.
    Grafana supports community-driven graphs for most of the widely used software, which can be directly imported to the Grafana Community.

    What is a Panel?

    Panels are the most basic component of a dashboard and can display information in various ways, such as gauge, text, bar chart, graph, and so on. They provide information in a very interactive way. Users can view every panel separately and check the value of metrics within a specific time range. 
    The values on the panel are queried using PromQL, which is Prometheus Query Language. PromQL is a simple query language used to query metrics within Prometheus. It enables users to query data, aggregate and apply arithmetic functions to the metrics, and then further visualize them on panels.

    Here are some examples of panels:

0 0 votes
Article Rating

Leave a Reply

0 Comments
Inline Feedbacks
View all comments
© 2022 ExporterHub.io