logging-ext2 0.0.1__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {logging_ext2-0.0.1 → logging_ext2-0.1.1}/.gitignore +2 -0
- {logging_ext2-0.0.1 → logging_ext2-0.1.1}/PKG-INFO +4 -4
- {logging_ext2-0.0.1 → logging_ext2-0.1.1}/pyproject.toml +3 -3
- {logging_ext2-0.0.1 → logging_ext2-0.1.1}/src/logging_ext2/__about__.py +1 -1
- logging_ext2-0.1.1/src/logging_ext2/handlers.py +71 -0
- logging_ext2-0.1.1/src/logging_ext2/types.py +14 -0
- logging_ext2-0.1.1/tests/__init__.py +51 -0
- logging_ext2-0.0.1/tests/__init__.py +0 -3
- {logging_ext2-0.0.1 → logging_ext2-0.1.1}/LICENSE +0 -0
- {logging_ext2-0.0.1 → logging_ext2-0.1.1}/README.md +0 -0
- {logging_ext2-0.0.1 → logging_ext2-0.1.1}/src/logging_ext2/__init__.py +0 -0
@@ -1,10 +1,10 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: logging-ext2
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.1.1
|
4
4
|
Summary: extend python logging library
|
5
|
-
Project-URL: Documentation, https://github.com/
|
6
|
-
Project-URL: Issues, https://github.com/
|
7
|
-
Project-URL: Source, https://github.com/
|
5
|
+
Project-URL: Documentation, https://github.com/ramwin/logging-ext2#readme
|
6
|
+
Project-URL: Issues, https://github.com/ramwin/logging-ext2/issues
|
7
|
+
Project-URL: Source, https://github.com/ramwin/logging-ext2
|
8
8
|
Author-email: Xiang Wang <ramwin@qq.com>
|
9
9
|
License-Expression: MIT
|
10
10
|
License-File: LICENSE
|
@@ -27,9 +27,9 @@ classifiers = [
|
|
27
27
|
dependencies = []
|
28
28
|
|
29
29
|
[project.urls]
|
30
|
-
Documentation = "https://github.com/
|
31
|
-
Issues = "https://github.com/
|
32
|
-
Source = "https://github.com/
|
30
|
+
Documentation = "https://github.com/ramwin/logging-ext2#readme"
|
31
|
+
Issues = "https://github.com/ramwin/logging-ext2/issues"
|
32
|
+
Source = "https://github.com/ramwin/logging-ext2"
|
33
33
|
|
34
34
|
[tool.hatch.version]
|
35
35
|
path = "src/logging_ext2/__about__.py"
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# Xiang Wang <ramwin@qq.com>
|
4
|
+
|
5
|
+
|
6
|
+
import datetime
|
7
|
+
import subprocess
|
8
|
+
|
9
|
+
from logging import Handler, NOTSET
|
10
|
+
from pathlib import Path
|
11
|
+
from .types import PathWithDatetime
|
12
|
+
|
13
|
+
|
14
|
+
class TimedRotatingFileHandler(Handler):
|
15
|
+
"""
|
16
|
+
compare to logging.TimedRotatingFileHandler, this handler will write
|
17
|
+
log directly to file like 'info.log.2025-04-19'.
|
18
|
+
"""
|
19
|
+
|
20
|
+
def __init__(self, level=NOTSET, filename="log.log",
|
21
|
+
datetime_formatter="%Y-%m-%d", max_keep=10, flat_keep=2):
|
22
|
+
"""
|
23
|
+
params:
|
24
|
+
max_keep: how many files will the rotation keep
|
25
|
+
flat_keep: how many files will stay in text mod, the other (max_keep-flat_keep) will be compressed using gzip
|
26
|
+
"""
|
27
|
+
self.filename = Path(filename).name
|
28
|
+
self.base_dir = Path(filename).parent
|
29
|
+
self.datetime_formatter = datetime_formatter
|
30
|
+
self.current_time_str = self.get_time_str()
|
31
|
+
self.stream = self.init_stream()
|
32
|
+
self.max_keep = max_keep
|
33
|
+
self.flat_keep = flat_keep
|
34
|
+
super().__init__(level)
|
35
|
+
|
36
|
+
def init_stream(self):
|
37
|
+
filepath = self.base_dir.joinpath(
|
38
|
+
f"{self.filename}.{self.get_time_str()}")
|
39
|
+
return open(filepath, "a")
|
40
|
+
|
41
|
+
def get_time_str(self) -> str:
|
42
|
+
return datetime.datetime.now().strftime(self.datetime_formatter)
|
43
|
+
|
44
|
+
def emit(self, record):
|
45
|
+
if self.should_rollover():
|
46
|
+
self.do_rollover()
|
47
|
+
self.stream.write(self.format(record) + "\n")
|
48
|
+
self.stream.flush()
|
49
|
+
|
50
|
+
def should_rollover(self) -> bool:
|
51
|
+
new_time_str = self.get_time_str()
|
52
|
+
return new_time_str != self.current_time_str
|
53
|
+
|
54
|
+
def do_rollover(self):
|
55
|
+
self.stream.close()
|
56
|
+
paths: List[Path] = [
|
57
|
+
i
|
58
|
+
for i in self.base_dir.iterdir()
|
59
|
+
if i.is_file() and i.name.startswith(self.filename)
|
60
|
+
]
|
61
|
+
paths.sort(key=lambda x: x.name, reverse=True)
|
62
|
+
to_delete: Path
|
63
|
+
for to_delete in paths[self.max_keep:]:
|
64
|
+
to_delete.unlink(missing_ok=True)
|
65
|
+
for to_gzip_path in paths[self.flat_keep:self.max_keep]:
|
66
|
+
# here use the system gzip command to ignore exceptions like
|
67
|
+
# permission denied or file not found
|
68
|
+
if to_gzip_path.suffix == ".gz":
|
69
|
+
continue
|
70
|
+
subprocess.run(["gzip", to_gzip_path])
|
71
|
+
self.stream = self.init_stream()
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# Xiang Wang <ramwin@qq.com>
|
4
|
+
|
5
|
+
|
6
|
+
import datetime
|
7
|
+
from dataclasses import dataclass
|
8
|
+
from pathlib import Path
|
9
|
+
|
10
|
+
|
11
|
+
@dataclass
|
12
|
+
class PathWithDatetime:
|
13
|
+
path: Path
|
14
|
+
datetime: datetime.datetime
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# SPDX-FileCopyrightText: 2025-present Xiang Wang <ramwin@qq.com>
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
|
5
|
+
import logging
|
6
|
+
import time
|
7
|
+
import unittest
|
8
|
+
from logging_ext2.handlers import TimedRotatingFileHandler
|
9
|
+
|
10
|
+
|
11
|
+
class Test(unittest.TestCase):
|
12
|
+
|
13
|
+
def test(self):
|
14
|
+
loggera = logging.getLogger("loggera")
|
15
|
+
handlera = TimedRotatingFileHandler(
|
16
|
+
filename="tests/info.log",
|
17
|
+
datetime_formatter="%Y-%m-%d_%H:%M:%S",
|
18
|
+
max_keep=5, flat_keep=2)
|
19
|
+
loggera.addHandler(logging.StreamHandler())
|
20
|
+
loggera.addHandler(handlera)
|
21
|
+
loggera.setLevel(logging.INFO)
|
22
|
+
handlera.setFormatter(logging.Formatter("%(lineno)d %(process)d %(asctime)s %(message)s"))
|
23
|
+
|
24
|
+
loggerb = logging.getLogger("loggerb")
|
25
|
+
loggerb.addHandler(TimedRotatingFileHandler(
|
26
|
+
filename="tests/info.log",
|
27
|
+
datetime_formatter="%Y-%m-%d_%H:%M:%S",
|
28
|
+
max_keep=5, flat_keep=2))
|
29
|
+
loggerb.addHandler(logging.StreamHandler())
|
30
|
+
loggerb.setLevel(logging.INFO)
|
31
|
+
|
32
|
+
loggera.info("first")
|
33
|
+
loggera.info("second")
|
34
|
+
loggera.info("third")
|
35
|
+
loggerb.info("first")
|
36
|
+
loggerb.info("second")
|
37
|
+
loggerb.info("third")
|
38
|
+
time.sleep(1)
|
39
|
+
loggera.info("first")
|
40
|
+
loggera.info("second")
|
41
|
+
loggera.info("third")
|
42
|
+
loggerb.info("first")
|
43
|
+
loggerb.info("second")
|
44
|
+
loggerb.info("third")
|
45
|
+
time.sleep(1)
|
46
|
+
loggera.info("first")
|
47
|
+
loggera.info("second")
|
48
|
+
loggera.info("third")
|
49
|
+
loggerb.info("first")
|
50
|
+
loggerb.info("second")
|
51
|
+
loggerb.info("third")
|
File without changes
|
File without changes
|
File without changes
|