Уровень журнала как поле для драйвера ведения журнала Docker GELF

Я хочу получить логи стандартного вывода из контейнера докера и отправить их в стек ELK. До сих пор я знаю, что в Docker есть драйвер регистрации GELF.

Тем не менее, я не могу понять, как я могу разобрать ERROR, WARNING или же DEBUG сообщения из сообщения и поместите их в новое поле, как log_level в журнале сообщений, прежде чем Docker отправит их в ELK.

Лог сообщения должен быть примерно таким:

{
  "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"
}

Какой докер добавил "_logLevel" : "ERROR" перед отправкой в ​​ELK.

Благодарю.

1 ответ

Решение

Я думаю, что вы путаете то, что docker делает для вас и для чего нужен logstash (или потенциально logspout). Драйвер Docker Gelf добавляет следующие поля: Имя хоста - Идентификатор контейнера - Имя контейнера - Идентификатор изображения - Имя изображения - создано (время создания контейнера) - уровень (6 для стандартного вывода, 3 для stderr, не следует путать с уровнем журнала приложения). Эти вещи известны Докеру. Докер не имеет представления о вашем пользователе или клиенте. Эти поля не создаются драйвером или докером.


Чтобы добиться того, чего вы хотите, вы должны использовать фильтр grok в logstash:

мои сообщения имеют формат журнала:

$ {дата: формат = гггг-мм-дд ЧЧ: мм: сс.ффф} | ${correlationId} | ${level} | ${callSite} | ${} Сообщение

И я запускаю logstash из docker compose следующим образом:

  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"] } }'

и вот как я запускаю контейнер, который доставляет журналы в указанном формате (все идентичные, кроме даты):

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'

Я надеюсь, что это поможет вам начать. Убедитесь, что вы запускаете контейнеры, создающие журналы после logstash.

Возможно прочитайте документацию grok для получения дополнительной информации.

Другие вопросы по тегам