]> mj.ucw.cz Git - pynsc.git/commitdiff
Proper logging master
authorMartin Mareš <mj@ucw.cz>
Sun, 23 Nov 2025 12:33:03 +0000 (13:33 +0100)
committerMartin Mareš <mj@ucw.cz>
Sun, 23 Nov 2025 12:33:11 +0000 (13:33 +0100)
TODO
nsconfig/cli.py
nsconfig/core.py
nsconfig/daemon/__init__.py
nsconfig/daemon/bind.py

diff --git a/TODO b/TODO
index 51f4125bdedb4565355af168c8226502ca05957e..b98b5ad24e0fb847b2dc25cbc9257bd49f4cfa9c 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,3 +1,2 @@
 - DNSSEC
-- Logging
 - More records
index 7bebfc6b582b9f4bf7633283b7d95f3467a4d1ee..1f205d2c239d48ecbad2d3c9aca97913a6baf3a4 100644 (file)
@@ -1,13 +1,16 @@
 # PyNSC: Command-line interface
-# (c) 2024 Martin Mareš <mj@ucw.cz>
+# (c) 2024-2025 Martin Mareš <mj@ucw.cz>
 
 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':
index 91c6a35c2cbd073f158936941ac7032a883c2442..048984ce4f1f87b53f3fdb296460cf1b97020df8 100644 (file)
@@ -1,5 +1,5 @@
 # PyNSC: Main data structures
-# (c) 2024 Martin Mareš <mj@ucw.cz>
+# (c) 2024-2025 Martin Mareš <mj@ucw.cz>
 
 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:
index d9bf2c7f27b28624a56c34ba53c833e88fa72dff..4f9c7aebb00083517c0d6396fa566a1d59e86dbd 100644 (file)
@@ -1,7 +1,7 @@
 # PyNSC: Generic interface for generating daemon configuration
-# (c) 2024 Martin Mareš <mj@ucw.cz>
+# (c) 2024-2025 Martin Mareš <mj@ucw.cz>
 
-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)
 
 
index ea345309839c0982f3962c9bb4de3cad142c685f..0997a1c892617c0b63d6d00e0e874c915f9fa5ca 100644 (file)
@@ -1,6 +1,7 @@
 # PyNSC: Generator of configuration for BIND 9
-# (c) 2024 Martin Mareš <mj@ucw.cz>
+# (c) 2024-2025 Martin Mareš <mj@ucw.cz>
 
+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'])