问:journalctl用自己的元数据为消息加上前缀?

如何在日志消息中添加带有元数据的日志条目?

我想我可能不得不查看一个详细的输出,过滤掉换行符和所有额外的信息,find我正在寻找的项目(date时间,Docker CONTAINER_NAME,消息),并将其余全部忽略到一行。

可以使用类似awk换行符,仅抓取X,Y,Z行,并将它们显示在一行上? 那么怎样才能知道把每一个X,Y,Z线分组? 我的意思是,参数怎么会知道每个“分组”?

更多信息如下。


以下是两个来自两个不同的docker集装箱,我login到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" "-" 

正如你所看到的,你不能分辨哪个日志条目属于哪个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 

但是,杂志似乎没有任何破坏性,而-o verbose

Docker日志驱动程序的一部分使用journald,它增加了像CONTAINER_NAME这样的东西 – 这正是我正在寻找的东西。

我将如何使用类似于-o short的格式显示CONTAINER_NAME?

好的,我在打字的时候find了答案。 这是非常啰嗦。 所以一个bash别名将有所帮助(见最后)。 把它变成一个“维基答案”,因为我花了很长时间才输出,find答案。 也许它可以帮助别人有一天。


-o json可用的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 XXXX - - [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" "-" 

这正是我所追求的。 这也与所有其他logging条目兼容:

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

如果您不使用docker日志标记,则可以使用CONTAINER_NAME:

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

这应该适用于所有的Docker容器,不pipelinux系统日志logging。

剩下的就是把这个变成一个bash别名来快速引用。 添加到你的~/.bash_aliasessource ~/.bash_aliases

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

(“f”代表格式化)

然后,您可以直接运行journalctld ,并以docker集装箱名称为荣。