fix: resolve merge conflicts in ticket_whitelist, add retry logic for port 5001 in bug_report, and implement live GitLab issue deduplication in logger

This commit is contained in:
Mathis 2026-03-28 21:58:44 +01:00
parent c40c3f1f12
commit 16263d88bc
6 changed files with 525 additions and 54 deletions

View file

@ -3,10 +3,14 @@ import sys
import time
import functools
import asyncio
import json
import os
from datetime import datetime
from typing import Any, Callable
import traceback
REPORTED_ERRORS_FILE = "data/automated_reports.json"
class KubyLogger:
def __init__(self, name="KubyBot"):
self.logger = logging.getLogger(name)
@ -53,37 +57,69 @@ class KubyLogger:
def __init__(self, client):
super().__init__()
self.client = client
self.last_errors = {}
self.cooldown = 3600 # 1 hour cooldown per unique error
self.last_errors = self._load_reported_errors()
def _load_reported_errors(self):
if os.path.exists(REPORTED_ERRORS_FILE):
try:
with open(REPORTED_ERRORS_FILE, "r") as f:
return json.load(f)
except Exception as e:
print(f"Error loading reported errors: {e}")
return {}
def _save_reported_errors(self):
try:
os.makedirs(os.path.dirname(REPORTED_ERRORS_FILE), exist_ok=True)
with open(REPORTED_ERRORS_FILE, "w") as f:
json.dump(self.last_errors, f, indent=4)
except Exception as e:
print(f"Error saving reported errors: {e}")
def emit(self, record):
if record.levelno >= logging.ERROR:
# Extract message and first line of traceback if available
msg = record.getMessage()
error_key = msg
if record.exc_info:
error_key += str(record.exc_info[1])
# Use message + location + simplified traceback for unique key
# This key is used for the local cooldown
error_key = f"{record.name}.{record.funcName}:{record.lineno} - {msg}"
current_time = time.time()
if error_key in self.last_errors and current_time - self.last_errors[error_key] < self.cooldown:
return # Skip if same error within cooldown
last_time = self.last_errors.get(error_key, 0)
if current_time - last_time < self.cooldown:
return
self.last_errors[error_key] = current_time
self._save_reported_errors()
# Create issue (Fire and forget, we don't want to block logging)
# Prepare issue data
description = f"**Type:** {record.levelname}\n"
description += f"**Message:** {msg}\n"
description += f"**Source:** {record.name}.{record.funcName}:{record.lineno}\n\n"
if record.exc_info:
description += f"**Traceback:**\n```python\n{traceback.format_exc()}\n```"
title = f"[AUTO] Error: {msg[:50]}..."
title = f"[AUTO] Error: {msg[:100]}..."
labels = ["bug", "auto-report"]
# Async reporting flow
async def report_flow(client, t, d, l):
try:
# Check if an open issue with the SAME title already exists on GitLab
existing = await client.find_issue_by_title(t, state="opened")
if existing:
# If it exists, we don't create a new one to avoid clutter
return
# Otherwise, create it
await client.create_issue(t, d, l)
except Exception as e:
print(f"Error in automated reporting flow: {e}")
loop = asyncio.get_event_loop()
if loop.is_running():
loop.create_task(self.client.create_issue(title, description, labels=["bug", "auto-report"]))
else:
# Fallback if loop is not running (rare for this bot)
pass
loop.create_task(report_flow(self.client, title, description, labels))
gitlab_handler = GitLabHandler(gitlab_client)
gitlab_handler.setLevel(logging.ERROR)