beans-logging 6.0.1__tar.gz → 6.0.3__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 (33) hide show
  1. {beans_logging-6.0.1/src/beans_logging.egg-info → beans_logging-6.0.3}/PKG-INFO +13 -8
  2. {beans_logging-6.0.1 → beans_logging-6.0.3}/README.md +11 -6
  3. {beans_logging-6.0.1 → beans_logging-6.0.3}/pyproject.toml +1 -1
  4. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging/__init__.py +2 -4
  5. beans_logging-6.0.3/src/beans_logging/__version__.py +1 -0
  6. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging/_base.py +41 -63
  7. beans_logging-6.0.1/src/beans_logging/_consts.py → beans_logging-6.0.3/src/beans_logging/_constants.py +0 -2
  8. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging/_handlers.py +2 -4
  9. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging/_utils.py +25 -24
  10. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging/auto.py +2 -3
  11. beans_logging-6.0.3/src/beans_logging/config.py +138 -0
  12. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging/filters.py +0 -3
  13. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging/formats.py +0 -2
  14. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging/rotation.py +2 -4
  15. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging/sinks.py +0 -2
  16. {beans_logging-6.0.1 → beans_logging-6.0.3/src/beans_logging.egg-info}/PKG-INFO +13 -8
  17. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging.egg-info/SOURCES.txt +2 -3
  18. beans_logging-6.0.1/auto.py +0 -6
  19. beans_logging-6.0.1/src/beans_logging/__version__.py +0 -1
  20. beans_logging-6.0.1/src/beans_logging/schemas.py +0 -173
  21. {beans_logging-6.0.1 → beans_logging-6.0.3}/.python-version +0 -0
  22. {beans_logging-6.0.1 → beans_logging-6.0.3}/LICENSE.txt +0 -0
  23. {beans_logging-6.0.1 → beans_logging-6.0.3}/requirements/requirements.build.txt +0 -0
  24. {beans_logging-6.0.1 → beans_logging-6.0.3}/requirements/requirements.dev.txt +0 -0
  25. {beans_logging-6.0.1 → beans_logging-6.0.3}/requirements/requirements.docs.txt +0 -0
  26. {beans_logging-6.0.1 → beans_logging-6.0.3}/requirements/requirements.fastapi.txt +0 -0
  27. {beans_logging-6.0.1 → beans_logging-6.0.3}/requirements/requirements.test.txt +0 -0
  28. {beans_logging-6.0.1 → beans_logging-6.0.3}/requirements.txt +0 -0
  29. {beans_logging-6.0.1 → beans_logging-6.0.3}/setup.cfg +0 -0
  30. {beans_logging-6.0.1 → beans_logging-6.0.3}/setup.py +0 -0
  31. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging.egg-info/dependency_links.txt +0 -0
  32. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging.egg-info/requires.txt +0 -0
  33. {beans_logging-6.0.1 → beans_logging-6.0.3}/src/beans_logging.egg-info/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beans_logging
3
- Version: 6.0.1
4
- Summary: 'beans-logging' is a python package for simple logger and easily managing logging.
3
+ Version: 6.0.3
4
+ Summary: 'beans-logging' is a python package for simple logger and easily managing logs.
5
5
  Author-email: Batkhuu Byambajav <batkhuu10@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/bybatkhuu/module-python-logging
7
7
  Project-URL: Documentation, https://pylogging-docs.bybatkhuu.dev
@@ -100,7 +100,7 @@ It is a `Loguru` based custom logging package for python projects.
100
100
  [OPTIONAL] For **DEVELOPMENT** environment:
101
101
 
102
102
  - Install [**git**](https://git-scm.com/downloads)
103
- - Setup an [**SSH key**](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh) ([video tutorial](https://www.youtube.com/watch?v=snCP3c7wXw0))
103
+ - Setup an [**SSH key**](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)
104
104
 
105
105
  ### 2. 📥 Download or clone the repository
106
106
 
@@ -213,7 +213,7 @@ logger.info("Logging info.")
213
213
 
214
214
  ### **Simple**
215
215
 
216
- [**`configs/logger.yml`**](https://github.com/bybatkhuu/module-python-logging/blob/main/examples/simple/configs/logger.yml):
216
+ [**`configs/logger.yml`**](./examples/simple/configs/logger.yml):
217
217
 
218
218
  ```yml
219
219
  logger:
@@ -226,9 +226,11 @@ logger:
226
226
  enabled: true
227
227
  ```
228
228
 
229
- [**`main.py`**](https://github.com/bybatkhuu/module-python-logging/blob/main/examples/simple/main.py):
229
+ [**`main.py`**](./examples/simple/main.py):
230
230
 
231
231
  ```python
232
+ #!/usr/bin/env python
233
+
232
234
  from beans_logging.auto import logger
233
235
 
234
236
 
@@ -240,10 +242,12 @@ logger.warning("Warning something.")
240
242
  logger.error("Error occured.")
241
243
  logger.critical("CRITICAL ERROR.")
242
244
 
245
+
243
246
  def divide(a, b):
244
247
  _result = a / b
245
248
  return _result
246
249
 
250
+
247
251
  def nested(c):
248
252
  try:
249
253
  divide(5, c)
@@ -251,13 +255,14 @@ def nested(c):
251
255
  logger.error(err)
252
256
  raise
253
257
 
258
+
254
259
  try:
255
260
  nested(0)
256
- except Exception as err:
261
+ except Exception:
257
262
  logger.exception("Show me, what value is wrong:")
258
263
  ```
259
264
 
260
- Run the [**`examples/simple`**](https://github.com/bybatkhuu/module-python-logging/tree/main/examples/simple):
265
+ Run the [**`examples/simple`**](./examples/simple):
261
266
 
262
267
  ```sh
263
268
  cd ./examples/simple
@@ -303,7 +308,7 @@ ZeroDivisionError: division by zero
303
308
 
304
309
  ## ⚙️ Configuration
305
310
 
306
- [**`templates/configs/config.yml`**](./templates/configs/config.yml):
311
+ [**`templates/configs/logger.yml`**](./templates/configs/logger.yml):
307
312
 
308
313
  ```yaml
309
314
  logger:
@@ -38,7 +38,7 @@ It is a `Loguru` based custom logging package for python projects.
38
38
  [OPTIONAL] For **DEVELOPMENT** environment:
39
39
 
40
40
  - Install [**git**](https://git-scm.com/downloads)
41
- - Setup an [**SSH key**](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh) ([video tutorial](https://www.youtube.com/watch?v=snCP3c7wXw0))
41
+ - Setup an [**SSH key**](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)
42
42
 
43
43
  ### 2. 📥 Download or clone the repository
44
44
 
@@ -151,7 +151,7 @@ logger.info("Logging info.")
151
151
 
152
152
  ### **Simple**
153
153
 
154
- [**`configs/logger.yml`**](https://github.com/bybatkhuu/module-python-logging/blob/main/examples/simple/configs/logger.yml):
154
+ [**`configs/logger.yml`**](./examples/simple/configs/logger.yml):
155
155
 
156
156
  ```yml
157
157
  logger:
@@ -164,9 +164,11 @@ logger:
164
164
  enabled: true
165
165
  ```
166
166
 
167
- [**`main.py`**](https://github.com/bybatkhuu/module-python-logging/blob/main/examples/simple/main.py):
167
+ [**`main.py`**](./examples/simple/main.py):
168
168
 
169
169
  ```python
170
+ #!/usr/bin/env python
171
+
170
172
  from beans_logging.auto import logger
171
173
 
172
174
 
@@ -178,10 +180,12 @@ logger.warning("Warning something.")
178
180
  logger.error("Error occured.")
179
181
  logger.critical("CRITICAL ERROR.")
180
182
 
183
+
181
184
  def divide(a, b):
182
185
  _result = a / b
183
186
  return _result
184
187
 
188
+
185
189
  def nested(c):
186
190
  try:
187
191
  divide(5, c)
@@ -189,13 +193,14 @@ def nested(c):
189
193
  logger.error(err)
190
194
  raise
191
195
 
196
+
192
197
  try:
193
198
  nested(0)
194
- except Exception as err:
199
+ except Exception:
195
200
  logger.exception("Show me, what value is wrong:")
196
201
  ```
197
202
 
198
- Run the [**`examples/simple`**](https://github.com/bybatkhuu/module-python-logging/tree/main/examples/simple):
203
+ Run the [**`examples/simple`**](./examples/simple):
199
204
 
200
205
  ```sh
201
206
  cd ./examples/simple
@@ -241,7 +246,7 @@ ZeroDivisionError: division by zero
241
246
 
242
247
  ## ⚙️ Configuration
243
248
 
244
- [**`templates/configs/config.yml`**](./templates/configs/config.yml):
249
+ [**`templates/configs/logger.yml`**](./templates/configs/logger.yml):
245
250
 
246
251
  ```yaml
247
252
  logger:
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "beans_logging"
7
7
  authors = [{ name = "Batkhuu Byambajav", email = "batkhuu10@gmail.com" }]
8
- description = "'beans-logging' is a python package for simple logger and easily managing logging."
8
+ description = "'beans-logging' is a python package for simple logger and easily managing logs."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10,<4.0"
11
11
  keywords = [
@@ -1,8 +1,6 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  from ._base import Logger, logger, LoggerLoader
4
- from .schemas import LoggerConfigPM
5
- from ._consts import WarnEnum
2
+ from .config import LoggerConfigPM
3
+ from ._constants import WarnEnum
6
4
  from .__version__ import __version__
7
5
 
8
6
 
@@ -0,0 +1 @@
1
+ __version__ = "6.0.3"
@@ -1,28 +1,21 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- ## Standard libraries
1
+ # Standard libraries
4
2
  import os
5
3
  import copy
6
4
  import json
7
5
  import logging
8
- from typing import Union, Dict, Any
6
+ from typing import Any
9
7
 
10
- ## Third-party libraries
8
+ # Third-party libraries
11
9
  import yaml
12
10
  from loguru import logger
13
11
  from loguru._logger import Logger
14
- import pydantic
15
-
16
- if "2.0.0" <= pydantic.__version__:
17
- from pydantic import validate_call
18
- else:
19
- from pydantic import validate_arguments as validate_call
12
+ from pydantic import validate_call
20
13
 
21
- ## Internal modules
14
+ # Internal modules
22
15
  from ._utils import create_dir, deep_merge
23
16
  from ._handlers import InterceptHandler
24
17
  from .rotation import RotationChecker
25
- from .schemas import LoggerConfigPM
18
+ from .config import LoggerConfigPM
26
19
  from .sinks import std_sink
27
20
  from .formats import json_format
28
21
  from .filters import (
@@ -67,7 +60,7 @@ class LoggerLoader:
67
60
  @validate_call
68
61
  def __init__(
69
62
  self,
70
- config: Union[LoggerConfigPM, Dict[str, Any], None] = None,
63
+ config: LoggerConfigPM | dict[str, Any] | None = None,
71
64
  config_file_path: str = _CONFIG_FILE_PATH,
72
65
  auto_config_file: bool = True,
73
66
  auto_load: bool = False,
@@ -75,12 +68,14 @@ class LoggerLoader:
75
68
  """LoggerLoader constructor method.
76
69
 
77
70
  Args:
78
- config (Union[LoggerConfigPM,
79
- dict,
80
- None ], optional): New logger config to update loaded config. Defaults to None.
81
- config_file_path (str , optional): Logger config file path. Defaults to `LoggerLoader._CONFIG_FILE_PATH`.
82
- auto_config_file (bool , optional): Indicates whether to load logger config file or not. Defaults to True.
83
- auto_load (bool , optional): Indicates whether to load logger handlers or not. Defaults to False.
71
+ config (LoggerConfigPM | dict | None, optional): New logger config to update loaded config.
72
+ Defaults to None.
73
+ config_file_path (str , optional): Logger config file path. Defaults to
74
+ `LoggerLoader._CONFIG_FILE_PATH`.
75
+ auto_config_file (bool , optional): Indicates whether to load logger config
76
+ file or not. Defaults to True.
77
+ auto_load (bool , optional): Indicates whether to load logger
78
+ handlers or not. Defaults to False.
84
79
  """
85
80
 
86
81
  self.handlers_map = {"default": 0}
@@ -125,9 +120,7 @@ class LoggerLoader:
125
120
  return logger
126
121
 
127
122
  @validate_call
128
- def remove_handler(
129
- self, handler: Union[str, None] = None, handler_type: str = "NAME"
130
- ):
123
+ def remove_handler(self, handler: str | None = None, handler_type: str = "NAME"):
131
124
  """Remove all handlers or specific handler by name or id from logger.
132
125
 
133
126
  Raises:
@@ -162,7 +155,7 @@ class LoggerLoader:
162
155
  self.handlers_map.clear()
163
156
 
164
157
  @validate_call
165
- def update_config(self, config: Union[LoggerConfigPM, Dict[str, Any]]):
158
+ def update_config(self, config: LoggerConfigPM | dict[str, Any]):
166
159
  """Update logger config with new config.
167
160
 
168
161
  Args:
@@ -173,11 +166,7 @@ class LoggerLoader:
173
166
  """
174
167
 
175
168
  if isinstance(config, dict):
176
- if "2.0.0" <= pydantic.__version__:
177
- _config_dict = self.config.model_dump()
178
- else:
179
- _config_dict = self.config.dict()
180
-
169
+ _config_dict = self.config.model_dump()
181
170
  _merged_dict = deep_merge(_config_dict, config)
182
171
  try:
183
172
  self.config = LoggerConfigPM(**_merged_dict)
@@ -213,13 +202,11 @@ class LoggerLoader:
213
202
  # elif self.config_file_path.lower().endswith(".toml"):
214
203
  # _file_format = "TOML"
215
204
 
216
- ## Loading config from file, if it's exits:
205
+ # Loading config from file, if it's exits:
217
206
  if os.path.isfile(self.config_file_path):
218
207
  if _file_format == "YAML":
219
208
  try:
220
- with open(
221
- self.config_file_path, "r", encoding="utf-8"
222
- ) as _config_file:
209
+ with open(self.config_file_path, encoding="utf-8") as _config_file:
223
210
  _new_config_dict = yaml.safe_load(_config_file) or {}
224
211
  if "logger" not in _new_config_dict:
225
212
  logger.warning(
@@ -228,10 +215,7 @@ class LoggerLoader:
228
215
  return
229
216
 
230
217
  _new_config_dict = _new_config_dict["logger"]
231
- if "2.0.0" <= pydantic.__version__:
232
- _config_dict = self.config.model_dump()
233
- else:
234
- _config_dict = self.config.dict()
218
+ _config_dict = self.config.model_dump()
235
219
 
236
220
  _merged_dict = deep_merge(_config_dict, _new_config_dict)
237
221
  self.config = LoggerConfigPM(**_merged_dict)
@@ -242,9 +226,7 @@ class LoggerLoader:
242
226
  raise
243
227
  elif _file_format == "JSON":
244
228
  try:
245
- with open(
246
- self.config_file_path, "r", encoding="utf-8"
247
- ) as _config_file:
229
+ with open(self.config_file_path, encoding="utf-8") as _config_file:
248
230
  _new_config_dict = json.load(_config_file) or {}
249
231
  if "logger" not in _new_config_dict:
250
232
  logger.warning(
@@ -253,10 +235,7 @@ class LoggerLoader:
253
235
  return
254
236
 
255
237
  _new_config_dict = _new_config_dict["logger"]
256
- if "2.0.0" <= pydantic.__version__:
257
- _config_dict = self.config.model_dump()
258
- else:
259
- _config_dict = self.config.dict()
238
+ _config_dict = self.config.model_dump()
260
239
 
261
240
  _merged_dict = deep_merge(_config_dict, _new_config_dict)
262
241
  self.config = LoggerConfigPM(**_merged_dict)
@@ -280,10 +259,7 @@ class LoggerLoader:
280
259
  # return
281
260
 
282
261
  # _new_config_dict = _new_config_dict["logger"]
283
- # if "2.0.0" <= pydantic.__version__:
284
- # _config_dict = self.config.model_dump()
285
- # else:
286
- # _config_dict = self.config.dict()
262
+ # _config_dict = self.config.model_dump()
287
263
 
288
264
  # _merged_dict = deep_merge(_config_dict, _new_config_dict)
289
265
  # self.config = LoggerConfigPM(**_merged_dict)
@@ -296,7 +272,7 @@ class LoggerLoader:
296
272
  def _check_env(self):
297
273
  """Check environment variables for logger config."""
298
274
 
299
- ## Checking environment for DEBUG option:
275
+ # Checking environment for DEBUG option:
300
276
  _is_debug = False
301
277
  _ENV = str(os.getenv("ENV")).strip().lower()
302
278
  _DEBUG = str(os.getenv("DEBUG")).strip().lower()
@@ -314,7 +290,7 @@ class LoggerLoader:
314
290
  self.config.file.logs_dir = os.getenv("BEANS_LOGGING_LOGS_DIR")
315
291
 
316
292
  # if self.config.stream.use_color:
317
- # ## Checking terminal could support xterm colors:
293
+ # # Checking terminal could support xterm colors:
318
294
  # _TERM = str(os.getenv("TERM")).strip()
319
295
  # if not "xterm" in _TERM:
320
296
  # self.config.stream.use_color = False
@@ -536,7 +512,7 @@ class LoggerLoader:
536
512
 
537
513
  _intercept_handler = InterceptHandler()
538
514
 
539
- ## Intercepting all logs from standard (root logger) logging:
515
+ # Intercepting all logs from standard (root logger) logging:
540
516
  logging.basicConfig(handlers=[_intercept_handler], level=0, force=True)
541
517
 
542
518
  _intercepted_modules = set()
@@ -579,10 +555,10 @@ class LoggerLoader:
579
555
  f"Intercepted modules: {list(_intercepted_modules)}; Muted modules: {list(_muted_modules)};"
580
556
  )
581
557
 
582
- ### ATTRIBUTES ###
583
- ## handlers_map ##
558
+ # ATTRIBUTES #
559
+ # handlers_map
584
560
  @property
585
- def handlers_map(self) -> Dict[str, int]:
561
+ def handlers_map(self) -> dict[str, int]:
586
562
  try:
587
563
  return self.__handlers_map
588
564
  except AttributeError:
@@ -591,7 +567,7 @@ class LoggerLoader:
591
567
  return self.__handlers_map
592
568
 
593
569
  @handlers_map.setter
594
- def handlers_map(self, handlers_map: Dict[str, int]):
570
+ def handlers_map(self, handlers_map: dict[str, int]):
595
571
  if not isinstance(handlers_map, dict):
596
572
  raise TypeError(
597
573
  f"`handlers_map` attribute type {type(handlers_map)} is invalid, must be <dict>!."
@@ -599,9 +575,9 @@ class LoggerLoader:
599
575
 
600
576
  self.__handlers_map = copy.deepcopy(handlers_map)
601
577
 
602
- ## handlers_map ##
578
+ # handlers_map
603
579
 
604
- ## config ##
580
+ # config
605
581
  @property
606
582
  def config(self) -> LoggerConfigPM:
607
583
  try:
@@ -620,9 +596,9 @@ class LoggerLoader:
620
596
 
621
597
  self.__config = copy.deepcopy(config)
622
598
 
623
- ## config ##
599
+ # config
624
600
 
625
- ## config_file_path ##
601
+ # config_file_path
626
602
  @property
627
603
  def config_file_path(self) -> str:
628
604
  try:
@@ -648,11 +624,13 @@ class LoggerLoader:
648
624
  ):
649
625
  if not config_file_path.lower().endswith(".toml"):
650
626
  raise NotImplementedError(
651
- f"`config_file_path` attribute value '{config_file_path}' is invalid, TOML file format is not supported yet!"
627
+ f"`config_file_path` attribute value '{config_file_path}' is invalid, "
628
+ f"TOML file format is not supported yet!"
652
629
  )
653
630
 
654
631
  raise ValueError(
655
- f"`config_file_path` attribute value '{config_file_path}' is invalid, file must be '.yml', '.yaml' or '.json' format!"
632
+ f"`config_file_path` attribute value '{config_file_path}' is invalid, "
633
+ f"file must be '.yml', '.yaml' or '.json' format!"
656
634
  )
657
635
 
658
636
  if not os.path.isabs(config_file_path):
@@ -660,5 +638,5 @@ class LoggerLoader:
660
638
 
661
639
  self.__config_file_path = config_file_path
662
640
 
663
- ## config_file_path ##
664
- ### ATTRIBUTES ###
641
+ # config_file_path
642
+ # ATTRIBUTES #
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  from enum import Enum
4
2
 
5
3
 
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  import sys
4
2
  import logging
5
3
  from logging import LogRecord
@@ -25,13 +23,13 @@ class InterceptHandler(logging.Handler):
25
23
  record (LogRecord, required): Log needs to be handled.
26
24
  """
27
25
 
28
- ## Get corresponding Loguru level if it exists
26
+ # Get corresponding Loguru level if it exists
29
27
  try:
30
28
  _level = logger.level(record.levelname).name
31
29
  except ValueError:
32
30
  _level = record.levelno
33
31
 
34
- ## Find caller from where originated the logged message
32
+ # Find caller from where originated the logged message
35
33
  _frame, _depth = sys._getframe(6), 6
36
34
  while _frame and _frame.f_code.co_filename == logging.__file__:
37
35
  _frame = _frame.f_back
@@ -1,19 +1,12 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  import os
4
2
  import sys
5
3
  import copy
6
4
  import errno
7
5
 
8
6
  from loguru import logger
9
- import pydantic
10
-
11
- if "2.0.0" <= pydantic.__version__:
12
- from pydantic import validate_call
13
- else:
14
- from pydantic import validate_arguments as validate_call
7
+ from pydantic import validate_call
15
8
 
16
- from ._consts import WarnEnum
9
+ from ._constants import WarnEnum
17
10
 
18
11
 
19
12
  @validate_call
@@ -22,7 +15,8 @@ def create_dir(create_dir: str, warn_mode: WarnEnum = WarnEnum.DEBUG):
22
15
 
23
16
  Args:
24
17
  create_dir (str, required): Create directory path.
25
- warn_mode (str, optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'. Defaults to "DEBUG".
18
+ warn_mode (str, optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
19
+ Defaults to "DEBUG".
26
20
  """
27
21
 
28
22
  if not os.path.isdir(create_dir):
@@ -75,26 +69,33 @@ def deep_merge(dict1: dict, dict2: dict) -> dict:
75
69
  return _merged
76
70
 
77
71
 
78
- def get_default_logs_dir() -> str:
79
- """Return default logs directory path (current working directory + 'logs').
80
-
81
- Returns:
82
- str: Default logs directory path.
83
- """
84
-
85
- return os.path.join(os.getcwd(), "logs")
86
-
72
+ @validate_call
73
+ def get_slug_name(file_path: str | None = None) -> str:
74
+ """Slugify the file name from the given file path or the current script's file path.
87
75
 
88
- def get_app_name() -> str:
89
- """Return application name (sys.argv[0]).
76
+ Args:
77
+ file_path (str | None, optional): The file path to slugify. If None, uses the current script's file path.
78
+ Defaults to None.
90
79
 
91
80
  Returns:
92
- str: Application name.
81
+ str: The slugified file name.
93
82
  """
94
83
 
95
- return (
96
- os.path.splitext(os.path.basename(sys.argv[0]))[0]
84
+ if not file_path:
85
+ file_path = sys.argv[0]
86
+
87
+ _slug_name = (
88
+ os.path.splitext(os.path.basename(file_path))[0]
97
89
  .strip()
98
90
  .replace(" ", "-")
91
+ .replace("_", "-")
99
92
  .lower()
100
93
  )
94
+ return _slug_name
95
+
96
+
97
+ __all__ = [
98
+ "create_dir",
99
+ "deep_merge",
100
+ "get_slug_name",
101
+ ]
@@ -1,11 +1,10 @@
1
- # -*- coding: utf-8 -*-
1
+ # flake8: noqa
2
2
 
3
3
  import os
4
- from typing import Union
5
4
 
6
5
  from . import *
7
6
 
8
- logger_loader: Union[LoggerLoader, None] = None
7
+ logger_loader: LoggerLoader | None = None
9
8
  _DISABLE_DEFAULT_LOGGER = (
10
9
  str(os.getenv("BEANS_LOGGING_DISABLE_DEFAULT")).strip().lower()
11
10
  )
@@ -0,0 +1,138 @@
1
+ import os
2
+ import datetime
3
+ from typing import Any
4
+ from typing_extensions import Self
5
+
6
+ from pydantic import BaseModel, Field, field_validator, model_validator, ConfigDict
7
+
8
+ from ._constants import LogLevelEnum
9
+ from ._utils import get_slug_name
10
+
11
+
12
+ class ExtraBaseModel(BaseModel):
13
+ model_config = ConfigDict(extra="allow")
14
+
15
+
16
+ class StdHandlerConfigPM(ExtraBaseModel):
17
+ enabled: bool = Field(default=True)
18
+
19
+
20
+ class StreamConfigPM(ExtraBaseModel):
21
+ use_color: bool = Field(default=True)
22
+ use_icon: bool = Field(default=False)
23
+ format_str: str = Field(
24
+ default=(
25
+ "[<c>{time:YYYY-MM-DD HH:mm:ss.SSS Z}</c> | <level>{level_short:<5}</level> | <w>{name}:{line}</w>]: "
26
+ "<level>{message}</level>"
27
+ ),
28
+ min_length=8,
29
+ max_length=512,
30
+ )
31
+ std_handler: StdHandlerConfigPM = Field(default_factory=StdHandlerConfigPM)
32
+
33
+
34
+ class LogHandlersConfigPM(ExtraBaseModel):
35
+ enabled: bool = Field(default=False)
36
+ format_str: str = Field(
37
+ default="[{time:YYYY-MM-DD HH:mm:ss.SSS Z} | {level_short:<5} | {name}:{line}]: {message}",
38
+ min_length=8,
39
+ max_length=512,
40
+ )
41
+ log_path: str = Field(
42
+ default="{app_name}.std.all.log", min_length=4, max_length=1024
43
+ )
44
+ err_path: str = Field(
45
+ default="{app_name}.std.err.log", min_length=4, max_length=1024
46
+ )
47
+
48
+ @model_validator(mode="after")
49
+ def _check_log_path(self) -> Self:
50
+ if self.log_path == self.err_path:
51
+ raise ValueError(
52
+ f"`log_path` and `err_path` attributes have same value: '{self.log_path}', must be different!"
53
+ )
54
+
55
+ return self
56
+
57
+
58
+ class JsonHandlersConfigPM(ExtraBaseModel):
59
+ enabled: bool = Field(default=False)
60
+ use_custom: bool = Field(default=False)
61
+ log_path: str = Field(
62
+ default="{app_name}.json.all.log", min_length=4, max_length=1024
63
+ )
64
+ err_path: str = Field(
65
+ default="{app_name}.json.err.log", min_length=4, max_length=1024
66
+ )
67
+
68
+ @model_validator(mode="after")
69
+ def _check_log_path(self) -> Self:
70
+ if self.log_path == self.err_path:
71
+ raise ValueError(
72
+ f"`log_path` and `err_path` attributes have same value: '{self.log_path}', must be different!"
73
+ )
74
+
75
+ return self
76
+
77
+
78
+ class FileConfigPM(ExtraBaseModel):
79
+ logs_dir: str = Field(
80
+ default_factory=lambda: os.path.join(os.getcwd(), "logs"),
81
+ min_length=2,
82
+ max_length=1024,
83
+ )
84
+ rotate_size: int = Field(
85
+ default=10_000_000, ge=1_000, lt=1_000_000_000 # 10MB = 10 * 1000 * 1000
86
+ )
87
+ rotate_time: datetime.time = Field(default_factory=lambda: datetime.time(0, 0, 0))
88
+ backup_count: int = Field(default=90, ge=1)
89
+ encoding: str = Field(default="utf8", min_length=2, max_length=31)
90
+ log_handlers: LogHandlersConfigPM = Field(default_factory=LogHandlersConfigPM)
91
+ json_handlers: JsonHandlersConfigPM = Field(default_factory=JsonHandlersConfigPM)
92
+
93
+ @field_validator("rotate_time", mode="before")
94
+ @classmethod
95
+ def _check_rotate_time(cls, val: Any) -> Any:
96
+ if isinstance(val, str):
97
+ val = datetime.time.fromisoformat(val)
98
+
99
+ return val
100
+
101
+
102
+ class AutoLoadConfigPM(ExtraBaseModel):
103
+ enabled: bool = Field(default=True)
104
+ only_base: bool = Field(default=False)
105
+ ignore_modules: list[str] = Field(default=[])
106
+
107
+
108
+ class InterceptConfigPM(ExtraBaseModel):
109
+ auto_load: AutoLoadConfigPM = Field(default_factory=AutoLoadConfigPM)
110
+ include_modules: list[str] = Field(default=[])
111
+ mute_modules: list[str] = Field(default=[])
112
+
113
+
114
+ class ExtraConfigPM(ExtraBaseModel):
115
+ pass
116
+
117
+
118
+ class LoggerConfigPM(ExtraBaseModel):
119
+ app_name: str = Field(default_factory=get_slug_name, min_length=1, max_length=128)
120
+ level: LogLevelEnum = Field(default=LogLevelEnum.INFO)
121
+ use_backtrace: bool = Field(default=True)
122
+ use_diagnose: bool = Field(default=False)
123
+ stream: StreamConfigPM = Field(default_factory=StreamConfigPM)
124
+ file: FileConfigPM = Field(default_factory=FileConfigPM)
125
+ intercept: InterceptConfigPM = Field(default_factory=InterceptConfigPM)
126
+ extra: ExtraConfigPM | None = Field(default_factory=ExtraConfigPM)
127
+
128
+
129
+ __all__ = [
130
+ "StdHandlerConfigPM",
131
+ "StreamConfigPM",
132
+ "LogHandlersConfigPM",
133
+ "JsonHandlersConfigPM",
134
+ "FileConfigPM",
135
+ "AutoLoadConfigPM",
136
+ "InterceptConfigPM",
137
+ "LoggerConfigPM",
138
+ ]
@@ -1,6 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
-
4
1
  def add_level_short(record: dict) -> dict:
5
2
  """Filter for adding short level name to log record.
6
3
 
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  import json
4
2
  import traceback
5
3
 
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  import datetime
4
2
  from typing import TextIO
5
3
 
@@ -35,8 +33,8 @@ class RotationChecker:
35
33
  )
36
34
 
37
35
  if _current_dtime >= self._dtime_limit:
38
- ## The current time is already past the target time so it would rotate already.
39
- ## Add one day to prevent an immediate rotation.
36
+ # The current time is already past the target time so it would rotate already.
37
+ # Add one day to prevent an immediate rotation.
40
38
  self._dtime_limit += datetime.timedelta(days=1)
41
39
 
42
40
  def should_rotate(self, message: Message, file: TextIO) -> bool:
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  import sys
4
2
 
5
3
  from loguru._handler import Message
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beans_logging
3
- Version: 6.0.1
4
- Summary: 'beans-logging' is a python package for simple logger and easily managing logging.
3
+ Version: 6.0.3
4
+ Summary: 'beans-logging' is a python package for simple logger and easily managing logs.
5
5
  Author-email: Batkhuu Byambajav <batkhuu10@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/bybatkhuu/module-python-logging
7
7
  Project-URL: Documentation, https://pylogging-docs.bybatkhuu.dev
@@ -100,7 +100,7 @@ It is a `Loguru` based custom logging package for python projects.
100
100
  [OPTIONAL] For **DEVELOPMENT** environment:
101
101
 
102
102
  - Install [**git**](https://git-scm.com/downloads)
103
- - Setup an [**SSH key**](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh) ([video tutorial](https://www.youtube.com/watch?v=snCP3c7wXw0))
103
+ - Setup an [**SSH key**](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)
104
104
 
105
105
  ### 2. 📥 Download or clone the repository
106
106
 
@@ -213,7 +213,7 @@ logger.info("Logging info.")
213
213
 
214
214
  ### **Simple**
215
215
 
216
- [**`configs/logger.yml`**](https://github.com/bybatkhuu/module-python-logging/blob/main/examples/simple/configs/logger.yml):
216
+ [**`configs/logger.yml`**](./examples/simple/configs/logger.yml):
217
217
 
218
218
  ```yml
219
219
  logger:
@@ -226,9 +226,11 @@ logger:
226
226
  enabled: true
227
227
  ```
228
228
 
229
- [**`main.py`**](https://github.com/bybatkhuu/module-python-logging/blob/main/examples/simple/main.py):
229
+ [**`main.py`**](./examples/simple/main.py):
230
230
 
231
231
  ```python
232
+ #!/usr/bin/env python
233
+
232
234
  from beans_logging.auto import logger
233
235
 
234
236
 
@@ -240,10 +242,12 @@ logger.warning("Warning something.")
240
242
  logger.error("Error occured.")
241
243
  logger.critical("CRITICAL ERROR.")
242
244
 
245
+
243
246
  def divide(a, b):
244
247
  _result = a / b
245
248
  return _result
246
249
 
250
+
247
251
  def nested(c):
248
252
  try:
249
253
  divide(5, c)
@@ -251,13 +255,14 @@ def nested(c):
251
255
  logger.error(err)
252
256
  raise
253
257
 
258
+
254
259
  try:
255
260
  nested(0)
256
- except Exception as err:
261
+ except Exception:
257
262
  logger.exception("Show me, what value is wrong:")
258
263
  ```
259
264
 
260
- Run the [**`examples/simple`**](https://github.com/bybatkhuu/module-python-logging/tree/main/examples/simple):
265
+ Run the [**`examples/simple`**](./examples/simple):
261
266
 
262
267
  ```sh
263
268
  cd ./examples/simple
@@ -303,7 +308,7 @@ ZeroDivisionError: division by zero
303
308
 
304
309
  ## ⚙️ Configuration
305
310
 
306
- [**`templates/configs/config.yml`**](./templates/configs/config.yml):
311
+ [**`templates/configs/logger.yml`**](./templates/configs/logger.yml):
307
312
 
308
313
  ```yaml
309
314
  logger:
@@ -1,7 +1,6 @@
1
1
  .python-version
2
2
  LICENSE.txt
3
3
  README.md
4
- auto.py
5
4
  pyproject.toml
6
5
  requirements.txt
7
6
  setup.cfg
@@ -20,14 +19,14 @@ requirements/requirements.test.txt
20
19
  src/beans_logging/__init__.py
21
20
  src/beans_logging/__version__.py
22
21
  src/beans_logging/_base.py
23
- src/beans_logging/_consts.py
22
+ src/beans_logging/_constants.py
24
23
  src/beans_logging/_handlers.py
25
24
  src/beans_logging/_utils.py
26
25
  src/beans_logging/auto.py
26
+ src/beans_logging/config.py
27
27
  src/beans_logging/filters.py
28
28
  src/beans_logging/formats.py
29
29
  src/beans_logging/rotation.py
30
- src/beans_logging/schemas.py
31
30
  src/beans_logging/sinks.py
32
31
  src/beans_logging.egg-info/PKG-INFO
33
32
  src/beans_logging.egg-info/SOURCES.txt
@@ -1,6 +0,0 @@
1
- # flake8: noqa
2
-
3
- try:
4
- from .src.beans_logging.auto import *
5
- except ImportError:
6
- from src.beans_logging.auto import *
@@ -1 +0,0 @@
1
- __version__ = "6.0.1"
@@ -1,173 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- import datetime
4
- from typing import List
5
-
6
-
7
- import pydantic
8
- from pydantic import BaseModel, constr, Field
9
-
10
- if "2.0.0" <= pydantic.__version__:
11
- from pydantic import field_validator, model_validator, ConfigDict
12
- else:
13
- from pydantic import validator, root_validator
14
-
15
-
16
- from ._consts import LogLevelEnum
17
- from ._utils import get_default_logs_dir, get_app_name
18
-
19
-
20
- class ExtraBaseModel(BaseModel):
21
- if "2.0.0" <= pydantic.__version__:
22
- model_config = ConfigDict(extra="allow")
23
- else:
24
-
25
- class Config:
26
- extra = "allow"
27
-
28
-
29
- class StdHandlerPM(ExtraBaseModel):
30
- enabled: bool = Field(default=True)
31
-
32
-
33
- class StreamPM(ExtraBaseModel):
34
- use_color: bool = Field(default=True)
35
- use_icon: bool = Field(default=False)
36
- format_str: constr(strip_whitespace=True) = Field(
37
- default="[<c>{time:YYYY-MM-DD HH:mm:ss.SSS Z}</c> | <level>{level_short:<5}</level> | <w>{name}:{line}</w>]: <level>{message}</level>",
38
- min_length=3,
39
- max_length=511,
40
- )
41
- std_handler: StdHandlerPM = Field(default_factory=StdHandlerPM)
42
-
43
-
44
- class LogHandlersPM(ExtraBaseModel):
45
- enabled: bool = Field(default=False)
46
- format_str: constr(strip_whitespace=True) = Field(
47
- default="[{time:YYYY-MM-DD HH:mm:ss.SSS Z} | {level_short:<5} | {name}:{line}]: {message}",
48
- min_length=4,
49
- max_length=511,
50
- )
51
- log_path: constr(strip_whitespace=True) = Field(
52
- default="{app_name}.std.all.log", min_length=4, max_length=1023
53
- )
54
- err_path: constr(strip_whitespace=True) = Field(
55
- default="{app_name}.std.err.log", min_length=4, max_length=1023
56
- )
57
-
58
- if "2.0.0" <= pydantic.__version__:
59
-
60
- @model_validator(mode="after")
61
- def _check_log_path(self) -> "LogHandlersPM":
62
- if self.log_path == self.err_path:
63
- raise ValueError(
64
- f"`log_path` and `err_path` attributes are same: '{self.log_path}', must be different!"
65
- )
66
- return self
67
-
68
- else:
69
-
70
- @root_validator
71
- def _check_log_path(cls, values):
72
- _log_path, _err_path = values.get("log_path"), values.get("err_path")
73
- if _log_path == _err_path:
74
- raise ValueError(
75
- f"`log_path` and `err_path` attributes are same: '{_log_path}', must be different!"
76
- )
77
- return values
78
-
79
-
80
- class JsonHandlersPM(ExtraBaseModel):
81
- enabled: bool = Field(default=False)
82
- use_custom: bool = Field(default=False)
83
- log_path: constr(strip_whitespace=True) = Field(
84
- default="{app_name}.json.all.log", min_length=4, max_length=1023
85
- )
86
- err_path: constr(strip_whitespace=True) = Field(
87
- default="{app_name}.json.err.log", min_length=4, max_length=1023
88
- )
89
-
90
- if "2.0.0" <= pydantic.__version__:
91
-
92
- @model_validator(mode="after")
93
- def _check_log_path(self) -> "JsonHandlersPM":
94
- if self.log_path == self.err_path:
95
- raise ValueError(
96
- f"`log_path` and `err_path` attributes are same: '{self.log_path}', must be different!"
97
- )
98
- return self
99
-
100
- else:
101
-
102
- @root_validator
103
- def _check_log_path(cls, values):
104
- _log_path, _err_path = values.get("log_path"), values.get("err_path")
105
- if _log_path == _err_path:
106
- raise ValueError(
107
- f"`log_path` and `err_path` attributes are same: '{_log_path}', must be different!"
108
- )
109
- return values
110
-
111
-
112
- class FilePM(ExtraBaseModel):
113
- logs_dir: constr(strip_whitespace=True) = Field(
114
- default_factory=get_default_logs_dir, min_length=2, max_length=1023
115
- )
116
- rotate_size: int = Field(
117
- default=10_000_000, ge=1_000, lt=1_000_000_000 # 10MB = 10 * 1000 * 1000
118
- )
119
- rotate_time: datetime.time = Field(datetime.time(0, 0, 0))
120
- backup_count: int = Field(default=90, ge=1)
121
- encoding: constr(strip_whitespace=True) = Field(
122
- default="utf8", min_length=2, max_length=31
123
- )
124
- log_handlers: LogHandlersPM = Field(default_factory=LogHandlersPM)
125
- json_handlers: JsonHandlersPM = Field(default_factory=JsonHandlersPM)
126
-
127
- if "2.0.0" <= pydantic.__version__:
128
-
129
- @field_validator("rotate_time", mode="before")
130
- @classmethod
131
- def _check_rotate_time(cls, val):
132
- if isinstance(val, str):
133
- val = datetime.time.fromisoformat(val)
134
- return val
135
-
136
- else:
137
-
138
- @validator("rotate_time", pre=True, always=True)
139
- def _check_rotate_time(cls, val):
140
- if val and isinstance(val, str):
141
- val = datetime.time.fromisoformat(val)
142
- return val
143
-
144
-
145
- class AutoLoadPM(ExtraBaseModel):
146
- enabled: bool = Field(default=True)
147
- only_base: bool = Field(default=False)
148
- ignore_modules: List[str] = Field(default=[])
149
-
150
-
151
- class InterceptPM(ExtraBaseModel):
152
- auto_load: AutoLoadPM = Field(default_factory=AutoLoadPM)
153
- include_modules: List[str] = Field(default=[])
154
- mute_modules: List[str] = Field(default=[])
155
-
156
-
157
- class ExtraPM(ExtraBaseModel):
158
- pass
159
-
160
-
161
- class LoggerConfigPM(ExtraBaseModel):
162
- app_name: constr(strip_whitespace=True) = Field(
163
- default_factory=get_app_name,
164
- min_length=1,
165
- max_length=127,
166
- )
167
- level: LogLevelEnum = Field(default=LogLevelEnum.INFO)
168
- use_backtrace: bool = Field(default=True)
169
- use_diagnose: bool = Field(default=False)
170
- stream: StreamPM = Field(default_factory=StreamPM)
171
- file: FilePM = Field(default_factory=FilePM)
172
- intercept: InterceptPM = Field(default_factory=InterceptPM)
173
- extra: ExtraPM = Field(default_factory=ExtraPM)
File without changes
File without changes
File without changes