orionis 0.77.0__py3-none-any.whl → 0.78.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/framework.py +1 -1
- orionis/luminate/config/logging.py +74 -18
- orionis/luminate/services/log/log_service.py +128 -36
- {orionis-0.77.0.dist-info → orionis-0.78.0.dist-info}/METADATA +1 -1
- {orionis-0.77.0.dist-info → orionis-0.78.0.dist-info}/RECORD +9 -9
- {orionis-0.77.0.dist-info → orionis-0.78.0.dist-info}/LICENCE +0 -0
- {orionis-0.77.0.dist-info → orionis-0.78.0.dist-info}/WHEEL +0 -0
- {orionis-0.77.0.dist-info → orionis-0.78.0.dist-info}/entry_points.txt +0 -0
- {orionis-0.77.0.dist-info → orionis-0.78.0.dist-info}/top_level.txt +0 -0
orionis/framework.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
from dataclasses import dataclass, field
|
2
|
-
from
|
2
|
+
from datetime import time
|
3
|
+
from typing import Dict, Union
|
3
4
|
|
4
5
|
@dataclass
|
5
|
-
class
|
6
|
+
class Stack:
|
6
7
|
"""
|
7
8
|
Represents a single log file configuration.
|
8
9
|
|
@@ -17,7 +18,25 @@ class Single:
|
|
17
18
|
"""
|
18
19
|
path: str
|
19
20
|
level: str
|
20
|
-
|
21
|
+
|
22
|
+
|
23
|
+
@dataclass
|
24
|
+
class Hourly:
|
25
|
+
"""
|
26
|
+
Represents an hourly log file rotation configuration.
|
27
|
+
|
28
|
+
Attributes
|
29
|
+
----------
|
30
|
+
path : str
|
31
|
+
The file path where hourly logs are stored.
|
32
|
+
level : str
|
33
|
+
The logging level (e.g., 'info', 'error', 'debug').
|
34
|
+
retention_hours : int
|
35
|
+
The number of hours to retain log files before deletion.
|
36
|
+
"""
|
37
|
+
path: str
|
38
|
+
level: str
|
39
|
+
retention_hours: int
|
21
40
|
|
22
41
|
|
23
42
|
@dataclass
|
@@ -31,15 +50,53 @@ class Daily:
|
|
31
50
|
The file path where daily logs are stored.
|
32
51
|
level : str
|
33
52
|
The logging level (e.g., 'info', 'error', 'debug').
|
34
|
-
|
53
|
+
retention_days : int
|
35
54
|
The number of days to retain log files before deletion.
|
36
|
-
|
37
|
-
|
55
|
+
at_time : time
|
56
|
+
The time of day when the log rotation should occur.
|
57
|
+
"""
|
58
|
+
path: str
|
59
|
+
level: str
|
60
|
+
retention_days: int
|
61
|
+
at: time
|
62
|
+
|
63
|
+
|
64
|
+
@dataclass
|
65
|
+
class Weekly:
|
66
|
+
"""
|
67
|
+
Represents a weekly log file rotation configuration.
|
68
|
+
|
69
|
+
Attributes
|
70
|
+
----------
|
71
|
+
path : str
|
72
|
+
The file path where weekly logs are stored.
|
73
|
+
level : str
|
74
|
+
The logging level (e.g., 'info', 'error', 'debug').
|
75
|
+
retention_weeks : int
|
76
|
+
The number of weeks to retain log files before deletion.
|
77
|
+
"""
|
78
|
+
path: str
|
79
|
+
level: str
|
80
|
+
retention_weeks: int
|
81
|
+
|
82
|
+
|
83
|
+
@dataclass
|
84
|
+
class Monthly:
|
85
|
+
"""
|
86
|
+
Represents a monthly log file rotation configuration.
|
87
|
+
|
88
|
+
Attributes
|
89
|
+
----------
|
90
|
+
path : str
|
91
|
+
The file path where monthly logs are stored.
|
92
|
+
level : str
|
93
|
+
The logging level (e.g., 'info', 'error', 'debug').
|
94
|
+
retention_months : int
|
95
|
+
The number of months to retain log files before deletion.
|
38
96
|
"""
|
39
97
|
path: str
|
40
98
|
level: str
|
41
|
-
|
42
|
-
stream: bool
|
99
|
+
retention_months: int
|
43
100
|
|
44
101
|
|
45
102
|
@dataclass
|
@@ -56,20 +113,16 @@ class Chunked:
|
|
56
113
|
The file path where chunked logs are stored.
|
57
114
|
level : str
|
58
115
|
The logging level (e.g., 'info', 'error', 'debug').
|
59
|
-
|
116
|
+
max_mb_size : Union[int, str]
|
60
117
|
The maximum file size before creating a new chunk.
|
61
118
|
Can be an integer (bytes) or a string (e.g., '10MB', '500KB').
|
62
119
|
max_files : int
|
63
120
|
The maximum number of log files to retain before older files are deleted.
|
64
|
-
stream : bool
|
65
|
-
Whether to output logs to the console.
|
66
121
|
"""
|
67
|
-
|
68
122
|
path: str
|
69
123
|
level: str
|
70
|
-
|
71
|
-
|
72
|
-
stream: bool
|
124
|
+
mb_size: Union[int, str]
|
125
|
+
files: int
|
73
126
|
|
74
127
|
|
75
128
|
@dataclass
|
@@ -86,9 +139,12 @@ class Channels:
|
|
86
139
|
chunked : Chunked
|
87
140
|
Configuration for chunked log file storage.
|
88
141
|
"""
|
89
|
-
|
90
|
-
|
91
|
-
|
142
|
+
stack = Stack
|
143
|
+
hourly = Hourly
|
144
|
+
daily = Daily
|
145
|
+
weekly = Weekly
|
146
|
+
monthly = Monthly
|
147
|
+
chunked = Chunked
|
92
148
|
|
93
149
|
|
94
150
|
@dataclass
|
@@ -1,8 +1,11 @@
|
|
1
|
-
import os
|
2
1
|
import logging
|
2
|
+
import os
|
3
|
+
import re
|
4
|
+
from datetime import datetime
|
5
|
+
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
|
3
6
|
from pathlib import Path
|
4
|
-
from typing import Optional
|
5
7
|
from orionis.contracts.services.log.i_log_service import ILogguerService
|
8
|
+
from orionis.luminate.services.config.config_service import ConfigService
|
6
9
|
|
7
10
|
class LogguerService(ILogguerService):
|
8
11
|
"""
|
@@ -18,10 +21,10 @@ class LogguerService(ILogguerService):
|
|
18
21
|
|
19
22
|
Methods
|
20
23
|
-------
|
21
|
-
__init__(
|
22
|
-
Initializes the logger with
|
23
|
-
_initialize_logger(
|
24
|
-
Configures the logger with
|
24
|
+
__init__(config_service: ConfigService)
|
25
|
+
Initializes the logger with ConfigService
|
26
|
+
_initialize_logger(config_service: ConfigService)
|
27
|
+
Configures the logger with ConfigService settings.
|
25
28
|
info(message: str) -> None
|
26
29
|
Logs an informational message.
|
27
30
|
error(message: str) -> None
|
@@ -34,24 +37,32 @@ class LogguerService(ILogguerService):
|
|
34
37
|
Logs a debug message.
|
35
38
|
"""
|
36
39
|
|
37
|
-
def __init__(self,
|
40
|
+
def __init__(self, config_service : ConfigService):
|
38
41
|
"""
|
39
42
|
Initializes the logger with the specified path, log level, and filename.
|
40
43
|
|
41
44
|
Parameters
|
42
45
|
----------
|
43
|
-
|
44
|
-
The
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
The name of the log file. Defaults to 'orionis.log'.
|
46
|
+
config_service : ConfigService
|
47
|
+
The configuration service instance.
|
48
|
+
"""
|
49
|
+
self.config_service = config_service
|
50
|
+
self._initialize_logger()
|
51
|
+
|
52
|
+
def _path_resolver(self, filename: str):
|
51
53
|
"""
|
52
|
-
|
54
|
+
Resolves the log file path based on the specified filename.
|
55
|
+
"""
|
56
|
+
base_path = Path(os.getcwd())
|
57
|
+
log_dir = base_path / "storage" / "logs"
|
58
|
+
|
59
|
+
# Create the log directory if it does not exist
|
60
|
+
if not log_dir.exists():
|
61
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
62
|
+
|
63
|
+
return log_dir / filename
|
53
64
|
|
54
|
-
def _initialize_logger(self
|
65
|
+
def _initialize_logger(self):
|
55
66
|
"""
|
56
67
|
Configures the logger with the specified settings.
|
57
68
|
|
@@ -61,12 +72,8 @@ class LogguerService(ILogguerService):
|
|
61
72
|
|
62
73
|
Parameters
|
63
74
|
----------
|
64
|
-
|
65
|
-
The
|
66
|
-
level : int
|
67
|
-
The logging level (e.g., logging.INFO, logging.ERROR).
|
68
|
-
filename : Optional[str]
|
69
|
-
The name of the log file.
|
75
|
+
config_service : ConfigService
|
76
|
+
The configuration service instance.
|
70
77
|
|
71
78
|
Raises
|
72
79
|
------
|
@@ -74,27 +81,112 @@ class LogguerService(ILogguerService):
|
|
74
81
|
If the logger cannot be initialized due to an error.
|
75
82
|
"""
|
76
83
|
try:
|
77
|
-
# Resolve the log directory and file path
|
78
|
-
if path is None:
|
79
|
-
base_path = Path(os.getcwd())
|
80
|
-
log_dir = base_path / "storage" / "logs"
|
81
84
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
+
channel : str = self.config_service.get("logging.default")
|
86
|
+
config : dict = self.config_service.get(f"logging.channels.{channel}", {})
|
87
|
+
path : str = config.get("path", 'logs/orionis.log')
|
88
|
+
app_timezone : str = self.config_service.get("app.timezone", "UTC")
|
89
|
+
|
90
|
+
if channel == "stack":
|
91
|
+
|
92
|
+
handlers = [
|
93
|
+
logging.FileHandler(
|
94
|
+
filename=self._path_resolver(path),
|
95
|
+
encoding="utf-8"
|
96
|
+
)
|
97
|
+
]
|
98
|
+
|
99
|
+
elif channel == "hourly":
|
100
|
+
|
101
|
+
handlers = [
|
102
|
+
TimedRotatingFileHandler(
|
103
|
+
filename=self._path_resolver(path),
|
104
|
+
when="h",
|
105
|
+
interval=1,
|
106
|
+
backupCount=config.get('retention_hours', 24),
|
107
|
+
encoding="utf-8",
|
108
|
+
utc= True if app_timezone == "UTC" else False
|
109
|
+
)
|
110
|
+
]
|
111
|
+
|
112
|
+
elif channel == "daily":
|
113
|
+
|
114
|
+
backup_count : str = config.get('retention_days', 30)
|
115
|
+
hour_at : str = config.get('at', "00:00")
|
116
|
+
if backup_count < 1 or not backup_count.isdigit():
|
117
|
+
raise ValueError("The 'retention_days' value must be an integer greater than 0.")
|
118
|
+
if not bool(re.match(r"^(?:[01]?\d|2[0-3]):[0-5]?\d$", hour_at)):
|
119
|
+
raise ValueError("The 'at' value must be a valid time in the format HH:MM.")
|
120
|
+
|
121
|
+
handlers = [
|
122
|
+
TimedRotatingFileHandler(
|
123
|
+
filename=self._path_resolver(path),
|
124
|
+
when="d",
|
125
|
+
interval=1,
|
126
|
+
backupCount=backup_count,
|
127
|
+
encoding="utf-8",
|
128
|
+
atTime=datetime.strptime(hour_at, "%H:%M").time(),
|
129
|
+
utc= True if app_timezone == "UTC" else False
|
130
|
+
)
|
131
|
+
]
|
132
|
+
|
133
|
+
elif channel == "weekly":
|
134
|
+
|
135
|
+
backup_count : str = config.get('retention_weeks', 4)
|
136
|
+
if backup_count < 1 or not backup_count.isdigit():
|
137
|
+
raise ValueError("The 'retention_weeks' value must be an integer greater than 0.")
|
138
|
+
handlers = [
|
139
|
+
TimedRotatingFileHandler(
|
140
|
+
filename=self._path_resolver(path),
|
141
|
+
when="w0",
|
142
|
+
interval=1,
|
143
|
+
backupCount=backup_count,
|
144
|
+
encoding="utf-8",
|
145
|
+
utc= True if app_timezone == "UTC" else False
|
146
|
+
)
|
147
|
+
]
|
148
|
+
|
149
|
+
elif channel == "monthly":
|
150
|
+
|
151
|
+
backup_count : str = config.get('retention_months', 2)
|
152
|
+
if backup_count < 1 or not backup_count.isdigit():
|
153
|
+
raise ValueError("The 'retention_months' value must be an integer greater than 0.")
|
154
|
+
handlers = [
|
155
|
+
TimedRotatingFileHandler(
|
156
|
+
filename=self._path_resolver(path),
|
157
|
+
when="midnight",
|
158
|
+
interval=30,
|
159
|
+
backupCount=backup_count,
|
160
|
+
encoding="utf-8",
|
161
|
+
utc= True if app_timezone == "UTC" else False
|
162
|
+
)
|
163
|
+
]
|
164
|
+
|
165
|
+
elif channel == "chunked":
|
166
|
+
|
167
|
+
max_bytes : str = config.get('mb_size', 5).replace("MB", "")
|
168
|
+
if max_bytes < 1 or not max_bytes.isdigit():
|
169
|
+
raise ValueError("The 'mb_size' value must be an integer greater than 0.")
|
170
|
+
backup_count : str = config.get('max_files', 5)
|
171
|
+
if backup_count < 1 or not backup_count.isdigit():
|
172
|
+
raise ValueError("The 'max_files' value must be an integer greater than 0.")
|
173
|
+
handlers = [
|
174
|
+
RotatingFileHandler(
|
175
|
+
filename=self._path_resolver(path),
|
176
|
+
maxBytes= max_bytes * 1024 * 1024,
|
177
|
+
backupCount=backup_count,
|
178
|
+
encoding="utf-8"
|
179
|
+
)
|
180
|
+
]
|
85
181
|
|
86
|
-
path = log_dir / filename
|
87
182
|
|
88
183
|
# Configure the logger
|
89
184
|
logging.basicConfig(
|
90
|
-
level=level,
|
185
|
+
level=config.get("level", "INFO").upper(),
|
91
186
|
format="%(asctime)s - %(message)s",
|
92
187
|
datefmt="%Y-%m-%d %H:%M:%S",
|
93
188
|
encoding="utf-8",
|
94
|
-
handlers=
|
95
|
-
logging.FileHandler(path, encoding="utf-8")
|
96
|
-
# logging.StreamHandler() # Uncomment to also log to the console
|
97
|
-
]
|
189
|
+
handlers=handlers
|
98
190
|
)
|
99
191
|
|
100
192
|
# Get the logger instance
|
@@ -1,6 +1,6 @@
|
|
1
1
|
orionis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
orionis/cli_manager.py,sha256=0bM-hABXJSoPGuvEgnqeaj9qcLP8VjTQ3z9Mb0TSEUI,1381
|
3
|
-
orionis/framework.py,sha256=
|
3
|
+
orionis/framework.py,sha256=M6GR_dTDAIhgQsjWISzWq42J6CbanHXfek4R1OVnad0,1386
|
4
4
|
orionis/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
orionis/contracts/bootstrap/i_command_bootstrapper.py,sha256=cfpYWSlNhOY1q_C9o0H7F381OoM0Oh0qaeqP-c85nzk,2457
|
6
6
|
orionis/contracts/bootstrap/i_config_bootstrapper.py,sha256=d2TXT74H2fCBbzWgrt9-ZG11S_H_YPQOEcJoIOrsgb0,4462
|
@@ -71,7 +71,7 @@ orionis/luminate/config/cache.py,sha256=nBKmDFDb91sbBriEsVLjMhrNb__j7YsRzZGQRDdA
|
|
71
71
|
orionis/luminate/config/cors.py,sha256=zWKUylPiaUzGXTJM3eLmwY0HcAD7iOLp9QiAoTyAL08,2275
|
72
72
|
orionis/luminate/config/database.py,sha256=oj-FQWtbwIYrJAQktSGBl96EZu78fr6IBcQxHbWDVBM,5619
|
73
73
|
orionis/luminate/config/filesystems.py,sha256=fAn4Wx6naIb8E4U2TXJhVnx0Ipxpxc_Ee2w_FWfwlHI,2444
|
74
|
-
orionis/luminate/config/logging.py,sha256=
|
74
|
+
orionis/luminate/config/logging.py,sha256=mx3ifEVjKNZgaRlql1D7u-KxRiewKRAbz5VDcwAubaw,4047
|
75
75
|
orionis/luminate/config/mail.py,sha256=3iYXG72bXiVns4sEPZ_A3-cGcFjGEGDXkuLKkk-hKtY,2102
|
76
76
|
orionis/luminate/config/queue.py,sha256=DYjP5zD09ISsIX117wtOfjiG_iQrcrPoQVeeftmuO3c,1739
|
77
77
|
orionis/luminate/config/session.py,sha256=7mOC_DfGIBDqAClSiewHoTA9Kht_zdHApvALcZc7cfY,1861
|
@@ -132,7 +132,7 @@ orionis/luminate/services/environment/environment_service.py,sha256=IgrfzLELNhnE
|
|
132
132
|
orionis/luminate/services/files/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
133
133
|
orionis/luminate/services/files/path_resolver_service.py,sha256=E-G_E2H5QAZyxeMssARp7l1OBSxQurxkUPoKdSOCKEE,2041
|
134
134
|
orionis/luminate/services/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
135
|
-
orionis/luminate/services/log/log_service.py,sha256=
|
135
|
+
orionis/luminate/services/log/log_service.py,sha256=tlKnBLtJPx-LK6nQt39xYA48jcNkaJt2_Xj-wgcpfXA,8842
|
136
136
|
orionis/luminate/support/dot_dict.py,sha256=FVHfBuAGTTVMjNG01Fix645fRNKKUMmNx61pYkxPL5c,1253
|
137
137
|
orionis/luminate/support/exception_to_dict.py,sha256=jpQ-c7ud1JLm8dTWbvMT1dI-rL3yTB2P8VxNscAX71k,2098
|
138
138
|
orionis/luminate/support/reflection.py,sha256=VYpluTQJ0W_m6jYQ9_L02sYFrk2wlLYtLY2yp9rZMKA,11944
|
@@ -153,9 +153,9 @@ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
153
153
|
tests/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
154
154
|
tests/tools/class_example.py,sha256=dIPD997Y15n6WmKhWoOFSwEldRm9MdOHTZZ49eF1p3c,1056
|
155
155
|
tests/tools/test_reflection.py,sha256=bhLQ7VGVod4B8sv-rW9AjnOumvaBVsoxieA3sdoM2yM,5244
|
156
|
-
orionis-0.
|
157
|
-
orionis-0.
|
158
|
-
orionis-0.
|
159
|
-
orionis-0.
|
160
|
-
orionis-0.
|
161
|
-
orionis-0.
|
156
|
+
orionis-0.78.0.dist-info/LICENCE,sha256=-_4cF2EBKuYVS_SQpy1uapq0oJPUU1vl_RUWSy2jJTo,1111
|
157
|
+
orionis-0.78.0.dist-info/METADATA,sha256=WDNwmK36LqcGJUK9AeNPmk-tzZ1zf0pSz47qs283Qh4,2978
|
158
|
+
orionis-0.78.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
159
|
+
orionis-0.78.0.dist-info/entry_points.txt,sha256=eef1_CVewfokKjrGBynXa06KabSJYo7LlDKKIKvs1cM,53
|
160
|
+
orionis-0.78.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
|
161
|
+
orionis-0.78.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|