adds logging model

This commit is contained in:
Michael Beck 2025-04-11 14:42:34 +02:00
parent e580a0d43d
commit 389bb57185

View File

@ -1,5 +1,169 @@
from .db import db from .db import db
import json
from datetime import datetime
from enum import Enum
class ActivityCategory(Enum):
"""Categories for activity logs."""
GUI_INTERACTION = "gui_interaction"
CONFIG_CHANGE = "config_change"
SCRAPER_COMMAND = "scraper_command"
SCRAPER_ACTIVITY = "scraper_activity"
SYSTEM = "system"
class ErrorSeverity(Enum):
"""Severity levels for error logging."""
DEBUG = "debug"
INFO = "info"
WARNING = "warning"
ERROR = "error"
CRITICAL = "critical"
class ActivityLog(db.Model):
"""Model for logging various activities in the application."""
id = db.Column(db.Integer, primary_key=True)
timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True)
category = db.Column(db.String(50), nullable=False, index=True)
action = db.Column(db.String(100), nullable=False)
description = db.Column(db.Text)
# Reference to related entities (optional)
paper_id = db.Column(db.Integer, db.ForeignKey('paper_metadata.id'), nullable=True)
user_id = db.Column(db.Integer, nullable=True) # For future authentication
# For config changes
config_key = db.Column(db.String(100), nullable=True)
old_value = db.Column(db.Text, nullable=True)
new_value = db.Column(db.Text, nullable=True)
# For scraper activities
status = db.Column(db.String(50), nullable=True)
source_ip = db.Column(db.String(50), nullable=True)
# Extra data as JSON
extra_data = db.Column(db.Text, nullable=True)
def set_extra_data(self, data_dict):
"""Serialize extra data as JSON string."""
if data_dict:
self.extra_data = json.dumps(data_dict)
def get_extra_data(self):
"""Deserialize JSON string to dictionary."""
if self.extra_data:
return json.loads(self.extra_data)
return {}
@classmethod
def log_gui_interaction(cls, action, description=None, paper_id=None, user_id=None, **extra):
"""Log a GUI interaction."""
log = cls(
category=ActivityCategory.GUI_INTERACTION.value,
action=action,
description=description,
paper_id=paper_id,
user_id=user_id
)
log.set_extra_data(extra)
db.session.add(log)
db.session.commit()
return log
@classmethod
def log_config_change(cls, config_key, old_value, new_value, user_id=None, **extra):
"""Log a configuration change."""
log = cls(
category=ActivityCategory.CONFIG_CHANGE.value,
action=f"Changed {config_key}",
config_key=config_key,
old_value=str(old_value),
new_value=str(new_value),
user_id=user_id
)
log.set_extra_data(extra)
db.session.add(log)
db.session.commit()
return log
@classmethod
def log_scraper_command(cls, action, status=None, user_id=None, **extra):
"""Log a scraper command (start/stop/pause)."""
log = cls(
category=ActivityCategory.SCRAPER_COMMAND.value,
action=action,
status=status,
user_id=user_id
)
log.set_extra_data(extra)
db.session.add(log)
db.session.commit()
return log
@classmethod
def log_scraper_activity(cls, action, paper_id=None, status=None, description=None, **extra):
"""Log a scraper activity (downloading, processing papers, etc.)."""
log = cls(
category=ActivityCategory.SCRAPER_ACTIVITY.value,
action=action,
paper_id=paper_id,
status=status,
description=description
)
log.set_extra_data(extra)
db.session.add(log)
db.session.commit()
return log
@classmethod
def log_error(cls, error_message, exception=None, severity=ErrorSeverity.ERROR.value,
source=None, paper_id=None, user_id=None, **extra):
"""Log system errors or warnings.
Args:
error_message: Brief description of the error
exception: The exception object if available
severity: Error severity level (debug, info, warning, error, critical)
source: Component/module where the error occurred
paper_id: Related paper ID if applicable
user_id: Related user ID if applicable
**extra: Any additional data to store
"""
details = {}
if exception:
details.update({
'exception_type': type(exception).__name__,
'exception_message': str(exception)
})
# Get traceback if available
import traceback
details['traceback'] = traceback.format_exc()
if source:
extra['source'] = source
log = cls(
category=ActivityCategory.SYSTEM.value,
action=f"{severity.upper()}: {error_message}"[:100], # Limit action length
description=error_message,
paper_id=paper_id,
user_id=user_id,
status=severity
)
# Add exception details to extra data
extra.update(details)
log.set_extra_data(extra)
db.session.add(log)
db.session.commit()
return log
class PaperMetadata(db.Model): class PaperMetadata(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
@ -19,7 +183,6 @@ class PaperMetadata(db.Model):
default=db.func.current_timestamp(), default=db.func.current_timestamp(),
onupdate=db.func.current_timestamp(), onupdate=db.func.current_timestamp(),
) )
# plus maybe timestamps for created/updated
class ScheduleConfig(db.Model): class ScheduleConfig(db.Model):