Logstash

le

Logstash fait maintenant partie de la collection d'armes secrètes d'ElasticSearch (avec Kibana).

Logstash fait maintenant partie de la collection d'armes secrètes d'ElasticSearch (avec Kibana).

Logstash est un aiguilleur de logs, il accepte différents formats d'évènements en entrée, les filtres, puis génère différents formats de sortie. Un rien confus, non?

Pour comprendre, il suffit de suivre la rivière. En anglais, il y a un jeu de mots avec log. Log a le sens de journal de bord (par extension, un évènement noté, utilisé en informatique), mais aussi de grume, le tronc d'arbre sans ses branches que l'on balance dans la rivière pour les récupérer plus bas. Par extension, il a aussi le sens de buche, logstash signifie donc "tas de bois pour l'hiver".

Pour percevoir l'intérêt de logstash, il faut donc reprendre le cheminement d'un log. Les logs (des évènements, donc) sont produits par une application, ils peuvent être directement écrits sur le disque, ou transiter par syslog. La plupart des langages ont normalisé ce traitement et utilisent des clones plus ou moins proches de log4j. Les logs peuvent être applicatif (Apache et son inébranlable common log format, Postfix ...) ou métier (dans une optique de debug, ou plus simplement pour voir ce qu'il se passe). Logstash propose de lire tous les flux qui vous intéressent, pour ensuite les explorer : le fameux pattern "entasse et cherche".

Architecture

Logstash est livré sous la forme d'un gros jar à tout faire. À l'intérieur se cache un ensemble de modules en Jruby qui eux, utilisent des bibliothèques matures et performantes en classique java. Jruby a l'avantage par rapport au traditionnel ruby de bien gérer les threads et la concurrence. Le code est concis et lisible, la création ou la modification de plugin ne fait pas peur. Le packaging de l'application manque, lui, de maturité. La version 1.3 est la première livraison depuis l'acquisition par ElasticSearch qui lui est bien packagé, on peut espérer prochainement de bonnes choses pour le déploiement de logstash.

Acquisition

Logstash est capable de lire des fichiers textes en flot, comme le ferait un "tail -f". Pour ne pas avoir à déployer du java sur des serveurs qui n'ont rien demandé, il existe beaver, une application python, qui fait la même chose.

Se brancher sur le fichier de sortie n'est pas l'approche la plus simple et la plus fiable, mais elle a l'avantage d'être neutre et non intrusive.

La méthode d'acquisition la plus simple est d'utiliser Logstash comme un serveur, et de lui envoyer les évènements, dans un protocole qui nous plait, syslog, par exemple, mais il en existe plusieurs.

Ajouter une sortie à rsyslog pour qu'il duplique un des flots de log à Logstash est trivial.

Le filtrage et le stockage ne sont pas forcément aussi rapides que le flot d'évènements en entrée, qui peut fluctuer fortement. Pour éviter toute congestion (dramatique pour les applications), il est possible d'utiliser une file d'attente. Redis avec RPUSH/BLPOP peut servir de file d'attente, mais RabbitMQ peut aussi s'en charger, ou d'autres produits plus exotiques.

Il est possible de chainer les logstashs, un logstash local envoie sur un logstash distant qui va enrichir le contenu avant de l'indexer, par exemple. La sérialisation est paramétrable (json, msgpack...), tout comme la couche transport (tcp, zeromq, websocket...).

Filtrage

Les logs sont historiquement dans un format lisible par un admin et par grep. Les sérialisations sont souvent rustiques, comme syslog qui note la date sans l'année, et avec une rigueur plus proche du freestyle. Les filtres de logstash sont capables d'aller loin : ils peuvent gérer le multiligne (les crashs logs), regrouper deux évènements (une entrée pour le début d'une action, une seconde entrée pour la fin), dédoublonner, anonymiser... Les regex ne sont pas oubliés, avec grok, un ensemble de métaregex qui pioche dans une liste de vrai regex. Grok permet des définitions étonnement lisible. Le parsing des dates est aussi bluffant (via Joda time), il est ainsi possible d'utiliser la date d'entrée du log, ou une date contenue dans le log (pour des imports postmortem ou périodiques). Il est possible d'effectuer des résolutions DNS (et leur reverse), et donc avec un peu d'astuce de questionner un RBL. Le parsing de user agent ou la geoIP font aussi partie des filtres.

Les filtres s'empilent, et le DSL de configuration permet de faire des tests. Avec les tags et les types, on peut à peu près faire ce que l'on veut.

Sortie

Les sorties sont très diverses. Le stockage est l'usage le plus intuitif, mais il est aussi possible de prévenir via mail/irc/xmpp..., de grapher via statsd ou directement graphite. Les SAAS de logging sont bien représentés. La destination reine reste quand même Elasticsearch, dans l'idée d'utiliser Kibana, le troisième de la bande ElasticSearch.

Évolution

Le combo logstash/elasticsearch/kibana est assez magique. Il permet de mettre en place très rapidement une solution de visualisation et d'exploration de logs. Il est clairement dans un état bêta, mais très prometteur et pragmatique. Des explorations dans l'intégration de mesures brutes sont faites (intégration de collectd), mais, bien que fan d'elasticsearch dans son rôle de statisticien, je doute fort de sa capacité à concurrencer un graphite ou un opentsdb. Une agglomération de sources au niveau de kibana me semble plus pertinente, il est clairement tentant de voir l'utilisation du CPU au moment où les logs pleurent. Kibana est un produit de visualisation complet, à base de widgets. Il est dans un état "cible mouvante", impensable de créer ses propres widgets pour l'instant, des bugs reports sont plus sages, comme forme de contribution. Par contre, l'intégration d'Elastic Search dans Javascript vient de sortir, une jolie bibliothèque avec deux sous projets dans l'air du temps : angular et jquery. Voilà, tout est maintenant disponible pour construire son propre tableau de bord.

Exemple

Authentification ratée ssh

Visualiser les gens qui n'arrivent pas à s'authentifier sur le ssh de votre serveur.

Rsyslog fait déjà une partie du tri, et il sait router les flux d'évènements. Attention, la syntaxe de configuration de la version stable (très dense) n'est pas celle que l'on trouve sur le site de Rsyslog.

/etc/rsyslog.d/logstash.conf

auth.* @@127.0.0.1:10515

Cette jolie syntaxe indique que tout le flux "auth" est envoyé en TCP (les deux @) en localhost sur le port 10515.

La configuration de logstash est plus contemporaine, elle suit la mode des pseudos DSL :

/etc/logstash/conf.d/auth.conf

input {
        syslog { # le début du log de syslog est automatiquement parsé
                host => "127.0.0.1"
                        port => 10515
                        type => "auth" # juste un typage arbitraire pour ensuite
        }
}
# Le log ressemble à ça :
# Dec 19 00:05:47 caverne sshd[31175]: Failed password for root from 222.175.114.134 port 1520 ssh2
filter {
        if [type] == "auth" and [program] == "sshd" {
                grok { # de la regex bien emballée
                        match => {
                                "message" => "Failed password for %{DATA:user} from %{IP:ip} port %{INT:port} ssh2"
                        }
                        add_tag => "ssh_failed"
                        break_on_match => false
                }
        }
        if "ssh_failed" in [tags] {
                metrics { # toutes les 60 secondes, on relève les compteurs
                        meter => [ "fails" ]
                        add_tag => "metric"
                        flush_interval => 60
                        clear_interval => 60
                        add_field => ["source", "beuha"] # it's a bug, I should use this : "%{[logsource]}"]
                }
                geoip { # pour le sport, on retrouve d'où vient le pénible
                        source => "ip"
                }
                dns { # Pour connaitre le provider, ou, au moins un indice
                    reverse => ["ip"]
                }
        }
}
output {
        stdout { # pour débuguer et voir la ville
                debug => true
        }
        if "ssh_failed" in [tags] {
            elasticsearch_http { # Pour pouvoir explorer avec Kibana
                host => "localhost"
            }
        }
        if "metric" in [tags] {
                graphite { # les données sont envoyés sur un graphite
                        metrics => {
                                "servers.%{source}.sshd.error" => "%{fails.count}"
                        }
                }
        }
}

Logstash est lancé à la main, pour voir ce qu'il se passe :

sudo -u logstash java -jar /opt/logstash/logstash.jar agent --verbose --debug -v -f /etc/logstash/conf.d/

Il faut bien sûr avoir installé un graphite et un elastic search avec son Kibana, pour vraiment en profiter.

En teaser, un exemple de log, avec des xxx dans l'IP du pénible :

{
       "message" => "Failed password for root from 61.147.74.xxx port 1374 ssh2",
    "@timestamp" => "2013-12-19T15:30:49.000Z",
      "@version" => "1",
          "type" => "auth",
          "host" => "127.0.0.1",
      "priority" => 13,
     "timestamp" => "Dec 19 16:30:49",
     "logsource" => "beuha",
       "program" => "sshd",
           "pid" => "6589",
      "severity" => 5,
      "facility" => 1,
"facility_label" => "user-level",
"severity_label" => "Notice",
          "user" => "root",
            "ip" => "61.147.74.xxx",
          "port" => 1374,
          "tags" => [
    [0] "ssh_failed"
],
         "geoip" => {
                  "ip" => "61.147.74.xxx",
       "country_code2" => "CN",
       "country_code3" => "CHN",
        "country_name" => "China",
      "continent_code" => "AS",
         "region_name" => "04",
           "city_name" => "Nanjing",
            "latitude" => 32.0617,
           "longitude" => 118.77780000000001,
            "timezone" => "Asia/Shanghai",
    "real_region_name" => "Jiangsu",
            "location" => [
        [0] 118.77780000000001,
        [1] 32.0617
    ]
}}

Service Conseil et accompagnement

Bearstech vous propose ses services Conseil et accompagnement elasticsearch

Découvrir ce service

Partager cet article

Flux RSS


Partager cet article :