处理 Nginx 日志通常用 Shell / Python / Awk 脚本就能搞定,具体取决于你想做什么(统计、切割、分析、清洗等)。下面我按常见场景给你一套实用方案。
默认 access.log 一般是:
192.168.1.1 - - [10/Oct/2024:12:00:01 +0800] "GET /index.html HTTP/1.1" 200 1234 "-" "Mozilla/5.0"
如果是 json 日志(推荐),处理会更简单。
Shell 脚本(logrotate 或手动)
#!/bin/bash
LOG_PATH=/var/log/nginx/access.log
DATE=$(date -d "yesterday" +%Y-%m-%d)
mv $LOG_PATH /var/log/nginx/access.$DATE.log
nginx -s reopen
✅ 建议配合 logrotate:
/var/log/nginx/*.log {
daily
rotate 30
missingok
notifempty
sharedscripts
postrotate
nginx -s reopen
endscript
}
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head
awk '{print $9}' access.log | sort | uniq -c | sort -nr
awk -F'"' '{print $2}' access.log | awk '{print $2}' | sort | uniq -c | sort -nr | head
awk '$4 >= "[10/Oct/2024:12:00:00" && $4 <= "[10/Oct/2024:13:00:00"' access.log
from collections import Counter
ip_counter = Counter()
status_counter = Counter()
with open("access.log") as f:
for line in f:
parts = line.split()
if len(parts) < 9:
continue
ip = parts[0]
status = parts[8]
ip_counter[ip] += 1
status_counter[status] += 1
print("TOP IP:")
for ip, count in ip_counter.most_common(5):
print(ip, count)
print("STATUS:")
print(status_counter)
Nginx 配置:
log_format json escape=json '{"time":"$time_local","ip":"$remote_addr","status":$status,"uri":"$request_uri"}';
Python 处理:
import json
with open("access.log") as f:
for line in f:
log = json.loads(line)
print(log["ip"], log["status"])
tail -f access.log | awk '{print $1}' | uniq -c
或用 GoAccess:
goaccess access.log -o report.html --log-format=COMBINED
如果你能告诉我:
我可以直接帮你写完整可用脚本。