From: Martin Mareš Date: Sun, 23 Nov 2025 12:33:03 +0000 (+0100) Subject: Proper logging X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;p=pynsc.git Proper logging --- diff --git a/TODO b/TODO index 51f4125..b98b5ad 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,2 @@ - DNSSEC -- Logging - More records diff --git a/nsconfig/cli.py b/nsconfig/cli.py index 7bebfc6..1f205d2 100644 --- a/nsconfig/cli.py +++ b/nsconfig/cli.py @@ -1,13 +1,16 @@ # PyNSC: Command-line interface -# (c) 2024 Martin MareÅ¡ +# (c) 2024-2025 Martin MareÅ¡ import argparse from argparse import Namespace +import logging from pathlib import Path from texttable import Texttable from nsconfig.core import Nsc, NscZonePrimary, NscZoneSecondary, NscZoneAlias +logger = logging.getLogger(__name__) + def do_test(nsc: Nsc, args: Namespace) -> None: test_dir = Path(args.output) @@ -95,6 +98,33 @@ def do_update(nsc: Nsc) -> None: nsc.daemon.reload_daemon() +class LogFormatter(logging.Formatter): + + LOG_PREFIX = { + logging.WARNING: "WARNING", + logging.ERROR: "ERROR", + logging.CRITICAL: "FATAL", + } + + def format(self, record): + out = super().format(record) + if record.levelno in LogFormatter.LOG_PREFIX: + out = LogFormatter.LOG_PREFIX[record.levelno] + ': ' + out + return out + + +def setup_logging() -> None: + log_formatter = LogFormatter('%(message)s') + + log_handler = logging.StreamHandler() + log_handler.setFormatter(log_formatter) + log_handler.setLevel(logging.INFO) + + root_logger = logging.getLogger() + root_logger.addHandler(log_handler) + root_logger.setLevel(logging.INFO) + + def main(nsc: Nsc) -> None: parser = argparse.ArgumentParser(description='Configure name server') subparsers = parser.add_subparsers(help='action to perform', dest='action', required=True, metavar='ACTION') @@ -110,6 +140,8 @@ def main(nsc: Nsc) -> None: args = parser.parse_args() + setup_logging() + nsc.process() if args.action == 'test': diff --git a/nsconfig/core.py b/nsconfig/core.py index 91c6a35..048984c 100644 --- a/nsconfig/core.py +++ b/nsconfig/core.py @@ -1,5 +1,5 @@ # PyNSC: Main data structures -# (c) 2024 Martin MareÅ¡ +# (c) 2024-2025 Martin MareÅ¡ from collections import defaultdict from datetime import datetime, timedelta @@ -25,6 +25,7 @@ from enum import Enum, auto import hashlib from ipaddress import ip_address, IPv4Address, IPv6Address, ip_network, IPv4Network, IPv6Network import json +import logging from pathlib import Path import socket import sys @@ -37,6 +38,8 @@ from nsconfig.util import IPAddress, IPNetwork, IPAddr, NameParseMode if TYPE_CHECKING: from nsconfig.daemon import NscDaemon +logger = logging.getLogger(__name__) + class NscNode: nsc_zone: 'NscZonePrimary' @@ -376,7 +379,7 @@ class NscZonePrimary(NscZone): else: self.state.serial = prev + 1 if prev >= base + 99: - print(f'WARNING: Serial number overflow for zone {self.name}, current is {self.state.serial}') + logger.warning(f'WARNING: Serial number overflow for zone {self.name}, current is {self.state.serial}') def process(self) -> None: if self.config.add_null_mx: diff --git a/nsconfig/daemon/__init__.py b/nsconfig/daemon/__init__.py index d9bf2c7..4f9c7ae 100644 --- a/nsconfig/daemon/__init__.py +++ b/nsconfig/daemon/__init__.py @@ -1,7 +1,7 @@ # PyNSC: Generic interface for generating daemon configuration -# (c) 2024 Martin MareÅ¡ +# (c) 2024-2025 Martin MareÅ¡ -from io import StringIO +import logging from pathlib import Path import subprocess import sys @@ -12,6 +12,8 @@ from nsconfig.core import Nsc, NscZone DaemonConfig = List[Tuple[str, List[str]]] +logger = logging.getLogger(__name__) + class NscDaemon: nsc: Nsc @@ -58,16 +60,16 @@ class NscDaemon: changed = True if changed: - print('Wrote new daemon configuration') + logger.info('Wrote new daemon configuration') else: - print('Daemon configuration not changed') + logger.info('Daemon configuration not changed') return changed def _run_command(self, argv, **kwargs) -> None: res = subprocess.run(argv, **kwargs) if res.returncode > 0: - print(f'Command failed: {argv}') + logger.error(f'Command failed: {argv}') sys.exit(1) diff --git a/nsconfig/daemon/bind.py b/nsconfig/daemon/bind.py index ea34530..0997a1c 100644 --- a/nsconfig/daemon/bind.py +++ b/nsconfig/daemon/bind.py @@ -1,6 +1,7 @@ # PyNSC: Generator of configuration for BIND 9 -# (c) 2024 Martin MareÅ¡ +# (c) 2024-2025 Martin MareÅ¡ +import logging from pathlib import Path from typing import List @@ -8,6 +9,9 @@ from nsconfig.core import NscZone, NscZonePrimary, NscZoneSecondary, NscZoneAlia from nsconfig.daemon import NscDaemon, DaemonConfig +logger = logging.getLogger(__name__) + + class NscDaemonBind(NscDaemon): config_dir_path: Path config_file: str @@ -72,10 +76,10 @@ class NscDaemonBind(NscDaemon): def reload_zone(self, z: NscZone) -> None: if (isinstance(z, NscZonePrimary) or isinstance(z, NscZoneAlias)) and not self.need_full_reload: - print(f'Reloading zone {z.name}') + logger.info(f'Reloading zone {z.name}') self._run_command([self.control_command, 'reload', z.name]) def reload_daemon(self) -> None: if self.need_full_reload: - print('Reloading daemon') + logger.info('Reloading daemon') self._run_command([self.control_command, 'reload'])