diff --git a/loglens/parsers/base.py b/loglens/parsers/base.py index 46b4c3b..b16382d 100644 --- a/loglens/parsers/base.py +++ b/loglens/parsers/base.py @@ -1,5 +1,3 @@ -'''Base parser class and data structures.''' - from abc import ABC, abstractmethod from dataclasses import dataclass, field from datetime import datetime @@ -8,82 +6,48 @@ from typing import Any, Optional class LogFormat(Enum): - '''Supported log formats.''' + """Supported log formats.""" JSON = "json" SYSLOG = "syslog" APACHE = "apache" - UNKNOWN = "unknown" + RAW = "raw" @dataclass -class ParsedLogEntry: - '''Represents a parsed log entry.''' +class ParsedEntry: + """Parsed log entry.""" raw_line: str - timestamp: Optional[datetime] = None - level: Optional[str] = None - message: str = "" - source: Optional[str] = None - host: Optional[str] = None - facility: Optional[str] = None - severity: Optional[str] = None - logger: Optional[str] = None - extra: dict[str, Any] = field(default_factory=dict) - line_number: int = 0 - error_pattern: Optional[str] = None + format: LogFormat + timestamp: Optional[str] + level: Optional[str] + message: str + metadata: dict[str, Any] = field(default_factory=dict) + severity: str = "info" - def to_dict(self) -> dict[str, Any]: - '''Convert to dictionary.''' - result = { + def to_dict(self) -> dict: + """Convert to dictionary.""" + return { "raw_line": self.raw_line, + "format": self.format.value, + "timestamp": self.timestamp, + "level": self.level, "message": self.message, - "line_number": self.line_number, + "metadata": self.metadata, + "severity": self.severity, } - if self.timestamp: - result["timestamp"] = self.timestamp.isoformat() - if self.level: - result["level"] = self.level - if self.source: - result["source"] = self.source - if self.host: - result["host"] = self.host - if self.facility: - result["facility"] = self.facility - if self.severity: - result["severity"] = self.severity - if self.logger: - result["logger"] = self.logger - if self.extra: - result["extra"] = self.extra - if self.error_pattern: - result["error_pattern"] = self.error_pattern - return result -class LogParser(ABC): - '''Abstract base class for log parsers.''' - - format_name: str = "base" +class BaseParser(ABC): + """Base parser class.""" @abstractmethod - def parse(self, line: str, line_number: int = 0) -> Optional[ParsedLogEntry]: - '''Parse a single log line.''' + def get_format(self) -> LogFormat: + """Get the format this parser handles.""" pass @abstractmethod - def can_parse(self, line: str) -> bool: - '''Check if this parser can handle the given line.''' + def parse(self, line: str) -> Optional[ParsedEntry]: + """Parse a log line.""" pass - - def parse_batch(self, lines: list[str]) -> list[ParsedLogEntry]: - '''Parse multiple lines.''' - results = [] - for i, line in enumerate(lines, 1): - try: - entry = self.parse(line, i) - if entry: - results.append(entry) - except Exception: - results.append(ParsedLogEntry(raw_line=line, message="Parse error", line_number=i)) - return results