Scan a line. Args: line: A log line with a timestamp. Returns: A datetime or `None` if no timestamp was found.
(self, line: str)
| 115 | self._timestamp_formats = TIMESTAMP_FORMATS.copy() |
| 116 | |
| 117 | def scan(self, line: str) -> datetime | None: |
| 118 | """Scan a line. |
| 119 | |
| 120 | Args: |
| 121 | line: A log line with a timestamp. |
| 122 | |
| 123 | Returns: |
| 124 | A datetime or `None` if no timestamp was found. |
| 125 | """ |
| 126 | if len(line) > 10_000: |
| 127 | line = line[:10000] |
| 128 | for index, timestamp_format in enumerate(self._timestamp_formats): |
| 129 | regex, parse_callable = timestamp_format |
| 130 | if (match := re.search(regex, line)) is not None: |
| 131 | try: |
| 132 | if (timestamp := parse_callable(match.group(0))) is None: |
| 133 | continue |
| 134 | except Exception: |
| 135 | continue |
| 136 | if index: |
| 137 | # Put matched format at the top so that |
| 138 | # the next line will be matched quicker |
| 139 | del self._timestamp_formats[index : index + 1] |
| 140 | self._timestamp_formats.insert(0, timestamp_format) |
| 141 | |
| 142 | return timestamp |
| 143 | return None |
| 144 | |
| 145 | |
| 146 | if __name__ == "__main__": |
no outgoing calls
no test coverage detected