原文:lemonHe - https://zhuanlan.zhihu.com/p/67754050
原文:遗忘曾经谢谢 - https://my.oschina.net/wForget/blog/3224595
cronolog日志切割神器
许多日志文件是不分割的,这样既不易于管理,也不易于分析统计。
cronolog作为日志过滤程序,可用来切割linux日志文件,通过对输入的日志按文件名模板和当前日期重新编排,来按格式生成所需日志。cronolog 旨在和一个Web服务器一起使用,如Apache、Nginx,分割访问日志为yy-mm-dd-hh格式的日志。
记录一下使用cronolog来切割nginx日志的过程。
安装cronolog
centos系统直接使用yum来安装cronolog和httpd。
yum install -y cronolog httpd
查看cronolog
使用which cronolog来查看是否已经安装好cronolog,如下则表示已经安装好。
配置nginx的conf文件
配置error按天输出,access按小时保存,在nginx.conf文件中将error_log和access_log进行如下配置:
error_log "pipe:/usr/sbin/cronolog /home/admin/logs/cronolog/%Y/%m/%Y-%m-%d-error.log" error;
access_log "pipe:/usr/sbin/cronolog /home/admin/logs/cronolog/%Y/%m/%Y-%m-%d-%H-access.log" main;
新建目录
新建目录用于保存日志。
mkdir -p /home/admin/logs/cronolog/
查看日志
运行过程中,会产生按照日志格式配置的文件,大功告成!
Nginx打印RequestBody
背景
新的日志收集构架中直接去掉 SpringBoot 服务,而是通过 Nginx 作为服务器,收集日志,打印成日志文件,通过 Flume 消费到 Kafka 中。由于日志收集的请求都是 Post JSON 的格式,所以需要在 Nginx 中获取 Post 的 Body。
问题
在配置 log_format 后,发现无法打印 $request_body
log_format user_log_format escape=json '{"time": "$msec", "ip": "$remote_addr", "ua": "$http_user_agent", "data": "$request_body"}';
查看官方文档,有如下注释。意思是说 $request_body 需要在带有 proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass 这些指令的 location 中,当 request_body 被读到内存缓冲区中使用。
The variable’s value is made available in locations processed by the proxy_pass, fastcgi_pass, uwsgi_pass, and scgi_pass directives when the request body was read to a memory buffer.
Nginx 安装
由于在解决问题的时候需要使用到 ngx_lua 模块,所以我是直接安装的 OpenResty。 官网:http://openresty.org/cn/ 安装文档:http://openresty.org/cn/installation.html
解决
在使用 (proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass) 指令的 location 中打印日志。
使用 HTTP Echo Module (OpenResty 中已经包括了这个模块)。
HTTP Echo Module 参考文档:https://www.nginx.com/resources/wiki/modules/echo/
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
include /usr/local/openresty/nginx/conf/mime.types;
default_type application/octet-stream;
# 日志文件格式 access.log nginx默认的日志文件
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent $host "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 日志文件格式 user_defined.log 数据会写到这个文件中
log_format user_log_format escape=json '{"time": "$msec", "ip": "$remote_addr", "ua": "$http_user_agent", "data": "$request_body"}';
server {
listen 8080;
set $p_body "";
location / {
access_log /data/nginx/logs/user_defined.log user_log_format;
echo_read_request_body;
echo '';
}
}
}
使用 ngx_lua 模块
Lua 参考文档:https://www.nginx.com/resources/wiki/modules/lua/
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
include /usr/local/openresty/nginx/conf/mime.types;
default_type application/octet-stream;
# 日志文件格式 access.log nginx默认的日志文件
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent $host "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 日志文件格式 user_defined.log 数据会写到这个文件中
log_format user_log_format escape=json '{"time": "$msec", "ip": "$remote_addr", "ua": "$http_user_agent", "data": "$request_body"}';
server {
listen 8080;
set $p_body "";
location / {
lua_need_request_body on;
content_by_lua 'local s = ngx.req.get_body_data()';
access_log /data/nginx/logs/user_defined.log user_log_format;
# echo ''; # 注意这个不能使用 echo 命令和 return 命令
}
}
}
还可以通过自定义的变量存放 request_body,然后再 log_format 中使用自定义变量打印。
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
include /usr/local/openresty/nginx/conf/mime.types;
default_type application/octet-stream;
# 日志文件格式 access.log nginx默认的日志文件
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent $host "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 日志文件格式 user_defined.log 数据会写到这个文件中
log_format user_log_format escape=json '{"time": "$msec", "ip": "$remote_addr", "ua": "$http_user_agent", "data": "$p_body"}';
server {
listen 8080;
set $p_body "";
location / {
lua_need_request_body on;
content_by_lua '
local p_body = ngx.req.get_body_data() or ""
ngx.var.p_body = p_body
';
access_log /data/nginx/logs/user_defined.log user_log_format;
# echo ''; # 注意这个不能使用 echo 命令和 return 命令
}
}
}
可用于做 app 等数据上报,打印成 日志文件,使用 filebeat 收集到 elk 中,做数据分析。