]> 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
 - DNSSEC
-- Logging
 - More records
 - More records
index 7bebfc6b582b9f4bf7633283b7d95f3467a4d1ee..1f205d2c239d48ecbad2d3c9aca97913a6baf3a4 100644 (file)
@@ -1,13 +1,16 @@
 # PyNSC: Command-line interface
 # 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 argparse
 from argparse import Namespace
+import logging
 from pathlib import Path
 from texttable import Texttable
 
 from nsconfig.core import Nsc, NscZonePrimary, NscZoneSecondary, NscZoneAlias
 
 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)
 
 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()
 
 
     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')
 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()
 
 
     args = parser.parse_args()
 
+    setup_logging()
+
     nsc.process()
 
     if args.action == 'test':
     nsc.process()
 
     if args.action == 'test':
index 91c6a35c2cbd073f158936941ac7032a883c2442..048984ce4f1f87b53f3fdb296460cf1b97020df8 100644 (file)
@@ -1,5 +1,5 @@
 # PyNSC: Main data structures
 # 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
 
 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 hashlib
 from ipaddress import ip_address, IPv4Address, IPv6Address, ip_network, IPv4Network, IPv6Network
 import json
+import logging
 from pathlib import Path
 import socket
 import sys
 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
 
 if TYPE_CHECKING:
     from nsconfig.daemon import NscDaemon
 
+logger = logging.getLogger(__name__)
+
 
 class NscNode:
     nsc_zone: 'NscZonePrimary'
 
 class NscNode:
     nsc_zone: 'NscZonePrimary'
@@ -376,7 +379,7 @@ class NscZonePrimary(NscZone):
             else:
                 self.state.serial = prev + 1
                 if prev >= base + 99:
             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:
 
     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
 # 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
 from pathlib import Path
 import subprocess
 import sys
@@ -12,6 +12,8 @@ from nsconfig.core import Nsc, NscZone
 
 DaemonConfig = List[Tuple[str, List[str]]]
 
 
 DaemonConfig = List[Tuple[str, List[str]]]
 
+logger = logging.getLogger(__name__)
+
 
 class NscDaemon:
     nsc: Nsc
 
 class NscDaemon:
     nsc: Nsc
@@ -58,16 +60,16 @@ class NscDaemon:
                 changed = True
 
         if changed:
                 changed = True
 
         if changed:
-            print('Wrote new daemon configuration')
+            logger.info('Wrote new daemon configuration')
         else:
         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:
 
         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)
 
 
             sys.exit(1)
 
 
index ea345309839c0982f3962c9bb4de3cad142c685f..0997a1c892617c0b63d6d00e0e874c915f9fa5ca 100644 (file)
@@ -1,6 +1,7 @@
 # PyNSC: Generator of configuration for BIND 9
 # 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
 
 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
 
 
 from nsconfig.daemon import NscDaemon, DaemonConfig
 
 
+logger = logging.getLogger(__name__)
+
+
 class NscDaemonBind(NscDaemon):
     config_dir_path: Path
     config_file: str
 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:
 
     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:
             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'])
             self._run_command([self.control_command, 'reload'])