Create more convenient constructor for LogParser
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 19 May 2022 10:19:17 +0000 (12:19 +0200)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 19 May 2022 11:21:16 +0000 (13:21 +0200)
src/log_read.py

index e50e046..3b973bf 100644 (file)
@@ -50,12 +50,12 @@ INTERFACE
 ------------------------------------------------------
 
 """
-
 import os
 import os.path
 import re
 from warnings import warn
 import logging
+from contextlib import contextmanager
 from .iter_helpers import zip_longest
 from .type_helpers import is_str_or_byte, is_file_obj
 
@@ -404,3 +404,25 @@ class LogParser(LineReader):
             else:
                 self.last_unparsed_line = raw_line
                 yield description, None, idx
+
+    @classmethod
+    @contextmanager
+    def create_for(cls, filename, *args, **kwargs):
+        """
+        Open single file, yield LogParser. Ensures file is closed afterwards.
+
+        This allows opening file and creation LogParser for it to one line:
+
+            with LogParser.create_for('/var/log/messages', SYS_LOG_PATTERN) as parser:
+                for _, matches, _ in parser:
+                    try:
+                        print(matches.groupdict())
+                    except Exception:
+                        print(f'UNPARSED: {parser.last_unparsed_line}')
+
+        :param str filename: something that :py:meth:`open` accepts
+        :param args: Forwarded to constructor
+        :param kwargs: Forwarded to constructor
+        """
+        with open(filename) as file_handle:
+            yield cls(file_handle, *args, **kwargs)