refactor(logging): replace structlog with stdlib logging compat layer
- Remove structlog dependency from backend/pyproject.toml - Add app.utils.logging_compat shim for keyword-arg logging API - Add app.utils.json_formatter for JSON log output with extra fields - Update all backend modules to use logging_compat.get_logger() - Update docstrings in log_sanitizer.py and json_formatter.py - Update test comment in test_async_utils.py - Record 406 failing tests in Docs/Tasks.md for tracking
This commit is contained in:
@@ -15,7 +15,7 @@ import re
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.exceptions import (
|
||||
ActionAlreadyExistsError,
|
||||
@@ -47,7 +47,7 @@ from app.utils.config_file_utils import (
|
||||
)
|
||||
from app.utils.jail_socket import reload_all
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Internal wrappers for shared config helpers.
|
||||
|
||||
@@ -13,7 +13,7 @@ import secrets
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bcrypt
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.utils.async_utils import run_blocking
|
||||
|
||||
@@ -28,7 +28,7 @@ from app.repositories import settings_repo as default_settings_repo
|
||||
from app.utils.constants import SESSION_TOKEN_BYTES, SESSION_TOKEN_SIGNATURE_SEPARATOR
|
||||
from app.utils.time_utils import add_minutes, utc_now
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
# Settings key for password hash
|
||||
_KEY_PASSWORD_HASH = "master_password_hash"
|
||||
|
||||
@@ -16,7 +16,7 @@ import ipaddress
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
import aiohttp
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.exceptions import JailNotFoundError, JailOperationError
|
||||
from app.models._common import (
|
||||
@@ -69,7 +69,7 @@ if TYPE_CHECKING:
|
||||
from app.repositories.protocols import HistoryArchiveRepository
|
||||
from app.services.geo_cache import GeoCache
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
|
||||
async def get_fail2ban_db_path(socket_path: str) -> str:
|
||||
|
||||
@@ -8,14 +8,14 @@ from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.exceptions import JailNotFoundError, JailOperationError
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Awaitable, Callable
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
|
||||
class BanExecutor:
|
||||
|
||||
@@ -10,9 +10,9 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
|
||||
import aiohttp
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
#: HTTP status codes that should be retried for blocklist downloads.
|
||||
_BLOCKLIST_HTTP_RETRY_STATUSES: frozenset[int] = frozenset({429, 500, 502, 503, 504})
|
||||
|
||||
@@ -16,7 +16,7 @@ from typing import TYPE_CHECKING
|
||||
|
||||
import aiohttp
|
||||
import aiosqlite
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.models.blocklist import BlocklistSource, ImportSourceResult
|
||||
from app.repositories import import_run_repo
|
||||
@@ -29,7 +29,7 @@ if TYPE_CHECKING:
|
||||
|
||||
from app.services.geo_cache import GeoCache
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
#: fail2ban jail name for blocklist-origin bans.
|
||||
BLOCKLIST_JAIL: str = "blocklist-import"
|
||||
|
||||
@@ -6,11 +6,11 @@ or CIDR networks. Separates valid IPs from invalid/CIDR entries.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.utils.ip_utils import is_valid_ip, is_valid_network, normalise_ip
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
|
||||
class ParsedBlocklist:
|
||||
|
||||
@@ -19,7 +19,7 @@ from typing import TYPE_CHECKING
|
||||
|
||||
import aiohttp
|
||||
import aiosqlite
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.exceptions import BlocklistSourceHasLogsError
|
||||
from app.models.blocklist import (
|
||||
@@ -47,7 +47,7 @@ if TYPE_CHECKING:
|
||||
from app.config import Settings
|
||||
from app.services.geo_cache import GeoCache
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
#: Settings key used to persist the schedule config.
|
||||
_SCHEDULE_SETTINGS_KEY: str = "blocklist_schedule"
|
||||
|
||||
@@ -17,7 +17,7 @@ import contextlib
|
||||
import re
|
||||
from typing import TYPE_CHECKING, TypeVar, cast
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.utils.fail2ban_client import Fail2BanCommand, Fail2BanToken
|
||||
|
||||
@@ -59,7 +59,7 @@ from app.utils.fail2ban_response import (
|
||||
)
|
||||
from app.utils.path_utils import validate_log_target
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Custom exceptions
|
||||
|
||||
@@ -23,14 +23,14 @@ import ipaddress
|
||||
import socket
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.utils.ip_utils import is_private_ip
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
|
||||
def create_dns_validated_socket_factory() -> (
|
||||
|
||||
@@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.utils.constants import FAIL2BAN_SOCKET_TIMEOUT_FAST
|
||||
from app.utils.fail2ban_client import (
|
||||
@@ -13,7 +13,7 @@ from app.utils.fail2ban_client import (
|
||||
Fail2BanProtocolError,
|
||||
)
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
|
||||
class Fail2BanMetadataService:
|
||||
|
||||
@@ -13,7 +13,7 @@ import re
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.exceptions import (
|
||||
ConfigWriteError,
|
||||
@@ -48,7 +48,7 @@ from app.utils.config_file_utils import (
|
||||
from app.utils.jail_socket import reload_all
|
||||
from app.utils.regex_validator import RegexTimeoutError, validate_regex_pattern
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Internal wrappers for shared config helpers.
|
||||
|
||||
@@ -21,7 +21,7 @@ import time
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import aiohttp
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.models.geo import GeoInfo
|
||||
from app.repositories import geo_cache_repo
|
||||
@@ -33,7 +33,7 @@ if TYPE_CHECKING:
|
||||
import geoip2.database
|
||||
import geoip2.errors
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Constants
|
||||
@@ -208,9 +208,9 @@ class GeoCache:
|
||||
Returns:
|
||||
A dict with ``resolved`` and ``total`` counts.
|
||||
"""
|
||||
import structlog # noqa: PLC0415
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
log = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
unresolved = await self.get_unresolved_ips(db)
|
||||
if not unresolved:
|
||||
return {"resolved": 0, "total": 0}
|
||||
|
||||
@@ -13,7 +13,7 @@ import asyncio
|
||||
from collections.abc import Awaitable, Callable
|
||||
from typing import TypeVar, cast
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app import __version__
|
||||
from app.models.config_domain import DomainServiceStatus
|
||||
@@ -30,7 +30,7 @@ from app.utils.fail2ban_response import (
|
||||
to_dict,
|
||||
)
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Internal helpers
|
||||
|
||||
@@ -13,7 +13,7 @@ from __future__ import annotations
|
||||
from datetime import UTC, datetime
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import aiohttp
|
||||
@@ -37,7 +37,7 @@ from app.utils.constants import DEFAULT_PAGE_SIZE
|
||||
from app.utils.fail2ban_db_utils import parse_data_json, ts_to_iso
|
||||
from app.utils.time_utils import since_unix
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Internal Helpers
|
||||
|
||||
@@ -16,7 +16,7 @@ import tempfile
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, cast
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.exceptions import (
|
||||
ConfigWriteError,
|
||||
@@ -59,7 +59,7 @@ if TYPE_CHECKING:
|
||||
|
||||
from app.services.protocols import HealthProbe
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
|
||||
def _parse_jails_sync(config_dir: Path) -> tuple[dict[str, dict[str, str]], dict[str, str]]:
|
||||
|
||||
@@ -20,7 +20,7 @@ import contextlib
|
||||
import ipaddress
|
||||
from typing import TYPE_CHECKING, cast
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.exceptions import JailNotFoundError, JailOperationError
|
||||
from app.models.ban_domain import DomainActiveBan
|
||||
@@ -61,7 +61,7 @@ if TYPE_CHECKING:
|
||||
from app.models.geo import GeoEnricher, GeoInfo
|
||||
from app.services.geo_cache import GeoCache
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
__all__ = ["reload_all"]
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import asyncio
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.exceptions import ConfigOperationError
|
||||
from app.models.config import (
|
||||
@@ -29,7 +29,7 @@ from app.utils.fail2ban_client import (
|
||||
)
|
||||
from app.utils.fail2ban_response import ok
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
_NON_FILE_LOG_TARGETS: frozenset[str] = frozenset(
|
||||
{"STDOUT", "STDERR", "SYSLOG", "SYSTEMD-JOURNAL"}
|
||||
|
||||
@@ -19,7 +19,7 @@ import configparser
|
||||
import re
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.exceptions import (
|
||||
ConfigFileNameError,
|
||||
@@ -59,7 +59,7 @@ if TYPE_CHECKING:
|
||||
JailFileConfigUpdate,
|
||||
)
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Internal helpers — INI parsing / patching
|
||||
|
||||
@@ -12,7 +12,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import cast
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.exceptions import Fail2BanConnectionError, Fail2BanProtocolError, ServerOperationError
|
||||
from app.models.server import ServerSettingsUpdate
|
||||
@@ -28,7 +28,7 @@ from app.utils.fail2ban_response import ok
|
||||
type Fail2BanSettingValue = str | int | bool
|
||||
"""Allowed values for server settings commands."""
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
|
||||
def _to_int(value: object | None, default: int) -> int:
|
||||
|
||||
@@ -8,14 +8,14 @@ from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.repositories import settings_repo
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
import aiosqlite
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
_KEY_MAP_COLOR_THRESHOLD_HIGH = "map_color_threshold_high"
|
||||
_KEY_MAP_COLOR_THRESHOLD_MEDIUM = "map_color_threshold_medium"
|
||||
|
||||
@@ -11,7 +11,7 @@ from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bcrypt
|
||||
import structlog
|
||||
from app.utils.logging_compat import get_logger
|
||||
|
||||
from app.db import init_db, open_db
|
||||
from app.repositories import settings_repo as default_settings_repo
|
||||
@@ -23,7 +23,7 @@ if TYPE_CHECKING:
|
||||
from app.repositories.protocols import SettingsRepository
|
||||
from app.services.protocols import Fail2BanMetadataService
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
log = get_logger(__name__)
|
||||
|
||||
# Keys used in the settings table.
|
||||
_KEY_PASSWORD_HASH = "master_password_hash"
|
||||
|
||||
Reference in New Issue
Block a user