1 | grep '/api/weapp/info' access.log | awk '{print $1}' | sort | uniq -c | sort -nr > result_ip.txt |
User: grep “keyword” access.log | awk ‘{print \$1}’ | sort | uniq -c | sort -nr 分析 nginx日志 有什么问题‘
Kimi: 这个命令组合在分析 Nginx 日志时看起来逻辑上是合理的,但仍然可能存在一些问题或需要注意的地方。以下是对每个部分的分析以及可能存在的问题:
命令解析
grep "keyword" access.log- 功能:从
access.log文件中筛选出包含关键字keyword的行。 - 潜在问题:
- 如果
keyword是一个正则表达式中的特殊字符(如.、*、?等),可能会导致匹配结果不符合预期。例如,grep "test*"和grep "test.*"的含义完全不同。 - 如果日志文件非常大,
grep会逐行读取文件,可能会消耗较多时间。
- 如果
- 功能:从
awk '{print \$1}'- 功能:提取每行的第一个字段(通常是客户端的 IP 地址)。
- 潜在问题:
- 如果日志格式不是标准的 Nginx 日志格式(例如自定义了日志格式),
$1可能不是 IP 地址。 - 如果日志中存在空行或格式不规范的行,可能会导致输出为空或错误。
- 如果日志格式不是标准的 Nginx 日志格式(例如自定义了日志格式),
sort- 功能:对提取的 IP 地址进行排序。
- 潜在问题:
- 如果数据量非常大,
sort会占用较多内存和时间。 - 默认情况下,
sort是按照字典顺序排序的,而不是按照数值顺序。如果需要按照数值顺序排序,需要使用-n参数。
- 如果数据量非常大,
uniq -c- 功能:统计每个 IP 地址出现的次数。
- 潜在问题:
- 如果没有先对数据进行排序(
sort),uniq -c无法正确统计重复项。因此,sort是必须的。 - 如果数据量非常大,
uniq -c也会占用较多内存和时间。
- 如果没有先对数据进行排序(
sort -nr- 功能:按照统计次数从高到低排序。
- 潜在问题:
- 如果数据量非常大,
sort -nr会占用较多内存和时间。 - 如果统计结果非常多,可能会导致输出信息过多,难以直观分析。
- 如果数据量非常大,
总体问题
性能问题:
- 如果日志文件非常大,整个命令链可能会运行缓慢,甚至可能因为内存不足而失败。
- 可以考虑使用更高效的工具(如
awk的内置排序功能)来优化性能。
日志格式问题:
- 如果 Nginx 的日志格式被修改过,
$1可能不是 IP 地址。需要确认日志格式是否为标准格式。
- 如果 Nginx 的日志格式被修改过,
关键字匹配问题:
- 如果
keyword是正则表达式的特殊字符,需要使用转义字符(\)来避免误匹配。
- 如果
输出结果问题:
- 如果统计结果非常多,可能需要进一步筛选或限制输出数量(例如使用
head命令)。
- 如果统计结果非常多,可能需要进一步筛选或限制输出数量(例如使用
改进建议
优化命令链:
可以将整个过程合并到一个
awk脚本中,减少中间过程的开销。例如:1
awk '/keyword/ {count[$1]++} END {for (ip in count) print count[ip], ip}' access.log | sort -nr
这样可以直接在
awk中完成统计和排序,避免多次调用外部命令。
处理大文件:
- 如果日志文件非常大,可以使用
split命令将日志文件分割成多个小文件,然后分别处理。
- 如果日志文件非常大,可以使用
确认日志格式:
- 确保日志格式为标准格式,或者根据实际格式调整
awk脚本中的字段提取逻辑。
- 确保日志格式为标准格式,或者根据实际格式调整
限制输出:
- 如果只需要查看前几个结果,可以在最后加上
head命令。例如:1
grep "keyword" access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 10
- 如果只需要查看前几个结果,可以在最后加上
通过这些改进,可以提高命令的效率和可靠性,同时避免一些潜在问题。
依葫芦画瓢一下:
log_format配置
log_format main ‘$remote_addr - $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘“$http_user_agent” “$http_x_forwarded_for”‘;
输出示例
117.136.31.243 - - [13/Mar/2019:14:01:55 +0800] “GET /api/common/getOrganizationsByParentId/1002 HTTP/1.1” 200 6152 “https://servicewechat.com/wx3ac9a9b999fe3552/20/page-frame.html" “Mozilla/5.0 (Linux; Android 5.1; OPPO A37m Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.121 Mobile Safari/537.36 MicroMessenger/7.0.3.1400(0x2700033B) Process/appbrand0 NetType/4G Language/zh_CN” “-“
- 常用命令
- IP相关统计
统计IP访问量
awk ‘{print $1}’ access.log | sort -n | uniq | wc -l
1
查看某一时间段的IP访问量(2019年3月14日16-17点)
grep “14/Mar/2019:1[6-7]” access.log | awk ‘{print $1}’ | sort | uniq -c| sort -nr | wc -l
1
查看访问最频繁的前100个IP
awk ‘{print $1}’ access.log | sort -n |uniq -c | sort -rn | head -n 100
1
查看访问100次以上的IP
awk ‘{print $1}’ access.log | sort -n |uniq -c |awk ‘{if($1 >100) print $0}’|sort -rn
1
查询某个IP的访问的请求列表,按请求的访问次数降序
grep ‘112.97.250.255’ access.log |awk ‘{print $7}’|sort |uniq -c |sort -rn |head -n 100
1
- 请求访问统计
查看访问最频繁的100个请求
awk ‘{print $7}’ access.log | sort |uniq -c | sort -rn | head -n 100
1
查看访问最频繁的100个请求,并排除js文件
grep -v “.php” access.log | awk ‘{print $7}’ | sort |uniq -c | sort -rn | head -n 100
1
查看访问次数超过100次的请求
cat access.log | cut -d ‘ ‘ -f 7 | sort |uniq -c | awk ‘{if ($1 > 100) print $0}’ | less
1
查看最近1000条记录,访问量最高的请求
tail -1000 access.log |awk ‘{print $7}’|sort|uniq -c|sort -nr|less
1
- 单位时间内请求量统计
按每秒统计请求数,显示top100的时间点
awk ‘{print $4}’ access.log |cut -c 14-21|sort|uniq -c|sort -nr|head -n 100
1
按每分钟统计请求数,显示top100的时间点
awk ‘{print $4}’ access.log |cut -c 14-18|sort|uniq -c|sort -nr|head -n 100
1
按每小时统计请求数,显示top100的时间点
awk ‘{print $4}’ access.log |cut -c 14-15|sort|uniq -c|sort -nr|head -n 100
1
- 性能分析
在nginx.conf log_format中最后一个字段加入$request_time
列出传输时间超过 3 秒的页面,显示前20条
cat access.log|awk ‘($NF > 3){print $7}’|sort -n|uniq -c|sort -nr|head -20
1
列出php页面请求时间超过3秒的页面,并统计其出现的次数,显示前100条
cat access.log|awk ‘($NF > 1 && $7~/.php/){print $7}’|sort -n|uniq -c|sort -nr|head -100