最近因为爬虫程序太多,想要为Python爬虫设计一个监控程序,主要功能包括一下几种:
1、监控爬虫的运行状态(是否在运行、运行时间等)
2、监控爬虫的性能(如请求频率、响应时间、错误率等)
3、资源使用情况(CPU、内存、网络等)
4、异常捕获与告警(当爬虫出现异常时能够及时通知)
要为Python爬虫创建一个监控程序,根据上面思路我们可以按照以下步骤实现,涵盖运行状态、性能指标、异常告警和可视化:
import time
import logging
import psutil
from prometheus_client import start_http_server, Counter, Gauge, Histogram
class SpiderMonitor:
def __init__(self, spider_name):
self.spider_name = spider_name
self.start_time = time.time()
# 初始化监控指标
self.requests_total = Counter(f'{spider_name}_requests_total', 'Total requests')
self.requests_failed = Counter(f'{spider_name}_requests_failed', 'Failed requests')
self.items_scraped = Counter(f'{spider_name}_items_scraped', 'Items scraped')
self.memory_usage = Gauge(f'{spider_name}_memory_usage', 'Memory usage (MB)')
self.request_latency = Histogram(f'{spider_name}_request_latency', 'Request latency (seconds)')
# 启动指标服务器
start_http_server(8000)
logging.basicConfig(filename=f'{spider_name}.log', level=logging.INFO)
def record_request(self, success=True, latency=0):
self.requests_total.inc()
if not success:
self.requests_failed.inc()
if latency > 0:
self.request_latency.observe(latency)
def record_item(self, count=1):
self.items_scraped.inc(count)
def update_resources(self):
process = psutil.Process()
self.memory_usage.set(process.memory_info().rss / 1024 / 1024) # MB
def log_error(self, error):
logging.error(f"[{time.ctime()}] ERROR: {error}")
def uptime(self):
return time.time() - self.start_timeimport requests
from monitor import SpiderMonitor
class MySpider:
def __init__(self):
self.monitor = SpiderMonitor("my_spider")
self.session = requests.Session()
def crawl(self, url):
start = time.time()
try:
response = self.session.get(url, timeout=10)
response.raise_for_status()
# 处理数据
items = self.parse(response)
self.monitor.record_item(len(items))
self.monitor.record_request(success=True, latency=time.time()-start)
return items
except Exception as e:
self.monitor.record_request(success=False)
self.monitor.log_error(f"URL: {url} - Error: {str(e)}")
return []
def parse(self, response):
# 解析逻辑
return [{"data": "sample"}]
def run(self):
while True:
self.crawl("https://example.com/data")
self.monitor.update_resources()
time.sleep(5)
if __name__ == "__main__":
spider = MySpider()
spider.run()import time
import subprocess
import smtplib
from email.mime.text import MIMEText
def check_heartbeat(spider_name):
"""检查最近15分钟是否有活动日志"""
try:
with open(f"{spider_name}.log") as f:
logs = f.readlines()[-100:]
return any(time.time() - get_log_time(line) < 900 for line in logs)
except FileNotFoundError:
return False
def get_log_time(log_line):
# 从日志行提取时间戳
timestamp_str = log_line.split("]")[0][1:]
return time.mktime(time.strptime(timestamp_str))
def send_alert(subject, message):
"""发送邮件告警"""
msg = MIMEText(message)
msg['Subject'] = f"[SPIDER ALERT] {subject}"
msg['From'] = 'monitor@example.com'
msg['To'] = 'admin@example.com'
with smtplib.SMTP('smtp.example.com') as server:
server.send_message(msg)
def monitor_daemon():
spider_name = "my_spider"
consecutive_failures = 0
while True:
if not check_heartbeat(spider_name):
consecutive_failures += 1
if consecutive_failures >= 3:
send_alert("Spider Down",
f"{spider_name} has been inactive for 45+ minutes")
else:
consecutive_failures = 0
time.sleep(300) # 每5分钟检查一次
if __name__ == "__main__":
monitor_daemon()[program:my_spider] command=python /path/to/my_spider.py autostart=true autorestart=true stderr_logfile=/var/log/spider.err.log
import redis r = redis.Redis() r.incr('global_requests_count')
这种监控方案提供实时性能跟踪、自动告警和可视化展示,能有效提升爬虫的稳定性和可维护性。最终我们可根据实际需求调整监控粒度和告警阈值。如有任何疑问可以留言讨论。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。