简体   繁体   中英

How to pretty format the Traefik log in JSON?

I have a Traefik service with the following configuration:

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

Then I watch the log with the command:

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

I expected the log to be formatted in JSON with indentation .

So I copy-pasted the non indented JSON output in an online JSON formatter but it only indented part of it, making the whole thing useless.

Your problem is that Traefik does not output a single JSON document, but one JSON document per line . You could beautify all documents using xargs and jq :

tail -f dev/docker/projects/common/volumes/logs/traefik.service.log | xargs -n 1 -d "\n" -- bash -c 'echo "$1" | jq' _

In your example, this will result in this output (even with syntax highlighting if your terminal supports that):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM