Produkt

Logstash auf OpenShift

UPDATE: In diesem Artikel wird für unser gehostetes Elasticsearch-Angebot noch sein früherer Name „Found“ verwendet. Bitte beachten Sie, dass „Found“ heute „Elastic Cloud“ heißt.

Beginnen Sie mit der Analyse Ihrer Logs auf OpenShift. Während OpenShift es Ihnen ermöglicht, die Logs Ihrer Apps zu tail, bietet Ihnen die Dreifaltigkeit aus Elasticsearch, Logstash und Kibana eine sehr flexible und leistungsstarke Toolchain, um diese Logs zu visualisieren und zu analysieren. Dieser Artikel erklärt, wie man eine Logstash-Cartridge auf OpenShift erstellt. Die Cartridge speist Ihre Logs in Elasticsearch ein, wo Sie die Kibana-Visualisierungs-Engine verwenden können, um Trends zu verfolgen, Anomalien zu erkennen und Vorfälle in Ihrer Umgebung zu inspizieren.

Einführung

OpenShift ist die PaaS-Initiative von RedHat, die sowohl ein öffentliches Angebot als auch eine Enterprise-Version umfasst, mit der Sie den immer beliebter werdenden Platform-as-a-Service-Ansatz in Ihre eigenen Rechenzentren und Ihre private Cloud bringen können.

 

Logstash ist ein Tool zur Verwaltung von Ereignissen und Logdaten. Logstash in Kombination mit Elasticsearch und Kibana bietet Ihnen eine sehr leistungsstarke Toolchain zum Suchen, Analysieren und Visualisieren Ihrer Logdaten. Dieses Trio wird im Volksmund als ELK-Stack bezeichnet.

 

Während OpenShift es Ihnen einfach macht, die Logs all Ihrer Apps zu „tailen“, ist das Tailing bei weitem nicht so leistungsfähig wie der ELK-Stack. Anwendungsspezifische Dinge wie das Logging werden jedoch konzeptbedingt dem überlassen, was OpenShift als Cartridges bezeichnet. Ein Cartridge bietet eine sehr spezifische Funktionalität, die Sie in die Gears der von Ihnen bereitgestellten Anwendungen integrieren. Ein Gear ist ein Container mit einem bestimmten Zweck, und Ihre Anwendung kann aus mehreren Gears bestehen.

 

In diesem Artikel erstellen wir eine einfache Logstash-Cartridge, die Sie problemlos in Ihre Anwendung integrieren können, um Einblicke in Ihre Logs zu gewinnen.

 

Annahmen und Ziele

Logstash verfügt über viele Ausgänge, darunter Elasticsearch, Graphite und S3, um nur einige zu nennen. Elasticsearch ist einer der am häufigsten verwendeten Ausgänge. Wir werden unsere Logstashes so konfigurieren, dass sie Logs an Elasticsearch ausgeben, aber dieser Ansatz lässt sich leicht auch auf andere Ausgänge verallgemeinern. Sie könnten sogar an ein vorgelagertes Logstash ausgeben, um zwischen Log-Versand und Log-Verarbeitung zu unterscheiden.

 

Wenn Sie einen gehosteten Elasticsearch-Cluster benötigen, probieren Sie doch Found aus.

 

Wir setzen eine gewisse Vertrautheit mit OpenShift voraus. Wenn Sie keine Erfahrung mit OpenShift haben, lesen Sie deren Getting-Started-Anleitung.

 

Das Ziel ist ein Cartridge, das Sie Ihrer Anwendung hinzufügen können, um anschließend zu beobachten, wie Logdaten in einem Elasticsearch-Cluster erscheinen. Danach können Sie Kibana verwenden, um Ihre Logdaten zu visualisieren und zu analysieren, Vorfälle zu inspizieren, Trends zu verfolgen und Anomalien in Ihrer Umgebung zu erkennen.

 

OpenShift-Konfiguration und -Logs

Cartridges werden in der Regel mit anwendungsspezifischen Konfigurationen (wie Datenbankanmeldedaten) über Umgebungsvariablen angepasst. Eine dieser Variablen, $OPENSHIFT_LOG_DIR, gibt an, wohin eine Cartridge log soll.

 

Cartridges können alles ausführen, daher gibt es kein Standard-Logging-Format oder gar ein Standard-Zeitstempelformat. Dies ist ein universelles Problem beim Logging, das Logstash sehr gut handhabt. Logstash verfügt über viele verschiedene Eingänge und Filter. Im folgenden Beispiel konfigurieren wir Logstash mit file -Eingängen, einigen Filtern zur Verarbeitung von Apache-Logs, Zeitstempeln und IPs und geben die Logs schließlich an Elasticsearch aus. Logstash kann noch viel mehr, und seine Dokumentation ist gut.

 

Log-Formate sind hochgradig anwendungsspezifisch, daher müssen Sie die Verarbeitung von Logstash entsprechend konfigurieren. Um ein konkretes Beispiel zu haben, betrachten wir eine einfache Python-Anwendung, die Zugriffs-Logs erstellt:

 
# Erstellen Sie eine Anwendung. Irgendetwas, das Logdaten erzeugt. Mit dieser App erhalten wir einen laufenden Webserver, der Zugriffs-Logs erzeugt – genau das, was wir brauchen.

$ rhc app create my-app python-2.6
Anwendungsoptionen
-------------------
Domain:     Namespace
Cartridges: python-2.6
Zahnradgröße:  Standard
Skalieren:    nein

Anwendung „my-app“ wird erstellt ... fertig

[ ... ]

Ihre Anwendung „my-app“ ist jetzt verfügbar.

  URL:        http://my-app-namespace.rhcloud.com/

[ ... ]

# Umgebungsvariablen konfigurieren, wie Cluster-Hostname und Authentifizierungsoptionen
$ rhc set-env --app my-app --env "OPENSHIFT_LOGSTASH_ES_HOST=dabadeee123-us-east-1.foundcluster.com"
Umgebungsvariable(n) werden festgelegt ... fertig
$ rhc set-env --app my-app --env "OPENSHIFT_LOGSTASH_ES_USER=readwrite"
Umgebungsvariable(n) werden festgelegt ... fertig
$ rhc set-env --app my-app --env "OPENSHIFT_LOGSTASH_ES_PASSWORD=secret"
Umgebungsvariable(n) werden festgelegt ... fertig

# Fügen Sie zum Schluss die Cartridge hinzu.
$ rhc cartridge add -a my-app https://cartreflect-claytondev.rhcloud.com/github/foundit/openshift-logstash-cartridge
Das Cartridge 'https://cartreflect-claytondev.rhcloud.com/github/foundit/openshift-logstash-cartridge' wird heruntergeladen und installiert
Hinzufügen von https://cartreflect-claytondev.rhcloud.com/github/foundit/openshift-logstash-cartridge zur App „my-app“ ... fertig

found-logstash-1.4.1 (Logstash 1.4.1)
-------------------------------------
  Von:  https://cartreflect-claytondev.rhcloud.com/github/foundit/openshift-logstash-cartridge
  Gears: Befindet sich bei python-2.6

Nach einer Weile sollten Logs im konfigurierten Elasticsearch-Cluster erscheinen. Wenn Sie Ihre Webanwendung aufrufen, sollten Zugriffs-Logs ähnlich den folgenden in python.log erscheinen:

 
1.2.3.4 - - [10/Jun/2014:10:31:17 -0400] "GET / HTTP/1.1" 200 39617 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36"

Diese werden dann von Logstash aufgenommen und wie folgt in Elasticsearch indexiert:

 
{
    "_type": "logs",
    "_source": {
        "tags": ["app-name", "gear-name", "namespace"],
        "@timestamp": "2014-06-10T14:31:18.907Z",
        "host": "ex-std-node7.prod.rhcloud.com",
        "path": "/var/lib/openshift/530001200012cd3502000122/app-root/logs/python.log",
        "message": "1.2.3.4 - - [10/Jun/2014:10:31:17 -0400] \"GET / HTTP/1.1\" 200 39617 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36\"",
        "@version": "1"
    },
    "_index": "logstash-2014.06.10",
    "_id": "dCfV_YUjSwOlISJWQMafaw"
}

Dies ist zwar ein guter Anfang, aber die interessantesten Informationen sind in der Zeichenfolge 1.2.3.4 - - [10/Jun/2014:10:31:17 -0400] "GET / HTTP/1.1\" 200 39617 \"-\" \"Mozilla/5.0 [...]" zusammengefasst.

 

Diese Zeichenfolge folgt dem Apache-Combined-Format, und Logstash verfügt über ein vordefiniertes Muster für den Abgleich. Wenn Sie bekannte Software verwenden, stehen die Chancen im Allgemeinen gut, dass Sie dafür Logstash-Muster finden. Werfen Sie einen Blick in das patterns-Verzeichnis von Logstash. Auch das Discover-Feature des Grok Debuggers kann nützlich sein. Wenn Sie die obige Log-Nachricht dort einfügen,%{COMBINEDAPACHELOG} wird ausgegeben. Im nächsten Abschnitt werden wir sehen, wie man es verwendet.

 

Anpassen der Cartridge

Die Basis-Cartridge, die auf GitHub (foundit/openshift-logstash-cartridge) verfügbar ist, hat eine sehr einfache Konfiguration, die das oben genannte Log erzeugt.

 

Um Logstash so zu konfigurieren, dass das Log ordnungsgemäß verarbeitet und die Daten extrahiert werden, müssen wir die Konfiguration ein wenig anpassen. Zuerst legen wir fest, dass die python.log-Datei vom Typ apache ist, und stellen dann sicher, dass wir anschließend alle Logs vom Typ apache entsprechend filtern.

 

Die Input- und Filter-Sektion der Logstash-Konfiguration sollte in etwa wie folgt aussehen. Das vollständige logstash.conf.erb finden Sie auf GitHub. logstash.conf.erb ist die Vorlage, die zum Generieren der Logstash-Konfigurationsdatei verwendet wird, wobei Umgebungsvariablen wie URLs und Authentifizierungsinformationen interpoliert werden.

 
Eingang {

    # Alles, was protokolliert wird, außer python.log
    Datei {
        path => "<%= ENV['OPENSHIFT_LOG_DIR'] %>*.log"
        # Fügen Sie einige OpenShift-Metadaten zu Filterzwecken hinzu.
        tags => ["<%= ENV['OPENSHIFT_APP_NAME'] %>", "<%= ENV['OPENSHIFT_GEAR_NAME'] %>", "<%= ENV['OPENSHIFT_NAMESPACE'] %>"]
        exclude => "python.log"
    }

    # Wir wissen, dass python.log Apache-Zugriffslogs enthält.
    Datei {
        path => "<%= ENV['OPENSHIFT_LOG_DIR'] %>python.log"
        tags => ["<%= ENV['OPENSHIFT_APP_NAME'] %>", "<%= ENV['OPENSHIFT_GEAR_NAME'] %>", "<%= ENV['OPENSHIFT_NAMESPACE'] %>"]
        type => "apache"
    }

}

Filter {
    if [type] == "apache" {

        # Dies extrahiert die verschiedenen Metadaten in der Log-Nachricht, wie Zeitstempel, IP, Methode usw.
        Grok {
            match => ["message", "%{COMBINEDAPACHELOG}"]
        }

        # Das Zeitformat in ein sinnvolles Format umwandeln.
        Datum {
            match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
        }

        # Log mit ungefähren Geoinformationen anreichern.
        geoip {
            source => "clientip"
        }

    }
}

Mit dieser Konfiguration erstellt Logstash Dokumente wie die folgenden:

 
{
    "_type": "apache",
    "_source": {
        "ident": "-",
        "tags": ["app-name", "gearname", "Namespace"],
        "type": "apache",
        "@timestamp": "2014-06-10T15:19:31.000Z",
        "request": "/",
        "auth": "-",
        "Reaktion": "200",
        "referrer": "\"-\"",
        "bytes": "39617",
        "host": "ex-std-node7.prod.rhcloud.com",
        "verb": "GET",
        „agent“: „Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) [...]“,
        "timestamp": "10/Jun/2014:11:19:31 -0400",
        "path": "/var/lib/openshift/539709b8e0b8cd3502000122/app-root/logs/python.log",
        "message": "1.2.3.4 - - [10/Jun/2014:11:19:31 -0400] \"GET / HTTP/1.1\" 200 39617 [...]",
        "@version": "1",
        "clientip": "1.2.3.4",
        "httpversion": "1.1",
        "geoip": {
          "region_name": "16",
          "ip": "1.2.3.4",
          "continent_code": "EU",
          "country_name": "Norway",
          "city_name": "Trondheim",
          "timezone": "Europe/Oslo",
          „longitude“: 10,416699999999992,
          "country_code3": "NOR",
          "country_code2": "NO",
          "location": [
            10,416699999999992,
            63,41669999999999
          ],
          "latitude": 63,41669999999999,
          "real_region_name": "Sor-Trondelag"
        }
    },
    "_index": "logstash-2014.06.10",
    "_id": "Z1N65K5-QTOwZ9z3jPgEUw"
}

Wir können noch viel mehr mit diesem Dokument anstellen. Wir können die Zugriffs-Logs basierend auf der Herkunft des Nutzers oder dessen besuchten Seiten analysieren und untersuchen, problematische Anfragen leicht finden und vieles mehr. Die folgende Abbildung zeigt ein Beispiel für ein Kibana-Dashboard, das die oben genannten Daten verwendet. Using Kibana to analyze access logs

 

Um das Cartridge anzupassen, forken Sie einfach das Repository und bearbeiten Sie conf/logstash.conf.erb mit Ihrer gewünschten Logstash-Konfiguration.

 

Passen Sie dann die URL an, wenn Sie Ihre Cartridge hinzufügen, d. h. ändern Sie foundit/openshift-logstash-cartridge in your-organization/repository-name.

 
$ rhc cartridge add -a my-app https://cartreflect-claytondev.rhcloud.com/github/your-organization/your-repo

Standardmäßig wird der Master-Branch verwendet. Sie können auch eine ?commit=branch-or-commit-id-Option in der URL übergeben, z. B. https://cartreflect-claytondev.rhcloud.com/github/foundit/openshift-logstash-cartridge?commit=python-sample.

 

Weitere Informationen zum Anpassen von Cartridges und zur Verwendung von Cartridges, die nicht öffentlich verfügbar sind, finden Sie im OpenShift-Leitfaden dazu, wie Cartridges heruntergeladen werden.

 

Log-freundliche Mappings

Wie wir gesehen haben, kümmert sich Logstash um das Senden von Logs an Elasticsearch. Wir müssen Elasticsearch jedoch noch mitteilen, wie diese Logs behandelt werden sollen. Wir müssen die Mappings für die resultierenden Indizes konfigurieren. (Siehe auch: Einführung in das Elasticsearch-Mapping und Ein Data-Exploration-Workflow für Mappings)

 

Normalerweise sendet Logstash Logs an den Index logstash-YYYY-MM-DD, wobei YYYY-MM-DD das Datum des Logs ist. Auf diese Weise können Sie Suchen auf bestimmte Datumsbereiche beschränken sowie alte Logs archivieren oder löschen.

 

Um unser Log-Mapping zu konfigurieren, müssen wir ein Index-Template definieren, das das Mapping für alle Indizes festlegt, deren Name auf logstash-* passt.

 

Das Folgende ist ein geeignetes Mapping für die oben erzeugten Logs. Zeichenfolge-Felder werden standardmäßig nicht analysiert, mit Ausnahme des Feldes message; der geoip-Standort ist als Typ geo_point konfiguriert, clientip als ein ip usw.

 
{
    "template": "logstash-*",
    "settings": {
        "index.refresh_interval": "5s"
    },
    "mappings": {
        „_default_“: {
            "_all": {
                "enabled" : true
            },
            "dynamic_templates": [
                {
                    "string_fields": {
                        "match": "*",
                        "match_mapping_type": "Zeichenfolge",
                        "Mapping": {
                            "type": "Zeichenfolge",
                            "index": "not_analyzed"
                        }
                    }
                }
            ],
            "properties": {
                "geoip": {
                    "properties": {
                        "location": {
                            "type": "geo_point"
                        }
                    }
                },
                "clientip": {
                    "type": "ip"
                },
                "bytes": {
                    "type": "long"
                },
                "message": {
                    "type": "Zeichenfolge",
                    "index": "analyzed",
                    "omit_norms": true
                }
            }
        }
    }
}

Um die Vorlage anzuwenden, senden Sie eine PUT-Anfrage an /_template/logstash mit dem JSON-Body:

 
$ curl https://user:pass@cluster-id.foundcluster.com:9243/_template/logstash -XPUT -d @index-template.json
{"acknowledged":true}

Anschließend verwendet Elasticsearch die im Index-Template festgelegten Einstellungen und Mappings, wann immer ein neuer logstash-index erstellt wird.

 

Zusammenfassung

Wir verfügen jetzt über eine Cartridge, die als Basis für benutzerdefinierte Logstash-Cartridges mit einer anwendungsspezifischeren Konfiguration dienen kann. Das Übertragen Ihrer Logs in einen Elasticsearch-Cluster für beeindruckende Suchvorgänge und Analytik ist jetzt nur noch eine Frage des Hinzufügens einer OpenStack-Cartridge.