ELK, étape 2 : logstash

Maintenant que nous avons paramétré ELK, voyons comment on peut aller un peu plus loin.

Logstash : Input

Fichiers

Reprenons le code utilisé précédemment

input {
  file { 
    path => "/var/log/apache2/access.log"
    type => "apache"
    start_position => "end"
  }
}

On peut dans cette section multiplier les entrées. Par exemple, on peut avoir plusieurs blocs de type « file », qui vont aller chercher sur des fichiers différents.

De même, l’option path peut contenir des wildcard et on demande dans ce cas à logstash d’analyser. Par exemple, imaginons qu’on veut analyser tout le répertoire de logs d’apache, on pourra mettre « /var/log/apache2/* ». En revanche, grâce à logrotate, on va trouver dans ce répertoire des fichiers compressés, qui va falloir exclure. On peut écrire :

input {
  file { 
    path => "/var/log/apache2/*"
    exclude => "*gz"
    type => "apache"
    start_position => "end"
  }
}

Réseau

Imaginons que vous vouliez récupérer des logs d’une machine distante. Vous pouvez via rsyslog envoyer vos logs vers le réseau.

Depuis la machine émettrice des logs, on va envoyer toutes les local5.* vers notre serveur logstash. Editons un fichier /etc/rsyslog.d/logstash.conf

local5.*           @1.2.3.4:1517

Dans ce cas, le serveur logstash a pour adresse ip 1.2.3.4, et on envoie les logs sur le port 1517 en UDP.

Pour envoyer les logs en TCP, il suffit de doubler l’arobase avant l’adresse ip.

Redémarrez le serveur rsyslog :

systemctl restart rsyslog

Sur la machine logstash, en input, on va rajouter

udp {
  port => 1517
}

Redémarrez logstash :

systemctl restart logstash

Et c’est tout… (pensez à changer udp en tcp selon ce que vous avez mis dans votre rsyslog)

Multi lignes

Supposons que nous ayons un fichier de log qui comprend des retours chariot au sein du même log (c’est le cas de postgresql par exemple). Nous pouvons ajouter dans le input l’instruction multiline.

Par exemple :

codec => multiline {
  pattern => "^\s"
  what => "previous"
}

Cela signifie que toute ligne qui commence par un espace (pattern ^\s des regexp) est considérée comme faisant partie de la ligne précédente.

Logstash : Les filtres

Conditions et remplacements

 Bon, c’est bien joli, mais je vais lire tous les fichiers de /var/log/apache2, je ne tiens pas compte des fichiers compressés… mais les fichiers d’erreur ? Ils n’ont pas la même syntaxe que les fichiers de logs classique. Il va donc falloir que je filtre avec l’instruction if. Je sais que tous les fichiers d’erreurs comprennent le mot « error » dans le nom.

filter {
  if [type] == "apache" {
    if "error" in [path] {
      grok {
        match => { "message" => "%{HTTPD24_ERRORLOG}" }
      }
    }
  }
  else
  {
    grok {
      match => { "message" => "%{COMBINEDAPACHELOG}" }
    }
  }
}

Ainsi, le pattern appliqué n’est pas le même si le nom du fichier comprend le mot « error ».

Allons plus loin, dans le cas où je suis sur un fichier d’erreur, je veux que le type du fichier devienne « apache_error » au lieu de « apache ». Cela me permettra de les filtrer plus vite dans Kibana.

Pour cela, j’utilise l’instruction « mutate » :

mutate {
  replace => {
    "type" => "apache_error"
  }
}

Ce qui donne au final :

filter {
  if [type] == "apache" {
    if "error" in [path] {
     mutate {
       replace => {
         "type" => "apache_error"
       }
     }
     grok {
        match => { "message" => "%{HTTPD24_ERRORLOG}" }
      }
    }
  }
  else
  {
    grok {
      match => { "message" => "%{COMBINEDAPACHELOG}" }
    }
  }
}

 

 

Laisser un commentaireAnnuler la réponse.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.