1.日志分类

     Nginx日志主要分为两种:访问日志和错误日志。日志开关在nginx配置文件中(nginx.conf)设置,两种日志都可以选择性关闭。

1.1访问日志

1.1.1简介

访问日志主要记录客户端访问nginx的每一个请求,格式可以自定义。通过访问日志,你可以得到用户地域来源、跳转来源、使用终端、使用某个URL访问量等相关信息。

1.1.2主要相关指令log_format

1log_format用来设置日志格式,也就是日志文件中每条日志的格式

2log_format name(格式名称) type(格式样式)

Log_format main $server_name  $remote_addr - $remote_user  [$time_local]  $request 

              $status  $upstream_status  $body_bytes_sent   $http_referer 

               $http_user_agent  $http_x_forwarded_for 

        $ssl_protocol $ssl_cipher $upstream_addr $request_time $upstream_response_time;

3)注意:log_format配置可以放在server里边,但是不能放在http外边

4)上面红色部分为Nginx默认指定的格式样式,每个样式的含义如下

虚拟主机名称:$server_name

远程客户端的ip地址:$remote_addr

空白:用一个-”占位符代替

远程客户端用户名称(用于记录浏览者进行身份验证时提供的名字,如登录tmooc的用户名,[email protected],如果没有登录就是空白):$remote_user

访问的时间与时区:[$time_local]比如18/Jul/2012:17:00:01 +0800,时间信息最后的“+0800”表示服务器所处时区位于UTC之后的8小时

请求的URIHTTP协议:$request。这是整个PV日志记录中最有用的信息,记录服务器收到一个什么样的请求

记录请求返回的http状态码:$status,比如成功是200

$upstream_statuupstream状态,比如成功是200

发送给客户端的文件主体内容的大小,$body_bytes_sent,比如899,可以将日志每条记录中的这个值累加起来以粗略估计服务器吞吐量

记录重哪个页面链接访问过来的,$http_referer

客户端浏览器信息:$http_user_agent

客户端的真实ip$http_x_forwarded_for,通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的ip地址。反向代理服务器在转发请的的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的ip地址和原来客户端的请求服务器地址

SSL协议版本:$ssl_protocol,比如TLSv1

交换数据中的算法:$ssl_cipher,比如RC4-SHA

upstream的地址:$upstream_addr,即真正提供服务的主机地址

整个请求的总时间:$request_time

请求过程中:upstream的响应时间,$upstream_response_time

请求数据大小:$request_length
返回数据大小:$bytes_sent
请求耗时:$request_time
所用连接序号:$connection
当前连接发生请求数:$connection_requests

5)典型记录

192.168.1.102 - scq2099yt [18/Mar/2013:23:30:42 +0800] "GET /stats/awstats.pl?config=scq2099yt HTTP/1.1" 200 899 "http://192.168.1.1/pv/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows XXX; Maxthon)"

1.1.3主要相关指令access_log

1access_log指令用来指定日志文件的存放路径(包含日志文件名)、格式和缓存大小

2access_log path(存放路径)[format(自定义日志格式名称) [buffer=size | off]],能够使用access_log指令的字段包括:httpserverlocation

设置 bufferbuffer 满 32k 才刷盘;假如 buffer不够32k但是需要5s 钟强制刷盘,配置如下,这也决定了是否实时看到日志以及日志对磁盘IO的影响

access_log /data/logs/nginx-access.log buffer=32k flush=5s;

3)注意:nginx进程设置的用户和组必须对日志路径有创建文件的权限,否则会报错

1.1.4 配置实例

这个是达内cdn项目需要调用里边的视频做的nginx servier

server

 {

   listen 80;

        location / {

            root   /data/streams;

            index  index.html index.htm;

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

              '$status $body_bytes_sent "$http_referer" '

              '"$http_user_agent" $http_x_forwarded_for';

    access_log  /usr/local/nginx/logs/videottsaccess.log  access9;

        }

 }

 

1.2错误日志

1.2.1简介

错误日志主要记录客户端访问nginx出错的日志,格式不支持自定义。通过错误日志,你可以得到系统某个服务或server的性能瓶颈等。因此,将日志好好利用,你可以得到很多有价值的信息。

1.2.2格式

1error_log path(存放路径) lenel(日志级别)

2)举例说明:error_log logs/error.log info;

     error_log /dev/null;将日志扔到垃圾桶

3path 含义同access_loglevel表示日志等级,具体如下

     [ debug | info | notice | warn | error | crit]

     从左至右,日志详细程度逐级递减,即debug最详细,crit最少

emerg: Emergency situations where the system is in an unusable state.

alert: Severe situation where action is needed promptly.

crit: Important problems that need to be addressed.

error: An Error has occurred. Something was unsuccessful.

warn: Something out of the ordinary happened, but not a cause for concern.

notice: Something normal, but worth noting has happened.

info: An informational message that might be nice to know.

debug: Debugging information that can be useful to pinpoint where a problem is occurring.

4error_log off 并不能关闭错误日志,而是会将错误日志记录到一个文件名为off的文件

     中,正确关闭错误日志记录功能的方法如下

1.2.3案例

error_log  /usr/local/nginx/logs/nginx_error.log  crit;

 

2.日志切割

2.1简介

1)有时候需要一天生成一次日志,然后统计每天的访问量

2)新版本的nginx支持自动切割并压缩日志

3)脚本也可以实现日志切割

2.2脚本实现

2.2.11每天一份日志情况1

  1. 日志文件太大,需要进行切割

  2. 一般是在0点进行切割,所以计划任务时间是 0 0 * * *

  3. 现在网上有人修改源码,可以实现日志分割功能

  4. 下边是一个比较好的例子

#!/bin/bash

LOGS_PATH=/usr/local/nginx/logs

YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)

mv ${LOGS_PATH}/access.log ${LOGS_PATH}/access_${YESTERDAY}.log

## 向 Nginx 主进程发送 USR1 信号。USR1 信号是重新打开日志文件

kill -USR1 $(cat /usr/local/nginx/nginx.pid)

2.2.22每天一份日志情况2

这个是同事要求这么做的,没办法,就这么搞吧

#!/bin/bash

# This script run at 00:00

# The Nginx logs path

logdir="/usr/local/nginx/logs/"

time=`date +%Y%m%d`

/bin/mv $logdir/access.log $logdir/access_$time.log

kill -USR1 `cat /usr/local/nginx/nginx.pid`                 //重新生成nginx日志

/usr/bin/find $logdir -mtime +2 -exec rm -f {} \;

1nginx的主进程收到USR1信号,会重新打开日志文件(nginx配置文件中的日志名称命名,就是配置文件中access_log项所设置的值,如果文件不存在,会自动创建一个新的文件xxx.log)

2)然后把日志文件的拥有者改为“工作进程(worker进程)”,目的是让worker进程就具备了对日志文件的读写权限(masterworker通常以不同用户运行,所以需要改变拥有者)。

3nginx主进程会关闭重名的日志文件(也就是刚才使用mv命令重命名成xxx.log_ 20130909.log的文件),并通知工作进程使用新打开的日志文件(刚才主进程打开的文件xxx.log)。具体实现上更细化点就是,主进程把USR1信号发给workerworker接到这个信号后,会重新打开日志文件(也就是配置文件中约定的xxx.log)

 

2.2.3 cronolog实现nginx日志分钟切割,自定义nginx日志格式实现统计

说明:
应公司需求,需要将nginx访问日志按分钟切割。这里参照网上的做法,通过cronolognginx产生的访问日志实时传入到pipe中。为了便于统计,自定义nginx访问日志格式。

1.crontab编译安装

wget http://cronolog.org/download/cronolog-1.6.2.tar.gz   //此版本已经是最新的,就更新到2002

tar zxvf cronolog-1.6.2.tar.gz

cd cronolog-1.6.2./configure

make

make install
2.自定义nginx格式,,以||分隔:

vim /usr/local/webserver/nginx/conf/nginx.conf  //以下为内容

log_format  access  '$remote_addr||$remote_user||[$time_local]||"$request"'

              '||$status||$body_bytes_sent||"$http_referer"'

              '||"$http_user_agent"||$http_x_forwarded_for';//此log_format一定要放在server{}前面,http{}里面。如果是按vhosts的形式来存储,请将log_format要放在server{}前面//相应的日志位置调用日志格式,并将日志写入管道。同一地址,可填定多条access_log。

access_log  /var/log/nginx/nobody_access_min.pipe  access;

access_log  /var/log/nginx/nobody_access_hour.log  access;   //此条access_log用于比对分钟切割产生的日志,确定是否有记录损失 
3.创建日志管道

mkfifo /var/log/nginx/nobody_access_min.pipe
4.添加脚本,实现以日期创建文件夹,内含00,01…..23文件,用于存放nobody.com的access日志

vim /tmp/nginx_log_mkdir_day.sh  //以下为内容#!/bin/bash

logs_path="/var/log/nginx/"

date_dir=`date +%Y%m%d`for i in `seq -w 0 23`;do

  /bin/mkdir -p ${logs_path}${date_dir}/$i;done
5.编辑crontab,添加以下信息:实现按天建目录,按小时切割日志

crontab -e00 00 * * * /bin/bash  /tmp/nginx_log_mkdir_day.sh00 */1 * * * /bin/bash  /tmp/nginx_log_hour_cut.sh   //此条,之前做日志小时切割时已经添加。
6.运行cronolog,每当有访问数据时,将nobody_access_min.pipe中的访问数据写进nobody_access_%Y%m%d%H%M.log

nohup cat /var/log/nginx/nobody_access_min.pipe | nohup /usr/local/sbin/cronolog /var/log/nginx/%Y%m%d/%H/nobody_access_%Y%m%d%H%M.log &//管道前后是两个命令,因此当我们关闭终端时,会发现cronolog也跟着消失了。所以需要两个nohup,而不是下面的命令:

nohup cat /var/log/nginx/nobody_access_min.pipe | /usr/local/sbin/cronolog /var/log/nginx/%Y%m%d/%H/nobody_access_%Y%m%d%H%M.log &
7.启动Nginx,若nginx已启动,可以通过/usr/local/webserver/nginx/sbin/nginx -s reload来重启

/usr/local/webserver/nginx/sbin/nginx -t  //测试nginx配置是否正确/usr/local/webserver/nginx/sbin/nginx
8.设置开机启动,并指定后台执行

vim /etc/rc.local    //在末尾添加以下信息

nohup cat /var/log/nginx/nobody_access_min.pipe | nohup /usr/local/sbin/cronolog /var/log/nginx/%Y%m%d/%H/nobody_access_%Y%m%d%H%M.log &

ulimit -SHn 65535

echo 67108864 >/proc/sys/kernel/shmmax/usr/local/webserver/php/sbin/php-fpm/usr/local/webserver/ngnix/sbin/nginx/data/mysql/3306/mysqld start 
9.数据对比,确定日志记录是否有丢失

wc -l /var/log/nginx/20121112/16/nobody_access_201211121*

wc -l /var/log/nginx/20121112/16/nobody_access_hour_2012111216.log
10.重启nginx的日志进程
由于cronolog(pipe)是只有访问时,才会生成记录。因此可能需要重启nginx的日志进程,使其重新生成nobody_access_hour.log日志,便于统计。

kill -USR1 `cat /usr/local/webserver/ngnix/nginx.pid`
附录:
1. 管道必须在nginx启动前启动。如果nginx未运行,开启cronolog后(即管道),nginx –t做检测会中断管道。而cronolog不开启,nginx –t及启动全部会受影响。(可以通过strace 查看,没试过strace)

2. 如无特殊要求,还是建议按天通过常规计划任务reload nginx方法进行截断。如需按时甚至按分截断,可以考虑通过计划任务+脚本处理。

3.日志分析

我们采用的是elk,请见我的下一篇文章