MapleX 3.1.3__tar.gz → 3.2.0__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.
Files changed (42) hide show
  1. {maplex-3.1.3/src/MapleX.egg-info → maplex-3.2.0}/PKG-INFO +3 -3
  2. {maplex-3.1.3 → maplex-3.2.0}/pyproject.toml +4 -4
  3. {maplex-3.1.3 → maplex-3.2.0}/readmes/LoggingBestPractice.md +1 -1
  4. {maplex-3.1.3 → maplex-3.2.0}/readmes/README_Json.md +8 -0
  5. maplex-3.2.0/readmes/README_Logger.md +246 -0
  6. {maplex-3.1.3 → maplex-3.2.0/src/MapleX.egg-info}/PKG-INFO +3 -3
  7. {maplex-3.1.3 → maplex-3.2.0}/src/MapleX.egg-info/SOURCES.txt +4 -0
  8. maplex-3.2.0/src/MapleX.egg-info/requires.txt +2 -0
  9. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/__init__.py +1 -1
  10. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/library/logger/__init__.py +2 -1
  11. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/library/logger/config.py +127 -18
  12. maplex-3.2.0/src/maplex/library/logger/consts/__init__.py +45 -0
  13. maplex-3.2.0/src/maplex/library/logger/consts/config_keys.py +21 -0
  14. maplex-3.2.0/src/maplex/library/logger/consts/defaults.py +7 -0
  15. maplex-3.2.0/src/maplex/library/logger/consts/dict_keys.py +11 -0
  16. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/library/logger/formatter.py +9 -6
  17. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/mapleLogger.py +25 -13
  18. maplex-3.1.3/readmes/README_Logger.md +0 -158
  19. maplex-3.1.3/src/MapleX.egg-info/requires.txt +0 -2
  20. {maplex-3.1.3 → maplex-3.2.0}/LICENSE +0 -0
  21. {maplex-3.1.3 → maplex-3.2.0}/MANIFEST.in +0 -0
  22. {maplex-3.1.3 → maplex-3.2.0}/README.md +0 -0
  23. {maplex-3.1.3 → maplex-3.2.0}/logErrorOutputSample.png +0 -0
  24. {maplex-3.1.3 → maplex-3.2.0}/logOutputSample.png +0 -0
  25. {maplex-3.1.3 → maplex-3.2.0}/readmes/README_ConsoleColors.md +0 -0
  26. {maplex-3.1.3 → maplex-3.2.0}/readmes/README_Exceptions.md +0 -0
  27. {maplex-3.1.3 → maplex-3.2.0}/readmes/README_MapleTree.md +0 -0
  28. {maplex-3.1.3 → maplex-3.2.0}/setup.cfg +0 -0
  29. {maplex-3.1.3 → maplex-3.2.0}/src/MapleX.egg-info/dependency_links.txt +0 -0
  30. {maplex-3.1.3 → maplex-3.2.0}/src/MapleX.egg-info/top_level.txt +0 -0
  31. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/jsonHandler.py +0 -0
  32. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/library/logger/consts.py +0 -0
  33. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/library/logger/file_handler.py +0 -0
  34. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/library/logger/log_levels.py +0 -0
  35. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/library/logger/utilities.py +0 -0
  36. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/mapleColors.py +0 -0
  37. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/mapleExceptions.py +0 -0
  38. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/mapleTreeEditor.py +0 -0
  39. {maplex-3.1.3 → maplex-3.2.0}/src/maplex/utils.py +0 -0
  40. {maplex-3.1.3 → maplex-3.2.0}/tests/test_logger_unittest.py +0 -0
  41. {maplex-3.1.3 → maplex-3.2.0}/tests/test_maplejson_unittest.py +0 -0
  42. {maplex-3.1.3 → maplex-3.2.0}/tests/test_mapletree_unittest.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MapleX
3
- Version: 3.1.3
3
+ Version: 3.2.0
4
4
  Summary: A Python library for simple logging, json file operations, Maple file format operations, and console color utilities.
5
5
  Author: Ryuji Hazama
6
6
  Project-URL: PyPI, https://pypi.org/project/MapleX/
@@ -16,8 +16,8 @@ Classifier: Operating System :: OS Independent
16
16
  Requires-Python: >=3.12
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: cryptography>=46.0.3
20
- Requires-Dist: pydantic>=2.12.5
19
+ Requires-Dist: cryptography>=49.0.0
20
+ Requires-Dist: pydantic>=2.13.4
21
21
  Dynamic: license-file
22
22
 
23
23
  # MapleX
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "MapleX"
7
- version = "3.1.3"
7
+ version = "3.2.0"
8
8
  description = """A Python library for simple logging, json file operations, Maple file format operations, and console color utilities."""
9
9
  keywords = ["logging", "logger", "json", "file operations", "maple file format", "console colors"]
10
10
  readme = "README.md"
@@ -13,8 +13,8 @@ authors = [
13
13
  {name = "Ryuji Hazama"}
14
14
  ]
15
15
  dependencies = [
16
- "cryptography>=46.0.3",
17
- "pydantic>=2.12.5"
16
+ "cryptography>=49.0.0",
17
+ "pydantic>=2.13.4",
18
18
  ]
19
19
  classifiers = [
20
20
  "Programming Language :: Python :: 3.12",
@@ -41,4 +41,4 @@ Homepage = "https://github.com/Ryuji-Hazama"
41
41
  Repository = "https://github.com/Ryuji-Hazama/MapleTree"
42
42
  Issues = "https://github.com/Ryuji-Hazama/MapleTree/issues"
43
43
  YouTube = "https://www.youtube.com/@ryujihazama"
44
- Instagram = "https://www.instagram.com/ryujihazama/"
44
+ Instagram = "https://www.instagram.com/ryujihazama/"
@@ -101,7 +101,7 @@
101
101
 
102
102
  ### `NONE`
103
103
 
104
-     The `NONE` level is a special level in `MapleX` that not commonly exists in other logging libraries. It is used to bypass all the log level filters and always output the log, or suppress all other log levels if you set this in the logger configuration. This is useful for debugging in production environments, where you want to log a specific event, but don't want to log any other lower level events under the same logger configuration. For example, you can set the log level to `NONE` for a specific logger to always log suspicious events, while setting the log level to `WARNING` for other loggers to only log warnings and errors.
104
+     The `NONE` level is a special level in `MapleX` that not commonly exists in other logging libraries. It is used to bypass all the log level filters and always output the log, or suppress all other log levels if you set this in the logger configuration. This is useful for debugging in production environments, where you want to log a specific event, but don't want to log any other lower level events under the same logger configuration. For example, you can set the log level to `NONE` for a specific logger to always log suspicious events, while setting the log level to `WARN` for other loggers to only log warnings and errors.
105
105
 
106
106
  ## Conclusion
107
107
 
@@ -94,6 +94,10 @@ jsonInstance = MapleJson("jsonFile.json", fileEncoding="shift_jis")
94
94
 
95
95
      **There is no *redo*** in encryption. **DO NOT FORGET** your encryption key, or *you will lose your data FOREVER.*
96
96
 
97
+ #### Disclaimers
98
+
99
+     This encryption is just a basic implementation using AES-128 (Fernet) and is intended for general use cases. It may not be suitable for highly sensitive data or scenarios requiring advanced security measures. If you need stronger security, consider using more robust encryption methods or libraries.
100
+
97
101
  ### Key
98
102
 
99
103
      A 32-byte byte-string key for encryption.
@@ -339,3 +343,7 @@ jsonFile.write(jsonData)
339
343
      Every class parameter has its own getter and setter functions, and you can set, change, or get those values after initializing the class.
340
344
 
341
345
  - You need to set the encryption key when you set the encryption to `True`.
346
+
347
+ ## Disclaimers for Encryption
348
+
349
+     The encryption provided by this library is just a basic implementation using AES-128 (Fernet) and is intended for general use cases. It may not be suitable for highly sensitive data or scenarios requiring advanced security measures. If you need stronger security, consider using more robust encryption methods or libraries.
@@ -0,0 +1,246 @@
1
+ # Logger Class
2
+
3
+     Logger class is a logging object for Python applications. It outputs application logs to log files and to standard output.
4
+
5
+ ## Logger Initialization
6
+
7
+ ```python
8
+ def __init__(
9
+ func: str = "",
10
+ workingDirectory: str | None = None,
11
+ cmdLogLevel: str | None = None,
12
+ fileLogLevel: str | None = None,
13
+ maxLogSize: float | None = None,
14
+ fileMode: Literal["append", "overwrite", "daily"] | None = None,
15
+ configFile: str = "config.json",
16
+ encoding: str | None = None,
17
+ ) -> None:
18
+ ```
19
+
20
+ |Property|Required|Value|Version|
21
+ |--------|--------|-----|-------|
22
+ |**`func`**||Primary function name||
23
+ |**`workingDirectory`**||Log file output directory||
24
+ |**`cmdLogLevel`**||Terminal output log level||
25
+ |**`fileLogLevel`**||Log file output log level||
26
+ |**`maxLogSize`**||Log file max size (MB)||
27
+ |**`fileMode`**||Logging file mode|`v3.0`|
28
+ |**`configFile`**||Logger configuration file path|`v3.0`|
29
+ |**`encoding`**||Log file encoding|`v3.0`|
30
+
31
+     The parameter overwrites the settings configured in `config.mpl`.
32
+
33
+ ## Functions
34
+
35
+ ### `getLogger()`
36
+
37
+ ```python
38
+ def getLogger(
39
+ name = "",
40
+ **kwargs
41
+ ) -> maplex.Logger:
42
+ ```
43
+
44
+ |Property|Required|Value|Version|
45
+ |--------|--------|-----|-------|
46
+ |**`name`**||Primary funcion name|`v3.0`|
47
+ |**`**kwargs`**||Other parameters|`v3.0`|
48
+
49
+     This get or creates a Logger instance.
50
+
51
+     If you already have a Logger class instance with the same name, the function returns the existing instance, and you can save your resources on the machine.
52
+
53
+ ```python
54
+ from maplex
55
+
56
+ logger = maplex.getLogger(__name__)
57
+ ```
58
+
59
+ ## Getters and Setters
60
+
61
+     Every class parameter has its own getter and setter functions, and you can set, change, or get those values after initializing the class.
62
+
63
+ ## Logging Methods
64
+
65
+ ```python
66
+ def trace(object: any) -> None:
67
+ def debug(object: any) -> None:
68
+ def info(object: any) -> None:
69
+ def warn(object: any) -> None:
70
+ def error(object: any, exception: Exception | None = None) -> None:
71
+ def fatal(object: any, exception: Exception | None = None) -> None:
72
+ ```
73
+
74
+ - You can use `exception` parameter to log the exception details along with a custom message in `error` and `fatal` methods in `v3.2.0` or later.
75
+
76
+     Each function outputs the log in each log level.
77
+
78
+ ## `ShowError` Function
79
+
80
+     This outputs the error logs and stuck trace.
81
+
82
+ Function:
83
+
84
+ ```python
85
+ def ShowError(
86
+ ex: Exception,
87
+ message: str | None = None,
88
+ fatal: bool = False
89
+ )
90
+ ```
91
+
92
+ |Property|Required|Value|
93
+ |--------|--------|-----|
94
+ |**`ex`**|\*|Exception|
95
+ |**`message`**||Custom error message|
96
+ |**`fatal`**||Show error as `FATAL`|
97
+
98
+ - If `fatal=True`, it outputs log as a `FATAL` log level.
99
+
100
+ ## Usage
101
+
102
+ ```python
103
+ from maplex
104
+
105
+ logger = maplex.getLogger("FunctionName")
106
+ logger.info("Hello there!")
107
+ ```
108
+
109
+ This outputs:
110
+
111
+ ```console
112
+ [INFO ][FunctionName] <module>(4) Hello there!
113
+ ```
114
+
115
+ File output will be: `AppLog.log`
116
+
117
+ ```log
118
+ (PsNo) yyyy-MM-dd HH:mm:ss.fff [INFO ][FunctionName] <module>(4) Hello there!
119
+ ```
120
+
121
+ ### Log Level
122
+
123
+ - `TRACE`
124
+ - `DEBUG`
125
+ - `INFO`
126
+ - `WARN`
127
+ - `ERROR`
128
+ - `FATAL`
129
+
130
+ ## Settings
131
+
132
+ - You can configure log settings with a JSON formatted file (default: `config.json`).
133
+ - If the configuration file does not exist, the instance auto-generates the file.
134
+ - Instance uses the parameter values to auto-generate a configuration file, or uses the default value if it was not specified.
135
+
136
+ Auto-generated configuration file (parameters not specified):
137
+
138
+ ```json
139
+ {
140
+ "MapleLogger": {
141
+ "ConsoleLogLevel": "INFO",
142
+ "FileLogLevel": "INFO",
143
+ "MaxLogSize": 3,
144
+ "WorkingDirectory": "logs",
145
+ "FileEncoding": "utf-8",
146
+ "Formats": {
147
+ "Timestamp": {
148
+ "Format": "%F %X.%f",
149
+ "Digits": null
150
+ },
151
+ "ConsoleLogFormat": "[{level}]{func} {callerFunc}{callerLine}",
152
+ "FileLogFormat": "({pid}) {timestamp} [{level}]{func} {callerName}{callerFunc}({callerLine})",
153
+ "Separator": ": "
154
+ }
155
+ }
156
+ }
157
+ ```
158
+
159
+ |Key|Value|
160
+ |---|-----|
161
+ |**`ConsoleLogLevel`**|Console log level|
162
+ |**`FileLogLevel`**|File log level|
163
+ |**`MaxLogSize`**|Log file max size (MB)|
164
+ |**`WorkingDirectory`**|Log file output path|
165
+ |**`FileEncoding`**|Log file encoding|
166
+ |**`Formats`**|Log format settings|
167
+ |**`NameSpaces`**|Namespace specific log level settings|
168
+
169
+ - To disable the log output, set the log level to `NONE`.
170
+ - You can use a `float` number for the file max size (E.g., `2.5` for `2.5MB`)
171
+ - You can also use a `str` for the file max size (E.g., `"3M"`)
172
+ - You can set the timestamp format with the `Format` key in the `Timestamp` section of the `Formats` settings.
173
+ - The default format is `%F %X.%f`, which outputs the timestamp as `yyyy-MM-dd HH:mm:ss.fff`. You can use any valid Python datetime format string.
174
+ - You can set the number of digits for the timestamp with the `Digits` key in the `Timestamp` section of the `Formats` settings.
175
+
176
+ ### Formats
177
+
178
+ &nbsp;&nbsp;&nbsp;&nbsp;`v3.2.0` or later
179
+
180
+ - You can set the log format for console and file output with the `ConsoleLogFormat` and `FileLogFormat` keys in the `Formats` settings.
181
+ - Also, you can set the timestamp format with the `Format` key in the `Timestamp` section of the `Formats` settings.
182
+
183
+ ```json
184
+ {
185
+ "MapleLogger": {
186
+ "Formats": {
187
+ "Timestamp": {
188
+ "Format": "%F %X.%f",
189
+ "Digits": -3
190
+ },
191
+ "ConsoleLogFormat": "[{level}]{func} {callerFunc}{callerLine}",
192
+ "FileLogFormat": "({pid}) {timestamp} [{level}]{func} {callerName}{callerFunc}({callerLine})",
193
+ "Separator": ": "
194
+ }
195
+ }
196
+ }
197
+ ```
198
+
199
+ |Key|Value|
200
+ |---|-----|
201
+ |**`Timestamp.Format`**|Timestamp format string|
202
+ |**`Timestamp.Digits`**|Number of digits for the timestamp|
203
+ |**`ConsoleLogFormat`**|Console log format string|
204
+ |**`FileLogFormat`**|File log format string|
205
+ |**`Separator`**|Separator string between prefix and message|
206
+
207
+ - You can use standard Python datetime format strings for the `Timestamp.Format` key. For example, `%F %X.%f` outputs the timestamp as `yyyy-MM-dd HH:mm:ss.fff`.
208
+ - You can set the number of digits for the timestamp with the `Timestamp.Digits` key.
209
+ - The default value is `null`, which outputs the full length of the timestamp.
210
+ - However, I recommend using `-3` to output the timestamp with milliseconds, which is the most common format for logging.
211
+ - You can use a negative number to specify the number of digits to output from the end of the timestamp. For example, `-3` cuts the last three digits of the timestamp, which outputs the timestamp as `yyyy-MM-dd HH:mm:ss.fff`.
212
+ - You can use the following placeholders in the log format strings:
213
+
214
+ `{pid}`: Process ID
215
+ `{timestamp}`: Timestamp
216
+ `{level}`: Log level
217
+ `{func}`: Function name
218
+ `{callerName}`: Caller function name
219
+ `{callerFunc}`: Caller function name (with module name)
220
+ `{callerLine}`: Caller line number
221
+
222
+ ### Namespace Specific Log Level Settings
223
+
224
+ - You can set the log level for specific namespaces by adding a `NameSpaces` key in the configuration file.
225
+ - The `NameSpaces` key is a list of dictionaries, where each dictionary contains a `NameSpace`, a `ConsoleLogLevel`, and a `FileLogLevel`.
226
+
227
+ Example:
228
+
229
+ ```json
230
+ {
231
+ "MapleLogger": {
232
+ "ConsoleLogLevel": "INFO",
233
+ "FileLogLevel": "INFO",
234
+ "NameSpaces": [
235
+ {
236
+ "NameSpace": "MyNamespace",
237
+ "ConsoleLogLevel": "DEBUG",
238
+ "FileLogLevel": "INFO"
239
+ }
240
+ ]
241
+ }
242
+ }
243
+ ```
244
+
245
+ - In this example, the log level for the `MyNamespace` namespace is set to `DEBUG` for console output and `INFO` for file output. All other namespaces will use the default log levels specified in the `ConsoleLogLevel` and `FileLogLevel` keys.
246
+ - You can use this setting to control the log output for different parts of your application, allowing you to have more detailed logs for specific namespaces while keeping the overall log output at a higher level.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MapleX
3
- Version: 3.1.3
3
+ Version: 3.2.0
4
4
  Summary: A Python library for simple logging, json file operations, Maple file format operations, and console color utilities.
5
5
  Author: Ryuji Hazama
6
6
  Project-URL: PyPI, https://pypi.org/project/MapleX/
@@ -16,8 +16,8 @@ Classifier: Operating System :: OS Independent
16
16
  Requires-Python: >=3.12
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: cryptography>=46.0.3
20
- Requires-Dist: pydantic>=2.12.5
19
+ Requires-Dist: cryptography>=49.0.0
20
+ Requires-Dist: pydantic>=2.13.4
21
21
  Dynamic: license-file
22
22
 
23
23
  # MapleX
@@ -29,6 +29,10 @@ src/maplex/library/logger/file_handler.py
29
29
  src/maplex/library/logger/formatter.py
30
30
  src/maplex/library/logger/log_levels.py
31
31
  src/maplex/library/logger/utilities.py
32
+ src/maplex/library/logger/consts/__init__.py
33
+ src/maplex/library/logger/consts/config_keys.py
34
+ src/maplex/library/logger/consts/defaults.py
35
+ src/maplex/library/logger/consts/dict_keys.py
32
36
  tests/test_logger_unittest.py
33
37
  tests/test_maplejson_unittest.py
34
38
  tests/test_mapletree_unittest.py
@@ -0,0 +1,2 @@
1
+ cryptography>=49.0.0
2
+ pydantic>=2.13.4
@@ -52,7 +52,7 @@ __all__ = [
52
52
  'winUnHide'
53
53
  ]
54
54
 
55
- __version__ = "3.1.3"
55
+ __version__ = "3.2.0"
56
56
  __author__ = "Ryuji Hazama"
57
57
  __license__ = "MIT"
58
58
 
@@ -2,7 +2,7 @@
2
2
  Split mapleLogger.py into multiple files for better organization and maintainability.
3
3
  """
4
4
 
5
- from .config import LoggerConfig
5
+ from .config import LoggerConfig, TimeStamp
6
6
  from .file_handler import FileHandler
7
7
  from .formatter import Formatter
8
8
  from .log_levels import LogLevel
@@ -14,6 +14,7 @@ __all__ = [
14
14
  "LoggerConfig",
15
15
  "LogLevel",
16
16
  "getConsoleColors",
17
+ "TimeStamp",
17
18
  "toLogLevel",
18
19
  "toLogSize",
19
20
  "isLogLevel"
@@ -21,6 +21,18 @@ from .utilities import *
21
21
  from library.logger.log_levels import LogLevel
22
22
 
23
23
 
24
+ class TimeStamp(BaseModel):
25
+
26
+ timestampFormat: str | None = None
27
+ digits: int | None = None
28
+
29
+ class Formats(BaseModel):
30
+
31
+ consoleFormat: str | None = None
32
+ fileFormat: str | None = None
33
+ separator: str | None = None
34
+ timestamp: TimeStamp | None = None
35
+
24
36
  class LoggerConfig(BaseModel):
25
37
 
26
38
  func: str | None = None
@@ -32,12 +44,10 @@ class LoggerConfig(BaseModel):
32
44
  fileMode: Literal["append", "overwrite", "daily"] | None = None
33
45
  configFile: str = "config.json"
34
46
  encoding: str | None = None
35
- timestampFormat: str | None = None
36
47
  getLogger: bool | None = None
37
48
  consoleAlignWidth: int | None = None
38
49
  fileAlignWidth: int | None = None
39
- consoleFormat: str = CONSOLE_FORMAT
40
- fileFormat: str = FILE_FORMAT
50
+ formats: Formats | None = None
41
51
 
42
52
  logConfInstance: None = None
43
53
  logConf: dict[str, object] | None = None
@@ -51,9 +61,7 @@ class LoggerConfig(BaseModel):
51
61
  try:
52
62
 
53
63
  super().__init__(**config)
54
-
55
64
  self.consoleColors = getConsoleColors()
56
-
57
65
  self.logConfInstance = self.checkConfigFile(config.get(CONFIG_FILE, self.configFile))
58
66
  self.checkOutputDirectory(config.get(WORKING_DIRECTORY, None))
59
67
  self.setLogFileName(config.get(FILE_MODE, "append"))
@@ -62,11 +70,13 @@ class LoggerConfig(BaseModel):
62
70
  self.setLogFileSize(config.get(MAX_LOG_SIZE, None))
63
71
  self.setOutputLogLevels(config.get(CONSOLE_LOG_LEVEL, None), config.get(FILE_LOG_LEVEL, None))
64
72
  self.setFileEncoding(config.get(FILE_ENCODING, None))
65
- self.setTimestampFormat(config.get(TIMESTAMP_FORMAT, None))
73
+ self.setTimestampFormat(config.get(PARAM_TIMESTAMP, None))
74
+ self.setOutputFormat(config.get(CONSOLE_LOG_FORMAT, None), config.get(FILE_LOG_FORMAT, None), config.get(SEPARATOR, None))
66
75
  self.saveLogSettings(self.logConfInstance)
67
76
 
68
77
  except Exception as ex:
69
78
 
79
+ print(ex)
70
80
  print(f"{self.consoleColors.Red}Error: Failed to initialize logger config: {ex}{self.consoleColors.Reset}")
71
81
  raise ex
72
82
 
@@ -245,10 +255,26 @@ class LoggerConfig(BaseModel):
245
255
  print(f"{self.consoleColors.Red}Warning: Infinite log file size is not recommended. Using default value.{self.consoleColors.Reset}")
246
256
  self.maxLogSize = 3000000
247
257
 
258
+ def getLogLevel(self) -> None:
259
+
260
+ '''
261
+ Get LogLevel configuration from config file.
262
+ Set namespace specific LogLevel if available, otherwise set default LogLevel.
263
+ '''
264
+
265
+ namespaceSettings = self.logConf.get(NAME_SPACES, [])
266
+ thisNamespaceSettings = next((ns for ns in namespaceSettings if ns.get(NAME_SPACE) == self.callerName), None)
267
+
268
+ if thisNamespaceSettings is not None:
269
+
270
+ self.consoleLogLevel = thisNamespaceSettings.get(CONSOLE_LOG_LEVEL, None)
271
+ self.fileLogLevel = thisNamespaceSettings.get(FILE_LOG_LEVEL, None)
272
+
248
273
  def setOutputLogLevels(self, cmdLogLevel: object, fileLogLevel: object) -> None:
249
274
 
250
- self.consoleLogLevel = self.__setLogLevel(CONSOLE_LOG_LEVEL, cmdLogLevel)
251
- self.fileLogLevel = self.__setLogLevel(FILE_LOG_LEVEL, fileLogLevel)
275
+ self.getLogLevel()
276
+ self.consoleLogLevel = self.__setLogLevel(CONSOLE_LOG_LEVEL, cmdLogLevel if self.consoleLogLevel is None else self.consoleLogLevel)
277
+ self.fileLogLevel = self.__setLogLevel(FILE_LOG_LEVEL, fileLogLevel if self.fileLogLevel is None else self.fileLogLevel)
252
278
 
253
279
  def __setLogLevel(self, fileOrConsole, loglevel: object) -> LogLevel:
254
280
 
@@ -260,7 +286,7 @@ class LoggerConfig(BaseModel):
260
286
 
261
287
  else:
262
288
 
263
- tempLogLevel = self.logConf.get(fileOrConsole, "INFO")
289
+ tempLogLevel = self.logConf.get(fileOrConsole, None)
264
290
 
265
291
  if tempLogLevel is None:
266
292
 
@@ -293,24 +319,107 @@ class LoggerConfig(BaseModel):
293
319
 
294
320
  self.encoding = fileEncoding
295
321
 
296
- def setTimestampFormat(self, timestampFormat: str) -> None:
322
+ def setTimestampFormat(self, timestampFormat: dict) -> None:
297
323
 
298
324
  """Set timestamp format for logs. Default is "%F %X.%f" (e.g. 2024-06-01 12:34:56.789). You can set this in config file with key "TimestampFormat"."""
299
325
 
326
+ if self.formats is None:
327
+
328
+ self.formats = Formats()
329
+
330
+ if self.formats.timestamp is None:
331
+
332
+ self.formats.timestamp = TimeStamp()
333
+
300
334
  if timestampFormat is not None:
301
335
 
302
- self.timestampFormat = timestampFormat
336
+ self.formats.timestamp.timestampFormat = timestampFormat.get(FORMAT, None)
337
+ self.formats.timestamp.digits = timestampFormat.get(DIGITS, 3)
303
338
 
304
339
  else:
305
340
 
306
- configTimestampFormat = self.logConf.get(TIMESTAMP_FORMAT, None)
341
+ timestampSettings = self.logConf.get(FORMATS, {}).get(TIMESTAMP, {})
342
+ configTimestampFormat = timestampSettings.get(FORMAT, None)
343
+ configTimestampDigits = timestampSettings.get(DIGITS, None)
307
344
 
308
345
  if configTimestampFormat is None:
309
346
 
310
- configTimestampFormat = "%F %X.%f"
311
- self.logConf[TIMESTAMP_FORMAT] = configTimestampFormat
347
+ configTimestampFormat = TIMESTAMP_FORMAT
348
+ timestampSettings[FORMAT] = configTimestampFormat
349
+ self.logConf.setdefault(FORMATS, {})[TIMESTAMP] = timestampSettings
350
+
351
+ if configTimestampDigits is None:
352
+
353
+ configTimestampDigits = MILLISECOND_DIGITS
354
+ timestampSettings[DIGITS] = configTimestampDigits
355
+ self.logConf.setdefault(FORMATS, {})[TIMESTAMP] = timestampSettings
356
+
357
+ if "TimestampFormat" in self.logConf:
358
+
359
+ # Show warning if old config key is used
360
+ print(f"{self.consoleColors.Yellow}Warning: 'TimestampFormat' key in config file is deprecated. Please use 'Formats.Timestamp' instead.{self.consoleColors.Reset}\nMore details: https://github.com/Ryuji-Hazama/MapleTree/blob/main/readmes/README_Logger.md#settings")
361
+
362
+ self.formats.timestamp.timestampFormat = configTimestampFormat
363
+ self.formats.timestamp.digits = configTimestampDigits
364
+
365
+ def setOutputFormat(self, consoleFormat: str, fileFormat: str, separator: str | None = None) -> None:
366
+
367
+ """Set output format for console and file logs. Default is "[{level}]{func} {callerFunc}{callerLine}" for console and "({pid}) {timestamp} [{level}]{func} {callerName}{callerFunc}({callerLine})" for file. You can set this in config file with keys "ConsoleLogFormat" and "FileLogFormat"."""
368
+
369
+ if self.formats is None:
370
+
371
+ self.formats = Formats()
372
+
373
+ # Console format
374
+
375
+ if consoleFormat is not None:
376
+
377
+ self.formats.consoleFormat = consoleFormat
378
+
379
+ else:
380
+
381
+ self.formats.consoleFormat = self.logConf.get(FORMATS, {}).get(CONSOLE_LOG_FORMAT, None)
382
+
383
+ if self.formats.consoleFormat is None:
384
+
385
+ self.formats.consoleFormat = CONSOLE_FORMAT
386
+ formatConf = self.logConf.get(FORMATS, {})
387
+ formatConf[CONSOLE_LOG_FORMAT] = CONSOLE_FORMAT
388
+ self.logConf[FORMATS] = formatConf
389
+
390
+ # File format
391
+
392
+ if fileFormat is not None:
393
+
394
+ self.formats.fileFormat = fileFormat
395
+
396
+ else:
397
+
398
+ self.formats.fileFormat = self.logConf.get(FORMATS, {}).get(FILE_LOG_FORMAT, None)
399
+
400
+ if self.formats.fileFormat is None:
401
+
402
+ self.formats.fileFormat = FILE_FORMAT
403
+ formatConf = self.logConf.get(FORMATS, {})
404
+ formatConf[FILE_LOG_FORMAT] = FILE_FORMAT
405
+ self.logConf[FORMATS] = formatConf
406
+
407
+ # Message separator
408
+
409
+ if separator is not None:
410
+
411
+ self.formats.separator = separator
412
+
413
+ else:
414
+
415
+ self.formats.separator = self.logConf.get(FORMATS, {}).get(SEPARATOR, None)
416
+
417
+ if self.formats.separator is None:
312
418
 
313
- self.timestampFormat = configTimestampFormat
419
+ self.formats.separator = DEFAULT_SEPARATOR
420
+ formatConf = self.logConf.get(FORMATS, {})
421
+ formatConf[SEPARATOR] = DEFAULT_SEPARATOR
422
+ self.logConf[FORMATS] = formatConf
314
423
 
315
424
  def saveLogSettings(self, logConfInstance: MapleJson | None) -> None:
316
425
 
@@ -348,12 +457,12 @@ class LoggerConfig(BaseModel):
348
457
  MAX_LOG_SIZE: self.maxLogSize,
349
458
  FILE_MODE: "daily" if self.logfile and "log_" in self.logfile else "append",
350
459
  FILE_ENCODING: self.encoding,
351
- TIMESTAMP_FORMAT: self.timestampFormat,
460
+ TIMESTAMP: self.formats.timestamp if self.formats.timestamp else None,
352
461
  GET_LOGGER: bool(self.func),
353
462
  CONSOLE_ALIGN_WIDTH: self.consoleAlignWidth,
354
463
  FILE_ALIGN_WIDTH: self.fileAlignWidth,
355
- CONSOLE_FORMAT: self.consoleFormat,
356
- FILE_FORMAT: self.fileFormat,
464
+ PARAM_CONSOLE_FORMAT: self.formats.consoleFormat,
465
+ PARAM_FILE_FORMAT: self.formats.fileFormat,
357
466
  PROCESS_ID: self.pid
358
467
  }
359
468
 
@@ -0,0 +1,45 @@
1
+ from .config_keys import *
2
+ from .defaults import *
3
+ from .dict_keys import *
4
+
5
+ __all__ = [
6
+ "CONFIG_KEY",
7
+ "CONSOLE",
8
+ "FILE",
9
+ "CONSOLE_LOG_LEVEL",
10
+ "FILE_LOG_LEVEL",
11
+ "MAX_LOG_SIZE",
12
+ "FILE_MODE",
13
+ "WORKING_DIRECTORY",
14
+ "FILE_ENCODING",
15
+ "FORMATS",
16
+ "TIMESTAMP",
17
+ "FORMAT",
18
+ "DIGITS",
19
+ "ALIGN_WIDTH",
20
+ "CONSOLE_LOG_FORMAT",
21
+ "FILE_LOG_FORMAT",
22
+ "SEPARATOR",
23
+ "NAME_SPACES",
24
+ "NAME_SPACE",
25
+ # Dictionary keys for internal use
26
+ "GET_LOGGER",
27
+ "FUNC",
28
+ "CONFIG_FILE",
29
+ "CONSOLE_ALIGN_WIDTH",
30
+ "FILE_ALIGN_WIDTH",
31
+ "CALLER_NAME",
32
+ "PROCESS_ID",
33
+ "PARAM_TIMESTAMP",
34
+ "PARAM_FORMATS",
35
+ "PARAM_CONSOLE_FORMAT",
36
+ "PARAM_FILE_FORMAT",
37
+ # Default values
38
+ "FILE_FORMAT",
39
+ "CONSOLE_FORMAT",
40
+ "DEFAULT_SEPARATOR",
41
+ "TIMESTAMP_FORMAT",
42
+ "MILLISECOND_DIGITS",
43
+ "FILE_MODE_OVERWRITE",
44
+ "FILE_MODE_DAILY",
45
+ ]
@@ -0,0 +1,21 @@
1
+ CONFIG_KEY = "MapleLogger"
2
+ CONSOLE = "Console"
3
+ FILE = "File"
4
+ CONSOLE_LOG_LEVEL = "ConsoleLogLevel"
5
+ FILE_LOG_LEVEL = "FileLogLevel"
6
+ MAX_LOG_SIZE = "MaxLogSize"
7
+ FILE_MODE = "FileMode"
8
+ WORKING_DIRECTORY = "WorkingDirectory"
9
+ FILE_ENCODING = "FileEncoding"
10
+
11
+ FORMATS = "Formats"
12
+ CONSOLE_LOG_FORMAT = "ConsoleLogFormat"
13
+ FILE_LOG_FORMAT = "FileLogFormat"
14
+ SEPARATOR = "Separator"
15
+ TIMESTAMP = "Timestamp"
16
+ FORMAT = "Format"
17
+ DIGITS = "Digits"
18
+
19
+ ALIGN_WIDTH = "AlignWidth"
20
+ NAME_SPACES = "NameSpaces"
21
+ NAME_SPACE = "NameSpace"
@@ -0,0 +1,7 @@
1
+ FILE_FORMAT = '({pid}) {timestamp} [{level}]{func} {callerName}{callerFunc}({callerLine})'
2
+ CONSOLE_FORMAT = '[{level}]{func} {callerFunc}{callerLine}'
3
+ DEFAULT_SEPARATOR = ': '
4
+ TIMESTAMP_FORMAT = "%F %X.%f"
5
+ MILLISECOND_DIGITS = None
6
+ FILE_MODE_OVERWRITE = 'overwrite'
7
+ FILE_MODE_DAILY = 'daily'
@@ -0,0 +1,11 @@
1
+ CONFIG_FILE = "configFile"
2
+ FUNC = "func"
3
+ GET_LOGGER = "getLogger"
4
+ CONSOLE_ALIGN_WIDTH = "consoleAlignWidth"
5
+ FILE_ALIGN_WIDTH = "fileAlignWidth"
6
+ CALLER_NAME = "CallerName"
7
+ PROCESS_ID = "pid"
8
+ PARAM_TIMESTAMP = "timestamp"
9
+ PARAM_FORMATS = "formats"
10
+ PARAM_CONSOLE_FORMAT = "consoleFormat"
11
+ PARAM_FILE_FORMAT = "fileFormat"
@@ -7,6 +7,7 @@ from datetime import datetime
7
7
  import inspect
8
8
  import os
9
9
 
10
+ from .config import TimeStamp
10
11
  from .consts import *
11
12
  from .log_levels import *
12
13
  from .utilities import *
@@ -29,8 +30,10 @@ class Formatter:
29
30
  self.consoleColors = getConsoleColors()
30
31
  self.logLevel = LogLevel
31
32
  self.config = config
32
- self.consoleFormat = config.get(CONSOLE_FORMAT, CONSOLE_FORMAT)
33
- self.fileFormat = config.get(FILE_FORMAT, FILE_FORMAT)
33
+ self.consoleFormat = config.get(PARAM_CONSOLE_FORMAT, CONSOLE_FORMAT)
34
+ self.fileFormat = config.get(PARAM_FILE_FORMAT, FILE_FORMAT)
35
+ self.timestampFormat = self.config.get(TIMESTAMP, TimeStamp()).timestampFormat or TIMESTAMP_FORMAT
36
+ self.timestampDigits = config.get(TIMESTAMP, TimeStamp()).digits or MILLISECOND_DIGITS
34
37
  self.pid = os.getpid()
35
38
  self.COLOR_CODE_LENGTH = 5
36
39
  self.COLOR_CODE_RESET_LENGTH = 4
@@ -69,7 +72,7 @@ class Formatter:
69
72
 
70
73
  return colorCodeLength
71
74
 
72
- def __getCurrentTimestamp(self, timestampFormat: str) -> str:
75
+ def __getCurrentTimestamp(self) -> str:
73
76
 
74
77
  """
75
78
  Get the current timestamp formatted according to the specified format string.
@@ -78,7 +81,7 @@ class Formatter:
78
81
  :return: The current timestamp as a formatted string.
79
82
  """
80
83
 
81
- return datetime.now().strftime(timestampFormat)
84
+ return datetime.now().strftime(self.timestampFormat)[:self.timestampDigits]
82
85
 
83
86
  def __getLogLevelColor(self, logLevel: LogLevel) -> str:
84
87
 
@@ -142,7 +145,7 @@ class Formatter:
142
145
 
143
146
  if '{timestamp}' in consoleFormat:
144
147
 
145
- timestamp = self.__getCurrentTimestamp(self.config.get(TIMESTAMP_FORMAT, '%Y-%m-%d %H:%M:%S'))
148
+ timestamp = self.__getCurrentTimestamp()
146
149
  consoleFormat = consoleFormat.replace('{timestamp}', timestamp)
147
150
 
148
151
  if '{level}' in consoleFormat:
@@ -193,7 +196,7 @@ class Formatter:
193
196
 
194
197
  if '{timestamp}' in fileFormat:
195
198
 
196
- timestamp = self.__getCurrentTimestamp(self.config.get(TIMESTAMP_FORMAT, '%Y-%m-%d %H:%M:%S'))
199
+ timestamp = self.__getCurrentTimestamp()
197
200
  fileFormat = fileFormat.replace('{timestamp}', timestamp)
198
201
 
199
202
  if '{level}' in fileFormat:
@@ -28,7 +28,7 @@ class Logger:
28
28
  fileMode: Literal["append", "overwrite", "daily"] | None = None,
29
29
  configFile: str = "config.json",
30
30
  encoding: str | None = None,
31
- timestampFormat: str | None = None,
31
+ timestamp: TimeStamp | None = None,
32
32
  **kwargs
33
33
  ) -> None:
34
34
 
@@ -48,7 +48,7 @@ class Logger:
48
48
  "fileMode": fileMode,
49
49
  "configFile": configFile,
50
50
  "encoding": encoding,
51
- "timestampFormat": timestampFormat,
51
+ "timestamp": timestamp,
52
52
  "getLogger": kwargs.get("getLogger", False),
53
53
  "consoleAlignWidth": kwargs.get("consoleAlignWidth", 16),
54
54
  "fileAlignWidth": kwargs.get("fileAlignWidth", 4)
@@ -166,7 +166,7 @@ class Logger:
166
166
 
167
167
  if loglevel >= self.config.consoleLogLevel:
168
168
  consolePrefix = self.formatter.format_console(loglevel, callerDepth)
169
- print(f"{consolePrefix}: {message}")
169
+ print(f"{consolePrefix}{self.config.formats.separator}{message}")
170
170
 
171
171
  if loglevel >= self.config.fileLogLevel:
172
172
 
@@ -177,7 +177,7 @@ class Logger:
177
177
  try:
178
178
 
179
179
  with open(self.config.logfile, "a", encoding=self.config.encoding) as f:
180
- print(f"{prefixString}: {message}", file=f)
180
+ print(f"{prefixString}{self.config.formats.separator}{message}", file=f)
181
181
 
182
182
  break
183
183
 
@@ -235,21 +235,33 @@ class Logger:
235
235
  ################################
236
236
  # Error
237
237
 
238
- def error(self, object: any):
238
+ def error(self, object: any, exception: Exception | None = None):
239
239
 
240
240
  '''Error log'''
241
241
 
242
- self.logWriter(self.LogLevel.ERROR, object, callerDepth=self.DEFAULT_CALLER_DEPTH)
242
+ if exception is None:
243
+
244
+ self.logWriter(self.LogLevel.ERROR, object, callerDepth=self.DEFAULT_CALLER_DEPTH)
245
+
246
+ else:
247
+
248
+ self.ShowError(exception, message=f"{object}", fatal=False, additionalCallerDepth=1)
243
249
 
244
250
  #
245
251
  ################################
246
252
  # Fatal
247
253
 
248
- def fatal(self, object: any):
254
+ def fatal(self, object: any, exception: Exception | None = None):
249
255
 
250
256
  '''Fatal log'''
251
257
 
252
- self.logWriter(self.LogLevel.FATAL, object, callerDepth=self.DEFAULT_CALLER_DEPTH)
258
+ if exception is None:
259
+
260
+ self.logWriter(self.LogLevel.FATAL, object, callerDepth=self.DEFAULT_CALLER_DEPTH)
261
+
262
+ else:
263
+
264
+ self.ShowError(exception, message=f"{object}", fatal=True, additionalCallerDepth=1)
253
265
 
254
266
  #
255
267
  ################################
@@ -265,7 +277,7 @@ class Logger:
265
277
  ################################
266
278
  # Error messages
267
279
 
268
- def ShowError(self, ex: Exception, message: str | None = None, fatal: bool = False):
280
+ def ShowError(self, ex: Exception, message: str | None = None, fatal: bool = False, additionalCallerDepth: int = 0) -> None:
269
281
 
270
282
  '''Show and log error'''
271
283
 
@@ -279,9 +291,9 @@ class Logger:
279
291
 
280
292
  if message is not None:
281
293
 
282
- self.logWriter(logLevel, message, callerDepth=self.DEFAULT_CALLER_DEPTH)
294
+ self.logWriter(logLevel, message, callerDepth=self.DEFAULT_CALLER_DEPTH + additionalCallerDepth)
283
295
 
284
- self.logWriter(logLevel, f"{ex}\n{traceback.format_exc()}", callerDepth=self.DEFAULT_CALLER_DEPTH)
296
+ self.logWriter(logLevel, f"{ex}\n{traceback.format_exc()}", callerDepth=self.DEFAULT_CALLER_DEPTH + additionalCallerDepth)
285
297
 
286
298
  #
287
299
  ################################
@@ -377,9 +389,9 @@ ToDo list:
377
389
 
378
390
  * Logger *
379
391
 
380
- - Add option to set date format
381
- - Add set* functions
382
392
  - Configure log format in config file
393
+ - Configure mili sec digits
394
+ - Add set* functions
383
395
 
384
396
  """
385
397
  """ * * * * * * * * * * * * * """
@@ -1,158 +0,0 @@
1
- # Logger Class
2
-
3
- &nbsp;&nbsp;&nbsp;&nbsp;Logger class is a logging object for Python applications. It outputs application logs to log files and to standard output.
4
-
5
- ## Logger Initialization
6
-
7
- ```python
8
- def __init__(
9
- func: str = "",
10
- workingDirectory: str | None = None,
11
- cmdLogLevel: str | None = None,
12
- fileLogLevel: str | None = None,
13
- maxLogSize: float | None = None,
14
- fileMode: Literal["append", "overwrite", "daily"] | None = None,
15
- configFile: str = "config.json",
16
- encoding: str | None = None,
17
- ) -> None:
18
- ```
19
-
20
- |Property|Required|Value|Version|
21
- |--------|--------|-----|-------|
22
- |**`func`**||Primary function name||
23
- |**`workingDirectory`**||Log file output directory||
24
- |**`cmdLogLevel`**||Terminal output log level||
25
- |**`fileLogLevel`**||Log file output log level||
26
- |**`maxLogSize`**||Log file max size (MB)||
27
- |**`fileMode`**||Logging file mode|`v3.0`|
28
- |**`configFile`**||Logger configuration file path|`v3.0`|
29
- |**`encoding`**||Log file encoding|`v3.0`|
30
-
31
- &nbsp;&nbsp;&nbsp;&nbsp;The parameter overwrites the settings configured in `config.mpl`.
32
-
33
- ## Functions
34
-
35
- ### `getLogger()`
36
-
37
- ```python
38
- def getLogger(
39
- name = "",
40
- **kwargs
41
- ) -> maplex.Logger:
42
- ```
43
-
44
- |Property|Required|Value|Version|
45
- |--------|--------|-----|-------|
46
- |**`name`**||Primary funcion name|`v3.0`|
47
- |**`**kwargs`**||Other parameters|`v3.0`|
48
-
49
- &nbsp;&nbsp;&nbsp;&nbsp;This get or creates a Logger instance.
50
-
51
- &nbsp;&nbsp;&nbsp;&nbsp;If you already have a Logger class instance with the same name, the function returns the existing instance, and you can save your resources on the machine.
52
-
53
- ```python
54
- from maplex
55
-
56
- logger = maplex.getLogger(__name__)
57
- ```
58
-
59
- ## Getters and Setters
60
-
61
- &nbsp;&nbsp;&nbsp;&nbsp;Every class parameter has its own getter and setter functions, and you can set, change, or get those values after initializing the class.
62
-
63
- ## Logging Methods
64
-
65
- ```python
66
- def trace(object: any) -> None:
67
- def debug(object: any) -> None:
68
- def info(object: any) -> None:
69
- def warn(object: any) -> None:
70
- def error(object: any) -> None:
71
- def fatal(object: any) -> None:
72
- ```
73
-
74
- &nbsp;&nbsp;&nbsp;&nbsp;Each function outputs the log in each log level.
75
-
76
- ## `ShowError` Function
77
-
78
- &nbsp;&nbsp;&nbsp;&nbsp;This outputs the error logs and stuck trace.
79
-
80
- Function:
81
-
82
- ```python
83
- def ShowError(
84
- ex: Exception,
85
- message: str | None = None,
86
- fatal: bool = False
87
- )
88
- ```
89
-
90
- |Property|Required|Value|
91
- |--------|--------|-----|
92
- |**`ex`**|\*|Exception|
93
- |**`message`**||Custom error message|
94
- |**`fatal`**||Show error as `FATAL`|
95
-
96
- - If `fatal=True`, it outputs log as a `FATAL` log level.
97
-
98
- ## Usage
99
-
100
- ```python
101
- from maplex
102
-
103
- logger = maplex.getLogger("FunctionName")
104
- logger.info("Hello there!")
105
- ```
106
-
107
- This outputs:
108
-
109
- ```console
110
- [INFO ][FunctionName] <module>(4) Hello there!
111
- ```
112
-
113
- File output will be: `AppLog.log`
114
-
115
- ```log
116
- (PsNo) yyyy-MM-dd HH:mm:ss.fff [INFO ][FunctionName] <module>(4) Hello there!
117
- ```
118
-
119
- ### Log Level
120
-
121
- - `TRACE`
122
- - `DEBUG`
123
- - `INFO`
124
- - `WARN`
125
- - `ERROR`
126
- - `FATAL`
127
-
128
- ## Settings
129
-
130
- - You can configure log settings with a JSON formatted file (default: `config.json`).
131
- - If the configuration file does not exist, the instance auto-generates the file.
132
- - Instance uses the parameter values to auto-generate a configuration file, or uses the default value if it was not specified.
133
-
134
- Auto-generated configuration file (parameters not specified):
135
-
136
- ```json
137
- {
138
- "MapleLogger": {
139
- "ConsoleLogLevel": "INFO",
140
- "FileLogLevel": "INFO",
141
- "MaxLogSize": 3.0,
142
- "WorkingDirectory": "/path/to/output/logs",
143
- "FileEncoding": "utf-8"
144
- }
145
- }
146
- ```
147
-
148
- |Key|Value|
149
- |---|-----|
150
- |**`ConsoleLogLevel`**|Console log level|
151
- |**`FileLogLevel`**|File log level|
152
- |**`MaxLogSize`**|Log file max size (MB)|
153
- |**`WorkingDirectory`**|Log file output path|
154
- |**`FileEncoding`**|Log file encoding|
155
-
156
- - To disable the log output, set the log level to `NONE`.
157
- - You can use a `float` number for the file max size (E.g., `2.5` for `2.5MB`)
158
- - You can also use a `str` for the file max size (E.g., `"3M"`)
@@ -1,2 +0,0 @@
1
- cryptography>=46.0.3
2
- pydantic>=2.12.5
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes