其实已经有好长时间没有写博客,这次的博客主要强调两点:一是日志对于运维工作的重要性;

二是如何很好的管理服务器的日志。博客主要从nginx的日志展开讲解,然后,通过logrotate工具

对日志进行管理,避免日志太大占满磁盘空间。


第一个部分:Nginx日志

    nginx是当前互联网中使用非常多的web服务,它能够实现负载均衡、反向代理、缓存等等功能,

但我要是这些,并不是本篇的内容,本篇主要是介绍nginx的日志。


日志的格式:

语法:log_format name string....


例子:

log_format  combined  '$remote_addr - $remote_user [$time_loca]'
		      ' "$request" $status $body_bytes_sent '
		      ' "$http_referer" "$http_user_agent" '
log_format  proxy     '$http_x_forwarded_for - $remote_user [$time_local]'
		      ' "$request" $status $body_bytes_sent '
		      ' "$http_referer" "$http_user_agent" '


相关变量的解析:

---------------------------------------------------------------------

$remote_addr,$http_x_forwarded_for:记录客户端IP地址

---------------------------------------------------------------------

$remote_user:记录客户端用户名称

---------------------------------------------------------------------

$request:记录请求的URL和HTTP协议

---------------------------------------------------------------------

$status:记录请求状态

---------------------------------------------------------------------

$body_bytes_sent:发送给客户端的字节数,不包括响应头的大小

---------------------------------------------------------------------

$bytes_sent:发送给客户端的总字节数

---------------------------------------------------------------------

$connection:连接的序列号

---------------------------------------------------------------------

$connection_requests:当前通过一个连接获得的请求数量

---------------------------------------------------------------------

$msec:日志写入时间,单位s,精度ms

---------------------------------------------------------------------

$http_referer:记录从哪个页面链接访问过来的

---------------------------------------------------------------------

$http_user_agent:记录客户端浏览器相关信息

---------------------------------------------------------------------

$request_length:请求的长度(包括请求行,请求头和请求正文)

---------------------------------------------------------------------

$request_time:请求处理时间

---------------------------------------------------------------------

$time_iso8601:ISO8601标准格式下的本地时间

---------------------------------------------------------------------

$time_local:通过日志格式下的本地时间

---------------------------------------------------------------------


假设,此时有一个站点为www.test.com,要将访问这个站点的信息记录到log中

http {

log_format  combined  '$remote_addr - $remote_user [$time_loca]'
		      ' "$request" $status $body_bytes_sent '
		      ' "$http_referer" "$http_user_agent" '

server {
	listen	80;
	server_name	www.test.com;
	root	/data/web/htdocs;
	index  index.php index.html index.htm;
	
	access_log	/var/log/nginx/test.access.log  combined;
	error_log	/var/log/nginx/test.error.log   error;	

	location ~ \.php$ {
		root /data/web/htdocs;
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_index index.php;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include fastcgi_params;
		}
	}
}


上面仅是一个例子,http段中只列出了定义访问日志的部分,其他部分没有写出


第二部分:logrotate管理日志

       logrotate是一个日志文件管理工具。用来把旧文件轮转、压缩、删除,并且创建新的日志文件。

我们可以根据日志文件的大小、天数等来转储,便于对日志文件管理,一般都是通过cron计划任务来完成的。


logrotate的配置文件主要由logrotate.conf和logrotate.d下面的所有文件构成,用户将自己的配置需求写到配置文件中;然后,通过crontab来执行,执行的周期可以是daily,weekly。可以在/etc/cron.daily中进行查看

[root@bbs01 cron.daily]# ls
logrotate  makewhatis.cron  mlocate.cron  prelink  readahead.cron  tmpwatch


可以看到在cron.daily目录中有logrotate,主要是执行了logrotate服务

#!/bin/sh

/usr/sbin/logrotate /etc/logrotate.conf >/dev/null 2>&1
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
    /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0


那我们如何知道,crontab在何时执行logrotate这个任务呢,在centos系统中,是由anacrontab自动执行的。配置中定义了每日,每周,每月执行任务的时间。

[root@bbs01 cron.daily]# vim /etc/anacrontab 
#period in days   delay in minutes   job-identifier   command
1       5       cron.daily              nice run-parts /etc/cron.daily
7       25      cron.weekly             nice run-parts /etc/cron.weekly
@monthly 45     cron.monthly            nice run-parts /etc/cron.monthly


以上就是logrotate整个的工作过程,那么如何配置我们的logrotate呢?

先看一个我在线上的配置,主要是针对nginx做的。

# cat /etc/logrotate.d/nginx
/usr/local/nginx/logs/*.log {
    rotate 5
    daily
    dateext
    postrotate
        /bin/kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)
    endscript
    missingok
    compress
}

格式很简单,先指定我们日志所处的位置,还能支持匹配,然后就是一些特定参数了。


参数的解释如下:

---------------------------------------------------------------------

compress:通过gzip 压缩转储旧的日志

---------------------------------------------------------------------

nocompress:不需要压缩时,用这个参数

---------------------------------------------------------------------

copytruncate:用于还在打开中的日志文件,把当前日志备份并截断

---------------------------------------------------------------------

nocopytruncate:备份日志文件但是不截断

---------------------------------------------------------------------

create mode owner group:使用指定的文件模式创建新的日志文件

---------------------------------------------------------------------

nocreate:不建立新的日志文件

---------------------------------------------------------------------

delaycompress:和 compress 一起使用时,转储的日志文件到下一次转储时才压缩

---------------------------------------------------------------------

dateext  切换后的日志文件会附加上一个短横线和YYYYMMDD格式的日期,没有这个配置项会附加一个小数点加一个数字序号

---------------------------------------------------------------------

nodelaycompress:覆盖 delaycompress 选项,转储同时压缩。

---------------------------------------------------------------------

errors address:专储时的错误信息发送到指定的Email 地址

---------------------------------------------------------------------

ifempty:即使是空文件也转储,这个是 logrotate 的缺省选项。

---------------------------------------------------------------------

notifempty:如果是空文件的话,不转储

---------------------------------------------------------------------

mail address:把转储的日志文件发送到指定的E-mail 地址

---------------------------------------------------------------------

missingok:如果日志文件丢失,继续下一个转储,不发出错误信息

---------------------------------------------------------------------

nomail:转储时不发送日志文件

---------------------------------------------------------------------

olddir directory:转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统

---------------------------------------------------------------------

noolddir:转储后的日志文件和当前日志文件放在同一个目录下

---------------------------------------------------------------------

prerotate/endscript:在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行

---------------------------------------------------------------------

postrotate/endscript:在转储以后需要执行的命令可以放入这个对,这两个关键字必须单独成行

---------------------------------------------------------------------

sharedscripts:所有的日志文件都轮转完毕后统一执行一次脚本

---------------------------------------------------------------------

daily:指定转储周期为每天

---------------------------------------------------------------------

weekly:指定转储周期为每周

---------------------------------------------------------------------

monthly:指定转储周期为每月

---------------------------------------------------------------------

rotate count:指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份

---------------------------------------------------------------------

size size:当日志文件到达指定的大小时才转储,Size 可以指定 bytes (缺省)以及KB (sizek)或

---------------------------------------------------------------------

prerotate/endscript

    在prerotate和endscript之间的行(他俩自己各占一行),在日志文件被轮转之前并且有需要轮转时,才会执行。

    该指令只能用于log文件定义中。

---------------------------------------------------------------------

postrotate/endscript

    在prerotate和endscript之间的行,在日志文件被轮转之后执行。

    该指令只能用于log文件定义中。

---------------------------------------------------------------------

firstaction/endscript

    在firstaction和endscript之间的行,在轮转所有匹配了通配符的日志被轮转之前,

    在prerotate执行之前,并且至少要有一个日志需要被轮转时,才会执行。

    只能用于log文件定义中,如果脚本错误退出,就不再继续往下进行。

---------------------------------------------------------------------

lastaction/endscript

    在lastaction和endscript之间的行,在轮转了所有匹配的日志后,在postrotate执行之后,

    并且至少要有一个日志被轮转了的情况下,才会执行。

---------------------------------------------------------------------


我们可以手动去执行logrotate立即管理日志,也可以等待crontab自动执行任务计划

手动执行过程,可以加-f、-d参数,-f去强制执行,-d则是debug模式

例如:logrotate -f -d /etc/logrotate.d/nginx


使用logrotate管理nginx的日志,优点在于:

1、不需要担心日志文件会将目录塞满,logrotate会保留特定个数文件;

2、每天的日志放在一个文件中,不需要一直往前翻,方便查阅;