Skip to content
Last9
Book demo

MongoDB

Monitor MongoDB database performance, slow queries, and memory usage with OpenTelemetry and Last9

Use OpenTelemetry to instrument your self-hosted MongoDB database and send telemetry data to Last9. This integration collects metrics, parses structured JSON logs, and extracts slow query details into structured attributes for analysis.

Prerequisites

Before setting up MongoDB monitoring, ensure you have:

  • MongoDB 4.x or 5.x+ installed and running
  • Administrative access to create MongoDB users and roles
  • OpenTelemetry Collector binary or container runtime
  • Last9 account with integration credentials

Database Setup

The setup process varies slightly between MongoDB versions. Choose the appropriate section for your MongoDB version:

  1. Create Monitoring Role and User

    Log into your MongoDB instance and create a custom role for index access metrics and a least-privilege monitoring user:

    use admin
    // Custom role for index access metrics (mongodb.index.access.count)
    db.createRole({
    role: "indexStatsRole",
    privileges: [
    {
    resource: { db: "admin", collection: "system.profile" },
    actions: [ "indexStats", "find" ]
    },
    {
    resource: { db: "config", collection: "system.profile" },
    actions: [ "indexStats", "find" ]
    },
    {
    resource: { db: "local", collection: "system.profile" },
    actions: [ "indexStats", "find" ]
    },
    {
    resource: { db: "", collection: "system.profile" },
    actions: [ "indexStats", "find" ]
    }
    ],
    roles: []
    })
    // Create monitoring user with least-privilege roles (NO root access)
    db.createUser({
    user: "otel",
    pwd: "YOUR_SECURE_PASSWORD",
    roles: [
    { role: "clusterMonitor", db: "admin" }, // Required: serverStatus, dbStats, top
    { role: "read", db: "local" }, // Required: replica set oplog monitoring
    { role: "indexStatsRole", db: "admin" } // Required: index access metrics
    ],
    mechanisms: [ "SCRAM-SHA-1" ]
    })
  2. Configure MongoDB Settings

    Edit /etc/mongod.conf to enable monitoring features:

    storage:
    dbPath: /var/lib/mongodb
    journal:
    enabled: true
    systemLog:
    destination: file
    logAppend: true
    path: /var/log/mongodb/mongod.log
    net:
    port: 27017
    bindIp: 0.0.0.0
    processManagement:
    timeZoneInfo: /usr/share/zoneinfo
    security:
    authorization: enabled
    operationProfiling:
    mode: all
    slowOpThresholdMs: 100
    setParameter:
    diagnosticDataCollectionEnabled: true
  3. Restart MongoDB Service

    sudo systemctl restart mongod

Install OpenTelemetry Collector

Choose the appropriate binary for your system architecture:

sudo apt-get update
sudo apt-get -y install wget systemctl
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.144.0/otelcol-contrib_0.144.0_linux_amd64.deb
sudo dpkg -i otelcol-contrib_0.144.0_linux_amd64.deb

Configure OpenTelemetry Collector

  1. Create Collector Configuration

    Create the collector configuration file at /etc/otelcol-contrib/config.yaml.

    Note: The MongoDB connection string format varies based on version:

    • For MongoDB 4.0-4.3: "127.0.0.1:27017/?authSource=admin&tls=false&directConnection=true"
    • For MongoDB ≥ 4.4 and 5.x+: "127.0.0.1:27017/?authSource=admin&directConnection=true"

    Replace MONGODB_USERNAME and MONGODB_PASSWORD with your actual MongoDB credentials.

    receivers:
    filelog:
    include: [/var/log/mongodb/*.log]
    include_file_path: true
    start_at: end
    retry_on_failure:
    enabled: true
    operators:
    - type: json_parser
    if: body matches "^\\{"
    timestamp:
    parse_from: attributes.t.$$date
    layout_type: gotime
    layout: "2006-01-02T15:04:05.999-07:00"
    severity:
    parse_from: attributes.s
    mapping:
    fatal: F
    error: E
    warn: W
    info: I
    debug: D1
    hostmetrics:
    collection_interval: 60s
    scrapers:
    cpu:
    metrics:
    system.cpu.logical.count:
    enabled: true
    memory:
    metrics:
    system.memory.utilization:
    enabled: true
    system.memory.limit:
    enabled: true
    load:
    disk:
    filesystem:
    metrics:
    system.filesystem.utilization:
    enabled: true
    network:
    paging:
    mongodb:
    hosts:
    - endpoint: "127.0.0.1:27017/?authSource=admin&directConnection=true"
    username: "MONGODB_USERNAME"
    password: "MONGODB_PASSWORD"
    collection_interval: 60s
    initial_delay: 1s
    timeout: 30s
    tls:
    insecure: true
    metrics:
    mongodb.operation.latency.time:
    enabled: true
    mongodb.page_faults:
    enabled: true
    mongodb.active.reads:
    enabled: true
    mongodb.active.writes:
    enabled: true
    mongodb.health:
    enabled: true
    mongodb.uptime:
    enabled: true
    mongodb.lock.acquire.count:
    enabled: true
    mongodb.lock.acquire.time:
    enabled: true
    processors:
    batch:
    timeout: 5s
    send_batch_size: 10000
    send_batch_max_size: 10000
    resourcedetection/system:
    detectors: ["system", "ec2"]
    system:
    hostname_sources: ["os"]
    transform/add_timestamp:
    flatten_data: true
    log_statements:
    - context: log
    statements:
    - set(observed_time, Now())
    - set(time_unix_nano, observed_time_unix_nano) where time_unix_nano == 0
    transform/add_service:
    flatten_data: true
    log_statements:
    - context: log
    statements:
    - set(resource.attributes["service.name"], "mongodb")
    transform/slow_queries:
    log_statements:
    - context: log
    conditions:
    - IsMatch(body, "Slow query")
    statements:
    - set(attributes["db.namespace"], attributes["attr"]["ns"]) where attributes["attr"]["ns"] != nil
    - set(attributes["db.operation.duration_ms"], attributes["attr"]["durationMillis"]) where attributes["attr"]["durationMillis"] != nil
    - set(attributes["db.plan_summary"], attributes["attr"]["planSummary"]) where attributes["attr"]["planSummary"] != nil
    - set(attributes["db.keys_examined"], attributes["attr"]["keysExamined"]) where attributes["attr"]["keysExamined"] != nil
    - set(attributes["db.docs_examined"], attributes["attr"]["docsExamined"]) where attributes["attr"]["docsExamined"] != nil
    - set(attributes["db.rows_affected"], attributes["attr"]["nreturned"]) where attributes["attr"]["nreturned"] != nil
    - set(attributes["db.query_hash"], attributes["attr"]["queryHash"]) where attributes["attr"]["queryHash"] != nil
    - set(attributes["db.system"], "mongodb")
    - set(attributes["slow_query"], true)
    - set(severity_text, "WARN") where attributes["attr"]["durationMillis"] != nil and attributes["attr"]["durationMillis"] > 100
    transform/hostmetrics:
    metric_statements:
    - context: datapoint
    statements:
    - set(attributes["host.name"], resource.attributes["host.name"])
    - set(attributes["database"], resource.attributes["database"])
    - set(attributes["server.address"], resource.attributes["server.address"])
    - set(attributes["cloud.account.id"], resource.attributes["cloud.account.id"])
    - set(attributes["cloud.availability_zone"], resource.attributes["cloud.availability_zone"])
    - set(attributes["cloud.platform"], resource.attributes["cloud.platform"])
    - set(attributes["cloud.provider"], resource.attributes["cloud.provider"])
    - set(attributes["cloud.region"], resource.attributes["cloud.region"])
    - set(attributes["host.type"], resource.attributes["host.type"])
    - set(attributes["host.image.id"], resource.attributes["host.image.id"])
    exporters:
    otlp/last9:
    endpoint: "{{ .Logs.WriteURL }}"
    headers:
    "Authorization": "{{ .Logs.AuthValue }}"
    debug:
    verbosity: detailed
    service:
    pipelines:
    logs:
    receivers: [filelog]
    processors:
    [
    batch,
    resourcedetection/system,
    transform/add_timestamp,
    transform/add_service,
    transform/slow_queries,
    ]
    exporters: [otlp/last9]
    metrics:
    receivers: [mongodb, hostmetrics]
    processors: [batch, resourcedetection/system, transform/hostmetrics]
    exporters: [otlp/last9]
  2. Start the Collector

    otelcol-contrib --config /etc/otelcol-contrib/config.yaml --feature-gates transform.flatten.logs

Memory Metrics

The MongoDB receiver collects mongodb.memory.usage by default with resident and virtual breakdowns. Combined with hostmetrics system memory, you can calculate MongoDB memory percentage:

MetricDescriptionUnit
mongodb.memory.usageMongoDB process memory (resident, virtual)By
mongodb.page_faultsPage faults indicating memory pressure{faults}
system.memory.utilizationSystem memory utilization ratio1
system.memory.limitTotal system memoryBy

Calculating memory usage percentage:

  • MongoDB memory % = mongodb.memory.usage{memory_type="resident"} / system.memory.limit * 100

Slow Query Monitoring

MongoDB 4.4+ outputs structured JSON logs. The filelog receiver parses these and the transform/slow_queries processor extracts slow query fields:

AttributeSource FieldDescription
db.namespaceattr.nsDatabase and collection (e.g., mydb.users)
db.operation.duration_msattr.durationMillisTotal execution time in milliseconds
db.plan_summaryattr.planSummaryExecution plan (COLLSCAN, IXSCAN, etc.)
db.keys_examinedattr.keysExaminedNumber of index keys scanned
db.docs_examinedattr.docsExaminedNumber of documents scanned
db.rows_affectedattr.nreturnedNumber of documents returned
db.query_hashattr.queryHashHash identifying the query shape
db.systemAlways set to mongodb
slow_queryAlways set to true for slow query logs

Slow queries (> 100ms) are automatically elevated to WARN severity. The threshold is controlled by slowOpThresholdMs in mongod.conf.

Verification

  1. Check Collector Status

    sudo systemctl status otelcol-contrib
  2. View Collector Logs

    sudo journalctl -u otelcol-contrib -f
  3. Verify Metrics in Last9

    Log into your Last9 account and check that MongoDB metrics are being received. Look for the mongodb service name.

Best Practices

  • Security: Use strong passwords for the monitoring user. The configuration above uses least-privilege roles — avoid granting root access.
  • Performance: Adjust slowOpThresholdMs based on your application’s performance requirements.
  • Storage: Monitor log file sizes and implement log rotation to prevent disk space issues.
  • Monitoring: Set up alerts for critical MongoDB metrics like connection count and replication lag.

Need Help?

If you encounter any issues or have questions: