Nginx日志配置及日志分析脚本案例

时间:2022-10-05 02:10:04

https://blog.csdn.net/bbwangj/article/details/82186162

nginx的log日志分为access log 和 error log

其中access log 记录了哪些用户,哪些页面以及用户浏览器、ip和其他的访问信息

error log 则是记录服务器错误日志

错误日志的形式如下:

201.158.69.116 - - [03/Jan/2013:21:17:20 -0600] fwf[-] tip[-] 127.0.0.1:9000 0.007 0.007 MX pythontab.com GET /html/test.html HTTP/1.1 "200" 2426 "http://a.com" "es-ES,es;q=0.8" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11"

187.171.69.177 - - [03/Jan/2013:21:17:20 -0600] fwf[-] tip[-] 127.0.0.1:9000 0.006 0.006 MX pythontab.com GET /html/test2.html HTTP/1.1 "200" 2426 "http://a.com" "es-ES,es;q=0.8" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11"

从上面我们可以看出几部分信息:

1.客户端(用户)IP地址。如:上例中的 201.158.69.116

2.访问时间。如:上例中的 [03/Jan/2013:21:17:20 -0600]

3.访问端口。如:上例中的 127.0.0.1:9000

4.响应时间。如:上例中的 0.007

5.请求时间。如:上例中的 0.007

6.用户地理位置代码(国家代码)。如:上例中的 MX(墨西哥)

7.请求的url地址(目标url地址)的host。如:上例中的 pythontab.com

8.请求方式(GET或者POST等)。如:上例中的 GET

9.请求url地址(去除host部分)。如:上例中的 /html/test.html

10.请求状态(状态码,200表示成功,404表示页面不存在,301表示永久重定向等,具体状态码可以在网上找相关文章,不再赘述)。如:上例中的 "200"

11.请求页面大小,默认为B(byte)。如:上例中的 2426

12.来源页面,即从哪个页面转到本页,专业名称叫做“referer”。如:上例中的 "http://a.com"

13.用户浏览器语言。如:上例中的 "es-ES,es;q=0.8"

14.用户浏览器其他信息,浏览器版本、浏览器类型等。如:上例中的  "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11"

其实nginx access日志的格式不是一成不变的,是可以自定义的。

在nginx的nginx.conf配置文件找到:log_format 这里就是日志的格式

看一下和上述日志匹配的log格式设置:

#access日志格式配置,具体参数不再细说,上面都已经说过了,自己对应一下即可

log_format main '$remote_addr - $remote_user [$time_local] '

'fwf[$http_x_forwarded_for] tip[$http_true_client_ip] '

'$upstream_addr $upstream_response_time $request_time '

'$geoip_country_code '

'$http_host $request '

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

'"$http_accept_language" "$http_user_agent" ';

#配置access log日志的存储位置及文件,注意:access.log文件是可以按日期进行分割的,方便查看及处理

access_log  /home/serversoft/nginx/log/access.log  main;

nginx access日志配置

access_log日志配置

access_log用来定义日志级别,日志位置。语法如下:
日志级别: debug > info > notice > warn > error > crit > alert > emerg

  1.  语法格式: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
  2.  access_log off;
  3.  默认值 : access_log logs/access.log combined;
  4.  作用域 : http, server, location, if in location, limit_except

实例一:

access_log /spool/logs/nginx-access.log compression buffer=32k;

log_format 定义日志格式

  1.  语法格式: log_format name [escape=default|json] string ...;
  2.  默认值 : log_format combined "...";
  3.  作用域 : http

实例一:

  1.  log_format compression '$remote_addr - $remote_user [$time_local] '
  2.  '"$request" $status $bytes_sent '
  3.  '"$http_referer" "$http_user_agent" "$gzip_ratio"';
  4.   
  5.  access_log /spool/logs/nginx-access.log compression buffer=32k;

常见的日志变量

  • $remote_addr$http_x_forwarded_for 记录客户端IP地址
  • $remote_user记录客户端用户名称
  • $request记录请求的URL和HTTP协议(GET,POST,DEL,等)
  • $status记录请求状态
  • $body_bytes_sent发送给客户端的字节数,不包括响应头的大小; 该变量与Apache模块mod_log_config里的“%B”参数兼容。
  • $bytes_sent发送给客户端的总字节数。
  • $connection连接的序列号。
  • $connection_requests 当前通过一个连接获得的请求数量。
  • $msec 日志写入时间。单位为秒,精度是毫秒。
  • $pipe如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.”。
  • $http_referer 记录从哪个页面链接访问过来的
  • $http_user_agent记录客户端浏览器相关信息
  • $request_length请求的长度(包括请求行,请求头和请求正文)。
  • $request_time 请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
  • $time_iso8601 ISO8601标准格式下的本地时间。
  • $time_local通用日志格式下的本地时间。

open_log_file_cache

使用open_log_file_cache来设置日志文件缓存(默认是off)。

  • max:设置缓存中的最大文件描述符数量,如果缓存被占满,采用LRU算法将描述符关闭。
  • inactive:设置存活时间,默认是10s
  • min_uses:设置在inactive时间段内,日志文件最少使用多少次后,该日志文件描述符记入缓存中,默认是1次
  • valid:设置检查频率,默认60s
  • off:禁用缓存
  1.  语法格式: open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
  2.  open_log_file_cache off;
  3.  默认值: open_log_file_cache off;
  4.  作用域: http, server, location

实例一

open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;

nginx日志调试技巧

设置 Nginx 仅记录来自于你的 IP 的错误

当你设置日志级别成 debug,如果你在调试一个在线的高流量网站的话,你的错误日志可能会记录每个请求的很多消息,这样会变得毫无意义。

events{...}中配置如下内容,可以使 Nginx 记录仅仅来自于你的 IP 的错误日志。

  1.  events {
  2.  debug_connection 1.2.3.4;
  3.  }

调试 nginx rewrite 规则

调试rewrite规则时,如果规则写错只会看见一个404页面,可以在配置文件中开启nginx rewrite日志,进行调试。

  1.  server {
  2.  error_log /var/logs/nginx/example.com.error.log;
  3.  rewrite_log on;
  4.  }

rewrite_log on; 开启后,它将发送所有的 rewrite 相关的日志信息到 error_log 文件中,使用 [notice] 级别。随后就可以在error_log 查看rewrite信息了。

使用location记录指定URL的日志

  1.  server {
  2.  error_log /var/logs/nginx/example.com.error.log;
  3.  location /static/ {
  4.  error_log /var/logs/nginx/static-error.log debug;
  5.  }
  6.  }

配置以上配置后,/static/ 相关的日志会被单独记录在static-error.log文件中。

nginx日志共三个参数
access_log: 定义日志的路径及格式。
log_format: 定义日志的模板。
open_log_file_cache: 定义日志文件缓存。

proxy_set_header X-Forwarded-For :如果后端Web服务器上的程序需要获取用户IP,从该Header头获取。proxy_set_header X-Forwarded-For $remote_addr;

常用例子

main格式

  1.  log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  2.  '$status $body_bytes_sent "$http_referer" '
  3.  '"$http_user_agent" "$http_x_forwarded_for"'
  4.  '$upstream_addr $upstream_response_time $request_time ';
  5.  access_log logs/access.log main;

json格式

  1.  log_format logstash_json '{"@timestamp":"$time_iso8601",'
  2.  '"host": "$server_addr",'
  3.  '"client": "$remote_addr",'
  4.  '"size": $body_bytes_sent,'
  5.  '"responsetime": $request_time,'
  6.  '"domain": "$host",'
  7.  '"url":"$request_uri",'
  8.  '"referer": "$http_referer",'
  9.  '"agent": "$http_user_agent",'
  10.  '"status":"$status",'
  11.  '"x_forwarded_for":"$http_x_forwarded_for"}';

解释:
$uri请求中的当前URI(不带请求参数,参数位于$args),不同于浏览器传递的$request_uri的值,它可以通过内部重定向,或者使用index指令进行修改。不包括协议和主机名,例如/foo/bar.html。
$request_uri 这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看$uri更改或重写URI。
也就是说:$request_uri是原始请求URL,$uri则是经过nginx处理请求后剔除参数的URL,所以会将汉字表现为union。
坑点:
使用$uri 可以在nginx对URL进行更改或重写,但是用于日志输出可以使用$request_uri代替,如无特殊业务需求,完全可以替换。

压缩格式

日志中增加了压缩的信息。

  1.  http {
  2.  log_format compression '$remote_addr - $remote_user [$time_local] '
  3.  '"$request" $status $body_bytes_sent '
  4.  '"$http_referer" "$http_user_agent" "$gzip_ratio"';
  5.   
  6.  server {
  7.  gzip on;
  8.  access_log /spool/logs/nginx-access.log compression;
  9.  ...
  10.  }
  11.  }

upstream格式

增加upstream消耗的时间。

  1.  http {
  2.  log_format upstream_time '$remote_addr - $remote_user [$time_local] '
  3.  '"$request" $status $body_bytes_sent '
  4.  '"$http_referer" "$http_user_agent"'
  5.  'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time"';
  6.   
  7.  server {
  8.  access_log /spool/logs/nginx-access.log upstream_time;
  9.  ...
  10.  }
  11.  }

统计status 出现的次数

  1.  awk '{print $9}' access.log | sort | uniq -c | sort -rn
  2.   
  3.  36461 200
  4.  483 500
  5.  87 404
  6.  9 400
  7.  3 302
  8.  1 499
  9.  1 403
  10.  1 301

显示返回302状态码的URL。

  1.  awk '($9 ~ /302/)' access.log | awk '{print $7}' | sort | uniq -c | sort -rn
  2.   
  3.  1 /wp-login.php
  4.  1 /wp-admin/plugins.php?action=activate&plugin=ewww-image-optimizer%2Fewww-image-optimizer.php&_wpnonce=cc4a379131
  5.  1 /wp-admin/

根据状态码进行请求次数排序

cat access.log | cut -d '"' -f3 | cut -d ' ' -f2 | sort | uniq -c | sort -r

输出样例:

  1. 210433 200

  2. 38587 302

  3. 17571 304

  4. 4544 502

  5. 2616 499

  6. 1144 500

  7. 706 404

  8. 355 504

  9. 355 301

  10. 252 000

  11. 9 403

  12. 6 206

  13. 2 408

  14. 2 400

或者使用awk:

awk '{print $9}' access.log | sort | uniq -c | sort -r

上例显示有704次404请求,接下来是如何找到这些请求的URL

awk '($9 ~ /404/)' access.log | awk '{print $7}' | sort | uniq -c | sort -r

输出样列:

  1. 21 /members/katrinakp/activity/2338/

  2. 19 /blogger-to-wordpress/robots.txt

  3. 14 /rtpanel/robots.txt

接下来考虑如果找到这些请求的IP地址,使用命令:

  1. awk -F\" '($2 ~ "/wp-admin/install.php"){print $1}' access.log | awk '{print $1}' | sort | uniq -c | sort -r

输出样例:

  1. 14 50.133.11.248

  2. 12 97.106.26.244

  3. 11 108.247.254.37

  4. 10 173.22.165.123

php后缀的404请求(通常是嗅探)

  1. awk '($9 ~ /404/)' access.log | awk -F\" '($2 ~ "^GET .*\.php")' | awk '{print $7}' | sort | uniq -c | sort -r | head -n 20

按URL的请求数排序

  1. awk -F\" '{print $2}' access.log | awk '{print $2}' | sort | uniq -c | sort -r

url包含XYZ:

awk -F\" '($2 ~ "ref"){print $2}' access.log | awk '{print $2}' | sort | uniq -c | sort -r

常用分析日志的脚本

1,查看nginx进程:
ps aux | grep nginx | grep -v grep | wc -l
2,查看80端口的tcp连接:
netstat -tan | grep "ESTABLISHED" | grep ":80" | wc -l
3,通过日志查看当天ip连接数,过滤重复:
cat access_log | grep "20/Oct/2008" | awk '{print $2}' | sort | uniq -c | sort -nr
4,当天ip连接数最高的ip都在干些什么(原来是蜘蛛):
cat access_log | grep "20/Oct/2008:00" | grep "122.102.7.212" | awk '{print $8}' | sort | uniq -c | sort -nr | head -n 10
5,当天访问页面排前10的url:
cat access_log | grep "20/Oct/2008:00" | awk '{print $8}' | sort | uniq -c | sort -nr | head -n 10
6,用tcpdump嗅探80端口的访问看看谁最高
tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr
<pre>
接着从日志里查看该ip在干嘛:
<pre lang="php">
cat access_log | grep 122.102.7.212| awk '{print $1"\t"$8}' | sort | uniq -c | sort -nr | less
7,查看某一时间段的ip连接数:
grep "2006:0[7-8]" www20060723.log | awk '{print $2}' | sort | uniq -c| sort -nr | wc -l
8,通过日志查看当天ip连接数,过滤重复
cat access.log | grep "20/Mar/2011" | awk '{print $3}' | sort | uniq -c | sort -nr,

9,当天访问页面排前10的url:
cat access.log | grep "20/Mar/2011" | awk '{print $8}' | sort | uniq -c | sort -nr | head -n 10

10,找出访问次数最多的10个IP
awk '{print $3}' access.log |sort |uniq -c|sort -nr|head,

11,找出某天访问次数最多的10个IP

cat /tmp/access.log | grep "20/Mar/2011" |awk '{print $3}'|sort |uniq -c|sort -nr|head,

12,当天ip连接数最高的ip都在干些什么:
cat access.log | grep "10.0.21.17" | awk '{print $8}' | sort | uniq -c | sort -nr | head -n 10
13,找出访问次数最多的几个分钟
 awk '{print $1}' access.log | grep "20/Mar/2011" |cut -c 14-18|sort|uniq -c|sort -nr|head