metrics.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. """
  2. Prometheus metrics 导出(可选功能)
  3. 需要安装:pip install prometheus-client
  4. """
  5. from pathlib import Path
  6. import pandas as pd
  7. import logging
  8. logger = logging.getLogger(__name__)
  9. try:
  10. from prometheus_client import Counter, Gauge, Histogram, write_to_textfile
  11. # 定义指标
  12. DECISIONS_TOTAL = Counter(
  13. 'ad_decisions_total',
  14. 'Total decisions made',
  15. ['action', 'account_id']
  16. )
  17. EXECUTION_DURATION = Histogram(
  18. 'ad_execution_duration_seconds',
  19. 'Execution duration in seconds'
  20. )
  21. APPROVAL_TIMEOUT = Counter(
  22. 'ad_approval_timeout_total',
  23. 'Approval timeouts'
  24. )
  25. ACTIVE_ADS = Gauge(
  26. 'ad_active_ads_count',
  27. 'Number of active ads'
  28. )
  29. PROMETHEUS_ENABLED = True
  30. except ImportError:
  31. logger.warning("prometheus_client 未安装,Prometheus metrics 功能不可用")
  32. PROMETHEUS_ENABLED = False
  33. def export_metrics():
  34. """从最近的决策报告导出指标到 Prometheus"""
  35. if not PROMETHEUS_ENABLED:
  36. logger.debug("Prometheus metrics 未启用,跳过导出")
  37. return
  38. try:
  39. reports_dir = Path("/app/outputs/reports")
  40. if not reports_dir.exists():
  41. logger.warning("报告目录不存在,跳过 metrics 导出")
  42. return
  43. # 查找最新的决策报告
  44. latest_csv = sorted(reports_dir.glob("llm_decisions_*.csv"), reverse=True)
  45. if not latest_csv:
  46. logger.warning("未找到决策报告,跳过 metrics 导出")
  47. return
  48. latest_csv = latest_csv[0]
  49. df = pd.read_csv(latest_csv)
  50. # 统计决策分布
  51. for _, row in df.iterrows():
  52. DECISIONS_TOTAL.labels(
  53. action=row.get('action', 'unknown'),
  54. account_id=str(row.get('account_id', 'unknown'))
  55. ).inc()
  56. # 统计活跃广告数
  57. if 'configured_status' in df.columns:
  58. active_count = len(df[df['configured_status'] == 'AD_STATUS_NORMAL'])
  59. ACTIVE_ADS.set(active_count)
  60. # 写入文件(供 Prometheus file_sd 抓取)
  61. metrics_file = Path('/app/outputs/metrics.prom')
  62. write_to_textfile(str(metrics_file), DECISIONS_TOTAL)
  63. logger.info(f"Prometheus metrics 已导出到 {metrics_file}")
  64. except Exception as e:
  65. logger.error(f"导出 Prometheus metrics 失败: {e}", exc_info=True)
  66. def record_execution_duration(duration_seconds: float):
  67. """记录执行耗时"""
  68. if PROMETHEUS_ENABLED:
  69. EXECUTION_DURATION.observe(duration_seconds)
  70. def record_approval_timeout():
  71. """记录审批超时事件"""
  72. if PROMETHEUS_ENABLED:
  73. APPROVAL_TIMEOUT.inc()