nginx日志分析之awk命令

grep “/api/mpAppidQuery/“ access.log | awk ‘{print $1}’ | sort | uniq -c | sort -nr > result_ip.txt

grep “115.62.245.169” access.log | awk ‘{print $12}’ | sort | uniq -c | sort -nr > result_ua.txt

User: grep “keyword” access.log | awk ‘{print \$1}’ | sort | uniq -c | sort -nr 分析 nginx日志 有什么问题‘
Kimi: 这个命令组合在分析 Nginx 日志时看起来逻辑上是合理的,但仍然可能存在一些问题或需要注意的地方。以下是对每个部分的分析以及可能存在的问题:

命令解析

  1. grep "keyword" access.log

    • 功能:从 access.log 文件中筛选出包含关键字 keyword 的行。
    • 潜在问题
      • 如果 keyword 是一个正则表达式中的特殊字符(如 .*? 等),可能会导致匹配结果不符合预期。例如,grep "test*"grep "test.*" 的含义完全不同。
      • 如果日志文件非常大,grep 会逐行读取文件,可能会消耗较多时间。
  2. awk '{print \$1}'

    • 功能:提取每行的第一个字段(通常是客户端的 IP 地址)。
    • 潜在问题
      • 如果日志格式不是标准的 Nginx 日志格式(例如自定义了日志格式),$1 可能不是 IP 地址。
      • 如果日志中存在空行或格式不规范的行,可能会导致输出为空或错误。
  3. sort

    • 功能:对提取的 IP 地址进行排序。
    • 潜在问题
      • 如果数据量非常大,sort 会占用较多内存和时间。
      • 默认情况下,sort 是按照字典顺序排序的,而不是按照数值顺序。如果需要按照数值顺序排序,需要使用 -n 参数。
  4. uniq -c

    • 功能:统计每个 IP 地址出现的次数。
    • 潜在问题
      • 如果没有先对数据进行排序(sort),uniq -c 无法正确统计重复项。因此,sort 是必须的。
      • 如果数据量非常大,uniq -c 也会占用较多内存和时间。
  5. sort -nr

    • 功能:按照统计次数从高到低排序。
    • 潜在问题
      • 如果数据量非常大,sort -nr 会占用较多内存和时间。
      • 如果统计结果非常多,可能会导致输出信息过多,难以直观分析。

总体问题

  1. 性能问题

    • 如果日志文件非常大,整个命令链可能会运行缓慢,甚至可能因为内存不足而失败。
    • 可以考虑使用更高效的工具(如 awk 的内置排序功能)来优化性能。
  2. 日志格式问题

    • 如果 Nginx 的日志格式被修改过,$1 可能不是 IP 地址。需要确认日志格式是否为标准格式。
  3. 关键字匹配问题

    • 如果 keyword 是正则表达式的特殊字符,需要使用转义字符(\)来避免误匹配。
  4. 输出结果问题

    • 如果统计结果非常多,可能需要进一步筛选或限制输出数量(例如使用 head 命令)。

改进建议

  1. 优化命令链

    • 可以将整个过程合并到一个 awk 脚本中,减少中间过程的开销。例如:

      1
      awk '/keyword/ {count[$1]++} END {for (ip in count) print count[ip], ip}' access.log | sort -nr

      这样可以直接在 awk 中完成统计和排序,避免多次调用外部命令。

  2. 处理大文件

    • 如果日志文件非常大,可以使用 split 命令将日志文件分割成多个小文件,然后分别处理。
  3. 确认日志格式

    • 确保日志格式为标准格式,或者根据实际格式调整 awk 脚本中的字段提取逻辑。
  4. 限制输出

    • 如果只需要查看前几个结果,可以在最后加上 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” “-“

  1. 常用命令
  2. 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

  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

  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

  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

分享到:

评论完整模式加载中...如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理