43 Observability

Die Beobachtbarkeit (Observability) moderner Systeme ist eine zentrale Herausforderung im DevOps-Umfeld. OpenSearch bietet leistungsfähige Werkzeuge, um die drei Säulen der Observability - Logs, Metriken und Traces - zu erfassen, zu analysieren und zu visualisieren. In diesem Kapitel lernen Sie, wie Sie diese Werkzeuge effektiv einsetzen können.

43.1 Grundlagen der Observability

Observability geht über einfaches Monitoring hinaus. Während Monitoring uns sagt, OB etwas nicht funktioniert, hilft uns Observability zu verstehen, WARUM etwas nicht funktioniert. Dies erreichen wir durch die Integration von:

  1. Logs: Detaillierte Ereignisaufzeichnungen
  2. Metriken: Quantitative Messungen über Zeit
  3. Traces: Verfolgung von Anfragen durch verteilte Systeme

43.2 Log-Aggregation und -Analyse

Logs sind oft der erste Anlaufpunkt bei der Fehlersuche. OpenSearch bietet leistungsfähige Funktionen zur Log-Verarbeitung.

43.2.1 Log-Ingest Pipeline einrichten

PUT _ingest/pipeline/log_enrichment
{
  "description": "Verarbeitet und strukturiert Anwendungslogs",
  "processors": [
    {
      "grok": {
        "field": "message",
        "patterns": [
          "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} \\[%{DATA:service}\\] %{DATA:trace_id} - %{GREEDYDATA:message_body}"
        ]
      }
    },
    {
      "date": {
        "field": "timestamp",
        "formats": ["ISO8601"]
      }
    },
    {
      "set": {
        "field": "environment",
        "value": "{{log_environment}}"
      }
    },
    {
      "script": {
        "lang": "painless",
        "source": """
          if (ctx.level == 'ERROR') {
            ctx.alert_level = 'high';
          } else if (ctx.level == 'WARN') {
            ctx.alert_level = 'medium';
          } else {
            ctx.alert_level = 'low';
          }
        """
      }
    }
  ]
}

Diese Pipeline:

43.2.2 Log-Index Template definieren

PUT _index_template/logs_template
{
  "index_patterns": ["logs-*"],
  "template": {
    "settings": {
      "number_of_shards": 3,
      "number_of_replicas": 1,
      "index.lifecycle.name": "logs_policy",
      "index.routing.allocation.include.data_type": "hot"
    },
    "mappings": {
      "properties": {
        "timestamp": { "type": "date" },
        "service": { "type": "keyword" },
        "level": { "type": "keyword" },
        "trace_id": { "type": "keyword" },
        "message_body": { "type": "text" },
        "environment": { "type": "keyword" },
        "alert_level": { "type": "keyword" },
        "metadata": {
          "type": "object",
          "dynamic": true
        }
      }
    }
  }
}

43.3 Metriken-Erfassung und -Visualisierung

Metriken geben uns quantitative Einblicke in den Systemzustand. OpenSearch kann verschiedene Metriken-Formate verarbeiten und visualisieren.

43.3.1 Metriken-Index konfigurieren

PUT /metrics-template
{
  "mappings": {
    "properties": {
      "timestamp": { "type": "date" },
      "host": { "type": "keyword" },
      "service": { "type": "keyword" },
      "metric_name": { "type": "keyword" },
      "metric_value": { "type": "float" },
      "unit": { "type": "keyword" },
      "tags": { "type": "keyword" }
    }
  },
  "settings": {
    "index.routing.allocation.include.data_type": "warm",
    "index.refresh_interval": "30s"
  }
}

43.3.2 Metriken visualisieren

Metriken-Visualisierungen in OpenSearch Dashboards erstellen wir mit der OpenSearch Query DSL:

GET metrics-*/_search
{
  "size": 0,
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "timestamp": {
              "gte": "now-1h",
              "lte": "now"
            }
          }
        },
        {
          "term": {
            "service": "web-frontend"
          }
        }
      ]
    }
  },
  "aggs": {
    "response_times": {
      "date_histogram": {
        "field": "timestamp",
        "fixed_interval": "1m"
      },
      "aggs": {
        "avg_response": {
          "avg": {
            "field": "metric_value"
          }
        },
        "response_percentiles": {
          "percentiles": {
            "field": "metric_value",
            "percents": [50, 90, 99]
          }
        }
      }
    }
  }
}

43.4 Distributed Tracing

Verteiltes Tracing hilft uns, den Weg einer Anfrage durch verschiedene Microservices zu verfolgen.

43.4.1 Trace-Index konfigurieren

PUT traces-template
{
  "mappings": {
    "properties": {
      "trace_id": { "type": "keyword" },
      "span_id": { "type": "keyword" },
      "parent_span_id": { "type": "keyword" },
      "service": { "type": "keyword" },
      "operation": { "type": "keyword" },
      "start_time": { "type": "date_nanos" },
      "duration": { "type": "long" },
      "status": { "type": "keyword" },
      "tags": {
        "type": "nested",
        "properties": {
          "key": { "type": "keyword" },
          "value": { "type": "keyword" }
        }
      }
    }
  }
}

43.4.2 Traces analysieren

Trace-Analyse mit der OpenSearch DSL:

GET traces-*/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "status": "error"
          }
        },
        {
          "range": {
            "duration": {
              "gte": "1000000"  // 1 Sekunde in Mikrosekunden
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "services": {
      "terms": {
        "field": "service",
        "size": 10
      },
      "aggs": {
        "avg_duration": {
          "avg": {
            "field": "duration"
          }
        }
      }
    }
  }
}

43.5 Integration der Observability-Daten

Die wahre Stärke von OpenSearch liegt in der Fähigkeit, Logs, Metriken und Traces zu korrelieren.

43.5.1 Korrelations-Dashboard erstellen

POST _plugins/_dashboards/api/saved_objects/visualization
{
  "attributes": {
    "title": "Service Health Overview",
    "visualizationType": "metrics",
    "params": {
      "type": "timeseries",
      "series": [
        {
          "id": "errors",
          "metrics": [
            {
              "id": "count",
              "type": "count"
            }
          ],
          "split_mode": "terms",
          "terms_field": "service",
          "terms_size": 10
        }
      ],
      "annotations": [
        {
          "fields": "message",
          "template": "{{message}}",
          "id": "error_logs",
          "index_pattern": "logs-*",
          "query_string": "level:ERROR"
        }
      ]
    }
  }
}

43.6 Alarme und Benachrichtigungen

Ein effektives Observability-System benötigt automatische Benachrichtigungen bei Problemen.

43.6.1 Alert-Definition

PUT _plugins/_alerting/monitors/service_health
{
  "type": "monitor",
  "name": "Service Health Monitor",
  "enabled": true,
  "schedule": {
    "period": {
      "interval": 1,
      "unit": "MINUTES"
    }
  },
  "inputs": [
    {
      "search": {
        "indices": ["metrics-*"],
        "query": {
          "bool": {
            "must": [
              {
                "range": {
                  "timestamp": {
                    "gte": "now-5m",
                    "lte": "now"
                  }
                }
              },
              {
                "term": {
                  "metric_name": "error_rate"
                }
              }
            ]
          }
        }
      }
    }
  ],
  "triggers": [
    {
      "name": "Error Rate Alert",
      "severity": "High",
      "condition": {
        "script": {
          "source": "ctx.results[0].hits.hits.stream().map(hit -> hit._source.metric_value).average().orElse(0) > 0.05"
        }
      },
      "actions": [
        {
          "name": "Notify Team",
          "destination_id": "slack_team_channel",
          "message_template": {
            "source": "Error rate exceeded threshold: {{ctx.results.0.hits.hits.0._source.metric_value}}"
          }
        }
      ]
    }
  ]
}

43.7 Best Practices für Observability

Bei der Implementierung von Observability sollten Sie beachten:

  1. Datenmanagement
  2. Performance
  3. Usability