Назад | Перейти на главную страницу

Q: journalctl для префикса сообщения с собственными метаданными?

Как бы одна приставка journald записи журнала с метаданными в сообщении журнала?

Я думаю, мне, возможно, придется просмотреть один из подробных выходных данных, отфильтровать разрывы строк и всю дополнительную информацию, найти только те элементы, которые я ищу (DateTime, Docker CONTAINER_NAME, Message), и проигнорировать все остальное в одной строке.

Может что-то вроде awk использоваться для удаления разрывов строк, захвата только строк X, Y, Z и отображения их в одной строке? Как тогда args узнает, что нужно сгруппировать все строки X, Y, Z? Я имею в виду, как args узнает о каждой "группировке"?

Больше информации следует.


Вот две строки из двух разных контейнеров докеров, которые я регистрирую в journald:

Apr 28 18:09:43 rschool dockerd[1366]: [pid: 9|app: 0|req: 1/1] 68.180.230.53 () {48 vars in 934 bytes} [Fri Apr 28 14:09:42 2017] GET /enrollment/info-sessions/ => generated 17175 bytes in 1072 msecs (HTTP/1.0 200) 3 headers in 112 bytes (1 switches on core 0)
Apr 28 18:09:43 rschool dockerd[1366]: 68.180.230.53 - - [28/Apr/2017:18:09:43 +0000] "GET /enrollment/info-sessions/ HTTP/1.1" 200 3495 "-" "Mozilla/5.0 (Macintosh; IntelMac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36" "-"

Как видите, нельзя определить, какая запись журнала принадлежит какому контейнеру докеров.

При просмотре полного сообщения журнала доступны метаданные. Вот одно из этих сообщений при просмотре с journald -o verbose:

_UID=0
_GID=0
_SYSTEMD_SLICE=system.slice
_BOOT_ID=f4a6e9569f0349d1817bd92ab779ebe3
_MACHINE_ID=a62f158e48fc45eeb32afaef98d24d5b
_HOSTNAME=rschool
_TRANSPORT=journal
_CAP_EFFECTIVE=3fffffffff
_PID=1366
_COMM=dockerd
_EXE=/usr/bin/dockerd
_CMDLINE=/usr/bin/dockerd -H fd://
_SYSTEMD_CGROUP=/system.slice/docker.service
_SYSTEMD_UNIT=docker.service
CONTAINER_NAME=rschool_web_1
CONTAINER_ID=732e5bf0d0a1
CONTAINER_ID_FULL=732e5bf0d0a1cc110cacce68850143aa3534
CONTAINER_TAG=rschool_web/rschool_web_1/732e5bf0d0a1
MESSAGE=[pid: 9|app: 0|req: 1/1] 68.180.230.53 () {48 vars in 934 bytes} [Fri Apr 28 14:09:42 2017] GET /enrollment/info-sessions/ => generated 17175 bytes in 1072 msecs (HTTP/1.0 200) 3 headers in 112 bytes (1 switches on core 0)
_SOURCE_REALTIME_TIMESTAMP=1493402983899475
Fri 2017-04-28 18:09:43.901030 UTC [s=9d2777df7c3e4658a6d3d2c7896376ce;i=13ca;b=f4a6e9569f0349d1817bd92ab779ebe3;m=c91fe4d38;t=54e3dfa5ca862;x=f8ee400046f7d86f]
PRIORITY=6

Но journald, похоже, не ограничивает -o verbose.

Являясь частью драйвера журнала Docker, использующего journald, он добавляет такие вещи, как CONTAINER_NAME - это именно то, что я ищу.

Как мне отобразить CONTAINER_NAME, используя формат, похожий на -o short?

Хорошо, я нашел ответ, когда печатал. Хотя это очень многословно. Так что псевдоним bash поможет (см. Конец). Превращение этого в «ответ вики», так как мне потребовалось много времени, чтобы напечатать и найти ответ. Может быть, однажды это поможет кому-нибудь другому.


Формат вывода JSON доступен с -o json.

Мы можем использовать jq чтобы выбрать что-то из json, отформатировать и объединить их и отобразить на одном.

journalctl -f -n 100 -o json | jq -r '.__REALTIME_TIMESTAMP + " " + .PRIORITY + " " + ._HOSTNAME + " " + ._SYSTEMD_UNIT + " " + .CONTAINER_TAG + " " + .MESSAGE'

Я использую докер tag возможность указать собственный тег. Например, мой docker-compose.production.yml переопределение выглядит так:

version: '2'
services:
    nginx:
        restart: always
        ports:
            - "80:80"
            - "443:443"
        logging:
            driver: journald
            options:
                tag: "{{.ImageName}}/{{.Name}}/{{.ID}}"

Это дает мне строку вроде:

1493405629162557 6 rschool docker.service nginx:1.12.0-alpine/rschool_nginx_1/0f6b8d772957 X.X.X.X - - [28/Apr/2017:18:53:49 +0000] "GET / HTTP/1.1" 200 4399 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36" "-"

Это именно то, что мне нужно. Это также совместимо со всеми другими записями журнала:

1493405535267844 4 rschool   [UFW BLOCK] IN=eth0 OUT= MAC=9e:51:e1...:08:00 SRC=X.X.X.X DST=X.X.X.X LEN=439 TOS=0x00 PREC=0x00 TTL=57 ID=41599 DF PROTO=UDP SPT=5273 DPT=5060 LEN=419 

Если вы не используете теги журнала докеров, вы можете просто использовать CONTAINER_NAME:

journalctl -f -n 100 -o json | jq -r '.__REALTIME_TIMESTAMP + " " + .PRIORITY + " " + ._HOSTNAME + " " + ._SYSTEMD_UNIT + " " + .CONTAINER_NAME + " " + .MESSAGE'

Это должно работать для всех контейнеров Docker, независимо от системного журнала Linux в journald.

Осталось только превратить это в псевдоним bash для быстрой ссылки. Добавьте это в свой ~/.bash_aliases и source ~/.bash_aliases:

alias journalctlf="journalctl -f -n 100 -o json | jq -r '.__REALTIME_TIMESTAMP + \" \" + .PRIORITY + \" \" + ._HOSTNAME + \" \" + ._SYSTEMD_UNIT + \" \" + .CONTAINER_NAME + \" \" + .MESSAGE'"

("f" означает форматированный)

Тогда ты можешь бежать journalctld прямо, и наслаждайтесь славой jorunald с именами контейнеров докеров.