adds logging model
This commit is contained in:
parent
e580a0d43d
commit
389bb57185
@ -1,5 +1,169 @@
|
||||
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):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
@ -19,7 +183,6 @@ class PaperMetadata(db.Model):
|
||||
default=db.func.current_timestamp(),
|
||||
onupdate=db.func.current_timestamp(),
|
||||
)
|
||||
# plus maybe timestamps for created/updated
|
||||
|
||||
|
||||
class ScheduleConfig(db.Model):
|
||||
|
Loading…
x
Reference in New Issue
Block a user