如何在 JSON 中漂亮地格式化 Traefik 日志?
How to pretty format the Traefik log in JSON?
我有一个具有以下配置的 Traefik 服务:
version: "3.9"
services:
reverse-proxy:
image: traefik:v2.3.4
networks:
common:
ports:
- target: 80
published: 80
mode: host
- target: 443
published: 443
mode: host
command:
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=common"
- "--entrypoints.web.address=:80"
# - "--entrypoints.websecure.address=:443"
- "--global.sendAnonymousUsage=true"
# Set a debug level custom log file
- "--log.level=DEBUG"
- "--log.format=json"
- "--log.filePath=/var/log/traefik.log"
- "--accessLog.filePath=/var/log/access.log"
# Enable the Traefik dashboard
- "--api.dashboard=true"
# - "traefik.constraint-label=common" TODO
deploy:
placement:
constraints:
- node.role == manager
labels:
# Expose the Traefik dashboard
- "traefik.enable=true"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.services.traefik.loadbalancer.server.port=888" # A port number required by Docker Swarm but not being used in fact
- "traefik.http.routers.dashboard.rule=Host(`traefik.learnintouch.com`)"
- "traefik.http.routers.traefik.entrypoints=web"
# - "traefik.http.routers.traefik.entrypoints=websecure"
# Basic HTTP authentication to secure the dashboard access
- "traefik.http.routers.traefik.middlewares=traefik-auth"
- "traefik.http.middlewares.traefik-auth.basicauth.users=stephane:$$apr1$$m72sBfSg$.NRvy75AZXAMtH3C2YTz/"
volumes:
# So that Traefik can listen to the Docker events
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "~/dev/docker/projects/common/volumes/logs/traefik.service.log:/var/log/traefik.log"
- "~/dev/docker/projects/common/volumes/logs/traefik.access.log:/var/log/access.log"
然后我用命令查看日志:
stephane@stephane-pc:~$ tail -f dev/docker/projects/common/volumes/logs/traefik.service.log
{"level":"info","msg":"I have to go...","time":"2021-07-03T10:18:10Z"}
{"level":"info","msg":"Stopping server gracefully","time":"2021-07-03T10:18:10Z"}
{"entryPointName":"web","level":"debug","msg":"Waiting 10s seconds before killing connections.","time":"2021-07-03T10:18:10Z"}
{"entryPointName":"web","level":"error","msg":"accept tcp [::]:80: use of closed network connection","time":"2021-07-03T10:18:10Z"}
我希望日志格式为 JSON 和 indentation
。
所以我将非缩进的 JSON 输出复制粘贴到 online JSON formatter 中,但它只缩进了一部分,使整个东西变得无用。
你的问题是 Traefik 不输出单个 JSON 文档,而是输出一个 JSON 文档 每行 。您可以使用 xargs
和 jq
:
美化所有文档
tail -f dev/docker/projects/common/volumes/logs/traefik.service.log | xargs -n 1 -d "\n" -- bash -c 'echo "" | jq' _
在您的示例中,这将导致此输出(如果您的终端支持语法突出显示,即使语法突出显示):
{
"level": "info",
"msg": "I have to go...",
"time": "2021-07-03T10:18:10Z"
}
{
"level": "info",
"msg": "Stopping server gracefully",
"time": "2021-07-03T10:18:10Z"
}
{
"entryPointName": "web",
"level": "debug",
"msg": "Waiting 10s seconds before killing connections.",
"time": "2021-07-03T10:18:10Z"
}
{
"entryPointName": "web",
"level": "error",
"msg": "accept tcp [::]:80: use of closed network connection",
"time": "2021-07-03T10:18:10Z"
}
我有一个具有以下配置的 Traefik 服务:
version: "3.9"
services:
reverse-proxy:
image: traefik:v2.3.4
networks:
common:
ports:
- target: 80
published: 80
mode: host
- target: 443
published: 443
mode: host
command:
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=common"
- "--entrypoints.web.address=:80"
# - "--entrypoints.websecure.address=:443"
- "--global.sendAnonymousUsage=true"
# Set a debug level custom log file
- "--log.level=DEBUG"
- "--log.format=json"
- "--log.filePath=/var/log/traefik.log"
- "--accessLog.filePath=/var/log/access.log"
# Enable the Traefik dashboard
- "--api.dashboard=true"
# - "traefik.constraint-label=common" TODO
deploy:
placement:
constraints:
- node.role == manager
labels:
# Expose the Traefik dashboard
- "traefik.enable=true"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.services.traefik.loadbalancer.server.port=888" # A port number required by Docker Swarm but not being used in fact
- "traefik.http.routers.dashboard.rule=Host(`traefik.learnintouch.com`)"
- "traefik.http.routers.traefik.entrypoints=web"
# - "traefik.http.routers.traefik.entrypoints=websecure"
# Basic HTTP authentication to secure the dashboard access
- "traefik.http.routers.traefik.middlewares=traefik-auth"
- "traefik.http.middlewares.traefik-auth.basicauth.users=stephane:$$apr1$$m72sBfSg$.NRvy75AZXAMtH3C2YTz/"
volumes:
# So that Traefik can listen to the Docker events
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "~/dev/docker/projects/common/volumes/logs/traefik.service.log:/var/log/traefik.log"
- "~/dev/docker/projects/common/volumes/logs/traefik.access.log:/var/log/access.log"
然后我用命令查看日志:
stephane@stephane-pc:~$ tail -f dev/docker/projects/common/volumes/logs/traefik.service.log
{"level":"info","msg":"I have to go...","time":"2021-07-03T10:18:10Z"}
{"level":"info","msg":"Stopping server gracefully","time":"2021-07-03T10:18:10Z"}
{"entryPointName":"web","level":"debug","msg":"Waiting 10s seconds before killing connections.","time":"2021-07-03T10:18:10Z"}
{"entryPointName":"web","level":"error","msg":"accept tcp [::]:80: use of closed network connection","time":"2021-07-03T10:18:10Z"}
我希望日志格式为 JSON 和 indentation
。
所以我将非缩进的 JSON 输出复制粘贴到 online JSON formatter 中,但它只缩进了一部分,使整个东西变得无用。
你的问题是 Traefik 不输出单个 JSON 文档,而是输出一个 JSON 文档 每行 。您可以使用 xargs
和 jq
:
tail -f dev/docker/projects/common/volumes/logs/traefik.service.log | xargs -n 1 -d "\n" -- bash -c 'echo "" | jq' _
在您的示例中,这将导致此输出(如果您的终端支持语法突出显示,即使语法突出显示):
{
"level": "info",
"msg": "I have to go...",
"time": "2021-07-03T10:18:10Z"
}
{
"level": "info",
"msg": "Stopping server gracefully",
"time": "2021-07-03T10:18:10Z"
}
{
"entryPointName": "web",
"level": "debug",
"msg": "Waiting 10s seconds before killing connections.",
"time": "2021-07-03T10:18:10Z"
}
{
"entryPointName": "web",
"level": "error",
"msg": "accept tcp [::]:80: use of closed network connection",
"time": "2021-07-03T10:18:10Z"
}