openresty+graylog 记录proxy 请求以及响应日志

openresty nginx 的增强版,同时基于灵活的生命周期阶段,我们可以做好多灵活的事情,以下就是一个
简单的处理请求以及响应log记录的,原本的打算是基于log_filter_by_lua 阶段处理的,后边发现直接使用
access_log 更简单省事,同时集成graylog灵活的log 处理能力,我们可以快速的实现proxy 请求以及响应
内容记录

环境准备

  • nginx 配置
    注意处理body 部分,我们需要使用ctx 进行数据存储方便读取response 数据(因为nginx 基于chunk 的数据传输)
    同时我们需要使用escape=json (格式以及中文处理)
 
worker_processes  1;
user root;  
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    gzip  on;
    log_format graylog2_json escape=json '{ "timestamp": "$time_iso8601", '
                     '"remote_addr": "$remote_addr", '
                     '"body_bytes_sent": $body_bytes_sent, '
                     '"request_time": $request_time, '
                     '"response_status": $status, '
                     '"request": "$request", '
                     '"request_method": "$request_method", '
                     '"host": "$host",'
                     '"request_body":"$request_body",'
                     '"response_body":"$resp_body",'
                     '"upstream_cache_status": "$upstream_cache_status",'
                     '"upstream_addr": "$upstream_addr",'
                     '"http_x_forwarded_for": "$http_x_forwarded_for",'
                     '"http_referrer": "$http_referer", '
                     '"http_user_agent": "$http_user_agent" }';
    real_ip_header     X-Forwarded-For;
    real_ip_recursive on;
    upstream api {
       server xxxx:port weight=20;
       server xxx:port weight=10;
       server xxxx:port weight=10;
    }
    server {
        listen       80;
        charset utf-8;
        default_type text/html;
        location / {
           set $resp_body "";
           access_log  /usr/local/openresty/nginx/logs/access_test.log  graylog2_json;
           access_log syslog:server=graylog-server:12301 graylog2_json;
           body_filter_by_lua_block {
                local resp_body = string.sub(ngx.arg[1], 1, 1000)  
                ngx.ctx.buffered = string.sub((ngx.ctx.buffered or "") .. resp_body, 1, 1000)
               -- arg[2] is true if this is the last chunk
                 if ngx.arg[2] then
                  ngx.var.resp_body = ngx.ctx.buffered
                end
           }
           proxy_set_header Host $http_host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $remote_addr;
           client_body_buffer_size 10M;
           client_max_body_size 10G;
           proxy_buffers 1024 4k;
           proxy_read_timeout 120s;
           proxy_connect_timeout 2s;
           proxy_pass http://api;
           real_ip_header     X-Forwarded-For;
           real_ip_recursive on; 
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

一些说明

我们最好是对于不同的log提供不同的索引(可以基于规则处理数据存储),这样可以减少一些问题,同时对于openresty
的body_filter 需要做一些处理才能准确的获取response数据

参考资料

https://github.com/petestorey26/graylog-content-pack-nginx-json
https://nginx.org/en/docs/syslog.html
https://docs.graylog.org/en/3.3/
https://docs.graylog.org/en/3.3/pages/content_packs.html

原文地址:https://www.cnblogs.com/rongfengliang/p/13070463.html