Add methods to more easily add handlers
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 19 Dec 2019 16:16:20 +0000 (17:16 +0100)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Wed, 10 Nov 2021 09:28:29 +0000 (10:28 +0100)
src/log_helpers.py

index 924eb42..288a695 100644 (file)
@@ -43,6 +43,7 @@ Further ideas: ::
 
 import logging
 from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL, NOTSET
+from logging.handlers import RotatingFileHandler
 from math import log10, floor
 import sys
 
@@ -181,6 +182,7 @@ class I2nLogger:
        only counts calls with priority above this logger's level)
     * provides shorter method names: dbg, note, warn, err
     * adds a NullHandler if `streams` and `files` and `handlers` are all `None`
+    * convenience functions to add most frequently used handlers
 
     ..note:: Creating multiple instances with the same name is not allowed and
              will result in an error. Use :py:func:`get_logger` instead of this
@@ -364,6 +366,49 @@ class I2nLogger:
         for handler in self._log.handlers:
             handler.setLevel(self._level)
 
+    def add_handler(self, *args, **kwargs):
+        return self._log.addHandler(*args, **kwargs)
+
+    def add_stream_handler(self, stream=sys.stdout, level='debug'):
+        """
+        Add a stream handler to the current logger that logs to given stream.
+
+        Note that the default here is stdout, not the python-default (stderr).
+        """
+        handler = logging.StreamHandler(stream)
+        handler.setLevel(self._level)
+        self._log.addHandler(handler)
+
+    def add_syslog_handler(self):
+        """Add a handler that logs to syslog."""
+        handler = SysLogHandler(address='/dev/log')
+        handler.setLevel(self._level)
+        self._log.addHandler(handler)
+
+    def add_file_handler(self, filename, mode='a', max_bytes=5*1024*1024,
+                         max_rotations=100, **kwargs):
+        """
+        Add a handler that logs to given file.
+
+        For convenience creates a
+        :py:class:`logging.handlers.RotatingFileHandler` to avoid huge log
+        files filling up the disc in case of error.
+
+        :param str mode: Mode with which to open log file; forwarded to handler
+        :param int max_bytes: Max size in bytes of a log file before it is
+                              renamed to `[filename].1` and logging continues
+                              with an empty `[filename]`.
+        :param int max_rots: Max number of rotated files to keep
+        :param dict kwargs: All other args (e.g. `encoding`) are forwarded to
+                            handler constructor. `maxBytes` and `backupCount`
+                            are overwritten with `max_bytes` and `max_rots`.
+        """
+        kwargs['maxBytes'] = max_bytes
+        kwargs['backupCount'] = max_rotations
+        handler = RotatingFileHandler(filename, mode, **kwargs)
+        handler.setLevel(self._level)
+        self._log.addHandler(handler)
+
 
 def n_digits(number):
     """ returns the number of digits a number has in decimal format