从零搭建日志分析与监控体系
📚 目录导读
统计接口调用频次的核心价值
你是否遇到过:线上服务突然变慢,却不知道哪个接口被疯狂调用?老板问“这个API每天有多少请求”,你只能靠瞎猜?

接口频次统计是运维和开发人员的必备技能,它能帮助:
- 性能调优:识别高频调用接口,提前优化瓶颈
- 故障定位:发现异常突增(如爬虫攻击、死循环请求)
- 容量规划:根据调用量合理分配服务器资源
常见实现方案对比
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 访问日志分析 | 所有Web服务 | 无侵入,生效快 | 依赖日志采集 |
| 应用代码埋点 | 自研系统 | 数据精确 | 需修改代码 |
| 中间件拦截 | API网关、Nginx | 统一管理 | 需部署组件 |
| 数据库计数器 | 低频场景 | 简单粗暴 | 高并发有瓶颈 |
推荐组合:日志分析 + 预聚合(如Redis计数)是最实用的“黄金搭档”。
实战:Python脚本统计API频次
假设你有Nginx访问日志(如:/var/log/nginx/access.log),每行格式:
168.1.1 - - [10/Feb/2025:12:00:01 +0800] "POST /api/order HTTP/1.1" 200 1234
1 基础统计脚本
import re
from collections import Counter
def parse_log(file_path):
"""提取API路径并统计频次"""
pattern = r'"\w+ (/[/\w-]+) HTTP' # 匹配请求路径
api_counter = Counter()
with open(file_path, 'r') as f:
for line in f:
match = re.search(pattern, line)
if match:
api = match.group(1)
api_counter[api] += 1
return api_counter
if __name__ == "__main__":
result = parse_log("access.log")
for api, count in result.most_common(20):
print(f"{api}: {count} 次")
输出示例:
/api/order: 15832 次
/api/user/info: 10921 次
/api/payment/callback: 234 次
2 带时间窗口的统计
from datetime import datetime, timedelta
import re
def count_by_hour(log_file, target_date):
"""统计某天每小时的调用量"""
hourly_count = {i:0 for i in range(24)}
date_pattern = target_date.strftime("%d/%b/%Y")
with open(log_file, 'r') as f:
for line in f:
if date_pattern not in line:
continue
# 提取小时信息
hour_match = re.search(r':(\d{2}):', line)
if hour_match:
hour = int(hour_match.group(1))
hourly_count[hour] += 1
return hourly_count
# 使用示例
from datetime import date
today = date.today()
result = count_by_hour("access.log", today)
for hour, count in result.items():
print(f"{hour}:00 - {count}")
Shell脚本快速统计方案
无需编程环境?一行Shell搞定:
# 统计Top 10接口
grep -oP '"\w+ /\K[^"]+' access.log | sort | uniq -c | sort -rn | head -10
# 按分钟统计请求量
awk '{print $4}' access.log | cut -d: -f1-2 | sort | uniq -c | sort -rn
关键参数解析:
-oP:使用Perl兼容正则,仅输出匹配部分\K:重置匹配起点,只保留API路径uniq -c:去重并计数
实时监控与告警集成
1 对接Prometheus
# prometheus_client 示例
from prometheus_client import Counter, start_http_server
import time
REQUEST_COUNT = Counter('api_requests_total', 'Total API requests', ['method', 'endpoint'])
def process_request(method, endpoint):
REQUEST_COUNT.labels(method=method, endpoint=endpoint).inc()
# 启动指标暴露端
start_http_server(8000)
while True:
time.sleep(1)
2 阈值告警(基于Python)
ALERT_THRESHOLD = 1000 # 每分钟超过1000次触发
def check_alert(api, current_count):
if current_count > ALERT_THRESHOLD:
send_alert(f"API {api} 调用频次异常:{current_count}/min")
# 可联动:调用限流API、触发自动扩容
FAQ:常见问题与解决方案
❓ Q1:日志文件太大(10GB+),脚本处理太慢怎么办?
A:推荐以下策略:
- 行级处理:使用
awk、sed替代Python(纯C实现,快10倍) - 分片读取:
for i in split -l 500000 access.log; do python count.py $i ; done - 流式处理:使用
tail -F配合缓冲,实时消费新日志
❓ Q2:如何区分正常流量和爬虫攻击?
A:在统计中加入IP维度:
# 统计每个IP的调用频次
ip_counter = Counter()
ip_api_pair = {} # 记录IP调用的API列表
# 如果同一IP每秒请求超过50次→标记为异常
❓ Q3:统计结果和实际流量有差异?
A:常见原因:
- 日志轮转导致重复统计 → 使用
inotify监控日志新建事件 - 负载均衡器日志和业务日志混杂 → 增加服务标识字段(如
X-Request-ID)
❓ Q4:需要统计第三方API的调用频次?
A:可通过代理拦截(如Nginx反向代理)或DNS劫持统一记录:
http {
log_format extended '$remote_addr - $upstream_response_time "$request"';
server {
location / {
proxy_pass http://third_party_service;
access_log /var/log/third_api.log extended;
}
}
}
📌 总结与最佳实践
通过脚本统计接口调用频次,无需昂贵APM工具,也能实现精准监控,建议遵循:
- 日志先行:确保Nginx/应用日志包含完整请求信息
- 分级统计:秒级用Redis,小时级用日志分析,天级用离线任务
- 自动化:将脚本做成crontab任务,结果写入时序数据库
立即行动:复制上面的Python脚本,在测试环境运行5分钟,你就能看到线上最真实的接口调用图谱。
(本文技术验证环境:Python 3.9 + Ubuntu 20.04 + Nginx 1.18)