nginx日志切割

使用log-rotate

nginx命令和信号控制

  1. nginx -s stop 快速关闭,不管有没有正在处理的请求 nginx -s quit 优雅关闭方式,推出前完成已经接受的连接请求
  2. nginx -c nginx配置文件地址 启动
  3. nginx -s reload 重启
  4. nginx -s reopen 重新打开日志
  5. nginx -t 检查配置文件是否正确
  6. kill -INT pid 表示快速关闭
  7. kill -HUP pid表示重启
  8. 通过信号控制的方式实现和命令相同的功能

nginx内置变量

变量名称 变量描述
$arg_PARAMETER 客户端GET请求中PARAMETER 字段的值
$args 客户端请求中的参数
$binary_remote_addr 远程地址的二进制表示
$body_bytes_sent 已发送的消息体字节数
$content_length HTTP请求信息中content-length的字段
$content_type 请求信息中content-type字段
$cookie_COOKIE 客户端请求中COOKIE头域的值
$document_root 针对当前请求的根路径设置值
$document_uri 与$uri相同
$host 请求信息中的host头域,如果请求中没有Host行,则等于设置的服务器名
$http_HEADER HTTP请求信息里的HEADER地段
$http_host 与$host相同,但是如果请求信息中没有host行,则可能不同客户端cookie信息
$http_cookie 客户端cookie信息
$http_referer 客户端是从哪一个地址跳转过来的
$http_user_agent 客户端代理信息,也就是你客户端浏览器
$http_via 最后一个访问服务器的IP
$http_x_forwarded_for 相当于访问网路访问的路径
$is_args 如果有args的值,则等于”?”,否则为空
$limit_rate 对连接速率的限制
$nginx_version 当前Nginx的版本
$pid 当前Nginx服务器的进程的进程ID
$query_string 与$args相同
$remote_addr 客户端IP地址
$remote_port 客户端的端口
$remote_user 客户端的用户名,用于 auth basic module验证
$request 客户端请求
$request_body 客户端发送的报文体
$request_body_file 发送后端服务器的本地临时缓存文件的名称
$request_filename 当前请求的文件路径名,由root或alias指令与URI请求生成
$request_method 请求后端数据的方法,例如”GET”,”POST”
$request_uri 请求的URI,带参数,不包含主机名
$scheme 所用的协议,如http或者HTTPS,比如rewrite^(.+)$$scheme://mysite.name$redirect
$sent_http_cache_control 对应http请求头中的Cache-Control,需要打开chrome浏览器,右键检查,选中network,点中其中一个请求的资源
$sent_http_connection 对应http请求中的Connection
$sent_http_content_type 对应http请求中的Content-Type
$sent_last_modified 对应请求中的Last-Modified
$server_addr 服务端的地址
$server_name 请求到达的服务器名
$server_port 请求到达服务器端口号
$server_protocol 请求协议的版本号,HTTP1.0/HTTP1.1
$uri 请求的不带请求参数的URI,可能和最初的值有不同,比如经过重定向之类的

定义日志轮滚策略

vim nginx-log-rotate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/Data/apps/nginx/logs/*.log {
nocompress
daily
copytruncate
create
notifempty
rotate 7
olddir /Data/apps/nginx/logs
missingok
dateext
postrotate
/bin/kill -HUP `cat /Data/apps/nginx/sbin/nginx.pid 2> /dev/null` 2> /dev/null || true
endscript
}
  • /data/weblogs/*.log使用通配符时,/data/weblogs/目录下的所有匹配到的日志文件都将切割。如果要切割特定日志文件,就指定到该文件。

设置计划任务

vim /etc/crontab

1
59 23 * * * root ( /usr/sbin/logrotate -f /PATH/TO/nginx-log-rotate)

使用脚本

参数和执行流程说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
复制log_format main '$year-$month-$day-$hour:$minutes:$seconds|$request_method|$request_uri|$http_host|$server_name|$status|$request_time|$remote_addr|$http_x_forwarded_for|$http_referer|$http_user_agent';


main 表示给当前格式的命名
$year-$month-$day-$hour:$minutes:$seconds 使用自己定义的变量
$request_method 请求方法,比如GET或者POST
$request_uri 请求URI
$http_host 请求信息中的host
$server_name 实际nginx匹配到的host(因为一个server可以有多个name,这个时候貌似输出的是第一个name,所以多个的时候可能会和$http_host不一致)
$status 返回的http状态码
$request_time 请求所花费的时间
$remote_addr 正常请求中的客户端ip地址,但是如果经过反向代理,这个时候是127.0.0.1
$http_x_forwarded_for 如果经过反向代理,这个字段可以拿到原本的ip地址
$http_referer 来源地址,如果是通过其他网页来源访问到的,这里可以看到
$http_user_agent 浏览器请求头


在说明一下时间格式
nginx日志有默认两种时间格式可以选择(目前只查询到这两个)
$time_local
输出格式: 01/Jul/2020:10:56:37

$time_iso8601
2020-07-01T11:16:35+08:00

但是上面两种都不是我们想要的,我们想要的是这种格式
yyyy-MM-dd HH:mm:ss
2020-07-01 11:21:00


所以需要我们对日志进行设置
nginx中的变量都是全局变量,但是只会对当前共享
所以需要在每一个server中定义出对应的变量,这样在每次日志记录的时候就可以使用这些变量了
如果觉得这种方法太麻烦,也可以使用自编译的nginx或者openresty,这样可以直接通过lua解决
这个问题,也可以在源代码中修改格式,因为我们这边是通过yum安装的,同时为了通用性,就选择这
种添加变量的方式解决


如果觉得这段代码稍微有点长,不愿意接受
那么可以单独写一个配置文件,然后使用include的方式倒入

按照日期存放

1
2
3
# 自定义格式
log_format main '$year-$month-$day $hour:$minutes:$seconds|$request_method|$request_uri|$http_host|$server_name|$status|$request_time|$remote_addr|$http_x_forwarded_for|$http_referer|$http_user_agent';
#必须在server里添加自定义变量

按天分割日志

1
2
3
4
5
6
7
8
9
10
复制
if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})") {
set $year $1;
set $month $2;
set $day $3;
set $hour $4;
set $minutes $5;
set $seconds $6;
}
access_log /var/logs/nginx/access/$server_name_$year-$month-$day-access.log main;

按小时、分、秒分割

1
2
3
4
5
6
7
8
9
10
复制if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})")
{
set $year $1;
set $month $2;
set $day $3;
set $hour $4;
set $minutes $5;
set $seconds $6;
}
access_log /var/logs/xxxx/access/xxxxx_xx_access_$year-$month-$day-$hour-$minutes-$seconds.log main;

不记录日志

1
2
3
4
5
6
7
8
9
复制# 对不需要记录访问日志的server添加这两个代码可以关闭日志记录
server {
....
#不记录访问日志
access_log off;
#不记录错误日志
error_log /dev/null;
....
}

其他注意事项

1
2
3
4
5
6
7
复制1. access日志修改目录后,记得要把访问权限给nginx的对应用户
chown nginx:nginx /usr/local/nginx/logs/acces
或者
chmod -R 777 /usr/local/nginx/logs/acceserror
2. 错误日志不能使用日期格式,这个没有办法
3. 错误日志虽然不能修改日期格式,但是可以修改文件路径
4. 需要在http下面添加root的对应路径,或者server下面添加,否则比如反向代理这种接口会无法写出日志