orionis 0.404.0__py3-none-any.whl → 0.405.0__py3-none-any.whl
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.
- orionis/foundation/config/logging/entities/chunked.py +10 -2
- orionis/foundation/config/logging/entities/daily.py +10 -2
- orionis/foundation/config/logging/entities/hourly.py +10 -2
- orionis/foundation/config/logging/entities/monthly.py +10 -2
- orionis/foundation/config/logging/entities/stack.py +11 -3
- orionis/foundation/config/logging/entities/weekly.py +10 -2
- orionis/foundation/config/logging/validators/path.py +6 -0
- orionis/metadata/framework.py +1 -1
- orionis/services/log/handlers/filename.py +64 -0
- orionis/services/log/handlers/size_rotating.py +9 -40
- orionis/services/log/handlers/timed_rotating.py +9 -41
- orionis/services/log/log_service.py +9 -52
- {orionis-0.404.0.dist-info → orionis-0.405.0.dist-info}/METADATA +1 -1
- {orionis-0.404.0.dist-info → orionis-0.405.0.dist-info}/RECORD +24 -23
- tests/foundation/config/logging/test_foundation_config_logging_chunked.py +12 -34
- tests/foundation/config/logging/test_foundation_config_logging_daily.py +11 -11
- tests/foundation/config/logging/test_foundation_config_logging_hourly.py +7 -8
- tests/foundation/config/logging/test_foundation_config_logging_monthly.py +7 -10
- tests/foundation/config/logging/test_foundation_config_logging_stack.py +6 -11
- tests/foundation/config/logging/test_foundation_config_logging_weekly.py +6 -5
- {orionis-0.404.0.dist-info → orionis-0.405.0.dist-info}/WHEEL +0 -0
- {orionis-0.404.0.dist-info → orionis-0.405.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.404.0.dist-info → orionis-0.405.0.dist-info}/top_level.txt +0 -0
- {orionis-0.404.0.dist-info → orionis-0.405.0.dist-info}/zip-safe +0 -0
|
@@ -26,10 +26,10 @@ class Chunked(BaseConfigEntity):
|
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
28
|
path: str = field(
|
|
29
|
-
default = 'storage/log/
|
|
29
|
+
default = 'storage/log/chunked.log',
|
|
30
30
|
metadata = {
|
|
31
31
|
"description": "The file path where the log is stored.",
|
|
32
|
-
"default": "storage/log/
|
|
32
|
+
"default": "storage/log/chunked.log",
|
|
33
33
|
},
|
|
34
34
|
)
|
|
35
35
|
|
|
@@ -78,6 +78,14 @@ class Chunked(BaseConfigEntity):
|
|
|
78
78
|
# Validate 'level' using the IsValidLevel validator
|
|
79
79
|
IsValidLevel(self.level)
|
|
80
80
|
|
|
81
|
+
# Assign the level value.
|
|
82
|
+
if isinstance(self.level, Level):
|
|
83
|
+
self.level = self.level.value
|
|
84
|
+
elif isinstance(self.level, str):
|
|
85
|
+
self.level = Level[self.level.strip().upper()].value
|
|
86
|
+
elif isinstance(self.level, int):
|
|
87
|
+
self.level = self.level
|
|
88
|
+
|
|
81
89
|
# Validate 'mb_size'
|
|
82
90
|
if not isinstance(self.mb_size, int):
|
|
83
91
|
raise OrionisIntegrityException(
|
|
@@ -18,10 +18,10 @@ class Daily(BaseConfigEntity):
|
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
20
|
path: str = field(
|
|
21
|
-
default = 'storage/log/
|
|
21
|
+
default = 'storage/log/daily.log',
|
|
22
22
|
metadata = {
|
|
23
23
|
"description": "The file path where the log is stored.",
|
|
24
|
-
"default": "storage/log/
|
|
24
|
+
"default": "storage/log/daily.log",
|
|
25
25
|
},
|
|
26
26
|
)
|
|
27
27
|
|
|
@@ -63,6 +63,14 @@ class Daily(BaseConfigEntity):
|
|
|
63
63
|
# Validate 'level' using the IsValidLevel validator
|
|
64
64
|
IsValidLevel(self.level)
|
|
65
65
|
|
|
66
|
+
# Assign the level value.
|
|
67
|
+
if isinstance(self.level, Level):
|
|
68
|
+
self.level = self.level.value
|
|
69
|
+
elif isinstance(self.level, str):
|
|
70
|
+
self.level = Level[self.level.strip().upper()].value
|
|
71
|
+
elif isinstance(self.level, int):
|
|
72
|
+
self.level = self.level
|
|
73
|
+
|
|
66
74
|
# Validate 'retention_days'
|
|
67
75
|
if not isinstance(self.retention_days, int):
|
|
68
76
|
raise OrionisIntegrityException(
|
|
@@ -16,10 +16,10 @@ class Hourly(BaseConfigEntity):
|
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
18
|
path: str = field(
|
|
19
|
-
default = 'storage/log/
|
|
19
|
+
default = 'storage/log/hourly.log',
|
|
20
20
|
metadata = {
|
|
21
21
|
"description": "The file path where the log is stored.",
|
|
22
|
-
"default": "storage/log/
|
|
22
|
+
"default": "storage/log/hourly.log",
|
|
23
23
|
},
|
|
24
24
|
)
|
|
25
25
|
|
|
@@ -56,6 +56,14 @@ class Hourly(BaseConfigEntity):
|
|
|
56
56
|
# Validate 'level' using the IsValidLevel validator
|
|
57
57
|
IsValidLevel(self.level)
|
|
58
58
|
|
|
59
|
+
# Assign the level value.
|
|
60
|
+
if isinstance(self.level, Level):
|
|
61
|
+
self.level = self.level.value
|
|
62
|
+
elif isinstance(self.level, str):
|
|
63
|
+
self.level = Level[self.level.strip().upper()].value
|
|
64
|
+
elif isinstance(self.level, int):
|
|
65
|
+
self.level = self.level
|
|
66
|
+
|
|
59
67
|
# Validate 'retention_hours'
|
|
60
68
|
if not isinstance(self.retention_hours, int) or self.retention_hours < 0:
|
|
61
69
|
raise OrionisIntegrityException(
|
|
@@ -16,10 +16,10 @@ class Monthly(BaseConfigEntity):
|
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
18
|
path: str = field(
|
|
19
|
-
default = 'storage/log/
|
|
19
|
+
default = 'storage/log/monthly.log',
|
|
20
20
|
metadata = {
|
|
21
21
|
"description": "The file path where the log is stored.",
|
|
22
|
-
"default": "storage/log/
|
|
22
|
+
"default": "storage/log/monthly.log",
|
|
23
23
|
},
|
|
24
24
|
)
|
|
25
25
|
|
|
@@ -55,6 +55,14 @@ class Monthly(BaseConfigEntity):
|
|
|
55
55
|
# Validate 'level' using the IsValidLevel validator
|
|
56
56
|
IsValidLevel(self.level)
|
|
57
57
|
|
|
58
|
+
# Assign the level value.
|
|
59
|
+
if isinstance(self.level, Level):
|
|
60
|
+
self.level = self.level.value
|
|
61
|
+
elif isinstance(self.level, str):
|
|
62
|
+
self.level = Level[self.level.strip().upper()].value
|
|
63
|
+
elif isinstance(self.level, int):
|
|
64
|
+
self.level = self.level
|
|
65
|
+
|
|
58
66
|
# Validate 'retention_months'
|
|
59
67
|
if not isinstance(self.retention_months, int):
|
|
60
68
|
raise OrionisIntegrityException(
|
|
@@ -10,10 +10,10 @@ class Stack(BaseConfigEntity):
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
path: str = field(
|
|
13
|
-
default = 'storage/log/
|
|
13
|
+
default = 'storage/log/stack.log',
|
|
14
14
|
metadata = {
|
|
15
15
|
"description": "The file path where the log is stored.",
|
|
16
|
-
"default": "storage/log/
|
|
16
|
+
"default": "storage/log/stack.log",
|
|
17
17
|
},
|
|
18
18
|
)
|
|
19
19
|
|
|
@@ -37,4 +37,12 @@ class Stack(BaseConfigEntity):
|
|
|
37
37
|
IsValidPath(self.path)
|
|
38
38
|
|
|
39
39
|
# Validate 'level' using the IsValidLevel validator
|
|
40
|
-
IsValidLevel(self.level)
|
|
40
|
+
IsValidLevel(self.level)
|
|
41
|
+
|
|
42
|
+
# Assign the level value.
|
|
43
|
+
if isinstance(self.level, Level):
|
|
44
|
+
self.level = self.level.value
|
|
45
|
+
elif isinstance(self.level, str):
|
|
46
|
+
self.level = Level[self.level.strip().upper()].value
|
|
47
|
+
elif isinstance(self.level, int):
|
|
48
|
+
self.level = self.level
|
|
@@ -16,10 +16,10 @@ class Weekly(BaseConfigEntity):
|
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
18
|
path: str = field(
|
|
19
|
-
default = 'storage/log/
|
|
19
|
+
default = 'storage/log/weekly.log',
|
|
20
20
|
metadata = {
|
|
21
21
|
"description": "The file path where the log is stored.",
|
|
22
|
-
"default": "storage/log/
|
|
22
|
+
"default": "storage/log/weekly.log",
|
|
23
23
|
},
|
|
24
24
|
)
|
|
25
25
|
|
|
@@ -57,6 +57,14 @@ class Weekly(BaseConfigEntity):
|
|
|
57
57
|
# Validate 'level' using the IsValidLevel validator
|
|
58
58
|
IsValidLevel(self.level)
|
|
59
59
|
|
|
60
|
+
# Assign the level value.
|
|
61
|
+
if isinstance(self.level, Level):
|
|
62
|
+
self.level = self.level.value
|
|
63
|
+
elif isinstance(self.level, str):
|
|
64
|
+
self.level = Level[self.level.strip().upper()].value
|
|
65
|
+
elif isinstance(self.level, int):
|
|
66
|
+
self.level = self.level
|
|
67
|
+
|
|
60
68
|
# Validate 'retention_weeks'
|
|
61
69
|
if not isinstance(self.retention_weeks, int):
|
|
62
70
|
raise OrionisIntegrityException(
|
|
@@ -18,6 +18,8 @@ class __IsValidPath:
|
|
|
18
18
|
def __call__(self, value: Any) -> None:
|
|
19
19
|
"""
|
|
20
20
|
Validates that the provided value is a non-empty string representing a file path.
|
|
21
|
+
This method checks if the value is a string and not empty. It also ensures that the string ends with '.log',
|
|
22
|
+
indicating that it is a log file path.
|
|
21
23
|
|
|
22
24
|
Args:
|
|
23
25
|
value (Any): The value to validate as a file path.
|
|
@@ -29,6 +31,10 @@ class __IsValidPath:
|
|
|
29
31
|
raise OrionisIntegrityException(
|
|
30
32
|
f"File cache configuration error: 'path' must be a non-empty string, got {repr(value)}."
|
|
31
33
|
)
|
|
34
|
+
if not value.endswith('.log'):
|
|
35
|
+
raise OrionisIntegrityException(
|
|
36
|
+
f"File cache configuration error: 'path' must end with '.log', got {repr(value)}."
|
|
37
|
+
)
|
|
32
38
|
|
|
33
39
|
# Exported singleton instance
|
|
34
40
|
IsValidPath = __IsValidPath()
|
orionis/metadata/framework.py
CHANGED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
class FileNameLogger:
|
|
6
|
+
|
|
7
|
+
def __init__(self, path: str) -> None:
|
|
8
|
+
"""
|
|
9
|
+
Initialize the FileNameLogger.
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
path : str
|
|
14
|
+
The original file path for the log file.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
# If the path is not a string or is empty, raise a ValueError
|
|
18
|
+
if not isinstance(path, str) or not path:
|
|
19
|
+
raise ValueError("The 'path' parameter must be a non-empty string.")
|
|
20
|
+
|
|
21
|
+
# Set the instance variable __path to the stripped path
|
|
22
|
+
self.__path = path.strip()
|
|
23
|
+
|
|
24
|
+
def generate(self) -> str:
|
|
25
|
+
"""
|
|
26
|
+
Generate a new log file path with a timestamp prefix.
|
|
27
|
+
|
|
28
|
+
Returns
|
|
29
|
+
-------
|
|
30
|
+
str
|
|
31
|
+
The full path to the log file with a timestamped file name.
|
|
32
|
+
|
|
33
|
+
Notes
|
|
34
|
+
-----
|
|
35
|
+
The method ensures that the directory for the log file exists.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
# Split the original path to extract the base name and extension
|
|
39
|
+
if '/' in self.__path:
|
|
40
|
+
parts = self.__path.split('/')
|
|
41
|
+
elif '\\' in self.__path:
|
|
42
|
+
parts = self.__path.split('\\')
|
|
43
|
+
else:
|
|
44
|
+
parts = self.__path.split(os.sep)
|
|
45
|
+
|
|
46
|
+
# Get the base name and extension
|
|
47
|
+
filename, ext = os.path.splitext(parts[-1])
|
|
48
|
+
|
|
49
|
+
# Create the path without the last part
|
|
50
|
+
path = os.path.join(*parts[:-1]) if len(parts) > 1 else ''
|
|
51
|
+
|
|
52
|
+
# Prefix the base name with a timestamp
|
|
53
|
+
prefix = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
54
|
+
|
|
55
|
+
# Join the path, prefix, and filename to create the full path
|
|
56
|
+
full_path = os.path.join(path, f"{prefix}_{filename}{ext}")
|
|
57
|
+
|
|
58
|
+
# Ensure the log directory exists
|
|
59
|
+
log_dir = Path(full_path).parent
|
|
60
|
+
if not log_dir.exists():
|
|
61
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
|
62
|
+
|
|
63
|
+
# Return the full path as a string
|
|
64
|
+
return full_path
|
|
@@ -1,52 +1,21 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
1
|
from logging.handlers import RotatingFileHandler
|
|
3
|
-
from
|
|
4
|
-
import os
|
|
2
|
+
from orionis.services.log.handlers.filename import FileNameLogger
|
|
5
3
|
|
|
6
4
|
class PrefixedSizeRotatingFileHandler(RotatingFileHandler):
|
|
7
5
|
|
|
8
|
-
def rotation_filename(self, default_name):
|
|
6
|
+
def rotation_filename(self, default_name) -> str:
|
|
9
7
|
"""
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
Generate a rotated log filename by prefixing the original filename with a timestamp.
|
|
9
|
+
|
|
10
|
+
Parameters
|
|
11
|
+
----------
|
|
12
|
+
default_name : str
|
|
14
13
|
The original file path to be rotated.
|
|
15
|
-
The new file path with a timestamp prefix added to the base name.
|
|
16
|
-
Notes
|
|
17
|
-
-----
|
|
18
|
-
- The timestamp is based on the current local time.
|
|
19
|
-
- The method ensures that the parent directory for the new file exists.
|
|
20
14
|
|
|
21
15
|
Returns
|
|
22
16
|
-------
|
|
23
17
|
str
|
|
24
|
-
The new
|
|
18
|
+
The new file path with the base name prefixed by a timestamp in the format 'YYYYMMDD_HHMMSS'.
|
|
25
19
|
"""
|
|
26
|
-
# Split the original path to extract the base name and extension
|
|
27
|
-
if '/' in default_name:
|
|
28
|
-
parts = default_name.split('/')
|
|
29
|
-
elif '\\' in default_name:
|
|
30
|
-
parts = default_name.split('\\')
|
|
31
|
-
else:
|
|
32
|
-
parts = default_name.split(os.sep)
|
|
33
|
-
|
|
34
|
-
# Get the base name and extension
|
|
35
|
-
filename, ext = os.path.splitext(parts[-1])
|
|
36
|
-
|
|
37
|
-
# Create the path without the last part
|
|
38
|
-
path = os.path.join(*parts[:-1]) if len(parts) > 1 else ''
|
|
39
|
-
|
|
40
|
-
# Prefix the base name with a timestamp
|
|
41
|
-
prefix = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
42
|
-
|
|
43
|
-
# Join the path, prefix, and filename to create the full path
|
|
44
|
-
full_path = os.path.join(path, f"{prefix}_{filename}{ext}")
|
|
45
|
-
|
|
46
|
-
# Ensure the log directory exists
|
|
47
|
-
log_dir = Path(full_path).parent
|
|
48
|
-
if not log_dir.exists():
|
|
49
|
-
log_dir.mkdir(parents=True, exist_ok=True)
|
|
50
20
|
|
|
51
|
-
|
|
52
|
-
return full_path
|
|
21
|
+
return FileNameLogger(default_name).generate()
|
|
@@ -1,53 +1,21 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
1
|
from logging.handlers import TimedRotatingFileHandler
|
|
3
|
-
from
|
|
4
|
-
import os
|
|
2
|
+
from orionis.services.log.handlers.filename import FileNameLogger
|
|
5
3
|
|
|
6
4
|
class PrefixedTimedRotatingFileHandler(TimedRotatingFileHandler):
|
|
7
5
|
|
|
8
|
-
def rotation_filename(self, default_name):
|
|
6
|
+
def rotation_filename(self, default_name) -> str:
|
|
9
7
|
"""
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
Generate a rotated log filename by prefixing the original filename with a timestamp.
|
|
9
|
+
|
|
10
|
+
Parameters
|
|
11
|
+
----------
|
|
12
|
+
default_name : str
|
|
14
13
|
The original file path to be rotated.
|
|
15
|
-
The new file path with a timestamp prefix added to the base name.
|
|
16
|
-
Notes
|
|
17
|
-
-----
|
|
18
|
-
- The timestamp is based on the current local time.
|
|
19
|
-
- The method ensures that the parent directory for the new file exists.
|
|
20
14
|
|
|
21
15
|
Returns
|
|
22
16
|
-------
|
|
23
17
|
str
|
|
24
|
-
The new
|
|
18
|
+
The new file path with the base name prefixed by a timestamp in the format 'YYYYMMDD_HHMMSS'.
|
|
25
19
|
"""
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
if '/' in default_name:
|
|
29
|
-
parts = default_name.split('/')
|
|
30
|
-
elif '\\' in default_name:
|
|
31
|
-
parts = default_name.split('\\')
|
|
32
|
-
else:
|
|
33
|
-
parts = default_name.split(os.sep)
|
|
34
|
-
|
|
35
|
-
# Get the base name and extension
|
|
36
|
-
filename, ext = os.path.splitext(parts[-1])
|
|
37
|
-
|
|
38
|
-
# Create the path without the last part
|
|
39
|
-
path = os.path.join(*parts[:-1]) if len(parts) > 1 else ''
|
|
40
|
-
|
|
41
|
-
# Prefix the base name with a timestamp
|
|
42
|
-
prefix = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
43
|
-
|
|
44
|
-
# Join the path, prefix, and filename to create the full path
|
|
45
|
-
full_path = os.path.join(path, f"{prefix}_{filename}{ext}")
|
|
46
|
-
|
|
47
|
-
# Ensure the log directory exists
|
|
48
|
-
log_dir = Path(full_path).parent
|
|
49
|
-
if not log_dir.exists():
|
|
50
|
-
log_dir.mkdir(parents=True, exist_ok=True)
|
|
51
|
-
|
|
52
|
-
# Return the full path as a string
|
|
53
|
-
return full_path
|
|
21
|
+
return FileNameLogger(default_name).generate()
|
|
@@ -2,6 +2,7 @@ from orionis.foundation.config.logging.entities.logging import Logging
|
|
|
2
2
|
from orionis.foundation.config.logging.enums import Level
|
|
3
3
|
from orionis.services.log.contracts.log_service import ILoggerService
|
|
4
4
|
from orionis.services.log.exceptions import LoggerRuntimeError
|
|
5
|
+
from orionis.services.log.handlers.filename import FileNameLogger
|
|
5
6
|
from orionis.services.log.handlers.size_rotating import PrefixedSizeRotatingFileHandler
|
|
6
7
|
from orionis.services.log.handlers.timed_rotating import PrefixedTimedRotatingFileHandler
|
|
7
8
|
|
|
@@ -40,7 +41,13 @@ class LoggerService(ILoggerService):
|
|
|
40
41
|
try:
|
|
41
42
|
self.__config = Logging(**kwargs)
|
|
42
43
|
except Exception as e:
|
|
43
|
-
raise LoggerRuntimeError(
|
|
44
|
+
raise LoggerRuntimeError(
|
|
45
|
+
f"Error initializing logger configuration: {e}. "
|
|
46
|
+
"Please check the provided parameters. "
|
|
47
|
+
f"Expected a Logging dataclass or a configuration dictionary. "
|
|
48
|
+
f"Type received: {type(config).__module__}.{type(config).__name__}. "
|
|
49
|
+
f"Expected: {Logging.__module__}.{Logging.__name__} or dict."
|
|
50
|
+
)
|
|
44
51
|
|
|
45
52
|
# If config is a dictionary, convert it to Logging
|
|
46
53
|
elif isinstance(config, dict):
|
|
@@ -53,56 +60,6 @@ class LoggerService(ILoggerService):
|
|
|
53
60
|
# Initialize LoggerService
|
|
54
61
|
self.__initLogger()
|
|
55
62
|
|
|
56
|
-
def __filename(self, original_path:str) -> str:
|
|
57
|
-
"""
|
|
58
|
-
Generates a rotated log filename by prefixing the original filename with a timestamp.
|
|
59
|
-
This method takes an original file path, extracts its directory, base name, and extension,
|
|
60
|
-
and returns a new file path where the base name is prefixed with the current timestamp
|
|
61
|
-
in the format 'YYYYMMDD_HHMMSS'. If the target directory does not exist, it is created.
|
|
62
|
-
The original file path to be rotated.
|
|
63
|
-
The new file path with a timestamp prefix added to the base name.
|
|
64
|
-
Notes
|
|
65
|
-
-----
|
|
66
|
-
- The timestamp is based on the current local time.
|
|
67
|
-
- The method ensures that the parent directory for the new file exists.
|
|
68
|
-
|
|
69
|
-
Returns
|
|
70
|
-
-------
|
|
71
|
-
str
|
|
72
|
-
The new filename with a timestamp prefix in the format 'YYYYMMDD_HHMMSS'.
|
|
73
|
-
"""
|
|
74
|
-
import os
|
|
75
|
-
from datetime import datetime
|
|
76
|
-
from pathlib import Path
|
|
77
|
-
|
|
78
|
-
# Split the original path to extract the base name and extension
|
|
79
|
-
if '/' in original_path:
|
|
80
|
-
parts = original_path.split('/')
|
|
81
|
-
elif '\\' in original_path:
|
|
82
|
-
parts = original_path.split('\\')
|
|
83
|
-
else:
|
|
84
|
-
parts = original_path.split(os.sep)
|
|
85
|
-
|
|
86
|
-
# Get the base name and extension
|
|
87
|
-
filename, ext = os.path.splitext(parts[-1])
|
|
88
|
-
|
|
89
|
-
# Create the path without the last part
|
|
90
|
-
path = os.path.join(*parts[:-1]) if len(parts) > 1 else ''
|
|
91
|
-
|
|
92
|
-
# Prefix the base name with a timestamp
|
|
93
|
-
prefix = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
94
|
-
|
|
95
|
-
# Join the path, prefix, and filename to create the full path
|
|
96
|
-
full_path = os.path.join(path, f"{prefix}_{filename}{ext}")
|
|
97
|
-
|
|
98
|
-
# Ensure the log directory exists
|
|
99
|
-
log_dir = Path(full_path).parent
|
|
100
|
-
if not log_dir.exists():
|
|
101
|
-
log_dir.mkdir(parents=True, exist_ok=True)
|
|
102
|
-
|
|
103
|
-
# Return the full path as a string
|
|
104
|
-
return full_path
|
|
105
|
-
|
|
106
63
|
def __initLogger(self):
|
|
107
64
|
"""
|
|
108
65
|
Configures the logger with the specified settings.
|
|
@@ -131,7 +88,7 @@ class LoggerService(ILoggerService):
|
|
|
131
88
|
config_channels = getattr(self.__config.channels, channel)
|
|
132
89
|
|
|
133
90
|
# Get the path from the channel configuration
|
|
134
|
-
path: str =
|
|
91
|
+
path: str = FileNameLogger(getattr(config_channels, 'path')).generate()
|
|
135
92
|
|
|
136
93
|
# Get Level from the channel configuration, defaulting to 10 (DEBUG)
|
|
137
94
|
level: Level | int = getattr(config_channels, 'level', 10)
|
|
@@ -199,18 +199,18 @@ orionis/foundation/config/filesystems/entitites/public.py,sha256=wB3zjoVzgAdGZw8
|
|
|
199
199
|
orionis/foundation/config/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
200
200
|
orionis/foundation/config/logging/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
201
201
|
orionis/foundation/config/logging/entities/channels.py,sha256=ep4yRP7N84ZCzy3uV0jW7dJdZMG7g1jN8X9TAto2fl0,6077
|
|
202
|
-
orionis/foundation/config/logging/entities/chunked.py,sha256=
|
|
203
|
-
orionis/foundation/config/logging/entities/daily.py,sha256=
|
|
204
|
-
orionis/foundation/config/logging/entities/hourly.py,sha256=
|
|
202
|
+
orionis/foundation/config/logging/entities/chunked.py,sha256=VOrnPzJS9cN2roOqZ-P5TL_-ww1G4ZcX9NZVcu6s6qc,3816
|
|
203
|
+
orionis/foundation/config/logging/entities/daily.py,sha256=4YaSR7bkc21zkSPir4Snvm1RFFqa9QWxbCmlK9-2NCk,3969
|
|
204
|
+
orionis/foundation/config/logging/entities/hourly.py,sha256=ZmkW1jp8DJgBZTnxPlz3dU0mCJiEpnbpN2L_dMOCPZ4,2919
|
|
205
205
|
orionis/foundation/config/logging/entities/logging.py,sha256=Uo937rlOGKKI_7QHPRT5-egfHOf4D6q41j5i8Vkgreo,2781
|
|
206
|
-
orionis/foundation/config/logging/entities/monthly.py,sha256=
|
|
207
|
-
orionis/foundation/config/logging/entities/stack.py,sha256=
|
|
208
|
-
orionis/foundation/config/logging/entities/weekly.py,sha256=
|
|
206
|
+
orionis/foundation/config/logging/entities/monthly.py,sha256=HeyngHxxP2rNwbSrpgwVwz2asfQlj_qWPFhk-wcTR4c,2908
|
|
207
|
+
orionis/foundation/config/logging/entities/stack.py,sha256=0zsLFav9P45kb_89wRnd9Fv-k1RnBf2WSs-5HDrZX9w,1702
|
|
208
|
+
orionis/foundation/config/logging/entities/weekly.py,sha256=nJTFZp2nQHUGAJZaVykQ97--f-0mfzdWnGRG_OV1M6M,2854
|
|
209
209
|
orionis/foundation/config/logging/enums/__init__.py,sha256=QUTGa3iIds08ycR7d-Oqa11P07G-djFLGco9ziJjg0E,57
|
|
210
210
|
orionis/foundation/config/logging/enums/levels.py,sha256=9ELSmWnlaB14uqp5OsKXltsF5aVbxwdLQxYp8pjQAbk,872
|
|
211
211
|
orionis/foundation/config/logging/validators/__init__.py,sha256=ZJmPiObyJgbGCgFFz20Ryu4CX5z-cPW9ZWxirQrJoZ0,121
|
|
212
212
|
orionis/foundation/config/logging/validators/level.py,sha256=FOO_c-EKcIBoCexIT98YMyrs8jDFEYj8eDY5kW3b184,1994
|
|
213
|
-
orionis/foundation/config/logging/validators/path.py,sha256=
|
|
213
|
+
orionis/foundation/config/logging/validators/path.py,sha256=_U1lA3XFAcbaFkoZJQ2xiSD1_Candm1a-dvgGmE_8Ek,1461
|
|
214
214
|
orionis/foundation/config/mail/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
215
215
|
orionis/foundation/config/mail/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
216
216
|
orionis/foundation/config/mail/entities/file.py,sha256=EL9RCFAEJGbdYB-ynXt6wSWVkyuITAJCmTHsknOeuCI,2525
|
|
@@ -254,7 +254,7 @@ orionis/foundation/providers/path_resolver_provider.py,sha256=pJE9HJ4hdsUTZ4TXHL
|
|
|
254
254
|
orionis/foundation/providers/progress_bar_provider.py,sha256=budmwU2N8WE74x7Vq3xDAFHyjtWq0cbrIGbclqw00Mg,607
|
|
255
255
|
orionis/foundation/providers/workers_provider.py,sha256=KZ_c8Rpf0-JhpkVYr8BvhQtXMAc1t_LFh0frHRz_h30,572
|
|
256
256
|
orionis/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
257
|
-
orionis/metadata/framework.py,sha256=
|
|
257
|
+
orionis/metadata/framework.py,sha256=hBFQx1fpJP69hWCNKNK8d99kZm-0JQWAVwGQ6jhNZ70,4960
|
|
258
258
|
orionis/metadata/package.py,sha256=tqLfBRo-w1j_GN4xvzUNFyweWYFS-qhSgAEc-AmCH1M,5452
|
|
259
259
|
orionis/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
260
260
|
orionis/services/asynchrony/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -315,14 +315,15 @@ orionis/services/introspection/modules/contracts/reflection.py,sha256=YLqKg5Ehad
|
|
|
315
315
|
orionis/services/introspection/objects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
316
316
|
orionis/services/introspection/objects/types.py,sha256=vNKWc2b7K-X7B2X8RCimgAWQqbQlVT-aL24nUB8t_yQ,6343
|
|
317
317
|
orionis/services/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
318
|
-
orionis/services/log/log_service.py,sha256=
|
|
318
|
+
orionis/services/log/log_service.py,sha256=IrqAXR4uMlR1kjvh6quPUgf_wJdR9oPe_sQKSoQMQCE,8148
|
|
319
319
|
orionis/services/log/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
320
320
|
orionis/services/log/contracts/log_service.py,sha256=ky7T2EIvJQMV0tKMSwFsUxDBoA24xYro8ChC6-7iUtY,546
|
|
321
321
|
orionis/services/log/exceptions/__init__.py,sha256=PPn_LBV3U-0Yi69ZLDQmlkbmlL1iLTleLw-s88Ipg9o,84
|
|
322
322
|
orionis/services/log/exceptions/runtime.py,sha256=LnaK0w0WlgxtZ9Zjn9RYIgp6fbQZmXZ_1fy9dkuA2jQ,468
|
|
323
323
|
orionis/services/log/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
324
|
-
orionis/services/log/handlers/
|
|
325
|
-
orionis/services/log/handlers/
|
|
324
|
+
orionis/services/log/handlers/filename.py,sha256=nq9eqwFt60oVA5CSsIwO-At37mQgxTd08aYSOpvnIrs,1989
|
|
325
|
+
orionis/services/log/handlers/size_rotating.py,sha256=oE2dQ7GWeKRq5X4j6030mg_ZKZ1urUFXY-ZOG6lSquI,690
|
|
326
|
+
orionis/services/log/handlers/timed_rotating.py,sha256=9wPf-dSt3E-KG8BGusnMp3gXu2oy_RWGGkqDm9zO5FU,701
|
|
326
327
|
orionis/services/paths/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
327
328
|
orionis/services/paths/resolver.py,sha256=9PXTawN3QV142Fhe7C2EqXyAlf984Hc05A_M2cqXAps,3217
|
|
328
329
|
orionis/services/paths/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -399,7 +400,7 @@ orionis/test/records/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
|
|
|
399
400
|
orionis/test/records/logs.py,sha256=EOQcloMVdhlNl2lU9igQz8H4b-OtKtiwh2pgr_QZWOI,13186
|
|
400
401
|
orionis/test/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
401
402
|
orionis/test/view/render.py,sha256=zd7xDvVfmQ2HxZamDTzL2-z2PpyL99EaolbbM7wTah4,5014
|
|
402
|
-
orionis-0.
|
|
403
|
+
orionis-0.405.0.dist-info/licenses/LICENCE,sha256=-_4cF2EBKuYVS_SQpy1uapq0oJPUU1vl_RUWSy2jJTo,1111
|
|
403
404
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
404
405
|
tests/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
405
406
|
tests/example/test_example.py,sha256=yctjQT5ocYEu__kNvJxmQJ-l5yxRMkohwcfYWSjWDVo,25566
|
|
@@ -431,12 +432,12 @@ tests/foundation/config/filesystems/test_foundation_config_filesystems_public.py
|
|
|
431
432
|
tests/foundation/config/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
432
433
|
tests/foundation/config/logging/test_foundation_config_logging.py,sha256=vCYAp8qe6SOo1VJQcb1_R5JMQe00HCl78D4E-43Dxm8,3183
|
|
433
434
|
tests/foundation/config/logging/test_foundation_config_logging_channels.py,sha256=c4OT2o_ml48uqwsCChXffRxFMjqpS3yTplZyvIqsEhA,8990
|
|
434
|
-
tests/foundation/config/logging/test_foundation_config_logging_chunked.py,sha256=
|
|
435
|
-
tests/foundation/config/logging/test_foundation_config_logging_daily.py,sha256=
|
|
436
|
-
tests/foundation/config/logging/test_foundation_config_logging_hourly.py,sha256=
|
|
437
|
-
tests/foundation/config/logging/test_foundation_config_logging_monthly.py,sha256=
|
|
438
|
-
tests/foundation/config/logging/test_foundation_config_logging_stack.py,sha256=
|
|
439
|
-
tests/foundation/config/logging/test_foundation_config_logging_weekly.py,sha256=
|
|
435
|
+
tests/foundation/config/logging/test_foundation_config_logging_chunked.py,sha256=TL-pLde4LAvHTcj01RT_Sa_OkwbQHzKrAH-9UGKVaMY,7021
|
|
436
|
+
tests/foundation/config/logging/test_foundation_config_logging_daily.py,sha256=Sf5vG6WL558N41dukprA5iiT1LoBXi1ak19QGSZpAsI,7076
|
|
437
|
+
tests/foundation/config/logging/test_foundation_config_logging_hourly.py,sha256=zjDDXykck_gH9TLPcoESwgjUd-6qZJDjjFwD_Xz2Yak,6765
|
|
438
|
+
tests/foundation/config/logging/test_foundation_config_logging_monthly.py,sha256=59AKYce42PqVVNGu_FjsQtR2EtXePUvYwgF4MkA01WM,6370
|
|
439
|
+
tests/foundation/config/logging/test_foundation_config_logging_stack.py,sha256=BYTtZmbJlGeW_7qXo7AlyQZOluvZDzMgBTM68hbq2nc,5302
|
|
440
|
+
tests/foundation/config/logging/test_foundation_config_logging_weekly.py,sha256=g-x3VCN_L1jrrSrsW1UkBWYpKeuK5ASAAzhlKQJDkvQ,7697
|
|
440
441
|
tests/foundation/config/mail/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
441
442
|
tests/foundation/config/mail/test_foundation_config_mail.py,sha256=xR3HY218J7vecdM1h0TaAfX4DGl90PUgmktlylT_4S8,4209
|
|
442
443
|
tests/foundation/config/mail/test_foundation_config_mail_file.py,sha256=9apGs381QxaO9gwwDTAtObF61AMFTd61c1Sfx1nZeYM,3023
|
|
@@ -500,8 +501,8 @@ tests/support/wrapper/test_services_wrapper_docdict.py,sha256=nTNrvJkMSPx_aopEQ9
|
|
|
500
501
|
tests/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
501
502
|
tests/testing/test_testing_result.py,sha256=fnH7hjumNSErAFGITJgq2LHxSzvPF2tdtmHL9kyAv-Y,4409
|
|
502
503
|
tests/testing/test_testing_unit.py,sha256=d3CRGo6608fMzYcZKIKapjx_af2aigqWiKSiuK9euIY,7600
|
|
503
|
-
orionis-0.
|
|
504
|
-
orionis-0.
|
|
505
|
-
orionis-0.
|
|
506
|
-
orionis-0.
|
|
507
|
-
orionis-0.
|
|
504
|
+
orionis-0.405.0.dist-info/METADATA,sha256=1u7dsi1VYe_Did8uVReWXV86li9KpwBA6n6qrVtKmKA,4772
|
|
505
|
+
orionis-0.405.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
506
|
+
orionis-0.405.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
|
|
507
|
+
orionis-0.405.0.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
508
|
+
orionis-0.405.0.dist-info/RECORD,,
|
|
@@ -25,7 +25,7 @@ class TestFoundationConfigLoggingChunked(AsyncTestCase):
|
|
|
25
25
|
None
|
|
26
26
|
"""
|
|
27
27
|
chunked = Chunked()
|
|
28
|
-
self.assertEqual(chunked.path, "storage/log/
|
|
28
|
+
self.assertEqual(chunked.path, "storage/log/chunked.log")
|
|
29
29
|
self.assertEqual(chunked.level, Level.INFO.value)
|
|
30
30
|
self.assertEqual(chunked.mb_size, 10)
|
|
31
31
|
self.assertEqual(chunked.files, 5)
|
|
@@ -85,39 +85,19 @@ class TestFoundationConfigLoggingChunked(AsyncTestCase):
|
|
|
85
85
|
"""
|
|
86
86
|
Test validation of the `mb_size` attribute.
|
|
87
87
|
|
|
88
|
-
Ensures that valid integer and string formats are accepted, and invalid
|
|
89
|
-
values raise `OrionisIntegrityException`.
|
|
90
|
-
|
|
91
88
|
Returns
|
|
92
89
|
-------
|
|
93
90
|
None
|
|
94
91
|
"""
|
|
95
|
-
|
|
96
|
-
try:
|
|
97
|
-
Chunked(mb_size=1)
|
|
98
|
-
Chunked(mb_size=100)
|
|
99
|
-
except OrionisIntegrityException:
|
|
100
|
-
self.fail("Valid mb_size should not raise exception")
|
|
101
|
-
|
|
102
|
-
# Test string formats
|
|
103
|
-
chunked = Chunked(mb_size="10MB")
|
|
92
|
+
chunked = Chunked(mb_size=10)
|
|
104
93
|
self.assertEqual(chunked.mb_size, 10)
|
|
105
94
|
|
|
106
|
-
chunked = Chunked(mb_size=
|
|
107
|
-
self.assertEqual(chunked.mb_size,
|
|
108
|
-
|
|
109
|
-
chunked = Chunked(mb_size="10485760B")
|
|
110
|
-
self.assertEqual(chunked.mb_size, 10)
|
|
95
|
+
chunked = Chunked(mb_size=1000)
|
|
96
|
+
self.assertEqual(chunked.mb_size, 1000)
|
|
111
97
|
|
|
112
|
-
# Test invalid cases
|
|
113
|
-
with self.assertRaises(OrionisIntegrityException):
|
|
114
|
-
Chunked(mb_size=0)
|
|
115
|
-
with self.assertRaises(OrionisIntegrityException):
|
|
116
|
-
Chunked(mb_size=-1)
|
|
117
|
-
with self.assertRaises(OrionisIntegrityException):
|
|
118
|
-
Chunked(mb_size="invalid")
|
|
119
98
|
with self.assertRaises(OrionisIntegrityException):
|
|
120
|
-
Chunked(mb_size=
|
|
99
|
+
chunked = Chunked(mb_size=2048)
|
|
100
|
+
self.assertEqual(chunked.mb_size, 2048)
|
|
121
101
|
|
|
122
102
|
async def testFilesValidation(self):
|
|
123
103
|
"""
|
|
@@ -149,16 +129,14 @@ class TestFoundationConfigLoggingChunked(AsyncTestCase):
|
|
|
149
129
|
"""
|
|
150
130
|
Test handling of whitespace in `path` and `level` attributes.
|
|
151
131
|
|
|
152
|
-
Ensures that leading and trailing whitespace in `path` and `level` are
|
|
153
|
-
handled as expected.
|
|
154
|
-
|
|
155
132
|
Returns
|
|
156
133
|
-------
|
|
157
134
|
None
|
|
158
135
|
"""
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
136
|
+
with self.assertRaises(OrionisIntegrityException):
|
|
137
|
+
chunked = Chunked(path=" logs/app.log ", level=" debug ")
|
|
138
|
+
self.assertEqual(chunked.path, " logs/app.log ")
|
|
139
|
+
self.assertEqual(chunked.level, Level.DEBUG.value)
|
|
162
140
|
|
|
163
141
|
async def testToDictMethod(self):
|
|
164
142
|
"""
|
|
@@ -175,7 +153,7 @@ class TestFoundationConfigLoggingChunked(AsyncTestCase):
|
|
|
175
153
|
chunked_dict = chunked.toDict()
|
|
176
154
|
|
|
177
155
|
self.assertIsInstance(chunked_dict, dict)
|
|
178
|
-
self.assertEqual(chunked_dict['path'], "storage/log/
|
|
156
|
+
self.assertEqual(chunked_dict['path'], "storage/log/chunked.log")
|
|
179
157
|
self.assertEqual(chunked_dict['level'], Level.INFO.value)
|
|
180
158
|
self.assertEqual(chunked_dict['mb_size'], 10)
|
|
181
159
|
self.assertEqual(chunked_dict['files'], 5)
|
|
@@ -199,7 +177,7 @@ class TestFoundationConfigLoggingChunked(AsyncTestCase):
|
|
|
199
177
|
)
|
|
200
178
|
chunked_dict = custom_chunked.toDict()
|
|
201
179
|
self.assertEqual(chunked_dict['path'], "custom/logs/app.log")
|
|
202
|
-
self.assertEqual(chunked_dict['level'],
|
|
180
|
+
self.assertEqual(chunked_dict['level'], 30)
|
|
203
181
|
self.assertEqual(chunked_dict['mb_size'], 20)
|
|
204
182
|
self.assertEqual(chunked_dict['files'], 10)
|
|
205
183
|
|
|
@@ -25,10 +25,10 @@ class TestFoundationConfigLoggingDaily(AsyncTestCase):
|
|
|
25
25
|
None
|
|
26
26
|
"""
|
|
27
27
|
daily = Daily()
|
|
28
|
-
self.assertEqual(daily.path, "storage/log/
|
|
28
|
+
self.assertEqual(daily.path, "storage/log/daily.log")
|
|
29
29
|
self.assertEqual(daily.level, Level.INFO.value)
|
|
30
30
|
self.assertEqual(daily.retention_days, 7)
|
|
31
|
-
self.assertEqual(daily.at, "00:00
|
|
31
|
+
self.assertEqual(daily.at, "00:00")
|
|
32
32
|
|
|
33
33
|
async def testPathValidation(self):
|
|
34
34
|
"""
|
|
@@ -122,7 +122,7 @@ class TestFoundationConfigLoggingDaily(AsyncTestCase):
|
|
|
122
122
|
"""
|
|
123
123
|
# Test time object
|
|
124
124
|
daily = Daily(at=time(12, 30))
|
|
125
|
-
self.assertEqual(daily.at, "12:30
|
|
125
|
+
self.assertEqual(daily.at, "12:30")
|
|
126
126
|
|
|
127
127
|
# Test invalid type
|
|
128
128
|
with self.assertRaises(OrionisIntegrityException):
|
|
@@ -134,15 +134,15 @@ class TestFoundationConfigLoggingDaily(AsyncTestCase):
|
|
|
134
134
|
"""
|
|
135
135
|
Test handling of whitespace in path and level attributes.
|
|
136
136
|
|
|
137
|
-
Ensures that whitespace in path and level is preserved or handled as expected.
|
|
138
|
-
|
|
139
137
|
Returns
|
|
140
138
|
-------
|
|
141
139
|
None
|
|
142
140
|
"""
|
|
143
|
-
|
|
144
|
-
self.
|
|
145
|
-
|
|
141
|
+
|
|
142
|
+
with self.assertRaises(OrionisIntegrityException):
|
|
143
|
+
daily = Daily(path=" logs/app.log ", level=" debug ")
|
|
144
|
+
self.assertEqual(daily.path, " logs/app.log ")
|
|
145
|
+
self.assertEqual(daily.level, Level.DEBUG.value)
|
|
146
146
|
|
|
147
147
|
async def testToDictMethod(self):
|
|
148
148
|
"""
|
|
@@ -159,10 +159,10 @@ class TestFoundationConfigLoggingDaily(AsyncTestCase):
|
|
|
159
159
|
daily_dict = daily.toDict()
|
|
160
160
|
|
|
161
161
|
self.assertIsInstance(daily_dict, dict)
|
|
162
|
-
self.assertEqual(daily_dict['path'], "storage/log/
|
|
162
|
+
self.assertEqual(daily_dict['path'], "storage/log/daily.log")
|
|
163
163
|
self.assertEqual(daily_dict['level'], Level.INFO.value)
|
|
164
164
|
self.assertEqual(daily_dict['retention_days'], 7)
|
|
165
|
-
self.assertEqual(daily_dict['at'], "00:00
|
|
165
|
+
self.assertEqual(daily_dict['at'], "00:00")
|
|
166
166
|
|
|
167
167
|
async def testCustomValuesToDict(self):
|
|
168
168
|
"""
|
|
@@ -184,7 +184,7 @@ class TestFoundationConfigLoggingDaily(AsyncTestCase):
|
|
|
184
184
|
self.assertEqual(daily_dict['path'], "custom/logs/app.log")
|
|
185
185
|
self.assertEqual(daily_dict['level'], Level.WARNING.value)
|
|
186
186
|
self.assertEqual(daily_dict['retention_days'], 14)
|
|
187
|
-
self.assertEqual(daily_dict['at'], "23:59
|
|
187
|
+
self.assertEqual(daily_dict['at'], "23:59")
|
|
188
188
|
|
|
189
189
|
async def testHashability(self):
|
|
190
190
|
"""
|
|
@@ -24,7 +24,7 @@ class TestFoundationConfigLoggingHourly(AsyncTestCase):
|
|
|
24
24
|
None
|
|
25
25
|
"""
|
|
26
26
|
hourly = Hourly()
|
|
27
|
-
self.assertEqual(hourly.path, "storage/log/
|
|
27
|
+
self.assertEqual(hourly.path, "storage/log/hourly.log")
|
|
28
28
|
self.assertEqual(hourly.level, Level.INFO.value)
|
|
29
29
|
self.assertEqual(hourly.retention_hours, 24)
|
|
30
30
|
|
|
@@ -113,16 +113,15 @@ class TestFoundationConfigLoggingHourly(AsyncTestCase):
|
|
|
113
113
|
"""
|
|
114
114
|
Test whitespace handling in path and level attributes.
|
|
115
115
|
|
|
116
|
-
Verifies that leading and trailing whitespace in the `path` and `level`
|
|
117
|
-
attributes are handled as expected.
|
|
118
|
-
|
|
119
116
|
Returns
|
|
120
117
|
-------
|
|
121
118
|
None
|
|
122
119
|
"""
|
|
123
|
-
|
|
124
|
-
self.
|
|
125
|
-
|
|
120
|
+
|
|
121
|
+
with self.assertRaises(OrionisIntegrityException):
|
|
122
|
+
hourly = Hourly(path=" logs/app.log ", level=" debug ")
|
|
123
|
+
self.assertEqual(hourly.path, " logs/app.log ")
|
|
124
|
+
self.assertEqual(hourly.level, Level.DEBUG.value)
|
|
126
125
|
|
|
127
126
|
async def testToDictMethod(self):
|
|
128
127
|
"""
|
|
@@ -138,7 +137,7 @@ class TestFoundationConfigLoggingHourly(AsyncTestCase):
|
|
|
138
137
|
hourly = Hourly()
|
|
139
138
|
hourly_dict = hourly.toDict()
|
|
140
139
|
self.assertIsInstance(hourly_dict, dict)
|
|
141
|
-
self.assertEqual(hourly_dict['path'], "storage/log/
|
|
140
|
+
self.assertEqual(hourly_dict['path'], "storage/log/hourly.log")
|
|
142
141
|
self.assertEqual(hourly_dict['level'], Level.INFO.value)
|
|
143
142
|
self.assertEqual(hourly_dict['retention_hours'], 24)
|
|
144
143
|
|
|
@@ -25,7 +25,7 @@ class TestFoundationConfigLoggingMonthly(AsyncTestCase):
|
|
|
25
25
|
- Default retention_months is 4.
|
|
26
26
|
"""
|
|
27
27
|
monthly = Monthly()
|
|
28
|
-
self.assertEqual(monthly.path, "storage/log/
|
|
28
|
+
self.assertEqual(monthly.path, "storage/log/monthly.log")
|
|
29
29
|
self.assertEqual(monthly.level, Level.INFO.value)
|
|
30
30
|
self.assertEqual(monthly.retention_months, 4)
|
|
31
31
|
|
|
@@ -106,15 +106,12 @@ class TestFoundationConfigLoggingMonthly(AsyncTestCase):
|
|
|
106
106
|
async def testWhitespaceHandling(self):
|
|
107
107
|
"""
|
|
108
108
|
Test whitespace handling in path and level attributes.
|
|
109
|
-
|
|
110
|
-
Verifies
|
|
111
|
-
--------
|
|
112
|
-
- Whitespace in path is preserved.
|
|
113
|
-
- Whitespace in level is handled correctly.
|
|
114
109
|
"""
|
|
115
|
-
|
|
116
|
-
self.
|
|
117
|
-
|
|
110
|
+
|
|
111
|
+
with self.assertRaises(OrionisIntegrityException):
|
|
112
|
+
monthly = Monthly(path=" logs/app.log ", level=" debug ")
|
|
113
|
+
self.assertEqual(monthly.path, " logs/app.log ")
|
|
114
|
+
self.assertEqual(monthly.level, Level.DEBUG.value)
|
|
118
115
|
|
|
119
116
|
async def testToDictMethod(self):
|
|
120
117
|
"""
|
|
@@ -127,7 +124,7 @@ class TestFoundationConfigLoggingMonthly(AsyncTestCase):
|
|
|
127
124
|
monthly = Monthly()
|
|
128
125
|
monthly_dict = monthly.toDict()
|
|
129
126
|
self.assertIsInstance(monthly_dict, dict)
|
|
130
|
-
self.assertEqual(monthly_dict['path'], "storage/log/
|
|
127
|
+
self.assertEqual(monthly_dict['path'], "storage/log/monthly.log")
|
|
131
128
|
self.assertEqual(monthly_dict['level'], Level.INFO.value)
|
|
132
129
|
self.assertEqual(monthly_dict['retention_months'], 4)
|
|
133
130
|
|
|
@@ -20,7 +20,7 @@ class TestFoundationConfigLoggingStack(AsyncTestCase):
|
|
|
20
20
|
Verifies that the default path and level match the expected values from the class definition.
|
|
21
21
|
"""
|
|
22
22
|
stack = Stack()
|
|
23
|
-
self.assertEqual(stack.path, "storage/log/
|
|
23
|
+
self.assertEqual(stack.path, "storage/log/stack.log")
|
|
24
24
|
self.assertEqual(stack.level, Level.INFO.value)
|
|
25
25
|
|
|
26
26
|
async def testPathValidation(self):
|
|
@@ -84,17 +84,12 @@ class TestFoundationConfigLoggingStack(AsyncTestCase):
|
|
|
84
84
|
async def testWhitespaceHandling(self):
|
|
85
85
|
"""
|
|
86
86
|
Test handling of whitespace in path and level attributes.
|
|
87
|
-
|
|
88
|
-
Ensures that whitespace is preserved in the path and trimmed in level strings.
|
|
89
87
|
"""
|
|
90
|
-
# Test path with whitespace
|
|
91
|
-
spaced_path = " logs/app.log "
|
|
92
|
-
stack = Stack(path=spaced_path)
|
|
93
|
-
self.assertEqual(stack.path, spaced_path)
|
|
94
88
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
89
|
+
with self.assertRaises(OrionisIntegrityException):
|
|
90
|
+
spaced_path = " logs/app.log "
|
|
91
|
+
stack = Stack(path=spaced_path)
|
|
92
|
+
self.assertEqual(stack.path, spaced_path)
|
|
98
93
|
|
|
99
94
|
async def testToDictMethod(self):
|
|
100
95
|
"""
|
|
@@ -111,7 +106,7 @@ class TestFoundationConfigLoggingStack(AsyncTestCase):
|
|
|
111
106
|
stack_dict = stack.toDict()
|
|
112
107
|
|
|
113
108
|
self.assertIsInstance(stack_dict, dict)
|
|
114
|
-
self.assertEqual(stack_dict['path'], "storage/log/
|
|
109
|
+
self.assertEqual(stack_dict['path'], "storage/log/stack.log")
|
|
115
110
|
self.assertEqual(stack_dict['level'], Level.INFO.value)
|
|
116
111
|
|
|
117
112
|
async def testCustomValuesToDict(self):
|
|
@@ -49,7 +49,7 @@ class TestFoundationConfigLoggingWeekly(AsyncTestCase):
|
|
|
49
49
|
None
|
|
50
50
|
"""
|
|
51
51
|
weekly = Weekly()
|
|
52
|
-
self.assertEqual(weekly.path, "storage/log/
|
|
52
|
+
self.assertEqual(weekly.path, "storage/log/weekly.log")
|
|
53
53
|
self.assertEqual(weekly.level, Level.INFO.value)
|
|
54
54
|
self.assertEqual(weekly.retention_weeks, 4)
|
|
55
55
|
|
|
@@ -144,9 +144,10 @@ class TestFoundationConfigLoggingWeekly(AsyncTestCase):
|
|
|
144
144
|
-------
|
|
145
145
|
None
|
|
146
146
|
"""
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
with self.assertRaises(OrionisIntegrityException):
|
|
148
|
+
weekly = Weekly(path=" logs/app.log ", level=" debug ")
|
|
149
|
+
self.assertEqual(weekly.path, " logs/app.log ")
|
|
150
|
+
self.assertEqual(weekly.level, Level.DEBUG.value)
|
|
150
151
|
|
|
151
152
|
async def testToDictMethod(self):
|
|
152
153
|
"""
|
|
@@ -162,7 +163,7 @@ class TestFoundationConfigLoggingWeekly(AsyncTestCase):
|
|
|
162
163
|
weekly = Weekly()
|
|
163
164
|
weekly_dict = weekly.toDict()
|
|
164
165
|
self.assertIsInstance(weekly_dict, dict)
|
|
165
|
-
self.assertEqual(weekly_dict['path'], "storage/log/
|
|
166
|
+
self.assertEqual(weekly_dict['path'], "storage/log/weekly.log")
|
|
166
167
|
self.assertEqual(weekly_dict['level'], Level.INFO.value)
|
|
167
168
|
self.assertEqual(weekly_dict['retention_weeks'], 4)
|
|
168
169
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|