pythonLogs 4.0.4__tar.gz → 4.0.6__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.
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/PKG-INFO +4 -3
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/README.md +3 -1
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/pyproject.toml +1 -2
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/pythonLogs/basic_log.py +8 -1
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/pythonLogs/constants.py +13 -0
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/pythonLogs/factory.py +75 -58
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/pythonLogs/log_utils.py +2 -12
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/pythonLogs/settings.py +1 -1
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/pythonLogs/thread_safety.py +33 -17
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/pythonLogs/timed_rotating.py +1 -1
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/LICENSE +0 -0
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/pythonLogs/.env.example +0 -0
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/pythonLogs/__init__.py +0 -0
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/pythonLogs/memory_utils.py +0 -0
- {pythonlogs-4.0.4 → pythonlogs-4.0.6}/pythonLogs/size_rotating.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pythonLogs
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.6
|
|
4
4
|
Summary: High-performance Python logging library with file rotation and optimized caching for better performance
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: python3,python-3,python,log,logging,logger,logutils,log-utils,pythonLogs
|
|
@@ -21,7 +21,6 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
22
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
23
23
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
-
Requires-Dist: pydantic (>=2.11.7,<3.0.0)
|
|
25
24
|
Requires-Dist: pydantic-settings (>=2.10.1,<3.0.0)
|
|
26
25
|
Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
|
|
27
26
|
Project-URL: Homepage, https://pypi.org/project/pythonLogs
|
|
@@ -35,8 +34,10 @@ Description-Content-Type: text/markdown
|
|
|
35
34
|
[](https://pypi.python.org/pypi/pythonLogs)
|
|
36
35
|
[](https://pepy.tech/projects/pythonLogs)
|
|
37
36
|
[](https://codecov.io/gh/ddc/pythonLogs)
|
|
38
|
-
[](https://github.com/ddc/pythonLogs/actions/workflows/workflow.yml)
|
|
38
|
+
[](https://sonarcloud.io/dashboard?id=ddc_pythonLogs)
|
|
39
39
|
[](https://actions-badge.atrox.dev/ddc/pythonLogs/goto?ref=main)
|
|
40
|
+
[](https://github.com/psf/black)
|
|
40
41
|
[](https://www.python.org/downloads)
|
|
41
42
|
|
|
42
43
|
[](https://github.com/sponsors/ddc)
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
[](https://pypi.python.org/pypi/pythonLogs)
|
|
6
6
|
[](https://pepy.tech/projects/pythonLogs)
|
|
7
7
|
[](https://codecov.io/gh/ddc/pythonLogs)
|
|
8
|
-
[](https://github.com/ddc/pythonLogs/actions/workflows/workflow.yml)
|
|
9
|
+
[](https://sonarcloud.io/dashboard?id=ddc_pythonLogs)
|
|
9
10
|
[](https://actions-badge.atrox.dev/ddc/pythonLogs/goto?ref=main)
|
|
11
|
+
[](https://github.com/psf/black)
|
|
10
12
|
[](https://www.python.org/downloads)
|
|
11
13
|
|
|
12
14
|
[](https://github.com/sponsors/ddc)
|
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "pythonLogs"
|
|
7
|
-
version = "4.0.
|
|
7
|
+
version = "4.0.6"
|
|
8
8
|
description = "High-performance Python logging library with file rotation and optimized caching for better performance"
|
|
9
9
|
license = "MIT"
|
|
10
10
|
readme = "README.md"
|
|
@@ -32,7 +32,6 @@ classifiers = [
|
|
|
32
32
|
|
|
33
33
|
[tool.poetry.dependencies]
|
|
34
34
|
python = "^3.10"
|
|
35
|
-
pydantic = "^2.11.7"
|
|
36
35
|
pydantic-settings = "^2.10.1"
|
|
37
36
|
python-dotenv = "^1.1.1"
|
|
38
37
|
|
|
@@ -34,7 +34,14 @@ class BasicLog:
|
|
|
34
34
|
logger.setLevel(self.level)
|
|
35
35
|
logging.Formatter.converter = get_timezone_function(self.timezone)
|
|
36
36
|
_format = get_format(self.showlocation, self.appname, self.timezone)
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
# Only add handler if logger doesn't have any handlers
|
|
39
|
+
if not logger.handlers:
|
|
40
|
+
handler = logging.StreamHandler()
|
|
41
|
+
formatter = logging.Formatter(_format, datefmt=self.datefmt)
|
|
42
|
+
handler.setFormatter(formatter)
|
|
43
|
+
logger.addHandler(handler)
|
|
44
|
+
|
|
38
45
|
self.logger = logger
|
|
39
46
|
# Register weak reference for memory tracking
|
|
40
47
|
register_logger_weakref(logger)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
+
import logging
|
|
2
3
|
from enum import Enum
|
|
3
4
|
|
|
4
5
|
# File and Directory Constants
|
|
@@ -40,3 +41,15 @@ class RotateWhen(str, Enum):
|
|
|
40
41
|
SUNDAY = "W6"
|
|
41
42
|
HOURLY = "H"
|
|
42
43
|
DAILY = "D"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Level mapping for performance optimization
|
|
47
|
+
LEVEL_MAP = {
|
|
48
|
+
LogLevel.DEBUG.value.lower(): logging.DEBUG,
|
|
49
|
+
LogLevel.WARNING.value.lower(): logging.WARNING,
|
|
50
|
+
LogLevel.WARN.value.lower(): logging.WARNING,
|
|
51
|
+
LogLevel.ERROR.value.lower(): logging.ERROR,
|
|
52
|
+
LogLevel.CRITICAL.value.lower(): logging.CRITICAL,
|
|
53
|
+
LogLevel.CRIT.value.lower(): logging.CRITICAL,
|
|
54
|
+
LogLevel.INFO.value.lower(): logging.INFO,
|
|
55
|
+
}
|
|
@@ -3,6 +3,7 @@ import atexit
|
|
|
3
3
|
import logging
|
|
4
4
|
import threading
|
|
5
5
|
import time
|
|
6
|
+
from dataclasses import dataclass
|
|
6
7
|
from enum import Enum
|
|
7
8
|
from typing import Dict, Optional, Tuple, Union
|
|
8
9
|
from pythonLogs.basic_log import BasicLog
|
|
@@ -12,6 +13,25 @@ from pythonLogs.size_rotating import SizeRotatingLog
|
|
|
12
13
|
from pythonLogs.timed_rotating import TimedRotatingLog
|
|
13
14
|
|
|
14
15
|
|
|
16
|
+
@dataclass
|
|
17
|
+
class LoggerConfig:
|
|
18
|
+
"""Configuration class to group logger parameters"""
|
|
19
|
+
level: Optional[Union[LogLevel, str]] = None
|
|
20
|
+
name: Optional[str] = None
|
|
21
|
+
directory: Optional[str] = None
|
|
22
|
+
filenames: Optional[list | tuple] = None
|
|
23
|
+
encoding: Optional[str] = None
|
|
24
|
+
datefmt: Optional[str] = None
|
|
25
|
+
timezone: Optional[str] = None
|
|
26
|
+
streamhandler: Optional[bool] = None
|
|
27
|
+
showlocation: Optional[bool] = None
|
|
28
|
+
maxmbytes: Optional[int] = None
|
|
29
|
+
when: Optional[Union[RotateWhen, str]] = None
|
|
30
|
+
sufix: Optional[str] = None
|
|
31
|
+
rotateatutc: Optional[bool] = None
|
|
32
|
+
daystokeep: Optional[int] = None
|
|
33
|
+
|
|
34
|
+
|
|
15
35
|
class LoggerType(str, Enum):
|
|
16
36
|
"""Available logger types"""
|
|
17
37
|
BASIC = "basic"
|
|
@@ -80,7 +100,7 @@ class LoggerFactory:
|
|
|
80
100
|
|
|
81
101
|
# Check if logger already exists in the registry
|
|
82
102
|
if name in cls._logger_registry:
|
|
83
|
-
logger,
|
|
103
|
+
logger, _ = cls._logger_registry[name]
|
|
84
104
|
# Update timestamp for LRU tracking
|
|
85
105
|
cls._logger_registry[name] = (logger, time.time())
|
|
86
106
|
return logger
|
|
@@ -189,21 +209,8 @@ class LoggerFactory:
|
|
|
189
209
|
@staticmethod
|
|
190
210
|
def create_logger(
|
|
191
211
|
logger_type: Union[LoggerType, str],
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
directory: Optional[str] = None,
|
|
195
|
-
filenames: Optional[list | tuple] = None,
|
|
196
|
-
encoding: Optional[str] = None,
|
|
197
|
-
datefmt: Optional[str] = None,
|
|
198
|
-
timezone: Optional[str] = None,
|
|
199
|
-
streamhandler: Optional[bool] = None,
|
|
200
|
-
showlocation: Optional[bool] = None, # Size rotating specific
|
|
201
|
-
maxmbytes: Optional[int] = None, # Timed rotating specific
|
|
202
|
-
when: Optional[Union[RotateWhen, str]] = None,
|
|
203
|
-
sufix: Optional[str] = None,
|
|
204
|
-
rotateatutc: Optional[bool] = None,
|
|
205
|
-
# Common
|
|
206
|
-
daystokeep: Optional[int] = None,
|
|
212
|
+
config: Optional[LoggerConfig] = None,
|
|
213
|
+
**kwargs
|
|
207
214
|
) -> logging.Logger:
|
|
208
215
|
|
|
209
216
|
"""
|
|
@@ -211,20 +218,8 @@ class LoggerFactory:
|
|
|
211
218
|
|
|
212
219
|
Args:
|
|
213
220
|
logger_type: Type of logger to create (LoggerType enum or string)
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
directory: Log directory path
|
|
217
|
-
filenames: List/tuple of log filenames
|
|
218
|
-
encoding: File encoding
|
|
219
|
-
datefmt: Date format string
|
|
220
|
-
timezone: Timezone for timestamps
|
|
221
|
-
streamhandler: Enable console output
|
|
222
|
-
showlocation: Show file location in logs
|
|
223
|
-
maxmbytes: Max file size in MB (size rotating only)
|
|
224
|
-
when: When to rotate (RotateWhen enum or string: MIDNIGHT, HOURLY, DAILY, etc.)
|
|
225
|
-
sufix: Date suffix for rotated files (timed rotating only)
|
|
226
|
-
rotateatutc: Rotate at UTC time (timed rotating only)
|
|
227
|
-
daystokeep: Days to keep old logs
|
|
221
|
+
config: LoggerConfig object with logger parameters
|
|
222
|
+
**kwargs: Individual logger parameters (for backward compatibility)
|
|
228
223
|
|
|
229
224
|
Returns:
|
|
230
225
|
Configured logger instance
|
|
@@ -239,50 +234,72 @@ class LoggerFactory:
|
|
|
239
234
|
except ValueError:
|
|
240
235
|
raise ValueError(f"Invalid logger type: {logger_type}. Valid types: {[t.value for t in LoggerType]}")
|
|
241
236
|
|
|
237
|
+
# Merge config and kwargs (kwargs take precedence for backward compatibility)
|
|
238
|
+
if config is None:
|
|
239
|
+
config = LoggerConfig()
|
|
240
|
+
|
|
241
|
+
# Create a new config with kwargs overriding config values
|
|
242
|
+
final_config = LoggerConfig(
|
|
243
|
+
level=kwargs.get('level', config.level),
|
|
244
|
+
name=kwargs.get('name', config.name),
|
|
245
|
+
directory=kwargs.get('directory', config.directory),
|
|
246
|
+
filenames=kwargs.get('filenames', config.filenames),
|
|
247
|
+
encoding=kwargs.get('encoding', config.encoding),
|
|
248
|
+
datefmt=kwargs.get('datefmt', config.datefmt),
|
|
249
|
+
timezone=kwargs.get('timezone', config.timezone),
|
|
250
|
+
streamhandler=kwargs.get('streamhandler', config.streamhandler),
|
|
251
|
+
showlocation=kwargs.get('showlocation', config.showlocation),
|
|
252
|
+
maxmbytes=kwargs.get('maxmbytes', config.maxmbytes),
|
|
253
|
+
when=kwargs.get('when', config.when),
|
|
254
|
+
sufix=kwargs.get('sufix', config.sufix),
|
|
255
|
+
rotateatutc=kwargs.get('rotateatutc', config.rotateatutc),
|
|
256
|
+
daystokeep=kwargs.get('daystokeep', config.daystokeep)
|
|
257
|
+
)
|
|
258
|
+
|
|
242
259
|
# Convert enum values to strings for logger classes
|
|
243
|
-
level_str = level.value if isinstance(level, LogLevel) else level
|
|
244
|
-
when_str = when.value if isinstance(when, RotateWhen) else when
|
|
260
|
+
level_str = final_config.level.value if isinstance(final_config.level, LogLevel) else final_config.level
|
|
261
|
+
when_str = final_config.when.value if isinstance(final_config.when, RotateWhen) else final_config.when
|
|
245
262
|
|
|
246
263
|
# Create logger based on type
|
|
247
264
|
match logger_type:
|
|
248
265
|
case LoggerType.BASIC:
|
|
249
266
|
logger_instance = BasicLog(
|
|
250
267
|
level=level_str,
|
|
251
|
-
name=name,
|
|
252
|
-
encoding=encoding,
|
|
253
|
-
datefmt=datefmt,
|
|
254
|
-
timezone=timezone,
|
|
255
|
-
showlocation=showlocation, )
|
|
268
|
+
name=final_config.name,
|
|
269
|
+
encoding=final_config.encoding,
|
|
270
|
+
datefmt=final_config.datefmt,
|
|
271
|
+
timezone=final_config.timezone,
|
|
272
|
+
showlocation=final_config.showlocation, )
|
|
256
273
|
|
|
257
274
|
case LoggerType.SIZE_ROTATING:
|
|
258
275
|
logger_instance = SizeRotatingLog(
|
|
259
276
|
level=level_str,
|
|
260
|
-
name=name,
|
|
261
|
-
directory=directory,
|
|
262
|
-
filenames=filenames,
|
|
263
|
-
maxmbytes=maxmbytes,
|
|
264
|
-
daystokeep=daystokeep,
|
|
265
|
-
encoding=encoding,
|
|
266
|
-
datefmt=datefmt,
|
|
267
|
-
timezone=timezone,
|
|
268
|
-
streamhandler=streamhandler,
|
|
269
|
-
showlocation=showlocation, )
|
|
277
|
+
name=final_config.name,
|
|
278
|
+
directory=final_config.directory,
|
|
279
|
+
filenames=final_config.filenames,
|
|
280
|
+
maxmbytes=final_config.maxmbytes,
|
|
281
|
+
daystokeep=final_config.daystokeep,
|
|
282
|
+
encoding=final_config.encoding,
|
|
283
|
+
datefmt=final_config.datefmt,
|
|
284
|
+
timezone=final_config.timezone,
|
|
285
|
+
streamhandler=final_config.streamhandler,
|
|
286
|
+
showlocation=final_config.showlocation, )
|
|
270
287
|
|
|
271
288
|
case LoggerType.TIMED_ROTATING:
|
|
272
289
|
logger_instance = TimedRotatingLog(
|
|
273
290
|
level=level_str,
|
|
274
|
-
name=name,
|
|
275
|
-
directory=directory,
|
|
276
|
-
filenames=filenames,
|
|
291
|
+
name=final_config.name,
|
|
292
|
+
directory=final_config.directory,
|
|
293
|
+
filenames=final_config.filenames,
|
|
277
294
|
when=when_str,
|
|
278
|
-
sufix=sufix,
|
|
279
|
-
daystokeep=daystokeep,
|
|
280
|
-
encoding=encoding,
|
|
281
|
-
datefmt=datefmt,
|
|
282
|
-
timezone=timezone,
|
|
283
|
-
streamhandler=streamhandler,
|
|
284
|
-
showlocation=showlocation,
|
|
285
|
-
rotateatutc=rotateatutc, )
|
|
295
|
+
sufix=final_config.sufix,
|
|
296
|
+
daystokeep=final_config.daystokeep,
|
|
297
|
+
encoding=final_config.encoding,
|
|
298
|
+
datefmt=final_config.datefmt,
|
|
299
|
+
timezone=final_config.timezone,
|
|
300
|
+
streamhandler=final_config.streamhandler,
|
|
301
|
+
showlocation=final_config.showlocation,
|
|
302
|
+
rotateatutc=final_config.rotateatutc, )
|
|
286
303
|
|
|
287
304
|
case _:
|
|
288
305
|
raise ValueError(f"Unsupported logger type: {logger_type}")
|
|
@@ -12,7 +12,7 @@ from functools import lru_cache
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from typing import Callable, Set
|
|
14
14
|
from zoneinfo import ZoneInfo
|
|
15
|
-
from pythonLogs.constants import DEFAULT_FILE_MODE,
|
|
15
|
+
from pythonLogs.constants import DEFAULT_FILE_MODE, LEVEL_MAP
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
# Global cache for checked directories with thread safety and size limits
|
|
@@ -182,17 +182,7 @@ def get_level(level: str) -> int:
|
|
|
182
182
|
write_stderr(f"Unable to get log level. Setting default level to: 'INFO' ({logging.INFO})")
|
|
183
183
|
return logging.INFO
|
|
184
184
|
|
|
185
|
-
|
|
186
|
-
LogLevel.DEBUG.value.lower(): logging.DEBUG,
|
|
187
|
-
LogLevel.WARNING.value.lower(): logging.WARNING,
|
|
188
|
-
LogLevel.WARN.value.lower(): logging.WARNING,
|
|
189
|
-
LogLevel.ERROR.value.lower(): logging.ERROR,
|
|
190
|
-
LogLevel.CRITICAL.value.lower(): logging.CRITICAL,
|
|
191
|
-
LogLevel.CRIT.value.lower(): logging.CRITICAL,
|
|
192
|
-
LogLevel.INFO.value.lower(): logging.INFO,
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return level_map.get(level.lower(), logging.INFO)
|
|
185
|
+
return LEVEL_MAP.get(level.lower(), logging.INFO)
|
|
196
186
|
|
|
197
187
|
|
|
198
188
|
def get_log_path(directory: str, filename: str) -> str:
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
2
|
import functools
|
|
3
3
|
import threading
|
|
4
|
-
from typing import Any, Callable, Dict,
|
|
4
|
+
from typing import Any, Callable, Dict, Type, TypeVar
|
|
5
|
+
|
|
5
6
|
|
|
6
7
|
F = TypeVar('F', bound=Callable[..., Any])
|
|
7
8
|
|
|
@@ -58,34 +59,49 @@ def thread_safe(func: F) -> F:
|
|
|
58
59
|
return wrapper
|
|
59
60
|
|
|
60
61
|
|
|
62
|
+
def _get_wrappable_methods(cls: Type) -> list:
|
|
63
|
+
"""Helper function to get methods that should be made thread-safe."""
|
|
64
|
+
return [
|
|
65
|
+
method_name for method_name in dir(cls)
|
|
66
|
+
if (callable(getattr(cls, method_name, None)) and
|
|
67
|
+
not method_name.startswith('_') and
|
|
68
|
+
method_name not in ['__enter__', '__exit__', '__init__'])
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _ensure_class_has_lock(cls: Type) -> None:
|
|
73
|
+
"""Ensure the class has a lock attribute."""
|
|
74
|
+
if not hasattr(cls, '_lock'):
|
|
75
|
+
cls._lock = threading.RLock()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _should_wrap_method(cls: Type, method_name: str, original_method: Any) -> bool:
|
|
79
|
+
"""Check if a method should be wrapped with thread safety."""
|
|
80
|
+
return (hasattr(cls, method_name) and
|
|
81
|
+
callable(original_method) and
|
|
82
|
+
not hasattr(original_method, '_thread_safe_wrapped'))
|
|
83
|
+
|
|
84
|
+
|
|
61
85
|
def auto_thread_safe(thread_safe_methods: list = None):
|
|
62
86
|
"""Class decorator that adds automatic thread safety to specified methods."""
|
|
63
87
|
|
|
64
88
|
def decorator(cls: Type) -> Type:
|
|
65
|
-
|
|
66
|
-
if not hasattr(cls, '_lock'):
|
|
67
|
-
cls._lock = threading.RLock()
|
|
89
|
+
_ensure_class_has_lock(cls)
|
|
68
90
|
|
|
69
91
|
# Store thread-safe methods list
|
|
70
92
|
if thread_safe_methods:
|
|
71
93
|
cls._thread_safe_methods = thread_safe_methods
|
|
72
94
|
|
|
73
95
|
# Get methods to make thread-safe
|
|
74
|
-
methods_to_wrap = thread_safe_methods or
|
|
75
|
-
method_name for method_name in dir(cls)
|
|
76
|
-
if (callable(getattr(cls, method_name, None)) and
|
|
77
|
-
not method_name.startswith('_') and
|
|
78
|
-
method_name not in ['__enter__', '__exit__', '__init__'])
|
|
79
|
-
]
|
|
96
|
+
methods_to_wrap = thread_safe_methods or _get_wrappable_methods(cls)
|
|
80
97
|
|
|
81
98
|
# Wrap each method
|
|
82
99
|
for method_name in methods_to_wrap:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
setattr(cls, method_name, wrapped_method)
|
|
100
|
+
original_method = getattr(cls, method_name, None)
|
|
101
|
+
if _should_wrap_method(cls, method_name, original_method):
|
|
102
|
+
wrapped_method = thread_safe(original_method)
|
|
103
|
+
wrapped_method._thread_safe_wrapped = True
|
|
104
|
+
setattr(cls, method_name, wrapped_method)
|
|
89
105
|
|
|
90
106
|
return cls
|
|
91
107
|
|
|
@@ -132,4 +148,4 @@ class ThreadSafeContext:
|
|
|
132
148
|
return self
|
|
133
149
|
|
|
134
150
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
135
|
-
self.lock.release()
|
|
151
|
+
self.lock.release()
|
|
@@ -10,7 +10,7 @@ from pythonLogs.log_utils import (
|
|
|
10
10
|
get_logger_and_formatter,
|
|
11
11
|
get_stream_handler,
|
|
12
12
|
gzip_file_with_sufix,
|
|
13
|
-
|
|
13
|
+
remove_old_logs,
|
|
14
14
|
)
|
|
15
15
|
from pythonLogs.memory_utils import cleanup_logger_handlers, register_logger_weakref
|
|
16
16
|
from pythonLogs.settings import get_log_settings
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|