Implement TimedSwitchingFileHandler and prepare for PyPI

This commit is contained in:
Peter J. Holzer 2022-12-10 21:40:04 +01:00
parent 7d8bcbd5bf
commit 7c440b6ed3
5 changed files with 105 additions and 7 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
__pycache__

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Peter J. Holzer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,13 +1,27 @@
TimeoutSwitchingFileHandler
===========================
switchinglogfilehandlers
========================
This is a logging file handler for the Python logging system.
It automatically closes the log file after a period of inactivity
(or after the file has been open for some time whichever comes first)
and then opens a new file at the next emit.
A collection of switching log file handlers for the Python logging system.
Unlike the *rotating* log file handlers in the Python core which always
write to a file with a fixed name and peridically rename that, these
handlers always open a new file with a unique name - old files will
never be renamed.
TimedSwitchingFileHandler
-------------------------
This file handler starts a new file at regular intervals, comparable to
the TimedRotatingFileHandler.
TimeoutSwitchingFileHandler
---------------------------
This file handler automatically closes the log file after a period of
inactivity (or after the file has been open for some time whichever
comes first) and then opens a new file at the next emit.
This is useful for long-running processes where short periods of
activity alternate with periods of inactivity. Log switchs will
activity alternate with periods of inactivity. Log switchse will
typically occur during inactivity, so each log file will include one
complete active period. Also, since the log files are closed, they can
be safely compressed or removed.

23
pyproject.toml Normal file
View File

@ -0,0 +1,23 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "switchinglogfilehandlers"
version = "0.0.3"
authors = [
{ name="Peter J. Holzer", email="hjp@hjp.at" },
]
description = "A collection of switching log file handlers"
readme = "README.md"
requires-python = ">=3.7"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
[project.urls]
"Homepage" = "https://git.hjp.at:3000/hjp/switchinglogfilehandlers"
"Bug Tracker" = "https://git.hjp.at:3000/hjp/switchinglogfilehandlers/issues"

View File

@ -40,3 +40,42 @@ class TimeoutSwitchingFileHandler(logging.Handler):
self.fh.close()
self.fh = None
self.release()
class TimedSwitchingFileHandler(logging.Handler):
def __init__(self, filename, when='h', utc=False):
super().__init__()
self.basename = filename
when = when.lower()
if when == 's':
self.timestamp_format = "%Y-%m-%d-%H-%M-%S"
elif when == 'm':
self.timestamp_format = "%Y-%m-%d-%H-%M"
elif when == 'h':
self.timestamp_format = "%Y-%m-%d-%H"
elif when == 'd':
self.timestamp_format = "%Y-%m-%d"
elif when == 'w':
self.timestamp_format = "%Gw%V"
else:
raise ValueError(f"Unknown value “{when}” for when")
self.utc = utc
self.current_filename = None
self.fh = None
def emit(self, record):
msg = self.format(record)
now = time.time()
if self.utc:
now_tm = time.gmtime(now)
else:
now_tm = time.localtime(now)
new_filename = self.basename + time.strftime(self.timestamp_format, now_tm) + ".log"
if new_filename != self.current_filename:
if self.fh:
self.fh.close()
self.fh = open(new_filename, "a")
self.current_filename = new_filename
self.fh.write(msg)
self.fh.write("\n")
self.fh.flush()