本文以nginx日志文件为例,讲解下logrotate日志管理工具的用法。
配置:
1、在/etc/logrotate.d目录下,创建一个用于nginx日志的配置文件。
如下:
#vim /etc/logrotate.d/nginx
daily
rotate 5
missingok
notifempty
sharedscripts
postrotate
if [ -f /usr/local/nginx/logs/nginx.pid ]; then
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
fi
endscript
}
保存退出。
2、执行logrotate
在/usr/local/nginx/logs目录中会产生
error.log
error.log.1
有如上内容,说明logrotate配置成功。
3、让logrotate每天进行一次滚动
在crontab中添加一行定时脚本。
59 23 * * * /usr/sbin/logrotate -f /etc/logrotate.d/nginx
每天23点59分进行日志滚动
4、配置文件说明
rotate:保留最5次滚动的日志
notifempty:日志文件为空不进行滚动
sharedscripts:运行postrotate脚本
脚本:
if [ -f /usr/local/nginx/logs/nginx.pid ]; then
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
fi
endscript
此脚本平滑重启nginx,并重新生成日志文件。
Nginx日志仅支持按照server_name或文件大小进行划分,有时需要实现类似apache服务器中按天生成日志的功能。
对于网上的一些文章,甚至用到命令kill -9 `cat Nginx.pid`,杀掉Nginx子进程,有点太疯狂。
以前在做openstack的云存储开发时,对rsyslog的日志进行分割的方法,参考其实现了nginx日志的分割。
原理:
1,从一台已安装apache的机器上的apache bin目录下把rotatelogs拷贝到本机的/opt/nginx_logs下
cp rotatelogs /opt/nginx_logs/
chmod +x /opt/nginx_logs/rotatelogs
2,创建有名管道
mkfifo /opt/nginx_logs/abc_www/access_log
3,在nginx配置文件server中添加:
4,创建日志目录
5,创建日志分割脚本,防止rotatelogs被kill掉
baselogdir=/opt/nginx_logs/abc_www
rotatelogs=/opt/nginx_logs/rotatelogs
while [ 1 ]
do
echo `date +"%F %T"`" rotatelogs access start"
$rotatelogs $baselogdir/log/access_%Y%m%d.log 86400 480 < $baselogdir/access_log
echo `date +"%F %T"`" rotatelogs access stop"
sleep 1;
done
6,创建启动日志分割脚本
sh /opt/nginx_logs/abc_www/rotate.sh >> /opt/nginx_logs/abc_www/log/access-rotate.log 2>&1 &
7,最终效果
如此,便实现了nginx日志的按天分割,与apache中的一样了,也满足了需求,欢呼一下吧。
您可能感兴趣的文章:
nginx 日志分割的小脚本
分享:Logrotate分割nginx日志的脚本
nginx日志配置、Nginx日志分割
一个分割ngnix网站日志的Shell脚本
每天自动分割Nginx日志文件的Shell脚本
有个给某大客户(游戏下载类)的特殊需求设计,因为文件大小差距很大——估计是大版本和补丁的区别——又走的是同一个域名,而squid在响应比较大的文件时,尤其是初次下载
时,性能比较差,所以拆成两组服务器,squid服务于较小的文件,通过pull方式从peer层获取,nginx服务于较大的文件,通过push方式由peer层分发同步。外部发布域名一
律解析到squid服务器组上,请求透传到peer层的nginx,nginx分析这个url的content-length,如果大于阈值,则不返回文件,而是302到nginx服务器组的独立域名下的相应
url去。
注意:
nginx的内部变量里有一个$content-length,是不能用在这里的,官方wiki是这么解释这个变量的:”This variable is equal to line Content-Length in the
header of request”。
可见,这个变量是请求头的内容,一般见于POST请求用来限定POST信息的长度;而不是我们需要的响应头的内容。
最后是修改了nginx的src完成的功能。
其实可以使用http_perl_module完成的。而且还可以扩展302跳转的功能,把独立域名改成直接通过remote_addr定向到最近IP上。
以下内容仅限测试与学习使用。
首先,在nginx.conf中配置:
perl_modules perl;
perl_require SizeDiff.pm;
server {
listen 80;
server_name dl.gamedomain.com;
location / {
perl SizeDiff::handler;
}
}
}
然后,在perl/SizeDiff.pm文件中,如下:
use Nginx::Simple;
sub main {
my $self = shift;
my $webroot = '/www/dl.gamedomain.com/'
return HTTP_NOT_ALLOWED unless $self->uri =~ m!^(/.+/)[^/]+$!;
my $file = $webroot . $1 . $self->filename;
my @filestat = stat($file) or return HTTP_NOT_FOUND;
my $filesize = $filestat[7];
if ( $filesize < 8 * 1024 * 1024 ) {
return OK;
} else {
$self->location('http://bigfile.cdndomain.com'.$self->uri);
}
};
1
基本就是这样子,之前还考虑过如果不是push方式,可以在perl里考虑使用LWP获取header,不过仔细想想:
第一,万一源站开启了chunked获取不到content-length呢?
第二,就算可以,如果一个文件是1个G,那再去下载这1个G的文件下来,这个perl进程肯定挂了——官方wiki里可是连DNS解析时间都认为太长……也就是说,这个设想不适合在
peer层,而是在loadbalance的角色,通过lwp的header结果,小文件upstream到后端的squid,大文件location到另外的nginx。
另一个可改进之处,就是self->location前面,可以结合Net::IP::Match::Regexp模块或者自己完成的类似功能,来针对self->remote_addr选择最近的服务器组IP,最后返回
location(“http://$ip$uri”)。
闲来神笔,仅作参考,呵呵。
不妨作为研究nginx与squid的文档吧,,祝大家学习进步。