43 Monitoring-Integration: Von Logs zu Actionable Insights

MongoDB’s Slow-Query-Log und Profiler sind mächtig für Ad-hoc-Analysis – man connectet zur Database, queried system.profile, identifiziert Probleme. Aber für Production-Systeme mit dutzenden oder hunderten Databases ist manuelles Query-Loggen nicht skalierbar. Man braucht automatisiertes Monitoring – kontinuierliches Collecting von Metrics, zentralisiertes Aggregieren über alle Databases, Visualisierung in Dashboards, und Alerting bei Anomalien. Dies erfordert Integration mit Monitoring-Systemen – entweder MongoDB-spezifische Tools wie Atlas oder generische Infrastructure-Monitoring wie Prometheus+Grafana oder ELK-Stack.

Die Herausforderung ist nicht technisch – alle diese Tools können mit MongoDB integrieren – sondern strategisch: Welche Metrics sammeln? Wie lange retentieren? Welche Alerts konfigurieren? Wie False-Positives minimieren? Ein schlecht konfiguriertes Monitoring-System generiert Noise – tausende Alerts, die alle ignoriert werden. Ein gut konfiguriertes System generiert Signals – wenige, actionable Alerts auf real Probleme.

Dieses Kapitel behandelt Monitoring-Integration systematisch – von MongoDB Atlas (Managed-Solution) über self-hosted Options (Prometheus, ELK) bis zu Custom-Solutions. Der Fokus ist auf praktischen Setups für Production-Environments.

43.1 MongoDB Atlas: Fully-Managed-Monitoring

Für Teams, die MongoDB Atlas nutzen (MongoDB’s Managed-Cloud-Service), ist Monitoring built-in und umfassend. Atlas hat Performance-Advisor, Query-Profiler, Real-Time-Metrics, und Automated-Index-Suggestions.

Performance-Advisor:

Atlas analysiert kontinuierlich Query-Patterns und schlägt Index-Optimizations vor:

Performance Advisor Recommendations:

1. Create Index on orders collection
   { customerId: 1, orderDate: -1 }
   Impact: 15,234 queries (avg 2.3s → 0.05s)
   
2. Drop unused Index on products collection
   { legacyField: 1 }
   Usage: 2 queries in last 30 days

Diese Recommendations sind datengetrieben – Atlas tracked welche Queries langsam sind, analysiert ihre Patterns, und generiert spezifische Index-Suggestions mit Impact-Estimates. Dies ist transformativ für Teams ohne dedizierte DBA-Expertise.

Real-Time-Metrics-Dashboard:

Atlas zeigt Live-Metrics: - Operations per Second (Read/Write) - Query-Execution-Times (p50, p95, p99) - Connections (active/available) - Disk-IOPS und Network-Throughput - Slow-Queries mit automatischer EXPLAIN-Analysis

Custom-Alerts:

Atlas erlaubt Custom-Alert-Rules:

Alert: Slow-Query-Rate-Spike
Condition: Slow-Queries (> 100ms) exceed 100/minute
Action: Email to ops@company.com, PagerDuty-Alert

Vorteile von Atlas-Monitoring:

  1. Zero-Setup: Funktioniert out-of-the-box, keine Configuration nötig
  2. MongoDB-Native: Versteht MongoDB-spezifische Patterns (etwa Aggregation-Pipeline-Analysis)
  3. Automated-Suggestions: Performance-Advisor gibt konkrete Actions
  4. Historical-Data: 30-Tage-Retention (oder mehr bei höheren Tiers)

Nachteile:

  1. Atlas-Only: Funktioniert nicht mit self-hosted MongoDB
  2. Cost: Höhere Tiers für erweiterte Monitoring-Features
  3. Limited-Customization: Dashboards sind pre-defined, nicht fully-customizable

Für Teams, die bereits Atlas nutzen, ist das built-in Monitoring die einfachste Lösung. Für self-hosted MongoDB muss man andere Tools nutzen.

43.2 Prometheus + Grafana: Infrastructure-Monitoring-Standard

Prometheus ist der De-Facto-Standard für Infrastructure-Monitoring in Cloud-Native-Environments. Es scraped Metrics von Targets (via HTTP-Endpoints), speichert sie in Time-Series-Database, und erlaubt flexible Querying. Grafana visualisiert diese Metrics in Dashboards.

Architecture:

MongoDB → MongoDB-Exporter → Prometheus → Grafana
                ↓
          Alertmanager

Der MongoDB-Exporter ist ein Sidecar-Process, der MongoDB-Metrics exposed als Prometheus-Format. Prometheus scraped diese periodisch. Grafana visualisiert. Alertmanager handelt Alerts.

MongoDB-Exporter-Setup:

Mehrere Exporter existieren – der populärste ist Percona’s MongoDB-Exporter:

# Install
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

# Run
./mongodb_exporter \
  --mongodb.uri=mongodb://monitoring_user:password@localhost:27017 \
  --web.listen-address=:9216 \
  --collect-all

Der Exporter connected zu MongoDB, sammelt Metrics, und exposed sie auf Port 9216. Prometheus scraped diesen Endpoint.

Prometheus-Configuration:

# prometheus.yml
scrape_configs:
  - job_name: 'mongodb'
    static_configs:
      - targets: ['mongodb-exporter:9216']
    scrape_interval: 15s

Prometheus scraped alle 15 Sekunden. Für Production sind 15-30 Sekunden typical – öfter generiert zu viel Data-Volume, seltener misst man Spikes.

Key-Metrics vom Exporter:

# Operations per Second
mongodb_op_counters_total{type="query"}
mongodb_op_counters_total{type="insert"}
mongodb_op_counters_total{type="update"}

# Connections
mongodb_connections{state="current"}
mongodb_connections{state="available"}

# Slow Queries (custom metric via Profiler-Integration)
mongodb_slow_queries_total
mongodb_slow_query_duration_seconds

# Index Metrics
mongodb_index_usage_count
mongodb_collection_scans_total

# Disk and Memory
mongodb_storage_size_bytes
mongodb_memory_resident_bytes

Grafana-Dashboard:

Grafana hat pre-built MongoDB-Dashboards, oder man erstellt Custom:

{
  "dashboard": {
    "title": "MongoDB Performance",
    "panels": [
      {
        "title": "Query Rate",
        "targets": [
          {
            "expr": "rate(mongodb_op_counters_total{type='query'}[5m])"
          }
        ]
      },
      {
        "title": "Slow Queries (> 100ms)",
        "targets": [
          {
            "expr": "rate(mongodb_slow_queries_total[5m])"
          }
        ]
      },
      {
        "title": "Connection Usage",
        "targets": [
          {
            "expr": "mongodb_connections{state='current'} / mongodb_connections{state='available'}"
          }
        ]
      }
    ]
  }
}

Alerting-Rules:

# alert-rules.yml
groups:
  - name: mongodb
    interval: 30s
    rules:
      - alert: HighSlowQueryRate
        expr: rate(mongodb_slow_queries_total[5m]) > 10
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "High slow query rate detected"
          description: "{{ $value }} slow queries per second"
      
      - alert: ConnectionPoolExhaustion
        expr: mongodb_connections{state="current"} / mongodb_connections{state="available"} > 0.8
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Connection pool near exhaustion"

Diese Alerts triggern Notifications via Alertmanager – Email, Slack, PagerDuty, etc.

Vorteile von Prometheus+Grafana:

  1. Open-Source: Kostenlos, Community-Support
  2. Flexible: Vollständig customizable Dashboards und Alerts
  3. Ecosystem: Integriert mit hunderten anderen Systems
  4. Self-Hosted: Volle Kontrolle über Data-Retention und Privacy

Nachteile:

  1. Setup-Overhead: Erfordert Infrastructure (Prometheus-Server, Grafana, Exporters)
  2. Limited-MongoDB-Specifics: Generisches Monitoring, nicht MongoDB-aware wie Atlas
  3. Retention-Management: Man muss Data-Retention selbst managen (Prometheus default: 15 Tage)

Der ELK-Stack (Elasticsearch, Logstash, Kibana) ist für Log-Aggregation designed. Statt numerische Metrics (wie Prometheus) sammelt ELK structured Logs – etwa MongoDB’s Profiler-Logs.

Architecture:

MongoDB system.profile → Logstash → Elasticsearch → Kibana

Logstash liest system.profile, parst die Logs, und schickt sie zu Elasticsearch. Kibana visualisiert und erlaubt Full-Text-Search über alle Logs.

Logstash-Configuration:

# logstash-mongodb.conf
input {
  mongodb {
    uri => "mongodb://logstash_user:password@localhost:27017/admin"
    placeholder_db_dir => "/var/lib/logstash/mongodb"
    collection => "system.profile"
    batch_size => 1000
    parse_method => "simple"
  }
}

filter {
  # Extract key fields
  mutate {
    rename => {
      "millis" => "duration_ms"
      "op" => "operation"
      "ns" => "namespace"
    }
  }
  
  # Tag slow queries
  if [duration_ms] > 1000 {
    mutate {
      add_tag => ["very_slow"]
    }
  } else if [duration_ms] > 100 {
    mutate {
      add_tag => ["slow"]
    }
  }
}

output {
  elasticsearch {
    hosts => ["http://elasticsearch:9200"]
    index => "mongodb-queries-%{+YYYY.MM.dd}"
  }
}

Dies streamed kontinuierlich Profiler-Logs zu Elasticsearch, indexed sie für Fast-Search.

Elasticsearch-Index-Template:

{
  "index_patterns": ["mongodb-queries-*"],
  "mappings": {
    "properties": {
      "duration_ms": { "type": "long" },
      "operation": { "type": "keyword" },
      "namespace": { "type": "keyword" },
      "command": { "type": "object" },
      "planSummary": { "type": "keyword" },
      "timestamp": { "type": "date" }
    }
  }
}

Kibana-Dashboard:

Kibana erlaubt komplexe Visualizations:

Full-Text-Search:

Das Killer-Feature von ELK ist Search – man kann arbitrary Queries suchen:

Find all queries auf "orders" Collection mit COLLSCAN:
namespace:"mydb.orders" AND planSummary:COLLSCAN

Find aggregation queries that took > 5 seconds:
operation:aggregate AND duration_ms:>5000

Use-Case-Example:

Nach einem Deployment steigen Slow-Queries. Man searched in Kibana:

timestamp:[now-1h TO now] AND duration_ms:>1000

Kibana zeigt alle Slow-Queries in letzter Stunde. Man sieht Pattern – alle sind auf eine neue Collection “analytics_temp”. Man inspected die Queries, identifiziert missing Index, created ihn. Problem gelöst.

Vorteile von ELK:

  1. Rich-Log-Context: Voller Query-Text, Execution-Plans, alles durchsuchbar
  2. Flexible-Search: Full-Text-Search über alle Query-History
  3. Long-Retention: Elasticsearch kann Jahre von Logs speichern (mit Tiered-Storage)
  4. Multi-Source: Integriert MongoDB-Logs mit Application-Logs, Infrastructure-Logs

Nachteile:

  1. High-Resource-Requirements: Elasticsearch ist RAM-hungry, braucht dedizierte Nodes
  2. Complexity: ELK-Setup ist non-trivial, erfordert Expertise
  3. Cost: Elasticsearch-Cluster können teuer sein bei Large-Scale

43.4 Custom-Monitoring: Lightweight-Solutions

Für Teams ohne Budget für Atlas oder Infrastructure für Prometheus/ELK gibt es Lightweight-Approaches – Custom-Scripts, die Metrics sammeln und irgendwo hinschicken.

Example: Slack-Alerts für Slow-Queries

// slow-query-monitor.js
const { MongoClient } = require('mongodb')
const axios = require('axios')

const SLACK_WEBHOOK = process.env.SLACK_WEBHOOK
const MONGODB_URI = process.env.MONGODB_URI
const THRESHOLD_MS = 1000

async function checkSlowQueries() {
  const client = await MongoClient.connect(MONGODB_URI)
  const db = client.db('admin')
  
  // Find slow queries in last 5 minutes
  const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000)
  
  const slowQueries = await db.collection('system.profile').find({
    ts: { $gte: fiveMinutesAgo },
    millis: { $gte: THRESHOLD_MS }
  }).toArray()
  
  if (slowQueries.length > 10) {
    // Alert: High slow-query rate
    await axios.post(SLACK_WEBHOOK, {
      text: `⚠️ *MongoDB Slow-Query Alert*`,
      attachments: [{
        color: 'warning',
        fields: [
          { title: 'Slow Queries', value: slowQueries.length, short: true },
          { title: 'Threshold', value: `>${THRESHOLD_MS}ms`, short: true }
        ]
      }]
    })
    
    // Log details to file
    fs.writeFileSync(
      `/var/log/mongodb-slow-${Date.now()}.json`,
      JSON.stringify(slowQueries, null, 2)
    )
  }
  
  await client.close()
}

// Run every 5 minutes
setInterval(checkSlowQueries, 5 * 60 * 1000)

Dies ist ein 50-Line-Script, das regelmäßig system.profile checked und bei Anomalies Slack-Alerts schickt. Kein Prometheus, kein ELK – nur Node.js und MongoDB-Driver.

Example: Export zu Cloud-Monitoring

Für Teams auf AWS/GCP/Azure kann man Metrics zu Cloud-Native-Monitoring exportieren:

// export-to-cloudwatch.js (AWS)
const AWS = require('aws-sdk')
const cloudwatch = new AWS.CloudWatch()

async function exportMetrics() {
  const stats = await db.serverStatus()
  
  await cloudwatch.putMetricData({
    Namespace: 'MongoDB',
    MetricData: [
      {
        MetricName: 'SlowQueries',
        Value: stats.metrics.queryExecutor.collectionScans.total,
        Unit: 'Count',
        Timestamp: new Date()
      },
      {
        MetricName: 'Connections',
        Value: stats.connections.current,
        Unit: 'Count',
        Timestamp: new Date()
      }
    ]
  }).promise()
}

setInterval(exportMetrics, 60000)  // Every minute

CloudWatch/Stackdriver/Azure-Monitor handeln dann Visualization, Alerting, Retention.

43.5 Monitoring-Best-Practices: Was messen, was alerten

Critical-Metrics (Always-Monitor):

  1. Slow-Query-Rate: Queries > 100ms per minute
  2. Collection-Scan-Rate: COLLSCAN operations per minute
  3. Connection-Pool-Usage: current / available connections
  4. Replication-Lag: Secondaries behind Primary (seconds)
  5. Disk-Space: Available disk percentage

Useful-Metrics (Monitor-for-Capacity-Planning):

  1. Operations-per-Second: Read/Write throughput
  2. Index-Hit-Rate: Index-Usage vs. Collection-Scans
  3. Memory-Usage: RAM used by indexes and caches
  4. Disk-IOPS: I/O-Operations per second

Nice-to-Have-Metrics (Advanced-Analysis):

  1. Query-Latency-Distribution: p50, p95, p99
  2. Per-Collection-Metrics: Operations per collection
  3. Lock-Wait-Time: Time spent waiting for locks

Alert-Thresholds:

Metric Warning Critical
Slow-Query-Rate > 10/min > 50/min
Collection-Scans > 100/min > 500/min
Connection-Pool > 70% > 90%
Replication-Lag > 10s > 60s
Disk-Space < 20% free < 10% free

Diese Thresholds sind Defaults – jede Application hat unterschiedliche Tolerances. E-Commerce während Black-Friday hat andere Thresholds als ein Internal-Tool.

Alert-Fatigue vermeiden:

Das größte Problem mit Monitoring ist Alert-Fatigue – so viele Alerts, dass man sie alle ignoriert. Best Practices:

  1. Alert auf Symptoms, nicht Causes: Alert auf “High Slow-Query-Rate”, nicht “Index xyz has 0 accesses”
  2. Group correlated Alerts: Wenn 5 Metrics anomalous sind wegen eines Problems, send 1 Alert, nicht 5
  3. Require Action: Jeder Alert sollte eine klare Action haben – wenn man nichts tun kann, ist es kein Alert sondern Noise
  4. Tune Thresholds: Wenn Alerts häufig False-Positives sind, adjust Thresholds
  5. Use escalation: Warning → Email, Critical → PagerDuty

Die folgende Tabelle fasst Monitoring-Solutions zusammen:

Solution Setup-Effort Cost MongoDB-Specificity Best-For
MongoDB Atlas Zero $ Native Atlas-Users
Prometheus+Grafana Medium Free (Infrastructure) Generic K8s/Cloud-Native
ELK Stack High $$ Generic Log-Analysis-Focus
Cloud-Monitoring Low $ (Usage-Based) Generic AWS/GCP/Azure-Users
Custom-Scripts Low Free Customizable Small-Teams/Tight-Budget

Monitoring ist nicht optional für Production-MongoDB. Die Frage ist nicht “sollten wir monitoren” sondern “wie monitoren wir effektiv”. Die Antwort hängt ab von Team-Size, Budget, Existing-Infrastructure, und MongoDB-Hosting (Atlas vs. Self-Hosted). Für Atlas-Users ist built-in Monitoring der No-Brainer. Für Self-Hosted in Kubernetes ist Prometheus+Grafana der Standard. Für Log-Heavy-Environments ist ELK optimal. Für Small-Teams mit minimal Resources sind Custom-Scripts ausreichend. Unabhängig vom Tool ist das Prinzip dasselbe: Continuous-Collecting von Metrics, Visualization in Dashboards, Actionable-Alerts auf Anomalies, und Iterative-Tuning basierend auf Real-Production-Data. Mit systematischem Monitoring wird MongoDB-Performance von opaque zu transparent – man sieht Probleme bevor sie Production-Impact haben, identifiziert Bottlenecks datengetrieben, und optimized kontinuierlich basierend auf Measurements statt Guesses.