Nginx快速入门:访问日志access.log参数详解 |访问日志记录自定义请求头(三)

wu@55555 2024-07-05 16:07:34 阅读 66

0. 引言

在企业的生产环境中,我们时常需要通过nginx的访问日志来统计流量、排查调用问题等,而nginx默认的日志格式所包含的信息远无法满足我们使用,因此常常需要对日志进行自定义,所以今天我们就来看如何自定义nginx的访问日志格式,并了解nginx的访问日志支持多少参数。

1. 自定义日志格式

首先我们在默认的<code>nginx.conf文件中可以看到,对访问日志是有默认定义的,其中包含了定义日志格式,定义日志文件位置。如下所示,其中main为定义的日志格式别名,你可以定义成其他的名称。

log_format main '$remote_addr - $remote_user [$time_local] "$request" '

'$status $body_bytes_sent "$http_referer" '

'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

默认日志输出示例

在这里插入图片描述

nginx的访问日志定义的语法是:

<code>log_format name [escape=default | json] string ...;

name: 定义的格式名称,自定义,后续在access_log参数中引用escape: 设置日志格式,默认为default,即默认输出,或者支持json, 按照json格式输出string: 要定义的日志格式的内容,可以在里面设置要记录的日志参数

在默认日志格式中,定义的参数含义如下:

参数 说明
$remote_addr 客户端IP地址
$remote_user 客户端用户名
$time_local 请求时间
$request 请求的URI和HTTP协议版本
$status 请求返回的状态码
$body_bytes_sent 发送给客户端的字节数
$http_referer 引用的页面地址
$http_user_agent 客户端代理信息, 比如浏览器信息等

nginx还支持的常用参数有:

参数 说明
$http_host 请求头中的 “Host” 字段的值,如果请求中没有 “Host” 字段,则会使用服务器监听的 server_name 中定义的第一个名称
$uri 请求的 URI,即 URL 的后半部分,不包括查询字符串
$ssl_protocol 使用的 SSL 协议版本,如 “SSLv3”、“TLSv1” 等
$ssl_cipher 用于加密连接的加密算法,例如 “AES128-SHA”
$http_x_forwarded_for 当前端有代理服务器时,设置web节点记录客户端地址的配置,此参数生效的前提是代理服务器也要进行相关的x_forwarded_for设置
$upstream_addr 后端服务器的地址和端口,用于识别请求被转发到的服务器
$request_body 客户端发送的请求体,即请求消息的主体部分,通常用于 POST 请求
$upstream_status 后端服务器的响应状态码,如 “200”、“404” 等
$upstream_header_time 后端服务器处理请求并返回响应头的时间
$upstream_response_time 后端服务器从开始处理请求到返回响应的整个时间
$bytes_sent 发送给客户端的字节数
$connection 连接序列号
$connection_requests 当前通过连接发出的请求数量
$msec 日志写入时间,单位为秒,精度是毫秒
$pipe 如果请求是通过http流水线发送,则其值为"p",否则为“."
$request_length 请求长度(包括请求行,请求头和请求体)
$request_time 请求处理时长,单位为秒,精度为毫秒,从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端进行日志写入为止
$time_iso8601 标准格式的本地时间,形如“2017-05-24T18:31:27+08:00”
$remote_addr 客户端IP
$request 完整的原始请求行,如 “GET / HTTP/1.1”
$request_uri 完整的请求地址,如 “https://baidu.com”

2. 日志配置案例

下面我们按照生产环境的日志标准配置一个样例,包括请求时间、地址、加密算法、响应时长、请求体大小等信息

log_format main escape=json '{"@timestamp":"$time_iso8601",'

'"remote_addr":"$remote_addr",'

'"remote_user":"$remote_user",'

'"http_host":"$http_host",'

'"uri":"$uri",'

'"http_referer":"$http_referer",'

'"ssl_protocol":"$ssl_protocol",'

'"ssl_cipher":"$ssl_cipher",'

'"http_x_forwarded_for":"$http_x_forwarded_for",'

'"upstream_addr":"$upstream_addr",'

'"bytes":$body_bytes_sent,'

'"request":"$request",'

'"request_length":$request_length,'

'"request_time":$request_time,'

'"upstream_status":$upstream_status,'

'"upstream_header_time":$upstream_header_time,'

'"upstream_response_time":$upstream_response_time,'

'"status":"$status",'

'"http_referer":"$http_referer",'

'"http_user_agent":"$http_user_agent"'

'}';

access_log /var/log/nginx/access.log main;

配置好记得重启,让配置生效

# 检查语法

nginx -t

# 重启

nginx -s reload

输出样式:

可以看到日志就以json格式的形式输出了

在这里插入图片描述

3. 日志记录自定义请求头

某些场景下,我们需要打印自定义的请求头,比如设置请求头参数为这次请求的流水号,这样将其打印后,我们就能快速定位到这笔请求的nginx日志了

1、而打印也很简单,就直接在日志格式里添加上这个header即可,如下添加一个自定义header:<code>http_x_seqno,需要注意的是这里日志中引用的header变量,需要是原来的请求头名称小写,并且前面加上"http_“,比如请求头是"x_seqno”, 那么这里配置的就是"$http_x_seqno"

log_format main escape=json '{"@timestamp":"$time_iso8601",'

'"http_user_agent":"$http_user_agent",'

'""http_x_seqno":"$http_x_seqno"'

'}';

access_log /var/log/nginx/access.log main;

2、如果这里直接重启访问,会发现日志并不会打印该header值,这是因为我们还需要在http或server模块中开启underscores_in_headers,以此支持读取下划线header

underscores_in_headers on; # 下划线支持,开启自定义header

在这里插入图片描述

然后重启nginx,测试访问

在这里插入图片描述

日志中会发现该header已经打印

在这里插入图片描述

4. 总结

如上,我们就掌握了关于nginx的访问日志的自定义,但还有一个问题,就是nginx的日志文件是一个,没有按天分割,时间一长,那么这个文件就会很大,影响我们维护阅读。于是如何实现nginx日志文件的按天分割呢?

以下提供几种思路,大家可以自己拓展:

1、借助脚本实现,通过编写脚本,通过<code>mv指令将日志文件迁移到有带日期名的日志文件,该脚本添加到linux每日定时任务中2、使用cronlog工具实现3、使用Logrotate工具实现

尽量避免使用通过在nginx http模块用map定义变量,然后声明日志文件名,或者其他类似的通过nginx本身变量声明而修改日志文件名的形式,因为这样每次请求进来都要进行判断,影响性能。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。