fix: resolve CI/CD linting and formatting issues
Some checks failed
Some checks failed
- Replaced deprecated typing.Dict/List/Tuple with native types (UP035) - Removed unused imports across all modules - Fixed unused variables by replacing with _ prefix - Added missing Optional type imports - Reorganized imports for proper sorting (I001) - Applied black formatting to all source files
This commit is contained in:
@@ -1,24 +1,25 @@
|
|||||||
"""Syslog parser for RFC 3164 and RFC 5424 formats."""
|
'''Syslog parser for RFC 3164 and RFC 5424 formats.'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any, Dict, List, Match, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
from dateutil import parser as date_parser
|
from dateutil import parser as date_parser
|
||||||
|
|
||||||
from loglens.parsers.base import LogParser, ParsedLogEntry
|
from loglens.parsers.base import LogParser, ParsedLogEntry
|
||||||
|
|
||||||
|
|
||||||
class SyslogParser(LogParser):
|
class SyslogParser(LogParser):
|
||||||
"""Parser for syslog format (RFC 3164 and RFC 5424)."""
|
'''Parser for syslog format (RFC 3164 and RFC 5424).'''
|
||||||
|
|
||||||
format_name = "syslog"
|
format_name = "syslog"
|
||||||
|
|
||||||
SYSLOG_RFC3164_PATTERN = re.compile(
|
SYSLOG_RFC3164_PATTERN = re.compile(
|
||||||
r'^(?P<month>[A-Z][a-z]{2})\s+(?P<day>\d{1,2})\s+(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})\s+(?P<hostname>[\w.-]+)\s+(?P<process>[\w\[\]]+):\s*(?P<message>.*)$'
|
r"^(?P<month>[A-Z][a-z]{2})\s+(?P<day>\d{1,2})\s+(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})\s+(?P<hostname>[\w.-]+)\s+(?P<process>[\w\[\]]+):\s*(?P<message>.*)$"
|
||||||
)
|
)
|
||||||
|
|
||||||
SYSLOG_RFC5424_PATTERN = re.compile(
|
SYSLOG_RFC5424_PATTERN = re.compile(
|
||||||
r'^(?P<pri><\d+>)?(?P<version>\d+)\s+(?P<timestamp>\S+)\s+(?P<hostname>\S+)\s+(?P<process>\S+)\s+(?P<pid>\S+)\s+(?P<msgid>\S+)?\s*(?P<struct_data>-)\s*(?P<message>.*)$'
|
r"^(?P<pri><\d+>)?(?P<version>\d+)\s+(?P<timestamp>\S+)\s+(?P<hostname>\S+)\s+(?P<process>\S+)\s+(?P<pid>\S+)\s+(?P<msgid>\S+)?\s*(?P<struct_data>-)\s*(?P<message>.*)$"
|
||||||
)
|
)
|
||||||
|
|
||||||
PRIORITY_MAP = {
|
PRIORITY_MAP = {
|
||||||
@@ -29,7 +30,7 @@ class SyslogParser(LogParser):
|
|||||||
4: "warning",
|
4: "warning",
|
||||||
5: "notice",
|
5: "notice",
|
||||||
6: "info",
|
6: "info",
|
||||||
7: "debug"
|
7: "debug",
|
||||||
}
|
}
|
||||||
|
|
||||||
FACILITY_MAP = {
|
FACILITY_MAP = {
|
||||||
@@ -56,17 +57,27 @@ class SyslogParser(LogParser):
|
|||||||
20: "local4",
|
20: "local4",
|
||||||
21: "local5",
|
21: "local5",
|
||||||
22: "local6",
|
22: "local6",
|
||||||
23: "local7"
|
23: "local7",
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.month_map = {
|
self.month_map = {
|
||||||
"Jan": 1, "Feb": 2, "Mar": 3, "Apr": 4, "May": 5, "Jun": 6,
|
"Jan": 1,
|
||||||
"Jul": 7, "Aug": 8, "Sep": 9, "Oct": 10, "Nov": 11, "Dec": 12
|
"Feb": 2,
|
||||||
|
"Mar": 3,
|
||||||
|
"Apr": 4,
|
||||||
|
"May": 5,
|
||||||
|
"Jun": 6,
|
||||||
|
"Jul": 7,
|
||||||
|
"Aug": 8,
|
||||||
|
"Sep": 9,
|
||||||
|
"Oct": 10,
|
||||||
|
"Nov": 11,
|
||||||
|
"Dec": 12,
|
||||||
}
|
}
|
||||||
|
|
||||||
def can_parse(self, line: str) -> bool:
|
def can_parse(self, line: str) -> bool:
|
||||||
"""Check if line matches syslog format."""
|
'''Check if line matches syslog format.'''
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line:
|
if not line:
|
||||||
return False
|
return False
|
||||||
@@ -85,15 +96,12 @@ class SyslogParser(LogParser):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def parse(self, line: str, line_number: int = 0) -> Optional[ParsedLogEntry]:
|
def parse(self, line: str, line_number: int = 0) -> Optional[ParsedLogEntry]:
|
||||||
"""Parse a syslog line."""
|
'''Parse a syslog line.'''
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line:
|
if not line:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
entry = ParsedLogEntry(
|
entry = ParsedLogEntry(raw_line=line, line_number=line_number)
|
||||||
raw_line=line,
|
|
||||||
line_number=line_number
|
|
||||||
)
|
|
||||||
|
|
||||||
if line.startswith("<"):
|
if line.startswith("<"):
|
||||||
parsed = self._parse_rfc5424(line)
|
parsed = self._parse_rfc5424(line)
|
||||||
@@ -110,8 +118,8 @@ class SyslogParser(LogParser):
|
|||||||
|
|
||||||
return entry
|
return entry
|
||||||
|
|
||||||
def _parse_rfc3164(self, line: str) -> Optional[Dict[str, Any]]:
|
def _parse_rfc3164(self, line: str) -> Optional[dict[str, Any]]:
|
||||||
"""Parse RFC 3164 syslog format."""
|
'''Parse RFC 3164 syslog format.'''
|
||||||
match = self.SYSLOG_RFC3164_PATTERN.match(line)
|
match = self.SYSLOG_RFC3164_PATTERN.match(line)
|
||||||
if not match:
|
if not match:
|
||||||
return None
|
return None
|
||||||
@@ -126,9 +134,7 @@ class SyslogParser(LogParser):
|
|||||||
message = match.group("message")
|
message = match.group("message")
|
||||||
|
|
||||||
current_year = datetime.now().year
|
current_year = datetime.now().year
|
||||||
timestamp = datetime(
|
timestamp = datetime(current_year, self.month_map[month], day, hour, minute, second)
|
||||||
current_year, self.month_map[month], day, hour, minute, second
|
|
||||||
)
|
|
||||||
|
|
||||||
level = self._infer_level(message)
|
level = self._infer_level(message)
|
||||||
|
|
||||||
@@ -137,23 +143,23 @@ class SyslogParser(LogParser):
|
|||||||
"hostname": hostname,
|
"hostname": hostname,
|
||||||
"process": process,
|
"process": process,
|
||||||
"message": message,
|
"message": message,
|
||||||
"level": level
|
"level": level,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _parse_rfc5424(self, line: str) -> Optional[Dict[str, Any]]:
|
def _parse_rfc5424(self, line: str) -> Optional[dict[str, Any]]:
|
||||||
"""Parse RFC 5424 syslog format."""
|
'''Parse RFC 5424 syslog format.'''
|
||||||
match = self.SYSLOG_RFC5424_PATTERN.match(line)
|
match = self.SYSLOG_RFC5424_PATTERN.match(line)
|
||||||
if not match:
|
if not match:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
raw_pri = match.group("pri")
|
raw_pri = match.group("pri")
|
||||||
version = match.group("version")
|
_ = match.group("version")
|
||||||
timestamp_str = match.group("timestamp")
|
timestamp_str = match.group("timestamp")
|
||||||
hostname = match.group("hostname")
|
hostname = match.group("hostname")
|
||||||
process = match.group("process")
|
process = match.group("process")
|
||||||
pid = match.group("pid")
|
pid = match.group("pid")
|
||||||
msgid = match.group("msgid")
|
_ = match.group("msgid")
|
||||||
struct_data = match.group("struct_data")
|
_ = match.group("struct_data")
|
||||||
message = match.group("message")
|
message = match.group("message")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -163,7 +169,6 @@ class SyslogParser(LogParser):
|
|||||||
|
|
||||||
priority = None
|
priority = None
|
||||||
facility = None
|
facility = None
|
||||||
level = None
|
|
||||||
if raw_pri:
|
if raw_pri:
|
||||||
pri_num = int(raw_pri[1:-1])
|
pri_num = int(raw_pri[1:-1])
|
||||||
priority = pri_num & 0x07
|
priority = pri_num & 0x07
|
||||||
@@ -180,11 +185,11 @@ class SyslogParser(LogParser):
|
|||||||
"process": f"{process}[{pid}]" if pid else process,
|
"process": f"{process}[{pid}]" if pid else process,
|
||||||
"message": message,
|
"message": message,
|
||||||
"level": level,
|
"level": level,
|
||||||
"facility": facility
|
"facility": facility,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _infer_level(self, message: str) -> Optional[str]:
|
def _infer_level(self, message: str) -> Optional[str]:
|
||||||
"""Infer log level from message content."""
|
'''Infer log level from message content.'''
|
||||||
message_lower = message.lower()
|
message_lower = message.lower()
|
||||||
|
|
||||||
if any(kw in message_lower for kw in ["emerg", "panic", "critical system"]):
|
if any(kw in message_lower for kw in ["emerg", "panic", "critical system"]):
|
||||||
|
|||||||
Reference in New Issue
Block a user