Logstash sur OpenShift
MISE À JOUR : cet article fait référence à notre offre Elasticsearch hébergée par son ancien nom, Found. Veuillez noter que Found est désormais connu sous le nom d'Elastic Cloud.
Commencez à analyser vos logs sur OpenShift. Bien qu'OpenShift vous permette de suivre les logs de vos applications, la trinité Elasticsearch/Logstash/Kibana vous offre une chaîne d'outils très flexible et puissante pour visualiser et analyser ces logs. Cet article explique comment créer une cartouche Logstash sur OpenShift. La cartouche alimente vos logs dans Elasticsearch, où vous pouvez utiliser le moteur de visualisation Kibana pour suivre les tendances, détecter les anomalies et inspecter les incidents dans votre environnement.
Introduction
OpenShift est l'initiative PaaS de RedHat, proposant à la fois une offre publique et une version entreprise qui vous permet d'adopter l'approche Platform-as-a-Service, de plus en plus populaire, au sein de vos propres centres de données et de votre cloud privé.
.Logstash est un outil de gestion des événements et des logs. Combiné à Elasticsearch et Kibana, Logstash vous offre une chaîne d'outils très puissante pour rechercher, analyser et visualiser vos logs. Ce trio est communément appelé la Suite ELK.
.Bien qu'OpenShift vous permette facilement de suivre les logs de toutes vos applications, cette fonctionnalité n'est pas aussi puissante que la Suite ELK. Cependant, par conception, les éléments spécifiques aux applications, comme le logging, sont laissés à ce qu'OpenShift appelle des cartridges. Un cartridge fournit une fonctionnalité très spécifique, que vous intégrez aux gears des applications que vous déployez. Un gear est un conteneur ayant un objectif précis, et votre application peut être composée de plusieurs gears.
.Dans cet article, nous allons créer une cartouche Logstash simple, que vous pourrez facilement intégrer à votre application pour obtenir des informations sur vos logs.
.Hypothèses et objectifs
Logstash possède de nombreuses sorties, notamment Elasticsearch, Graphite et S3 pour n’en citer que quelques-unes. Elasticsearch est l’une des sorties les plus largement utilisées. Nous configurerons nos instances Logstash pour envoyer les logs vers Elasticsearch, mais cette approche peut facilement être généralisée à d’autres sorties. Vous pourriez même effectuer une sortie vers un Logstash en amont, afin de distinguer l’expédition des logs du traitement des logs.
.Si vous avez besoin d'un cluster Elasticsearch hébergé, essayez Found.
.Nous supposons une certaine familiarité avec OpenShift. Si vous n'avez aucune expérience d'OpenShift, consultez leur guide de démarrage.
.L'objectif est d'avoir une cartouche que vous pouvez ajouter à votre application, puis de voir les logs apparaître dans un cluster Elasticsearch. Ensuite, vous pouvez utiliser Kibana pour visualiser et analyser vos logs, inspecter les incidents, suivre les tendances et détecter les anomalies dans votre environnement.
.Configuration et logs OpenShift
Les cartouches sont généralement personnalisées avec une configuration spécifique à l'application (telle que les identifiants de base de données) via des variables d'environnement. L'une de ces variables, $OPENSHIFT_LOG_DIR, indique où une cartouche doit effectuer son logging.
.Les cartouches peuvent tout exécuter, il n'existe donc pas de format de logging standard, ni même de format d'horodatage standard. Il s'agit d'un problème universel pour le logging, que Logstash gère très bien. Logstash dispose de nombreuses entrées et de nombreux filtres différents. Dans l'exemple qui suit, nous allons configurer Logstash avec des entrées file, quelques filtres pour traiter les logs Apache, les horodatages et les adresses IP, pour enfin envoyer en sortie les logs vers Elasticsearch. Logstash peut faire bien plus, et sa documentation est de qualité.
.Les formats de logs sont hautement spécifiques à chaque application ; vous devrez donc configurer le traitement de Logstash en conséquence. Pour avoir un exemple concret, nous allons examiner une application Python simple qui produit des logs d'accès :
.# Créez une application. N'importe quoi qui produit des logs. Avec cette application, nous aurons un serveur Web en cours d'exécution qui produit des logs d'accès, ce qui est tout ce dont nous avons besoin. $ rhc app create my-app python-2.6 Options d'application ------------------- Domaine : espace de nom Cartouches : python-2.6 Taille de l'équipement : par défaut Scaling : non Création de l'application « my-app »... terminée [ ... ] Votre application « my-app » est désormais disponible. URL : http://my-app-namespace.rhcloud.com/ [ ... ] # Configurer les variables d'environnement, comme le nom d'hôte du cluster et les options d'authentification $ rhc set-env --app my-app --env "OPENSHIFT_LOGSTASH_ES_HOST=dabadeee123-us-east-1.foundcluster.com" Définition de la ou des variable(s) d'environnement... terminé $ rhc set-env --app my-app --env "OPENSHIFT_LOGSTASH_ES_USER=readwrite" Définition de la ou des variable(s) d'environnement... terminé $ rhc set-env --app my-app --env "OPENSHIFT_LOGSTASH_ES_PASSWORD=secret" Définition de la ou des variable(s) d'environnement... terminé # Enfin, ajoute la cartouche. $ rhc cartridge add -a my-app https://cartreflect-claytondev.rhcloud.com/github/foundit/openshift-logstash-cartridge La cartouche 'https://cartreflect-claytondev.rhcloud.com/github/foundit/openshift-logstash-cartridge' sera téléchargé et installé Ajout de https://cartreflect-claytondev.rhcloud.com/github/foundit/openshift-logstash-cartridge vers l'application 'my-app' ... terminé found-logstash-1.4.1 (Logstash 1.4.1) ------------------------------------- De : https://cartreflect-claytondev.rhcloud.com/github/foundit/openshift-logstash-cartridge Gears : situé avec Python 2.6
Après un certain temps, les logs devraient commencer à apparaître dans le cluster Elasticsearch configuré. Si vous visitez votre application Web, des logs d'accès similaires à ce qui suit devraient apparaître dans python.log:
.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"
Celles-ci seront ensuite récupérées par Logstash et indexées dans Elasticsearch comme suit :
.{
"_type": "logs",
"_source": {
"tags": ["nom-de-l'application", "gear-name", "espace-de-nom"],
"@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"
}
Bien que ce soit un bon début, les informations les plus intéressantes sont regroupées dans la chaîne 1.2.3.4 - - [10/Jun/2014:10:31:17 -0400] "GET / HTTP/1.1\" 200 39617 \"-\" \"Mozilla/5.0 [...]".
.Cette chaîne suit le format Apache Combined, et Logstash dispose d'un modèle prédéfini pour y correspondre. En règle générale, si vous utilisez un logiciel connu, il est fort probable que vous trouviez des modèles Logstash correspondants. Jetez un œil au répertoire patterns de Logstash. La fonctionnalité Discoverdu Grok Debuggerpeut également s'avérer utile. Si vous y collez le message de log ci-dessus, il %{COMBINEDAPACHELOG} affichera. Dans la section suivante, nous verrons comment l'utiliser.
.Personnalisation de la cartouche
La cartouche de base, disponible sur GitHub (foundit/openshift-logstash-cartridge), possède une configuration très simple qui produit le log ci-dessus.
.Pour configurer Logstash afin de traiter correctement le log et d'extraire les données, nous devons modifier légèrement la configuration. Tout d'abord, nous indiquerons que le fichier python.logest de type apache, puis nous nous assurerons de filtrer ultérieurement tout log de type apache de manière appropriée.
.Nous souhaitons que les sections d'entrée (input) et de filtre (filter) de la configuration de Logstash ressemblent à ce qui suit. Consultez le fichier logstash.conf.erb complet sur GitHub. logstash.conf.erb est le modèle utilisé pour générer le fichier de configuration Logstash, en interpolant les variables d'environnement telles que les URL et les informations d'authentification.
.entrée {
# Tout ce qui est loggé, sauf python.log
file {
path => "<%= ENV['OPENSHIFT_LOG_DIR'] %>*.log"
# Ajoutez des métadonnées openshift à des fins de filtrage.
tags => ["<%= ENV['OPENSHIFT_APP_NAME'] %>", "<%= ENV['OPENSHIFT_GEAR_NAME'] %>", "<%= ENV['OPENSHIFT_NAMESPACE'] %>"]
exclude => "python.log"
}
# Nous savons que python.log contient des logs d’accès Apache.
file {
path => "<%= ENV['OPENSHIFT_LOG_DIR'] %>python.log"
tags => ["<%= ENV['OPENSHIFT_APP_NAME'] %>", "<%= ENV['OPENSHIFT_GEAR_NAME'] %>", "<%= ENV['OPENSHIFT_NAMESPACE'] %>"]
type => "apache"
}
}
"filters": {
if [type] == "apache" {
# Ceci extraira les différentes métadonnées du message de log, comme l'horodatage, l'IP, la méthode, etc.
grok {
match => ["message", "%{COMBINEDAPACHELOG}"]
}
# Convertir le format horaire en quelque chose d'exploitable.
date {
match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
}
# Annoter le log avec des informations géographiques approximatives.
geoip {
source => "clientip"
}
}
}
Avec cette configuration, Logstash produira des documents comme suit :
.{
"_type": "apache",
"_source": {
"ident": "-",
"tags": ["app-name", "gearname", "espace de nom"],
"type": "apache",
"@timestamp": "2014-06-10T15:19:31.000Z",
"request": "/",
"auth": "-",
"réponse": "200",
"referrer": "\"-\"",
"bytes" : "39617",
"host": "ex-std-node7.prod.rhcloud.com",
« verbe » : « 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"
}
Nous pouvons faire bien plus avec ce document. Nous pouvons ventiler les logs d'accès en fonction de la provenance de l'utilisateur, de ce qu'il visite, trouver facilement les requêtes problématiques, etc. La figure ci-dessous montre un exemple de tableau de bord Kibana qui utilise les données ci-dessus.
Pour personnaliser la cartouche, il suffit de forker le référentiel et de modifier conf/logstash.conf.erb avec la configuration Logstash souhaitée.
.Ensuite, personnalisez l'URL lorsque vous ajoutez votre cartouche, c'est-à-dire remplacez foundit/openshift-logstash-cartridge par your-organization/repository-name.
.$ rhc cartridge add -a my-app https://cartreflect-claytondev.rhcloud.com/github/your-organization/your-repo
Par défaut, elle utilisera la branche master. Vous pouvez également transmettre une option ?commit=branch-or-commit-iddans l'URL, par exemple https://cartreflect-claytondev.rhcloud.com/github/foundit/openshift-logstash-cartridge?commit=python-sample.
.Pour plus d'informations sur la personnalisation des cartouches et l'utilisation de cartouches non disponibles publiquement, consultez le guide OpenShift sur la façon dont les cartouches sont téléchargées.
.mapping adapté aux log
Comme nous l'avons vu, Logstash se charge d'envoyer les logs vers Elasticsearch. Nous devons encore indiquer à Elasticsearch comment traiter ces logs. Nous devons configurer les mappages pour les index résultants. (Voir aussi : Introduction au mapping Elasticsearch et Un workflow d'exploration de données pour les mappages)
.En règle générale, Logstash envoie les logs vers l’index logstash-YYYY-MM-DD, où YYYY-MM-DD correspond à la date du log. Cela vous permet de limiter les recherches à des plages de dates spécifiques, et d’archiver ou de supprimer les anciens logs.
.Pour configurer notre mapping de log, nous devons définir un modèle d'index, qui définit le mapping pour tous les index dont le nom correspond à logstash-*.
.Voici un mapping approprié pour les logs produits ci-dessus. Les champs de type chaîne (string) ne sont pas analysés par défaut, à l'exception du champ message; la localisation geoip est configurée pour être de type geo_point, clientip comme un ip, etc.
.{
"template": "logstash-*",
"settings": {
"index.refresh_interval": "5s"
},
"mappings": {
"_default_": {
"_all": {
"enabled": true
},
"dynamic_templates": [
{
"string_fields": {
"match": "*",
"match_mapping_type": "chaîne",
"mapping": {
"type": "chaîne",
"index": "not_analyzed"
}
}
}
],
"properties": {
« geoip » : {
"properties": {
"location": {
"type": "geo_point"
}
}
},
"clientip": {
"type": "ip"
},
"bytes" : {
"type": "long"
},
"message": {
"type": "chaîne",
"index": "analyzed",
"omit_norms": true
}
}
}
}
}
Pour appliquer le modèle, envoyez une requête PUTà /_template/logstash avec le corps JSON :
.$ curl https://user:pass@cluster-id.foundcluster.com:9243/_template/logstash -XPUT -d @index-template.json
{"acknowledged":true}
Ensuite, Elasticsearch utilisera les paramètres et les mapping spécifiés dans le modèle d'index chaque fois qu'il créera un nouvel index Logstash-index.
.Résumé
Nous disposons désormais d'un cartridge pouvant servir de base à des cartridges Logstash personnalisés avec une configuration plus spécifique à l'application. L'intégration de vos logs dans un cluster Elasticsearch pour des recherches et des analyses performantes n'est plus qu'une question d'ajout d'un cartridge OpenStack.
.