2017-05-04 8 views
3

Je souhaite obtenir des journaux stdout à partir d'un conteneur docker et les envoyer à la pile ELK. Jusqu'à présent, je sais qu'il existe un pilote de journalisation GELF dans Docker.Niveau de journalisation en tant que champ pour le pilote de journalisation Docker GELF

Cependant, je ne peux pas comprendre comment je peux analyser ERROR, WARNING ou DEBUG messages du message et les mettre dans un nouveau domaine comme log_level dans un message de journal avant Docker les envoie à ELK.

Message de journal devrait être quelque chose comme:

{ 
    "client": "127.0.0.1", 
    "user": "frank", 
    "timestamp": "2000-10-10 13:55:36 -0700", 
    "method": "GET", 
    "uri": "/apache_pb.gif", 
    "protocol": "HTTP/1.0", 
    "status": 200, 
    "size": 2326, 
    "message": "[ERROR] Error connecting to MongoDB", 
    "_logLevel" : "ERROR" 
} 

qui Docker ajouté "_logLevel" : "ERROR" avant d'envoyer à ELK.

Merci.

Répondre

4

Je pense que vous confondez ce que docker fait pour vous et ce que logstash (ou potentiellement logspout) est ici pour. Le pilote Docker Gelf ajoute les champs suivants: Nom d'hôte - ID du conteneur - Nom du conteneur - ID de l'image - Nom de l'image - créé (délai de création du conteneur) - niveau (6 pour stdout, 3 pour stderr, à ne pas confondre avec log. Ces choses sont connues de Docker. Docker n'a aucune idée de votre utilisateur ou client. Ces champs ne sont pas créés par le pilote gelf ou le docker.


Pour obtenir ce que vous voulez, vous devez utiliser un filtre grok dans logstash:

mes messages ont le format du journal:

$ {date: format = aaaa-mm- dd HH: mm: ss.fff} | $ {correlationId} | $ {niveau} | $ {callSite} | $ {Message}

Et je lance logstash de docker composer comme ceci:

logstash: 
    image: docker.elastic.co/logstash/logstash:5.3.1 
    logging: 
     driver: "json-file" 
    networks: 
     - logging 
    ports: 
     - "12201:12201" 
     - "12201:12201/udp" 
    entrypoint: logstash -e 'input { gelf { } } 
         filter{ 
           grok { 
            match=> ["message", "%{SPACE}%{DATESTAMP:timestamp}%{SPACE}\|%{SPACE}%{DATA:correlation_Id}%{SPACE}\|%{SPACE}%{DATA:log_level}%{SPACE}\|%{SPACE}%{DATA:call_site}%{SPACE}\|%{SPACE}%{DATA:message}%{SPACE}$$"] 
            overwrite => [ "message" ] 
           } 
           date { 
            locale => "en" 
            match => ["timestamp", "dd-MM-YYYY HH:mm:ss:SSS"] 
            target => "@timestamp" 
            remove_field => [ "timestamp" ] 
           } 
         } 
         output { stdout{ } elasticsearch { hosts => ["http://elasticsearch:9200"] } }' 

et voici comment je lance un conteneur qui fournit des journaux dans le format spécifié (tous identiques, sauf pour ce jour):

docker run --log-driver=gelf --log-opt gelf-address=udp://0.0.0.0:12201 ubuntu /bin/sh -c 'while true; do date "+%d-%m-%Y %H:%M:%S:%3N" | xargs printf "%s %s | 51c489da-2ba7-466e-abe1-14c236de54c5 | INFO | HostingLoggerExtensions.RequestFinished | Request finished in 35.1624ms 200 application/json; charset=utf-8 message end\n"; sleep 1 ; done' 

J'espère que cela vous aide à démarrer. Assurez-vous que vous démarrez les conteneurs en créant des journaux après logstash.

Peut-être lire le grok documentation pour plus d'informations.

+0

Merci, je vais essayer cette solution. – skynyrd