Set up comprehensive MongoDB performance monitoring using Prometheus metrics collection and Grafana dashboards with alerting rules for database health, connection pools, and query performance.
Prerequisites
- MongoDB 8.0 installed and running
- Prometheus server installed
- Grafana installed
- Basic MongoDB administration knowledge
What this solves
MongoDB performance monitoring requires real-time visibility into database metrics like query execution times, connection pool status, replica set health, and resource utilization. This tutorial shows you how to collect MongoDB metrics with Prometheus and visualize them in Grafana dashboards with automated alerting for production database environments.
Step-by-step configuration
Install MongoDB Exporter for Prometheus
The MongoDB Exporter collects database metrics and exposes them in Prometheus format. Download and install the latest version.
wget https://github.com/percona/mongodb_exporter/releases/download/v0.40.0/mongodb_exporter-0.40.0.linux-amd64.tar.gz
tar -xzf mongodb_exporter-0.40.0.linux-amd64.tar.gz
sudo mv mongodb_exporter-0.40.0.linux-amd64/mongodb_exporter /usr/local/bin/
sudo chmod +x /usr/local/bin/mongodb_exporter
Create MongoDB monitoring user
Create a dedicated MongoDB user with minimal permissions for metrics collection. This user needs read access to database statistics and replica set status.
mongosh --host localhost:27017
use admin
db.createUser({
user: "prometheus_monitor",
pwd: "secure_monitoring_password_2024",
roles: [
{ role: "read", db: "admin" },
{ role: "read", db: "local" },
{ role: "clusterMonitor", db: "admin" },
{ role: "readAnyDatabase", db: "admin" }
]
})
exit
Configure MongoDB Exporter service
Create a systemd service for the MongoDB Exporter with authentication credentials and collection settings.
[Unit]
Description=MongoDB Prometheus Exporter
After=network.target
[Service]
Type=simple
User=nobody
Group=nogroup
Environment=MONGODB_URI=mongodb://prometheus_monitor:secure_monitoring_password_2024@localhost:27017/admin
ExecStart=/usr/local/bin/mongodb_exporter --mongodb.uri=$MONGODB_URI --collect-all --web.listen-address=:9216
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Start and enable MongoDB Exporter
Enable the exporter service to start automatically and verify it's collecting metrics properly.
sudo systemctl daemon-reload
sudo systemctl enable --now mongodb-exporter
sudo systemctl status mongodb-exporter
Configure Prometheus to scrape MongoDB metrics
Add MongoDB Exporter as a scrape target in your Prometheus configuration. This assumes you have Prometheus installed and running.
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "mongodb_alerts.yml"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'mongodb'
static_configs:
- targets: ['localhost:9216']
scrape_interval: 30s
metrics_path: /metrics
Create MongoDB alerting rules
Define alert conditions for MongoDB performance issues, connection problems, and replica set failures.
groups:
- name: mongodb.rules
rules:
- alert: MongoDBDown
expr: mongodb_up == 0
for: 5m
labels:
severity: critical
annotations:
summary: "MongoDB instance is down"
description: "MongoDB instance {{ $labels.instance }} has been down for more than 5 minutes."
- alert: MongoDBHighConnections
expr: mongodb_connections{state="current"} / mongodb_connections{state="available"} > 0.8
for: 2m
labels:
severity: warning
annotations:
summary: "MongoDB connection usage high"
description: "MongoDB instance {{ $labels.instance }} is using {{ $value | humanizePercentage }} of available connections."
- alert: MongoDBSlowQueries
expr: rate(mongodb_op_latencies_ops_total{type="command"}[5m]) > 100
for: 2m
labels:
severity: warning
annotations:
summary: "MongoDB slow queries detected"
description: "MongoDB instance {{ $labels.instance }} is experiencing {{ $value }} slow queries per second."
- alert: MongoDBReplicaLag
expr: mongodb_replset_member_replication_lag > 10
for: 1m
labels:
severity: critical
annotations:
summary: "MongoDB replica lag high"
description: "MongoDB replica {{ $labels.instance }} is lagging by {{ $value }} seconds."
- alert: MongoDBHighMemoryUsage
expr: mongodb_memory{type="resident"} / 1024 / 1024 > 4000
for: 5m
labels:
severity: warning
annotations:
summary: "MongoDB high memory usage"
description: "MongoDB instance {{ $labels.instance }} is using {{ $value }}MB of memory."
Restart Prometheus with new configuration
Reload Prometheus configuration to start collecting MongoDB metrics and enable alerting rules.
sudo systemctl restart prometheus
sudo systemctl status prometheus
Import MongoDB dashboard into Grafana
Create a comprehensive Grafana dashboard for MongoDB monitoring. First, access your Grafana instance and import a dashboard configuration.
curl -s https://raw.githubusercontent.com/percona/grafana-dashboards/main/dashboards/MongoDB_Overview.json > mongodb_dashboard.json
Configure custom MongoDB dashboard
Create a custom dashboard with key MongoDB performance panels. Log into Grafana and create a new dashboard with these essential panels.
{
"dashboard": {
"title": "MongoDB Performance",
"panels": [
{
"title": "MongoDB Status",
"type": "stat",
"targets": [{
"expr": "mongodb_up",
"legendFormat": "MongoDB Up"
}]
},
{
"title": "Operations per Second",
"type": "graph",
"targets": [{
"expr": "rate(mongodb_op_counters_total[5m])",
"legendFormat": "{{ type }}"
}]
},
{
"title": "Connection Usage",
"type": "graph",
"targets": [{
"expr": "mongodb_connections",
"legendFormat": "{{ state }}"
}]
},
{
"title": "Memory Usage",
"type": "graph",
"targets": [{
"expr": "mongodb_memory",
"legendFormat": "{{ type }}"
}]
},
{
"title": "Query Execution Time",
"type": "graph",
"targets": [{
"expr": "mongodb_op_latencies_latency_total / mongodb_op_latencies_ops_total",
"legendFormat": "{{ type }}"
}]
}
]
}
}
Configure Grafana alerts
Set up Grafana alerts that complement your Prometheus alerting rules. Configure notification channels for email or Slack integration.
curl -X POST http://localhost:3000/api/alert-notifications \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_GRAFANA_API_KEY" \
-d '{
"name": "mongodb-alerts",
"type": "email",
"settings": {
"addresses": "admin@example.com",
"subject": "MongoDB Alert: {{ .Title }}"
}
}'
Configure replica set monitoring
If you're running a MongoDB replica set, add specific monitoring for replica lag and election status.
groups:
- name: mongodb.replica
rules:
- alert: MongoDBReplicaSetDown
expr: mongodb_replset_number_of_members - mongodb_replset_number_of_members{state="PRIMARY"} - mongodb_replset_number_of_members{state="SECONDARY"} > 0
for: 1m
labels:
severity: critical
annotations:
summary: "MongoDB replica set member down"
description: "MongoDB replica set has unhealthy members."
- alert: MongoDBNoPrimary
expr: mongodb_replset_number_of_members{state="PRIMARY"} == 0
for: 30s
labels:
severity: critical
annotations:
summary: "MongoDB replica set has no primary"
description: "MongoDB replica set {{ $labels.set }} has no primary member."
Configure advanced monitoring features
Enable MongoDB profiler for slow query tracking
Configure MongoDB's built-in profiler to capture slow queries for analysis in your monitoring dashboard.
mongosh --host localhost:27017
use admin
db.runCommand({ profile: 2, slowms: 100 })
db.system.profile.createIndex({ "command.find": 1 })
db.system.profile.createIndex({ "command.aggregate": 1 })
exit
Configure index usage monitoring
Set up monitoring for index usage statistics to identify missing or unused indexes affecting performance.
groups:
- name: mongodb.indexes
rules:
- alert: MongoDBCollectionScans
expr: rate(mongodb_metrics_query_executor_total{state="collectionScans"}[5m]) > 10
for: 2m
labels:
severity: warning
annotations:
summary: "High collection scans detected"
description: "MongoDB is performing {{ $value }} collection scans per second, consider adding indexes."
- alert: MongoDBHighIndexMisses
expr: rate(mongodb_metrics_cursor_total{state="totalNoTimeout"}[5m]) / rate(mongodb_metrics_cursor_total{state="totalOpened"}[5m]) < 0.9
for: 5m
labels:
severity: warning
annotations:
summary: "Low index hit ratio"
description: "MongoDB index hit ratio is {{ $value | humanizePercentage }}, review query patterns."
Verify your setup
Check that all monitoring components are working correctly and collecting metrics.
curl http://localhost:9216/metrics | grep mongodb_up
curl http://localhost:9090/api/v1/query?query=mongodb_up
sudo systemctl status mongodb-exporter prometheus grafana-server
Access your Grafana dashboard at http://your-server:3000 and verify that MongoDB metrics are being displayed correctly. Check that alerts are configured in both Prometheus and Grafana.
http://localhost:9090/targets to ensure the MongoDB exporter is being scraped successfully.Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Exporter shows "connection refused" | MongoDB authentication failure | Verify MongoDB user credentials and permissions with mongosh |
| Missing replica set metrics | Exporter not connected to replica set | Update MONGODB_URI to include replica set name: mongodb://user:pass@host/admin?replicaSet=rs0 |
| High memory usage alerts firing | Incorrect memory thresholds | Adjust alert thresholds in mongodb_alerts.yml based on your server capacity |
| Prometheus not scraping metrics | Network connectivity or firewall | Test connectivity: curl http://localhost:9216/metrics and check firewall rules |
| Grafana shows no data | Prometheus data source misconfigured | Verify Prometheus data source URL in Grafana settings: http://localhost:9090 |
| Alerts not firing | Alert rules syntax errors | Validate alert rules: promtool check rules /etc/prometheus/mongodb_alerts.yml |
Next steps
- Configure Prometheus Alertmanager with email notifications for production monitoring
- Configure MongoDB 8.0 replica set with automatic failover for high availability
- Configure MongoDB 8.0 backup automation with systemd timers and compression
- Set up Grafana alerting with Slack and Teams integration for team notifications
- Monitor MongoDB sharding cluster performance with Prometheus and Grafana
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Default values
MONGODB_HOST="localhost"
MONGODB_PORT="27017"
MONGODB_USER="prometheus_monitor"
MONGODB_PASS="secure_monitoring_password_2024"
EXPORTER_VERSION="0.40.0"
# Usage function
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " -h, --host MongoDB host (default: localhost)"
echo " -p, --port MongoDB port (default: 27017)"
echo " -u, --user MongoDB monitoring user (default: prometheus_monitor)"
echo " -w, --password MongoDB monitoring password (default: secure_monitoring_password_2024)"
echo " --help Show this help message"
exit 1
}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--host)
MONGODB_HOST="$2"
shift 2
;;
-p|--port)
MONGODB_PORT="$2"
shift 2
;;
-u|--user)
MONGODB_USER="$2"
shift 2
;;
-w|--password)
MONGODB_PASS="$2"
shift 2
;;
--help)
usage
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
usage
;;
esac
done
# Cleanup function for rollback
cleanup() {
echo -e "${RED}Error occurred. Cleaning up...${NC}"
systemctl stop mongodb-exporter 2>/dev/null || true
systemctl disable mongodb-exporter 2>/dev/null || true
rm -f /etc/systemd/system/mongodb-exporter.service
rm -f /usr/local/bin/mongodb_exporter
rm -rf /tmp/mongodb_exporter-*
systemctl daemon-reload
}
trap cleanup ERR
# Check if running as root
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}This script must be run as root${NC}"
exit 1
fi
echo -e "${GREEN}MongoDB 8.0 Performance Monitoring Setup${NC}"
echo "========================================"
# Auto-detect distribution
echo -e "${YELLOW}[1/8] Detecting distribution...${NC}"
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update"
FIREWALL_CMD="ufw"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf makecache"
FIREWALL_CMD="firewall-cmd"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum makecache"
FIREWALL_CMD="firewall-cmd"
;;
*)
echo -e "${RED}Unsupported distribution: $ID${NC}"
exit 1
;;
esac
echo -e "${GREEN}Detected: $PRETTY_NAME${NC}"
else
echo -e "${RED}Cannot detect distribution${NC}"
exit 1
fi
# Update package cache
echo -e "${YELLOW}[2/8] Updating package cache...${NC}"
$PKG_UPDATE
# Install prerequisites
echo -e "${YELLOW}[3/8] Installing prerequisites...${NC}"
$PKG_INSTALL wget tar curl
# Download and install MongoDB Exporter
echo -e "${YELLOW}[4/8] Installing MongoDB Exporter...${NC}"
cd /tmp
wget -q "https://github.com/percona/mongodb_exporter/releases/download/v${EXPORTER_VERSION}/mongodb_exporter-${EXPORTER_VERSION}.linux-amd64.tar.gz"
tar -xzf "mongodb_exporter-${EXPORTER_VERSION}.linux-amd64.tar.gz"
mv "mongodb_exporter-${EXPORTER_VERSION}.linux-amd64/mongodb_exporter" /usr/local/bin/
chmod 755 /usr/local/bin/mongodb_exporter
chown root:root /usr/local/bin/mongodb_exporter
rm -rf "mongodb_exporter-${EXPORTER_VERSION}.linux-amd64"*
# Create MongoDB monitoring user
echo -e "${YELLOW}[5/8] Creating MongoDB monitoring user...${NC}"
if command -v mongosh >/dev/null 2>&1; then
mongosh --quiet --host "${MONGODB_HOST}:${MONGODB_PORT}" --eval "
use admin;
try {
db.createUser({
user: '${MONGODB_USER}',
pwd: '${MONGODB_PASS}',
roles: [
{ role: 'read', db: 'admin' },
{ role: 'read', db: 'local' },
{ role: 'clusterMonitor', db: 'admin' },
{ role: 'readAnyDatabase', db: 'admin' }
]
});
print('MongoDB user created successfully');
} catch(e) {
if (e.codeName === 'DuplicateKey') {
print('User already exists, skipping...');
} else {
throw e;
}
}
"
else
echo -e "${RED}mongosh not found. Please create the monitoring user manually.${NC}"
fi
# Create systemd service
echo -e "${YELLOW}[6/8] Creating systemd service...${NC}"
cat > /etc/systemd/system/mongodb-exporter.service << EOF
[Unit]
Description=MongoDB Prometheus Exporter
After=network.target
[Service]
Type=simple
User=nobody
Group=nogroup
Environment=MONGODB_URI=mongodb://${MONGODB_USER}:${MONGODB_PASS}@${MONGODB_HOST}:${MONGODB_PORT}/admin
ExecStart=/usr/local/bin/mongodb_exporter --mongodb.uri=\$MONGODB_URI --collect-all --web.listen-address=:9216
Restart=always
RestartSec=5
RestartPreventExitStatus=0
KillMode=mixed
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target
EOF
chmod 644 /etc/systemd/system/mongodb-exporter.service
# Start and enable service
echo -e "${YELLOW}[7/8] Starting MongoDB Exporter service...${NC}"
systemctl daemon-reload
systemctl enable mongodb-exporter
systemctl start mongodb-exporter
# Configure firewall
echo -e "${YELLOW}[8/8] Configuring firewall...${NC}"
case "$PKG_MGR" in
apt)
if command -v ufw >/dev/null 2>&1; then
ufw allow 9216/tcp comment "MongoDB Exporter"
fi
;;
dnf|yum)
if command -v firewall-cmd >/dev/null 2>&1 && systemctl is-active --quiet firewalld; then
firewall-cmd --permanent --add-port=9216/tcp
firewall-cmd --reload
fi
;;
esac
# Verification
echo -e "${GREEN}Verifying installation...${NC}"
sleep 5
# Check service status
if systemctl is-active --quiet mongodb-exporter; then
echo -e "${GREEN}✓ MongoDB Exporter service is running${NC}"
else
echo -e "${RED}✗ MongoDB Exporter service is not running${NC}"
systemctl status mongodb-exporter
exit 1
fi
# Check if metrics endpoint is responding
if curl -s http://localhost:9216/metrics | head -n 1 | grep -q "HELP"; then
echo -e "${GREEN}✓ MongoDB Exporter metrics endpoint is responding${NC}"
else
echo -e "${RED}✗ MongoDB Exporter metrics endpoint is not responding${NC}"
exit 1
fi
# Display configuration summary
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}MongoDB Monitoring Setup Complete!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo "Service Status:"
echo " MongoDB Exporter: $(systemctl is-active mongodb-exporter)"
echo ""
echo "Endpoints:"
echo " Metrics: http://localhost:9216/metrics"
echo ""
echo "Next Steps:"
echo "1. Add MongoDB target to Prometheus configuration:"
echo " scrape_configs:"
echo " - job_name: 'mongodb'"
echo " static_configs:"
echo " - targets: ['localhost:9216']"
echo ""
echo "2. Import MongoDB Grafana dashboard (ID: 2583)"
echo "3. Configure alerting rules for production monitoring"
echo ""
echo -e "${GREEN}Installation completed successfully!${NC}"
Review the script before running. Execute with: bash install.sh