当前位置: 首页 > 工具软件 > ngxtop > 使用案例 >

使用ngxtop统计nginx请求

沃宇
2023-12-01
 
简介
ngxtop 类似于 top,用于短时间的实时监测 nginx server 的运行状态,做 trouble shooting。
如果需要长时间运行并且存储统计(webserver stats)以供外部系统使用,可以尝试 Luameter  https://luameter.com/
 
修复了bug的  https://github.com/yangchaobj/ngxtop.git,下文会有详述。
 
ngxin 原理
ngxtop 将 nginx 的 log 逐行读出,每一行逐个字段解析,并将结果插入 sqlite 数据库。
读完 log 文件后,使用 sql 语句查询数据,得到统计结果。
 
主要功能
分为 follow 和 no-follow 两种模式。
follow 只分析脚本执行时刻以后到来的 nginx log,进程等在那里不退出,实时统计。
no-follow 值分析文件里有的 log,对脚本执行后到来的 log 不统计。
 
常用的功能: 
1. 统计访问次数最多的请求
     ngxtop -l access_15.log --no-follow
2. 自定义排序的字段:
     按照 avg_bytes_sent 排序:
     ngxtop -l access_14.log --no-follow -o avg_bytes_sent
 
3. 列出前 n 个,默认是10个:
     ngxtop -l access_14.log --no-follow -n 15
 
4. 自定义过滤条件
     只统计成功的请求
     ngxtop -l access_14.log --no-follow -i 'status==200'
 
     只统计出错的请求
     ngxtop -l access_14.log --no-follow -i 'status==200'
 
     搜索客户端为 iPhone 的 log
     ngxtop -l access_14.log --no-follow -i 'http_user_agent.find('iPhone')'
     条件里是可以嵌 python 语句的,这些语句被 eval() 动态翻译并执行。需要注意的是这些语句如果抛出异常会导致 ngxtop 异常退出。
     
5. 分组过滤
     ngxtop 的处理原理是将所有的 log 解析后存入 sqlite,然后使用 sql 查询想要的结果。
     所以理论上 sql 能支持的查询,ngxtop 都能支持。
     -g 相当于 group by, -a 相当于 having。
     ngxtop 已经默认提供了 avg_bytes_sent, 2xx, 3xx, 4xx, 5xx 这些聚合字段,一般这些字段已经足够了。
     如果业务复杂了,想做出更多的查询,可以利用这两个参数自己组合条件。
 
     查看访问量最大的用户ip
     ngxtop -g remote_addr
 
安装
pip install ngxtop
安装后的执行脚本位于 /usr/local/bin/ngxtop
本身是一个 Python脚本,只是一个启动的入口:
     from ngxtop.ngxtop import main
 
主要逻辑都在 ngxtop 库里,文件位于:
     /usr/local/lib/python2.7/site-packages/ngxtop
 
 
遇到的问题
1. python2.7 缺乏 _sqlite3 库。
在开发机上运行 ngxtop 会报 ImportError: No module named _sqlite3
原因是没有 python2.7 对应的 _sqlite3.so
对于开发机31上的 python2.6 则有对应的库:
     /usr/lib64/python2.6/lib-dynload/_sqlite3.so
解决思路是编译 python 2.7,把这个 _sqlite3.so 拷过去
进入开发机 /data/install/Python-2.7.6/
     ./configure
     make
编译完成后找到编译好的 _sqlite3.so
     find . -name _sqlite3.so
显示文件位置 ./build/lib.linux-x86_64-2.7/_sqlite3.so,这就是我们要的文件。
将 _sqlite3.so 拷贝到 /usr/lib64/python2.7/lib-dynload/ 目录下:
     sudo cp /data/install/Python-2.7.6/build/lib.linux-x86_64-2.7/_sqlite3.so ./
 
执行 python,进入交互模式,输入:
     import sqlite3
没有提示异常,说明成功。
 
2. 运行 ngxtop 没有统计值
在虚机上测试 ngxtop 是没有问题的,对比虚机的 ngxlog 的格式,发现开发机的 ngxlog 多了一些属性。
将开发机的 ngxlog tail 出1行存为一 t.log,只保留到 $user_agent,后面多出的属性删掉。
用 t.log 测试 ngxtop,可以显示出统计值,测试通过。
 
通过调试发现,如果字段增多,ngxtop 的匹配是有问题的,匹配的正则式 pattern 如下:
(?P<remote_addr>.*) - (?P<remote_user>.*) \[(?P<time_local>.*)\] "(?P<request>.*)" (?P<status>.*) (?P<body_bytes_sent>.*) "(?P<http_referer>.*)" "(?P<http_user_agent>.*)"
要匹配的 ngxlog 如下:
10.18.110.79 - - [31/Mar/2016:14:19:00 +0800] "GET /favicon.ico HTTP/1.1" 200 1406 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0" "-" "yangchao-g.jifen.360.cn" "80" 0.000
匹配的结果:
{
     'remote_addr': '10.18.110.79',
     'remote_user': '-',
     'time_local': '31/Mar/2016:14:19:00 +0800',
     'request': 'GET /favicon.ico HTTP/1.1" 200 1406 "-',
     'status': '"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0"',
     'body_bytes_sent': '"-"',
     'http_referer': 'yangchao-g.jifen.360.cn',
     'http_user_agent': '80',
}
匹配过程如下:
{remote_add:10.18.110.79} - {remote_user:-} [{time_local:31/Mar/2016:14:19:00 +0800}] "{request:GET /favicon.ico HTTP/1.1" 200 1406 "-}" "{status:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0}" "{body_bytes_sent:-}" "{http_referer:yangchao-g.jifen.360.cn}" "{http_user_agent:80}" 0.000
 
很明显,request 多匹配的内容,应该加入非贪婪的标记,让匹配以最小的方式进行。
匹配的正则式是在 config_parser.py 中的 build_pattern() 函数中生成的。
关键的一句:
     pattern = re.sub(REGEX_LOG_FORMAT_VARIABLE, '(?P<\\1>.*)', pattern)
这里的匹配用的是 .*,是贪婪匹配,我们要做的是用非贪婪模式匹配:
     pattern = re.sub(REGEX_LOG_FORMAT_VARIABLE, '(?P<\\1>.* ?)', pattern)
 
再测试,匹配结果如下:
{
     'remote_addr': '10.18.110.79',
     'remote_user': '-',
     'time_local': '31/Mar/2016:14:19:00 +0800',
     'request': 'GET /favicon.ico HTTP/1.1',
     'status': '200',
     'body_bytes_sent': '1406',
     'http_referer': '-',
      'http_user_agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0',
}
 
已经是正确的结果了。
去掉所有的 pprint 调试语句,重新统计ngxlog,统计的结果如下:
~$ ngxtop -l ngxlog.log --no-follow
running for 0 seconds, 5 records processed: 12101.28 req/sec
 
Summary:
|   count |   avg_bytes_sent |   2xx |   3xx |   4xx |   5xx |
|---------+------------------+-------+-------+-------+-------|
|       5 |         4901.800 |     5 |     0 |     0 |     0 |
 
Detailed:
| request_path                       |   count |   avg_bytes_sent |   2xx |   3xx |   4xx |   5xx |
|------------------------------------+---------+------------------+-------+-------+-------+-------|
| /                                  |       1 |        19469.000 |     1 |     0 |     0 |     0 |
| /favicon.ico                       |       1 |         1406.000 |     1 |     0 |     0 |     0 |
| /theme/index/lottery/css/style.css |       1 |         1883.000 |     1 |     0 |     0 |     0 |
| /theme/v3/css/conf/360_head.css    |       1 |          763.000 |     1 |     0 |     0 |     0 |
| /theme/v3/css/conf/mall.css        |       1 |          988.000 |     1 |     0 |     0 |     0 |
 
 
已经提交了 pull-request:  https://github.com/lebinh/ngxtop/pull/62
修复的 git repro 位于  https://github.com/yangchaobj/ngxtop.git
 
 
 
 
 

转载于:https://www.cnblogs.com/yangchaobj/p/5342340.html

 类似资料: