Journald

問:journalctl 用自己的元數據為消息添加前綴?

  • April 28, 2017

如何journald在日誌消息中使用元數據為日誌條目添加前綴?

我想我可能必須查看其中一個詳細輸出,過濾掉換行符和所有額外資訊,只找到我正在尋找的項目(日期時間、Docker CONTAINER_NAME、消息),然後將其餘的全部忽略到一行。

可以使用類似的東西awk來去除換行符,只抓取 X、Y、Z 行,並將它們顯示在一行上嗎?那麼 args 如何知道對每條 X、Y、Z 行進行分組?我的意思是,args 如何知道每個“分組”?

更多資訊如下。


這是我正在記錄到日誌的兩個不同 docker 容器中的兩行:

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

如您所見,您無法分辨哪個日誌條目屬於哪個 docker 容器。

有元數據可用於查看完整的日誌消息。這是其中一條消息,當查看時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.

使用 journald 的 Docker 日誌驅動程序的一部分,它添加了諸如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'

我使用 dockertag選項來指定自定義標籤。例如,我的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 

如果你不使用 docker log 標籤,你可以只使用 CONTAINER_NAME:

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

這應該適用於所有 Docker 容器,無論 linux 系統日誌記錄到日誌。

剩下的就是把它變成一個 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直接執行,並用 docker 容器名稱沐浴在 jorunald 的榮耀中。

引用自:https://serverfault.com/questions/847238