NAC_Blockchain/memory/tools/activity_monitor.py

324 lines
11 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
"""
NAC Activity Monitor
监控编译活动,检测空闲时间
"""
import os
import time
import json
import subprocess
from datetime import datetime
from pathlib import Path
class ActivityMonitor:
def __init__(self, workspace_path, idle_timeout=2700):
"""
初始化活动监控器
Args:
workspace_path: NAC工作区路径
idle_timeout: 空闲超时时间默认2700秒45分钟
"""
self.workspace_path = Path(workspace_path)
self.idle_timeout = idle_timeout
self.last_activity_time = time.time()
self.activities = []
self.activity_log_path = self.workspace_path / 'memory' / 'logs'
self.activity_log_path.mkdir(parents=True, exist_ok=True)
# 监控的文件扩展名
self.watched_extensions = ['.rs', '.go', '.charter', '.toml', '.json', '.md']
# 监控的项目目录
self.watched_projects = [
'nac-blockchain',
'nac-asset-onchain',
'nac-quantum-explorer'
]
def record_activity(self, activity_type, details):
"""
记录活动
Args:
activity_type: 活动类型file_modified, git_commit, lint_check等
details: 活动详情
"""
activity = {
'type': activity_type,
'timestamp': datetime.now().isoformat(),
'details': details
}
self.activities.append(activity)
self.last_activity_time = time.time()
# 保存到日志文件
self._save_activity_log(activity)
def _save_activity_log(self, activity):
"""保存活动日志"""
today = datetime.now().strftime('%Y%m%d')
log_file = self.activity_log_path / f'activity_{today}.log'
with open(log_file, 'a') as f:
f.write(json.dumps(activity, ensure_ascii=False) + '\n')
def check_file_modifications(self):
"""
检查文件修改
使用git status检测修改的文件
"""
for project in self.watched_projects:
project_path = self.workspace_path / project
if not project_path.exists():
continue
try:
# 检查未提交的修改
result = subprocess.run(
['git', 'status', '--porcelain'],
cwd=project_path,
capture_output=True,
text=True,
timeout=5
)
if result.stdout.strip():
modified_files = []
for line in result.stdout.strip().split('\n'):
if line:
status = line[:2].strip()
filepath = line[3:].strip()
# 只关注监控的文件类型
if any(filepath.endswith(ext) for ext in self.watched_extensions):
modified_files.append({
'status': status,
'path': filepath
})
if modified_files:
self.record_activity('file_modified', {
'project': project,
'files': modified_files,
'count': len(modified_files)
})
except Exception as e:
print(f"检查文件修改失败 ({project}): {e}")
def check_git_commits(self):
"""
检查Git提交
检查今日的所有提交
"""
for project in self.watched_projects:
project_path = self.workspace_path / project
if not project_path.exists():
continue
try:
# 获取今日提交
result = subprocess.run(
['git', 'log', '--since=midnight', '--pretty=format:%h|%s|%an|%ad', '--date=iso'],
cwd=project_path,
capture_output=True,
text=True,
timeout=5
)
if result.stdout.strip():
commits = []
for line in result.stdout.strip().split('\n'):
if line:
parts = line.split('|')
if len(parts) == 4:
commits.append({
'hash': parts[0],
'message': parts[1],
'author': parts[2],
'date': parts[3]
})
if commits:
# 只记录最新的提交(避免重复)
last_recorded_hash = self._get_last_recorded_commit_hash(project)
new_commits = []
for commit in commits:
if commit['hash'] == last_recorded_hash:
break
new_commits.append(commit)
if new_commits:
self.record_activity('git_commit', {
'project': project,
'commits': new_commits,
'count': len(new_commits)
})
except Exception as e:
print(f"检查Git提交失败 ({project}): {e}")
def _get_last_recorded_commit_hash(self, project):
"""获取最后记录的提交哈希"""
today = datetime.now().strftime('%Y%m%d')
log_file = self.activity_log_path / f'activity_{today}.log'
if not log_file.exists():
return None
last_hash = None
with open(log_file, 'r') as f:
for line in f:
try:
activity = json.loads(line)
if activity['type'] == 'git_commit' and activity['details']['project'] == project:
commits = activity['details']['commits']
if commits:
last_hash = commits[0]['hash']
except:
continue
return last_hash
def check_lint_activity(self):
"""
检查Lint活动
检查今日的Lint检查记录
"""
today = datetime.now().strftime('%Y%m%d')
lint_log_file = self.activity_log_path / f'lint_{today}.log'
if lint_log_file.exists():
# 读取Lint日志
with open(lint_log_file, 'r') as f:
content = f.read()
if content:
# 记录Lint活动
self.record_activity('lint_check', {
'log_file': str(lint_log_file),
'size': len(content)
})
def is_idle(self):
"""
检查是否空闲
Returns:
bool: 如果空闲超过idle_timeout秒返回True
"""
idle_time = time.time() - self.last_activity_time
return idle_time > self.idle_timeout
def get_idle_time(self):
"""
获取当前空闲时间(秒)
Returns:
float: 空闲时间(秒)
"""
return time.time() - self.last_activity_time
def get_today_activities(self):
"""
获取今日所有活动
Returns:
list: 活动列表
"""
today = datetime.now().strftime('%Y%m%d')
log_file = self.activity_log_path / f'activity_{today}.log'
if not log_file.exists():
return []
activities = []
with open(log_file, 'r') as f:
for line in f:
try:
activity = json.loads(line)
activities.append(activity)
except:
continue
return activities
def get_activity_statistics(self):
"""
获取今日活动统计
Returns:
dict: 统计信息
"""
activities = self.get_today_activities()
stats = {
'total_activities': len(activities),
'file_modifications': 0,
'git_commits': 0,
'lint_checks': 0,
'files_modified_count': 0,
'commits_count': 0
}
for activity in activities:
activity_type = activity['type']
if activity_type == 'file_modified':
stats['file_modifications'] += 1
stats['files_modified_count'] += activity['details'].get('count', 0)
elif activity_type == 'git_commit':
stats['git_commits'] += 1
stats['commits_count'] += activity['details'].get('count', 0)
elif activity_type == 'lint_check':
stats['lint_checks'] += 1
return stats
def reset_idle_timer(self):
"""重置空闲计时器"""
self.last_activity_time = time.time()
def scan_all_activities(self):
"""
扫描所有活动
一次性检查所有类型的活动
"""
self.check_file_modifications()
self.check_git_commits()
self.check_lint_activity()
if __name__ == '__main__':
# 测试代码
import sys
workspace = '/home/ubuntu/nac-workspace'
if len(sys.argv) > 1:
workspace = sys.argv[1]
monitor = ActivityMonitor(workspace, idle_timeout=60) # 测试用1分钟超时
print(f"NAC Activity Monitor")
print(f"工作区: {workspace}")
print(f"空闲超时: {monitor.idle_timeout}")
print()
# 扫描活动
print("扫描活动...")
monitor.scan_all_activities()
# 显示统计
stats = monitor.get_activity_statistics()
print(f"\n今日活动统计:")
print(f" 总活动数: {stats['total_activities']}")
print(f" 文件修改: {stats['file_modifications']}次 ({stats['files_modified_count']}个文件)")
print(f" Git提交: {stats['git_commits']}次 ({stats['commits_count']}个提交)")
print(f" Lint检查: {stats['lint_checks']}")
# 显示空闲状态
idle_time = monitor.get_idle_time()
print(f"\n当前空闲时间: {idle_time:.0f}")
print(f"是否空闲: {'' if monitor.is_idle() else ''}")