問:journalctl 用自己的元數據為消息添加前綴?
如何
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'
我使用 docker
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
如果你不使用 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 的榮耀中。