nginx日志

Nignx的日志类型

我们进入到nginx目录下的log目录中,可以看到里面存放着三个文件,分别是access.log,error.log和nginx.pid文件,其中nginx.pid是用来记录当前nginx进程的pid号的,不属于日志文件。真正属于日志文件的是另外两个文件。

1
2
3
-rw-r--r-- 1 root root 90261926 Jun  9 09:38 access.log
-rw-r--r-- 1 root root 21159964 Jun 8 16:36 error.log
-rw-r--r-- 1 root root 5 May 24 15:18 nginx.pid

access.log日志文件

1、access.log文件的介绍

access文件用于存放每个用户访问网站的请求日志,开发运维人员通过访问日志来分析用户的浏览器行为。默认情况下,nginx会在log目录下生成该文件,无需用户配置。

2、access.log的相关配置

我们可以在$nginx_home/conf/nginx.conf配置文件中对nginx请求日志进行配置。配置的格式为:

1
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

其中,access_log是关键字,表示接下来的配置是关于access日志的配置,path为该日志文件的存储路径,后面还可以对日志输出格式、是否压缩、日志刷新时间等设置进行配置。可能有读者会留意到,上面截图中的用例在path后面写上了main,其实这里的main并不是什么关键字,而是nginx默认定义好的一个日志格式名称,我们可以在log_format中看到,nginx默认定义了一个名为main的日志输出格式。

关于日志输出格式的配置
nginx自带了一些变量,让我们能够作为日志输出格式进行配置,方便我们对用户的请求进行查询和统计。当然了,nginx其实默认的日志输出格式其实就已经把一些重要的请求参数保存到访问日志里面了,基本满足我们日常使用了,如果有需要可以根据下面的表单自定义配置所需要的日志格式。

参数 说明 示例
$remote_addr 客户端地址 211.28.65.253
$remote_user 客户端用户名称
$time_local 访问时间和时区 18/Jul/2012:17:00:01 +0800
$request 请求的URI和HTTP协议 “GET /article-10000.html HTTP/1.1”
$http_host 请求地址,即浏览器中你输入的地址(IP或域名) www.wang.com 192.168.100.100
$status HTTP请求状态 200
$upstream_status upstream状态 200
$body_bytes_sent 发送给客户端文件内容大小 1547
$http_referer URL跳转来源 https://www.baidu.com/
$http_user_agent 用户终端浏览器等信息 “Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; GTB7.0; .NET4.0C;”
$ssl_protocol SSL协议版本 TLSv1
$ssl_cipher 交换数据中的算法 RC4-SHA
$upstream_addr 后台upstream的地址,即真正提供服务的主机地址 10.10.10.100:80
$request_time 整个请求的总时间 0.205
$upstream_response_time 请求过程中,upstream响应时间 0.002

下面我们来简单地自定义一个日志输出格式,并且应用起来。

步骤一:在http标签下新增一个log_format格式


步骤二:在server标签中应用定义新的access_log配置
1
2
3
4
5
6
7
server {
listen 9600;
location / {
root html;
access_log logs/mine_access.log mine_format;
}
}
步骤三:使用nginx -s reload重新加载配置文件

(注意,如果这里提示说日志文件不存在的话,就自己先手动建一下文件即可)
自己手动访问几次服务,就可以看到新生成的日志格式会和我们定义的日志格式一致了。

关于刷新时间的配置
nginx默认情况下对访问日志是实时记录的,其实一定程度上来说是会占用cpu资源的,当然了大部分站点其实访问量并不大,所以实时记录日志所带来的性能消耗是可以忽略的。如果说对于访问量大且对性能要求较高的站点,可能会希望通过优化日志的输出频率来达到减少IO的效果。

1
2
3
4
location / {
root html;
access_log logs/mine_access.gz mine_format gzip flush=5s;
}

我们可以看一下官方对这个配置的介绍
配置完flush和buffer后,其实我们就相当于是有两个记录日志的节点了,一个是缓冲区满了,另外一个是到刷新日志的时间点了。缓冲区的存在使得nginx不需要针对每一个请求都做一次IO,可以节省一点系统资源。当然了,我们还可以开启gzip压缩(可选等级为1-9,级别越高压缩级别越高)来进一步减轻磁盘压力。

关闭访问日志的记录
只需要配置access_log为off即可

1
2
3
4
location / {
root html;
access_log off;
}

error.log错误日志

相比于访问日志来说,运维人员可能更加关注错误日志文件,错误日志文件记录了nginx运行过程中遇到的错误信息(注意,也包括用户请求没有正常响应的错误日志),向有时候我们nginx启动失败后,都可以在这个error日志中找到对应较为详情的报错信息。
这里贴一下官网对error.log的介绍,该错误日志的配置格式为:error_log path level,error_log为关键字,path为日志保存的路径,level为日志级别。默认情况下nginx会在logs目录下建立一个名为error.log的日志文件,且日志级别为error。可选的日志级别配置从低到高分别为debug, info, notice, warn, error, crit, alert, emerg。


我们可以简单演示一下,这个错误日志的用法

1
2
3
4
5
6
7
8
server {
listen 9600;
location / {
root html;
access_log logs/mine_access.log mine_format;
error_log logs/mine_error.log warn;
}
}

配置完后reload一下nginx配置,然后在浏览器中随意访问一下不存在的资源,我们就可以在日志文件里面看到相关的错误日志了。


Nignx的日志分割

nginx默认是不会进行日志文件的分割操作的,也就是所有访问日志会一直往access.log文件里面追加,时间一长的话这个文件就会变得很大,nginx的性能也会降低,而且运维人员在查看当天文件的也很不方便。所以一般来说,我们都会选择按日对日志文件进行切割。

logrotate结合crontab日志切割

vi /etc/logrotate.d/nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/var/log/nginx/*.log /var/log/nginx/*.html {
minsize 1024M
# 指定新建的日志文件权限以及所属用户和组
create 0644 nginx root
# 每月一次切割,取代默认的一周
monthly
#只保留一个日志.
rotate 3
missingok
dateext
notifempty
compress
delaycompress
sharedscripts
postrotate
if [ -f /usr/local/nginx/logs/nginx.pid ]; then
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
fi
endscript
}

logrotate参数说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 配置           # 说明
daily # 指定转储周期为每天
weekly # 指定转储周期为每周
monthly # 指定转储周期为每月
rotate count # 指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份
compress # 通过gzip 压缩转储以后的日志
nocompress # 不做gzip压缩处理
create mode owner group # 轮转时指定创建新文件的属性,如create 0777 nobody nobody
nocreate # 不建立新的日志文件
delaycompress # 和compress 一起使用时,转储的日志文件到下一次转储时才压缩
nodelaycompress # 覆盖 delaycompress 选项,转储同时压缩
missingok # 如果日志丢失,不报错继续滚动下一个日志
ifempty # 即使日志文件为空文件也做轮转,这个是logrotate的缺省选项
notifempty # 当日志文件为空时,不进行轮转
mail address # 把转储的日志文件发送到指定的E-mail 地址
olddir directory # 转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
noolddir # 转储后的日志文件和当前日志文件放在同一个目录下
sharedscripts # 运行postrotate脚本,作用是在所有日志都轮转后统一执行一次脚本。如果没有配置这个,那么每个日志轮转后都会执行一次脚本
prerotate # 在logrotate转储之前需要执行的指令,例如修改文件的属性等动作;必须独立成行
postrotate # 在logrotate转储之后需要执行的指令,例如重新启动 (kill -HUP) 某个服务!必须独立成行
dateext # 使用当期日期作为命名格式
dateformat .%s # 配合dateext使用,紧跟在下一行出现,定义文件切割后的文件名,必须配合dateext使用,只支持 %Y %m %d %s 这四个参数
size(minsize) log-size # 当日志文件到达指定的大小时才转储,log-size能指定bytes(缺省)及KB (sizek)或MB(sizem),例如 size 100M

配置crontab定时任务

crontab -e 配置 每月1日1点分割一次文件

1
0 0 1 1 * ? /usr/sbin/logrotate -vf /etc/logrotate.d/nginx

2024.12.27补充


Nginx日志分析

goaccess

[传送至官网] (https://goaccess.io/download)

定时生成

1
0 0 * * * /usr/local/bin/goaccess -a -d -f /var/log/nginx/access.log -p /usr/local/etc/goaccess/goaccess.conf -o /var/log/nginx/goaccess.html 2> /var/log/nginx/goaccess.log

nginx日志保留1月

logrotate 配置文件上文中已提到不在复述

1
0 0 1 1 * ? /usr/sbin/logrotate -vf /etc/logrotate.d/nginx