如何在 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 文档 每行 。您可以使用 xargsjq:

美化所有文档
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"
}