Files
Mofox-Core/scripts/view_hfc_stats.py
2025-06-22 09:19:09 +00:00

186 lines
5.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
HFC性能统计数据查看工具
"""
import sys
import json
import argparse
from pathlib import Path
from typing import Dict, Any
# 添加项目根目录到Python路径
sys.path.insert(0, str(Path(__file__).parent.parent))
def format_time(seconds: float) -> str:
"""格式化时间显示"""
if seconds < 1:
return f"{seconds * 1000:.1f}毫秒"
else:
return f"{seconds:.3f}"
def display_chat_stats(chat_id: str, stats: Dict[str, Any]):
"""显示单个聊天的统计数据"""
print(f"\n=== Chat ID: {chat_id} ===")
print(f"版本: {stats.get('version', 'unknown')}")
print(f"最后更新: {stats['last_updated']}")
overall = stats["overall"]
print("\n📊 总体统计:")
print(f" 总记录数: {overall['total_records']}")
print(f" 平均总时间: {format_time(overall['avg_total_time'])}")
print("\n⏱️ 各步骤平均时间:")
for step, avg_time in overall["avg_step_times"].items():
print(f" {step}: {format_time(avg_time)}")
print("\n🎯 按动作类型统计:")
by_action = stats["by_action"]
# 按比例排序
sorted_actions = sorted(by_action.items(), key=lambda x: x[1]["percentage"], reverse=True)
for action, action_stats in sorted_actions:
print(f" 📌 {action}:")
print(f" 次数: {action_stats['count']} ({action_stats['percentage']:.1f}%)")
print(f" 平均总时间: {format_time(action_stats['avg_total_time'])}")
if action_stats["avg_step_times"]:
print(" 步骤时间:")
for step, step_time in action_stats["avg_step_times"].items():
print(f" {step}: {format_time(step_time)}")
def display_comparison(stats_data: Dict[str, Dict[str, Any]]):
"""显示多个聊天的对比数据"""
if len(stats_data) < 2:
return
print("\n=== 多聊天对比 ===")
# 创建对比表格
chat_ids = list(stats_data.keys())
print("\n📊 总体对比:")
print(f"{'Chat ID':<20} {'版本':<12} {'记录数':<8} {'平均时间':<12} {'最常见动作':<15}")
print("-" * 70)
for chat_id in chat_ids:
stats = stats_data[chat_id]
overall = stats["overall"]
# 找到最常见的动作
most_common_action = max(stats["by_action"].items(), key=lambda x: x[1]["count"])
most_common_name = most_common_action[0]
most_common_pct = most_common_action[1]["percentage"]
version = stats.get("version", "unknown")
print(
f"{chat_id:<20} {version:<12} {overall['total_records']:<8} {format_time(overall['avg_total_time']):<12} {most_common_name}({most_common_pct:.0f}%)"
)
def view_session_logs(chat_id: str = None, latest: bool = False):
"""查看会话日志文件"""
log_dir = Path("log/hfc_loop")
if not log_dir.exists():
print("❌ 日志目录不存在")
return
if chat_id:
pattern = f"{chat_id}_*.json"
else:
pattern = "*.json"
log_files = list(log_dir.glob(pattern))
if not log_files:
print(f"❌ 没有找到匹配的日志文件: {pattern}")
return
if latest:
# 按文件修改时间排序,取最新的
log_files.sort(key=lambda f: f.stat().st_mtime, reverse=True)
log_files = log_files[:1]
for log_file in log_files:
print(f"\n=== 会话日志: {log_file.name} ===")
try:
with open(log_file, "r", encoding="utf-8") as f:
records = json.load(f)
if not records:
print(" 空文件")
continue
print(f" 记录数: {len(records)}")
print(f" 时间范围: {records[0]['timestamp']} ~ {records[-1]['timestamp']}")
# 统计动作分布
action_counts = {}
total_time = 0
for record in records:
action = record["action_type"]
action_counts[action] = action_counts.get(action, 0) + 1
total_time += record["total_time"]
print(f" 总耗时: {format_time(total_time)}")
print(f" 平均耗时: {format_time(total_time / len(records))}")
print(f" 动作分布: {dict(action_counts)}")
except Exception as e:
print(f" ❌ 读取文件失败: {e}")
def main():
parser = argparse.ArgumentParser(description="HFC性能统计数据查看工具")
parser.add_argument("--chat-id", help="指定要查看的Chat ID")
parser.add_argument("--logs", action="store_true", help="查看会话日志文件")
parser.add_argument("--latest", action="store_true", help="只显示最新的日志文件")
parser.add_argument("--compare", action="store_true", help="显示多聊天对比")
args = parser.parse_args()
if args.logs:
view_session_logs(args.chat_id, args.latest)
return
# 读取统计数据
stats_file = Path("data/hfc/time.json")
if not stats_file.exists():
print("❌ 统计数据文件不存在请先运行一些HFC循环以生成数据")
return
try:
with open(stats_file, "r", encoding="utf-8") as f:
stats_data = json.load(f)
except Exception as e:
print(f"❌ 读取统计数据失败: {e}")
return
if not stats_data:
print("❌ 统计数据为空")
return
if args.chat_id:
if args.chat_id in stats_data:
display_chat_stats(args.chat_id, stats_data[args.chat_id])
else:
print(f"❌ 没有找到Chat ID '{args.chat_id}' 的数据")
print(f"可用的Chat ID: {list(stats_data.keys())}")
else:
# 显示所有聊天的统计数据
for chat_id, stats in stats_data.items():
display_chat_stats(chat_id, stats)
if args.compare:
display_comparison(stats_data)
if __name__ == "__main__":
main()