Ubuntu 下通过 logrotate 和 crontab 自动按天分割 nginx 日志.
1. 修改 nginx 配置文件
在 http
块中增加 log_format
配置,并调整 nginx log 保存位置:
cd /etc/nginx
vim nginx.conf # 可能是只读文件
http {
# 省略其他配置项
##
# Logging Settings
##
log_format main '$http_host $remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /mnt/logs/nginx/access.log main;
error_log /mnt/logs/nginx/error.log;
# 省略其他配置项
}
注1:main 为 log_format 的 name,可自定义,但需要与 access_log 配置中保持一致。
2. 修改 logrotate 的 nginx 配置
cd /etc/logrotate.d
vim nginx # 可能是只读文件
/mnt/logs/nginx/*.log {
su root root
daily
missingok
rotate 14
size 200M
dateext
compress
delaycompress
notifempty
copytruncate
create 0777 www-data www-data
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
注01:文件中第一行为日志文件的位置,应该与 nginx.conf 中配置的 access_log 路径相对应。
注02:可以使用 su root root,来指定使用root权限执行。
注03:daily,每天执行一次,对应的,还有weekly, monthly。
注04:missingok,允许日志文件不存在,不报错。
注05:srotate 14,保留最近14个日志文件。
注06:dateext,使用日志作为备份文件的后缀名,eg: access.log-20191110, access.log-20191110.gz。
注07:compress,使用gzip压缩日志,对应的,nocompress 为不压缩日志。
注08:delaycompress,与compress配合使用,转存的文件在下一次执行时才会被压缩。
注09:copytruncate,用于还在写入中的日志文件,先将文件内容拷贝到其他文件,然后再清空文件,因为拷贝和清空存在时间差,会导致部分日志丢失。
注10:sharedscripts,所有日志文件轮转完成后统一执行一次脚本,而非每个文件执行一次。
注11:prerotate,logrotate转储之前需要执行的脚本。
注12:postrotate,logrotate转储之后需要执行的脚本,通常用于重启服务之类的操作。
注13:create,使用指定的 mode, user, group 来创建新文件。
注14:www-data, 因为nginx默认使用的是www-data用户。
3. 设置 logrotate.d/nginx 配置文件权限
为防止后续在对 logrotate 进行测试的过程中出现权限问题,需要将 logrotate.d/nginx 配置文件的权限设置为 0644
:
cd /etc/logrotate.d
sudo chmod 0644 nginx
以应对如下报错信息:
error: Ignoring syslog because of bad file mode - must be 0644 or 0444
4. 测试日志分割
cd /usr/sbin
sudo ./logrotate -f /etc/logrotate.d/nginx
如果日志文件较大,可能这里需要等待一会儿,如果没有报错的话,切换到日志目录,查看日志文件是否分割成功。
如果出现以下错误信息:
error: skipping "/mnt/logs/nginx/access.log" because parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.
error: skipping "/mnt/logs/nginx/error.log" because parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.
则需要在 logrotate.d/nginx 配置文件中设置 su root root
。
如果出现以下错误信息:
error: error switching euid to 0 and egid to 0: Operation not permitted
error: error creating output file /var/lib/logrotate/status.tmp: Permission denied
一般来说,有两个原因
- 第一个报错明显是说在生成新文件时,没有权限设置euid。就需要检查一下 logrotate.d/nginx 配置文件中指定的
create
配置, 一般我会配置为create 0777 www-data www-data
(www-data为nginx默认用户)。 - 第二个报错一般是由于没有使用
sudo
来执行 logrotate 命令导致的。
4. 配置 crontab
cd /etc
vim crontab # 可能是只读文件
在 crontab 中新增如下行,代表在每天的 00:00 执行。
# m h dom mon dow user command
0 0 * * * root /usr/sbin/logrotate -f /etc/logrotate.d/nginx
#