Search code examples
apache-apisix

apisix file logger, get body response in the log


i add file logger to apisix route with this config:

...
"plugins": {
  "key-auth": {
    ...
  },
  "file-logger": {
    "path": "/usr/local/apisix/apisix_log/test.log", 
    "log_format": {
      "ip_client": "$remote_addr",
      "http_verb": "$request_method",
      "request_body": "$request_body", 
      "consumer": "$consumer_name",
      "url": "$uri",
      "parametres": "$args",
      "http_code": "$status",
      "response_body": "$response_body",
      "temps_reponse": "$upstream_response_time"
    },
    "include_resp_body": true, 
    "buffer": {
      "size": 1048576,  
      "flush_interval": 100 
    },
    "rotate": {
      "max_size": 10, 
      "max_days": 7   
    }
  }
}

my docker compose

  apisix:
    container_name: apisix
    #image: apache/apisix:${APISIX_IMAGE_TAG:-3.11.0-debian}
    image: apache/apisix:3.7.0-debian
    volumes:
      - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
      - ./cert.pem:/usr/local/apisix/keycloak-cert.pem:ro
      #- ./apisix_log/test.log:/usr/local/apisix/apisix_log/test.log
      - type: bind
        source: ./apisix_log/test.log
        target: /usr/local/apisix/apisix_log/test.log
    restart: always
    depends_on:
      etcd:
        condition: service_healthy
    ports:
      - "9180:9180/tcp"
      - "9080:9080/tcp"
      - "9091:9091/tcp"
      - "9443:9443/tcp"
      - "9092:9092/tcp"
    networks:
      - apisix

apisix add line to the log in every request but the body response is not added. Example

{"http_code":200,"temps_reponse":0.048,"request_body":"{ \"sql\" : \"select emp.first_name,jobs.job_title,dept.department_name\nfrom employees emp,departments dept,jobs \nwhere emp.department_id = dept.department_id\nand emp.job_id = jobs.job_id and rownum = 1\"}","ip_client":"192.167.1.1","http_verb":"POST","url":"/ords/hr/jpa/getAll","route_id":"549761667391554410","consumer":"user_mas"}

Question : how configure the logger to have the response body in the log


Solution

  • You have to use $resp_body instead of $response_body.

    Example:

    "file-logger": {
      "path": "/usr/local/apisix/apisix_log/test.log", 
      "log_format": {
        "ip_client": "$remote_addr",
        "http_verb": "$request_method",
        "request_body": "$request_body", 
        "consumer": "$consumer_name",
        "url": "$uri",
        "parametres": "$args",
        "http_code": "$status",
        "response_body": "$resp_body",
        "temps_reponse": "$upstream_response_time"
      },
      "include_resp_body": true, 
      "buffer": {
        "size": 1048576,  
        "flush_interval": 100 
      },
      "rotate": {
        "max_size": 10, 
        "max_days": 7   
      }
    }
    

    Take a look at the official documentation:


    Full Example

    APISIX Deployment

    APISIX Docker + Etcd (traditional mode).

    File compose.yaml:

    services:
      etcd:
        image: bitnami/etcd:latest
        container_name: etcd
        environment:
          ALLOW_NONE_AUTHENTICATION: yes
          ETCD_ADVERTISE_CLIENT_URLS: http://etcd:2379
          ETCD_LISTEN_CLIENT_URLS: http://0.0.0.0:2379
        ports:
          - "2379:2379"
        healthcheck:
          test: "etcdctl endpoint health"
          interval: 5s
          timeout: 30s
          retries: 5
        volumes:
          - ./etcd_data:/bitnami/etcd/data
        networks:
          apisix:
    
      apisix:
        container_name: apisix
        image: apache/apisix:latest
        restart: always
        depends_on:
          etcd:
            condition: service_healthy
        volumes:
          - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
        ports:
          - "9080:9080/tcp"
          - "9180:9180/tcp"
        networks:
          apisix:
    
    networks:
      apisix:
        driver: bridge
    

    File apisix_conf/config.yaml:

    apisix:
      node_listen: 9080
      
    deployment:
      admin:
        admin_key:
          - name: "admin"
            key: edd1c9f034335f136f87ad84b625c8f1
            role: admin
        allow_admin:
          - 127.0.0.0/24
          - 0.0.0.0/0
        admin_listen:
          ip: 0.0.0.0
          port: 9180
      etcd:
        host:
          - http://etcd:2379
        prefix: "/apisix"
        timeout: 30
    

    Run Docker compose:

    docker compose -f compose.yaml up
    

    Test Route Configuration

    Create a route /file-logger/* which gets proxied to external echo service httpbin.org and enables the following plugins:

    • "proxy-rewrite" to rewrite the URI;
    • "file-logger" to write logs to file "/usr/local/apisix/logs/custom.log" (NB: the directory must exist when APISIX logs messages, otherwise the plugin will throw an error)
    curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f1" -X PUT -i -d '
    {
      "uri": "/file-logger/*",
      "upstream": {
        "type": "roundrobin",
        "nodes": {
          "httpbin.org": 1
        }
      },
      "plugins": {
        "proxy-rewrite": {
          "regex_uri": [
            "^/file-logger/(.*)",
            "/$1"
          ]
        },
        "file-logger": {
          "path": "/usr/local/apisix/logs/custom.log", 
          "log_format": {
            "ip_client": "$remote_addr",
            "http_verb": "$request_method",
            "request_body": "$request_body", 
            "consumer": "$consumer_name",
            "url": "$uri",
            "parametres": "$args",
            "http_code": "$status",
            "response_body": "$resp_body",
            "temps_reponse": "$upstream_response_time"
          },
          "include_resp_body": true, 
          "buffer": {
            "size": 1048576,  
            "flush_interval": 100 
          },
          "rotate": {
            "max_size": 10, 
            "max_days": 7   
          }
        }
      }
    }'
    

    Test the route:

    curl localhost:9080/file-logger/get
    
    {
      "args": {}, 
      "headers": {
        "Accept": "*/*", 
        "Host": "localhost", 
        "User-Agent": "curl/8.5.0", 
        "X-Amzn-Trace-Id": "Root=1-6799ef4e-0bddba55084fbf693baa0407", 
        "X-Forwarded-Host": "localhost"
      }, 
      "origin": "172.19.0.1, X.X.X.X", 
      "url": "http://localhost/get"
    }
    

    Check logs:

    docker exec apisix cat /usr/local/apisix/logs/custom.log
    
    {"ip_client":"172.19.0.1","route_id":"1","http_verb":"GET","http_code":200,"response_body":"{\n  \"args\": {}, \n  \"headers\": {\n    \"Accept\": \"*/*\", \n    \"Host\": \"localhost\", \n    \"User-Agent\": \"curl/8.5.0\", \n    \"X-Amzn-Trace-Id\": \"Root=1-6799ef4e-0bddba55084fbf693baa0407\", \n    \"X-Forwarded-Host\": \"localhost\"\n  }, \n  \"origin\": \"172.19.0.1, X.X.X.X\", \n  \"url\": \"http://localhost/get\"\n}\n","url":"/file-logger/get","temps_reponse":0.534}
    

    As you can see, the response body is now included :)