前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Nginx日志配置及日志分析脚本案例

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

作者头像
菲宇
发布2019-06-12 15:21:59
2.9K0
发布2019-06-12 15:21:59
举报
文章被收录于专栏:菲宇菲宇

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

代码语言:javascript
复制
语法格式:   access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
                     access_log off;
默认值   : access_log logs/access.log combined;
作用域   : http, server, location, if in location, limit_except

实例一:

代码语言:javascript
复制
access_log /spool/logs/nginx-access.log compression buffer=32k;

log_format 定义日志格式

代码语言:javascript
复制
语法格式:   log_format name [escape=default|json] string ...;
默认值    :    log_format combined "...";
作用域    :    http

实例一:

代码语言:javascript
复制
log_format compression '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';

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:禁用缓存
代码语言:javascript
复制
语法格式:   open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
                     open_log_file_cache off;
默认值:     open_log_file_cache off;
作用域:     http, server, location

实例一

代码语言:javascript
复制
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;

nginx日志调试技巧

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

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

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

代码语言:javascript
复制
events {
        debug_connection 1.2.3.4;
}

调试 nginx rewrite 规则

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

代码语言:javascript
复制
server {
        error_log    /var/logs/nginx/example.com.error.log;
        rewrite_log on;
}

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

使用location记录指定URL的日志

代码语言:javascript
复制
server {
        error_log    /var/logs/nginx/example.com.error.log;
        location /static/ { 
        error_log /var/logs/nginx/static-error.log debug; 
    }         
}

配置以上配置后,/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格式

代码语言:javascript
复制
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"'
                       '$upstream_addr $upstream_response_time $request_time ';
access_log  logs/access.log  main;

json格式

代码语言:javascript
复制
log_format logstash_json '{"@timestamp":"$time_iso8601",'
       '"host": "$server_addr",'
       '"client": "$remote_addr",'
       '"size": $body_bytes_sent,'
       '"responsetime": $request_time,'
       '"domain": "$host",'
       '"url":"$request_uri",'
       '"referer": "$http_referer",'
       '"agent": "$http_user_agent",'
       '"status":"$status",'
       '"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代替,如无特殊业务需求,完全可以替换。

压缩格式

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

代码语言:javascript
复制
http {
    log_format compression '$remote_addr - $remote_user [$time_local] '
                           '"$request" $status $body_bytes_sent '
                           '"$http_referer" "$http_user_agent" "$gzip_ratio"';

    server {
        gzip on;
        access_log /spool/logs/nginx-access.log compression;
        ...
    }
}

upstream格式

增加upstream消耗的时间。

代码语言:javascript
复制
http {
    log_format upstream_time '$remote_addr - $remote_user [$time_local] '
                             '"$request" $status $body_bytes_sent '
                             '"$http_referer" "$http_user_agent"'
                             'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time"';

    server {
        access_log /spool/logs/nginx-access.log upstream_time;
        ...
    }
}

统计status 出现的次数

代码语言:javascript
复制
awk '{print $9}' access.log | sort | uniq -c | sort -rn

36461 200 
483 500
87 404
9 400
3 302
1 499
1 403
1 301

显示返回302状态码的URL。

代码语言:javascript
复制
awk '($9 ~ /302/)' access.log | awk '{print $7}' | sort | uniq -c | sort -rn

1 /wp-login.php
1 /wp-admin/plugins.php?action=activate&plugin=ewww-image-optimizer%2Fewww-image-optimizer.php&_wpnonce=cc4a379131
1 /wp-admin/

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

代码语言:javascript
复制
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:

代码语言:javascript
复制
awk '{print $9}' access.log | sort | uniq -c | sort -r

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

代码语言:javascript
复制
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:

代码语言:javascript
复制
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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年08月29日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • nginx access日志配置
  • 常见的日志变量
  • nginx日志调试技巧
    • 设置 Nginx 仅记录来自于你的 IP 的错误
      • 调试 nginx rewrite 规则
        • 使用location记录指定URL的日志
          • 常用例子
            • main格式
            • json格式
            • 压缩格式
            • upstream格式
          • 统计status 出现的次数
            • 按URL的请求数排序
        • 根据状态码进行请求次数排序
        • 常用分析日志的脚本
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档