beans-logging 7.0.0__py3-none-any.whl → 8.0.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.
beans_logging/__init__.py CHANGED
@@ -1,12 +1,16 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from .__version__ import __version__
4
- from .config import LoggerConfigPM
4
+ from .schemas import LoguruHandlerPM, LogHandlerPM
5
+ from .config import get_default_handlers, LoggerConfigPM
5
6
  from ._core import Logger, logger, LoggerLoader
6
7
 
7
8
 
8
9
  __all__ = [
9
10
  "__version__",
11
+ "LoguruHandlerPM",
12
+ "LogHandlerPM",
13
+ "get_default_handlers",
10
14
  "LoggerConfigPM",
11
15
  "Logger",
12
16
  "logger",
@@ -1 +1 @@
1
- __version__ = "7.0.0"
1
+ __version__ = "8.0.0"
beans_logging/_builder.py CHANGED
@@ -1,9 +1,10 @@
1
1
  import os
2
2
  from typing import Any
3
+ from pathlib import Path
3
4
 
4
5
  from pydantic import validate_call
5
6
 
6
- from ._constants import LogHandlerTypeEnum, LogLevelEnum
7
+ from .constants import LogHandlerTypeEnum, LogLevelEnum
7
8
  from .schemas import LogHandlerPM
8
9
  from .config import LoggerConfigPM
9
10
  from .sinks import std_sink
@@ -34,117 +35,94 @@ def build_handler(handler: LogHandlerPM, config: LoggerConfigPM) -> dict[str, An
34
35
  dict[str, Any]: Loguru handler config as dictionary.
35
36
  """
36
37
 
37
- _handler_dict = handler.model_dump(by_alias=True, exclude_none=True)
38
-
39
- if _handler_dict.get("sink") is None:
40
- if _handler_dict.get("type") == LogHandlerTypeEnum.STD:
41
- _handler_dict["sink"] = std_sink
42
- elif _handler_dict.get("type") == LogHandlerTypeEnum.FILE:
43
- _logs_path: str = ""
44
- if _handler_dict.get("serialize") or _handler_dict.get("custom_serialize"):
45
- if _handler_dict.get("error"):
46
- _logs_path = os.path.join(
47
- config.default.file.logs_dir,
48
- config.default.file.json_.err_path,
49
- )
50
- else:
51
- _logs_path = os.path.join(
52
- config.default.file.logs_dir,
53
- config.default.file.json_.log_path,
54
- )
55
- else:
56
- if _handler_dict.get("error"):
57
- _logs_path = os.path.join(
58
- config.default.file.logs_dir,
59
- config.default.file.plain.err_path,
60
- )
61
- else:
62
- _logs_path = os.path.join(
63
- config.default.file.logs_dir,
64
- config.default.file.plain.log_path,
65
- )
66
-
67
- if "{app_name}" in _logs_path:
68
- _logs_path = _logs_path.format(app_name=config.app_name)
69
-
70
- _handler_dict["sink"] = _logs_path
38
+ if handler.sink is None:
39
+ if handler.h_type == LogHandlerTypeEnum.STD:
40
+ handler.sink = std_sink
71
41
  else:
72
42
  raise ValueError(
73
- "'sink' attribute is empty, required for any log handler except std and file handlers!"
43
+ "'sink' attribute is empty, required for any log handler except std handler!"
74
44
  )
75
45
 
76
- if _handler_dict.get("level") is None:
77
- if _handler_dict.get("error"):
78
- _handler_dict["level"] = config.default.level.err
79
- else:
80
- _handler_dict["level"] = config.default.level.base
46
+ _sink = handler.sink
47
+ if isinstance(_sink, (str, Path)):
48
+ if not os.path.isabs(_sink):
49
+ _sink = os.path.join(config.default.file.logs_dir, _sink)
81
50
 
82
- if (_handler_dict.get("custom_serialize") is None) and _handler_dict.get(
83
- "serialize"
84
- ):
85
- _handler_dict["custom_serialize"] = config.default.custom_serialize
51
+ if isinstance(_sink, Path):
52
+ _sink = str(_sink)
53
+
54
+ if "{app_name}" in _sink:
55
+ _sink = _sink.format(app_name=config.app_name)
86
56
 
87
- if _handler_dict.get("custom_serialize"):
88
- _handler_dict["serialize"] = False
89
- _handler_dict["format"] = json_formatter
57
+ handler.sink = _sink
90
58
 
91
- if (_handler_dict.get("format") is None) and (not _handler_dict.get("serialize")):
92
- if _handler_dict.get("type") == LogHandlerTypeEnum.STD:
93
- _handler_dict["format"] = config.default.std.format_str
59
+ if handler.level is None:
60
+ if handler.error:
61
+ handler.level = config.default.level.err
94
62
  else:
95
- _handler_dict["format"] = config.default.format_str
96
-
97
- if _handler_dict.get("filter") is None:
98
- if _handler_dict.get("type") == LogHandlerTypeEnum.STD:
99
- _handler_dict["filter"] = use_std_filter
100
- elif _handler_dict.get("type") == LogHandlerTypeEnum.FILE:
101
- if _handler_dict.get("serialize") or _handler_dict.get("custom_serialize"):
102
- if _handler_dict.get("error"):
103
- _handler_dict["filter"] = use_file_json_err_filter
63
+ handler.level = config.default.level.base
64
+
65
+ if (handler.custom_serialize is None) and handler.serialize:
66
+ handler.custom_serialize = config.default.custom_serialize
67
+
68
+ if handler.custom_serialize:
69
+ handler.serialize = False
70
+ handler.format_ = json_formatter
71
+
72
+ if (handler.format_ is None) and (not handler.serialize):
73
+ handler.format_ = config.default.format_str
74
+
75
+ if handler.filter_ is None:
76
+ if handler.h_type == LogHandlerTypeEnum.STD:
77
+ handler.filter_ = use_std_filter
78
+ elif handler.h_type == LogHandlerTypeEnum.FILE:
79
+ if handler.serialize or handler.custom_serialize:
80
+ if handler.error:
81
+ handler.filter_ = use_file_json_err_filter
104
82
  else:
105
- _handler_dict["filter"] = use_file_json_filter
83
+ handler.filter_ = use_file_json_filter
106
84
  else:
107
- if _handler_dict.get("error"):
108
- _handler_dict["filter"] = use_file_err_filter
85
+ if handler.error:
86
+ handler.filter_ = use_file_err_filter
109
87
  else:
110
- _handler_dict["filter"] = use_file_filter
88
+ handler.filter_ = use_file_filter
111
89
  else:
112
- _handler_dict["filter"] = use_all_filter
90
+ handler.filter_ = use_all_filter
113
91
 
114
- if _handler_dict.get("backtrace") is None:
115
- _handler_dict["backtrace"] = True
92
+ if handler.backtrace is None:
93
+ handler.backtrace = True
116
94
 
117
- if (_handler_dict.get("diagnose") is None) and (
118
- (_handler_dict.get("level") == LogLevelEnum.TRACE)
119
- or (_handler_dict.get("level") == 5)
95
+ if (handler.diagnose is None) and (
96
+ (handler.level == LogLevelEnum.TRACE) or (handler.level == 5)
120
97
  ):
121
- _handler_dict["diagnose"] = True
98
+ handler.diagnose = True
122
99
 
123
- if (_handler_dict.get("colorize") is None) and (
124
- _handler_dict.get("type") == LogHandlerTypeEnum.STD
125
- ):
126
- _handler_dict["colorize"] = config.default.std.colorize
127
-
128
- if _handler_dict.get("type") == LogHandlerTypeEnum.FILE:
129
- if _handler_dict.get("enqueue") is None:
130
- _handler_dict["enqueue"] = True
100
+ if handler.h_type == LogHandlerTypeEnum.FILE:
101
+ if handler.enqueue is None:
102
+ handler.enqueue = True
131
103
 
132
- if _handler_dict.get("rotation") is None:
133
- _handler_dict["rotation"] = Rotator(
104
+ if handler.rotation is None:
105
+ handler.rotation = Rotator(
134
106
  rotate_size=config.default.file.rotate_size,
135
107
  rotate_time=config.default.file.rotate_time,
136
108
  ).should_rotate
137
109
 
138
- if _handler_dict.get("retention") is None:
139
- _handler_dict["retention"] = config.default.file.retention
140
-
141
- if _handler_dict.get("encoding") is None:
142
- _handler_dict["encoding"] = config.default.file.encoding
143
-
144
- _handler_dict.pop("type", None)
145
- _handler_dict.pop("error", None)
146
- _handler_dict.pop("custom_serialize", None)
147
- _handler_dict.pop("enabled", None)
110
+ if handler.retention is None:
111
+ handler.retention = config.default.file.retention
112
+
113
+ if handler.encoding is None:
114
+ handler.encoding = config.default.file.encoding
115
+
116
+ _handler_dict = handler.model_dump(
117
+ by_alias=True,
118
+ exclude_none=True,
119
+ exclude={
120
+ "enabled",
121
+ "h_type",
122
+ "error",
123
+ "custom_serialize",
124
+ },
125
+ )
148
126
 
149
127
  return _handler_dict
150
128
 
beans_logging/_core.py CHANGED
@@ -17,10 +17,11 @@ from pydantic import validate_call
17
17
  from potato_util import io as io_utils
18
18
 
19
19
  # Internal modules
20
+ from .constants import DEFAULT_LOGURU_HANDLER_NAME, DEFAULT_NO_HANDLER_NAME_PREFIX
20
21
  from .schemas import LogHandlerPM, LoguruHandlerPM
21
22
  from .config import LoggerConfigPM
22
23
  from ._builder import build_handler
23
- from ._intercept import init_intercepter
24
+ from .intercepters import add_intercepter
24
25
 
25
26
 
26
27
  class LoggerLoader:
@@ -52,7 +53,7 @@ class LoggerLoader:
52
53
  **kwargs,
53
54
  ) -> None:
54
55
 
55
- self.handlers_map = {"default.loguru_handler": 0}
56
+ self.handlers_map = {DEFAULT_LOGURU_HANDLER_NAME: 0}
56
57
  if not config:
57
58
  config = LoggerConfigPM()
58
59
 
@@ -63,15 +64,15 @@ class LoggerLoader:
63
64
  self.config_path = config_path
64
65
 
65
66
  if auto_load:
66
- self.load()
67
+ self.load(load_config_file=True)
67
68
 
68
69
  @validate_call
69
- def load(self, load_config_file: bool = True) -> "Logger":
70
+ def load(self, load_config_file: bool = False) -> "Logger":
70
71
  """Load logger handlers based on logger config.
71
72
 
72
73
  Args:
73
74
  load_config_file (bool, optional): Whether to load config from file before loading handlers.
74
- Default is True.
75
+ Default is False.
75
76
 
76
77
  Returns:
77
78
  Logger: Main loguru logger instance.
@@ -84,7 +85,7 @@ class LoggerLoader:
84
85
  for _key, _handler in self.config.handlers.items():
85
86
  self.add_handler(name=_key, handler=_handler)
86
87
 
87
- init_intercepter(config=self.config)
88
+ add_intercepter(config=self.config)
88
89
  return logger
89
90
 
90
91
  def _load_config_file(self) -> None:
@@ -195,7 +196,7 @@ class LoggerLoader:
195
196
 
196
197
  _handler_id = logger.add(**_handler_dict)
197
198
  if not name:
198
- name = f"log_handler.{uuid.uuid4().hex}"
199
+ name = f"{DEFAULT_NO_HANDLER_NAME_PREFIX}{uuid.uuid4().hex}"
199
200
 
200
201
  self.handlers_map[name] = _handler_id
201
202
 
beans_logging/config.py CHANGED
@@ -1,20 +1,23 @@
1
- import sys
1
+ import os
2
2
  import datetime
3
3
  from typing import Any
4
4
 
5
- if sys.version_info >= (3, 11):
6
- from typing import Self
7
- else:
8
- from typing_extensions import Self
9
-
10
5
  import potato_util as utils
11
- from pydantic import Field, model_validator, field_validator
6
+ from pydantic import Field, field_validator
12
7
 
13
- from ._constants import LogHandlerTypeEnum, LogLevelEnum
14
- from .schemas import ExtraBaseModel, LogHandlerPM, LoguruHandlerPM
8
+ from .constants import (
9
+ LogLevelEnum,
10
+ LogHandlerTypeEnum,
11
+ DEFAULT_ALL_STD_HANDLER_NAME,
12
+ DEFAULT_ALL_FILE_HANDLER_NAME,
13
+ DEFAULT_ERR_FILE_HANDLER_NAME,
14
+ DEFAULT_ALL_JSON_HANDLER_NAME,
15
+ DEFAULT_ERR_JSON_HANDLER_NAME,
16
+ )
17
+ from .schemas import ExtraBaseModel, LogHandlerPM
15
18
 
16
19
 
17
- def _get_handlers() -> dict[str, LogHandlerPM]:
20
+ def get_default_handlers() -> dict[str, LogHandlerPM]:
18
21
  """Get default log handlers.
19
22
 
20
23
  Returns:
@@ -22,53 +25,46 @@ def _get_handlers() -> dict[str, LogHandlerPM]:
22
25
  """
23
26
 
24
27
  _log_handlers: dict[str, LogHandlerPM] = {
25
- "default.all.std_handler": LogHandlerPM(type_=LogHandlerTypeEnum.STD),
26
- "default.all.file_handler": LogHandlerPM(
27
- type_=LogHandlerTypeEnum.FILE, enabled=False
28
+ DEFAULT_ALL_STD_HANDLER_NAME: LogHandlerPM(
29
+ h_type=LogHandlerTypeEnum.STD,
30
+ format_=(
31
+ "[<c>{time:YYYY-MM-DD HH:mm:ss.SSS Z}</c> | <level>{extra[level_short]:<5}</level> | "
32
+ "<w>{name}:{line}</w>]: <level>{message}</level>"
33
+ ),
34
+ colorize=True,
35
+ ),
36
+ DEFAULT_ALL_FILE_HANDLER_NAME: LogHandlerPM(
37
+ enabled=False,
38
+ h_type=LogHandlerTypeEnum.FILE,
39
+ sink="{app_name}.all.log",
28
40
  ),
29
- "default.err.file_handler": LogHandlerPM(
30
- type_=LogHandlerTypeEnum.FILE, error=True, enabled=False
41
+ DEFAULT_ERR_FILE_HANDLER_NAME: LogHandlerPM(
42
+ enabled=False,
43
+ h_type=LogHandlerTypeEnum.FILE,
44
+ sink="{app_name}.err.log",
45
+ error=True,
31
46
  ),
32
- "default.all.json_handler": LogHandlerPM(
33
- type_=LogHandlerTypeEnum.FILE, serialize=True, enabled=False
47
+ DEFAULT_ALL_JSON_HANDLER_NAME: LogHandlerPM(
48
+ enabled=False,
49
+ h_type=LogHandlerTypeEnum.FILE,
50
+ sink="json/{app_name}.all.json.log",
51
+ serialize=True,
34
52
  ),
35
- "default.err.json_handler": LogHandlerPM(
36
- type_=LogHandlerTypeEnum.FILE, serialize=True, error=True, enabled=False
53
+ DEFAULT_ERR_JSON_HANDLER_NAME: LogHandlerPM(
54
+ enabled=False,
55
+ h_type=LogHandlerTypeEnum.FILE,
56
+ sink="json/{app_name}.err.json.log",
57
+ serialize=True,
58
+ error=True,
37
59
  ),
38
60
  }
39
61
 
40
62
  return _log_handlers
41
63
 
42
64
 
43
- class StdConfigPM(ExtraBaseModel):
44
- format_str: str = Field(
45
- default=(
46
- "[<c>{time:YYYY-MM-DD HH:mm:ss.SSS Z}</c> | <level>{extra[level_short]:<5}</level> | <w>{name}:{line}</w>]:"
47
- " <level>{message}</level>"
48
- ),
49
- min_length=8,
50
- max_length=512,
51
- )
52
- colorize: bool = Field(default=True)
53
-
54
-
55
- class PathsConfigPM(ExtraBaseModel):
56
- log_path: str = Field(..., min_length=4, max_length=1024)
57
- err_path: str = Field(..., min_length=4, max_length=1024)
58
-
59
- @model_validator(mode="after")
60
- def _check_log_path(self) -> Self:
61
- if self.log_path == self.err_path:
62
- raise ValueError(
63
- f"`log_path` and `err_path` attributes have same value: '{self.log_path}', must be different!"
64
- )
65
-
66
- return self
67
-
68
-
69
65
  class FileConfigPM(ExtraBaseModel):
70
66
  logs_dir: str = Field(
71
- default="./logs",
67
+ default_factory=lambda: os.path.join(os.getcwd(), "logs"),
72
68
  min_length=2,
73
69
  max_length=1024,
74
70
  )
@@ -79,21 +75,6 @@ class FileConfigPM(ExtraBaseModel):
79
75
  retention: int = Field(default=90, ge=1)
80
76
  encoding: str = Field(default="utf8", min_length=2, max_length=31)
81
77
 
82
- plain: PathsConfigPM = Field(
83
- default_factory=lambda: PathsConfigPM(
84
- log_path="{app_name}.all.log",
85
- err_path="{app_name}.err.log",
86
- )
87
- )
88
- json_: PathsConfigPM = Field(
89
- default_factory=lambda: PathsConfigPM(
90
- log_path="json/{app_name}.json.all.log",
91
- err_path="json/{app_name}.json.err.log",
92
- ),
93
- validation_alias="json",
94
- serialization_alias="json",
95
- )
96
-
97
78
  @field_validator("rotate_time", mode="before")
98
79
  @classmethod
99
80
  def _check_rotate_time(cls, val: Any) -> Any:
@@ -102,6 +83,14 @@ class FileConfigPM(ExtraBaseModel):
102
83
 
103
84
  return val
104
85
 
86
+ @field_validator("logs_dir", mode="before")
87
+ @classmethod
88
+ def _check_logs_dir(cls, val: Any) -> Any:
89
+ if isinstance(val, str) and (not os.path.isabs(val)):
90
+ val = os.path.abspath(val)
91
+
92
+ return val
93
+
105
94
 
106
95
  class LevelConfigPM(ExtraBaseModel):
107
96
  base: str | int | LogLevelEnum = Field(default=LogLevelEnum.INFO)
@@ -123,7 +112,6 @@ class LevelConfigPM(ExtraBaseModel):
123
112
 
124
113
  class DefaultConfigPM(ExtraBaseModel):
125
114
  level: LevelConfigPM = Field(default_factory=LevelConfigPM)
126
- std: StdConfigPM = Field(default_factory=StdConfigPM)
127
115
  format_str: str = Field(
128
116
  default="[{time:YYYY-MM-DD HH:mm:ss.SSS Z} | {extra[level_short]:<5} | {name}:{line}]: {message}",
129
117
  min_length=8,
@@ -151,36 +139,54 @@ class LoggerConfigPM(ExtraBaseModel):
151
139
  )
152
140
  default: DefaultConfigPM = Field(default_factory=DefaultConfigPM)
153
141
  intercept: InterceptConfigPM = Field(default_factory=InterceptConfigPM)
154
- handlers: dict[str, LogHandlerPM] = Field(default_factory=_get_handlers)
142
+ handlers: dict[str, LogHandlerPM] = Field(default_factory=get_default_handlers)
155
143
  extra: ExtraConfigPM | None = Field(default_factory=ExtraConfigPM)
156
144
 
157
145
  @field_validator("handlers", mode="before")
158
146
  @classmethod
159
- def _check_handlers(cls, val: Any) -> Any:
160
- if val:
161
- if not isinstance(val, dict):
147
+ def _check_handlers(cls, val: Any) -> dict[str, LogHandlerPM]:
148
+
149
+ _default_handlers = get_default_handlers()
150
+
151
+ if not val:
152
+ val = _default_handlers
153
+ return val
154
+
155
+ if not isinstance(val, dict):
156
+ raise TypeError(
157
+ f"'handlers' attribute type {type(val).__name__} is invalid, must be a dict of <LogHandlerPM> or dict!"
158
+ )
159
+
160
+ for _key, _handler in val.items():
161
+ if not isinstance(_handler, (LogHandlerPM, dict)):
162
162
  raise TypeError(
163
- f"'handlers' attribute type {type(val).__name__} is invalid, must be a dict of <LogHandlerPM>, "
164
- f"<LoguruHandlerPM> or dict!"
163
+ f"'handlers' attribute's '{_key}' key -> value type {type(_handler).__name__} is invalid, must be "
164
+ f"<LogHandlerPM> or dict!"
165
165
  )
166
166
 
167
- for _i, _handler in val.items():
168
- if not isinstance(_handler, (LogHandlerPM, LoguruHandlerPM, dict)):
169
- raise TypeError(
170
- f"'handlers' attribute index {_i} type {type(_handler).__name__} is invalid, must be "
171
- f"<LogHandlerPM>, <LoguruHandlerPM> or dict!"
172
- )
167
+ if isinstance(_handler, LogHandlerPM):
168
+ val[_key] = _handler.model_dump(
169
+ by_alias=True, exclude_unset=True, exclude_none=True
170
+ )
171
+
172
+ _default_dict = {
173
+ _key: _handler.model_dump(
174
+ by_alias=True, exclude_unset=True, exclude_none=True
175
+ )
176
+ for _key, _handler in _default_handlers.items()
177
+ }
178
+
179
+ if _default_dict != val:
180
+ val = utils.deep_merge(_default_dict, val)
173
181
 
174
- if isinstance(_handler, LoguruHandlerPM):
175
- val[_i] = LogHandlerPM(
176
- **_handler.model_dump(exclude_none=True, exclude_unset=True)
177
- )
178
- elif isinstance(_handler, dict):
179
- val[_i] = LogHandlerPM(**_handler)
182
+ for _key, _handler in val.items():
183
+ val[_key] = LogHandlerPM(**_handler)
180
184
 
181
185
  return val
182
186
 
183
187
 
184
188
  __all__ = [
185
189
  "LoggerConfigPM",
190
+ "InterceptConfigPM",
191
+ "get_default_handlers",
186
192
  ]
@@ -0,0 +1,46 @@
1
+ from enum import Enum
2
+
3
+
4
+ class LogHandlerTypeEnum(str, Enum):
5
+ STD = "STD"
6
+ FILE = "FILE"
7
+ SOCKET = "SOCKET"
8
+ HTTP = "HTTP"
9
+ SYSLOG = "SYSLOG"
10
+ QUEUE = "QUEUE"
11
+ MEMORY = "MEMORY"
12
+ NULL = "NULL"
13
+ CUSTOM = "CUSTOM"
14
+ UNKNOWN = "UNKNOWN"
15
+
16
+
17
+ class LogLevelEnum(str, Enum):
18
+ TRACE = "TRACE"
19
+ DEBUG = "DEBUG"
20
+ INFO = "INFO"
21
+ SUCCESS = "SUCCESS"
22
+ WARNING = "WARNING"
23
+ ERROR = "ERROR"
24
+ CRITICAL = "CRITICAL"
25
+
26
+
27
+ DEFAULT_LOGURU_HANDLER_NAME = "default.loguru.std_handler"
28
+ DEFAULT_ALL_STD_HANDLER_NAME = "default.all.std_handler"
29
+ DEFAULT_ALL_FILE_HANDLER_NAME = "default.all.file_handler"
30
+ DEFAULT_ERR_FILE_HANDLER_NAME = "default.err.file_handler"
31
+ DEFAULT_ALL_JSON_HANDLER_NAME = "default.all.json_handler"
32
+ DEFAULT_ERR_JSON_HANDLER_NAME = "default.err.json_handler"
33
+ DEFAULT_NO_HANDLER_NAME_PREFIX = "log_handler."
34
+
35
+
36
+ __all__ = [
37
+ "LogHandlerTypeEnum",
38
+ "LogLevelEnum",
39
+ "DEFAULT_LOGURU_HANDLER_NAME",
40
+ "DEFAULT_ALL_STD_HANDLER_NAME",
41
+ "DEFAULT_ALL_FILE_HANDLER_NAME",
42
+ "DEFAULT_ERR_FILE_HANDLER_NAME",
43
+ "DEFAULT_ALL_JSON_HANDLER_NAME",
44
+ "DEFAULT_ERR_JSON_HANDLER_NAME",
45
+ "DEFAULT_NO_HANDLER_NAME_PREFIX",
46
+ ]
@@ -45,7 +45,7 @@ class InterceptHandler(Handler):
45
45
 
46
46
 
47
47
  @validate_call
48
- def init_intercepter(config: LoggerConfigPM) -> None:
48
+ def add_intercepter(config: LoggerConfigPM) -> None:
49
49
  """Initialize log interceptor based on provided config.
50
50
 
51
51
  Args:
@@ -102,5 +102,5 @@ def init_intercepter(config: LoggerConfigPM) -> None:
102
102
 
103
103
  __all__ = [
104
104
  "InterceptHandler",
105
- "init_intercepter",
105
+ "add_intercepter",
106
106
  ]
beans_logging/schemas.py CHANGED
@@ -19,7 +19,7 @@ if TYPE_CHECKING:
19
19
  from loguru import Record, Message
20
20
  from pydantic import BaseModel, Field, ConfigDict, model_validator
21
21
 
22
- from ._constants import LogHandlerTypeEnum, LogLevelEnum
22
+ from .constants import LogHandlerTypeEnum, LogLevelEnum
23
23
 
24
24
 
25
25
  class ExtraBaseModel(BaseModel):
@@ -94,11 +94,7 @@ class LoguruHandlerPM(ExtraBaseModel):
94
94
 
95
95
 
96
96
  class LogHandlerPM(LoguruHandlerPM):
97
- type_: LogHandlerTypeEnum = Field(
98
- default=LogHandlerTypeEnum.UNKNOWN,
99
- validation_alias="type",
100
- serialization_alias="type",
101
- )
97
+ h_type: LogHandlerTypeEnum = Field(default=LogHandlerTypeEnum.UNKNOWN)
102
98
  sink: _SinkType | None = Field(default=None)
103
99
  level: str | int | LogLevelEnum | None = Field(default=None)
104
100
  custom_serialize: bool | None = Field(default=None)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beans_logging
3
- Version: 7.0.0
3
+ Version: 8.0.0
4
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
@@ -25,7 +25,7 @@ Requires-Dist: pydantic[timezone]<3.0.0,>=2.5.3
25
25
  Requires-Dist: loguru<1.0.0,>=0.7.3
26
26
  Requires-Dist: potato_util<1.0.0,>=0.2.0
27
27
  Provides-Extra: fastapi
28
- Requires-Dist: beans-logging-fastapi<2.0.0,>=1.0.0; extra == "fastapi"
28
+ Requires-Dist: beans-logging-fastapi<3.0.0,>=1.0.0; extra == "fastapi"
29
29
  Provides-Extra: test
30
30
  Requires-Dist: pytest<10.0.0,>=8.0.2; extra == "test"
31
31
  Requires-Dist: pytest-cov<8.0.0,>=5.0.0; extra == "test"
@@ -38,6 +38,7 @@ Requires-Dist: build<2.0.0,>=1.1.1; extra == "build"
38
38
  Requires-Dist: twine<7.0.0,>=6.0.1; extra == "build"
39
39
  Provides-Extra: docs
40
40
  Requires-Dist: pylint<5.0.0,>=3.0.4; extra == "docs"
41
+ Requires-Dist: click<8.2.2,>=8.0.0; extra == "docs"
41
42
  Requires-Dist: mkdocs-material<10.0.0,>=9.5.50; extra == "docs"
42
43
  Requires-Dist: mkdocs-awesome-nav<4.0.0,>=3.0.0; extra == "docs"
43
44
  Requires-Dist: mkdocstrings[python]<2.0.0,>=0.24.3; extra == "docs"
@@ -52,6 +53,7 @@ Requires-Dist: wheel<1.0.0,>=0.43.0; extra == "dev"
52
53
  Requires-Dist: build<2.0.0,>=1.1.1; extra == "dev"
53
54
  Requires-Dist: twine<7.0.0,>=6.0.1; extra == "dev"
54
55
  Requires-Dist: pylint<5.0.0,>=3.0.4; extra == "dev"
56
+ Requires-Dist: click<8.2.2,>=8.0.0; extra == "dev"
55
57
  Requires-Dist: mkdocs-material<10.0.0,>=9.5.50; extra == "dev"
56
58
  Requires-Dist: mkdocs-awesome-nav<4.0.0,>=3.0.0; extra == "dev"
57
59
  Requires-Dist: mkdocstrings[python]<2.0.0,>=0.24.3; extra == "dev"
@@ -102,42 +104,7 @@ It is a `Loguru` based custom logging package for python projects.
102
104
  - Install [**git**](https://git-scm.com/downloads)
103
105
  - Setup an [**SSH key**](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)
104
106
 
105
- ### 2. 📥 Download or clone the repository
106
-
107
- [TIP] Skip this step, if you're going to install the package directly from **PyPi** or **GitHub** repository.
108
-
109
- **2.1.** Prepare projects directory (if not exists):
110
-
111
- ```sh
112
- # Create projects directory:
113
- mkdir -pv ~/workspaces/projects
114
-
115
- # Enter into projects directory:
116
- cd ~/workspaces/projects
117
- ```
118
-
119
- **2.2.** Follow one of the below options **[A]**, **[B]** or **[C]**:
120
-
121
- **OPTION A.** Clone the repository:
122
-
123
- ```sh
124
- git clone https://github.com/bybatkhuu/module-python-logging.git && \
125
- cd module-python-logging
126
- ```
127
-
128
- **OPTION B.** Clone the repository (for **DEVELOPMENT**: git + ssh key):
129
-
130
- ```sh
131
- git clone git@github.com:bybatkhuu/module-python-logging.git && \
132
- cd module-python-logging
133
- ```
134
-
135
- **OPTION C.** Download source code:
136
-
137
- 1. Download archived **zip** file from [**releases**](https://github.com/bybatkhuu/module-python-logging/releases).
138
- 2. Extract it into the projects directory.
139
-
140
- ### 3. 📦 Install the package
107
+ ### 2. 📦 Install the package
141
108
 
142
109
  [NOTE] Choose one of the following methods to install the package **[A ~ F]**:
143
110
 
@@ -156,6 +123,9 @@ pip install git+https://github.com/bybatkhuu/module-python-logging.git
156
123
  **OPTION C.** Install from the downloaded **source code**:
157
124
 
158
125
  ```sh
126
+ git clone https://github.com/bybatkhuu/module-python-logging.git && \
127
+ cd ./module-python-logging
128
+
159
129
  # Install directly from the source code:
160
130
  pip install .
161
131
 
@@ -323,9 +293,6 @@ logger:
323
293
  level:
324
294
  base: INFO
325
295
  err: WARNING
326
- std:
327
- format_str: "[<c>{time:YYYY-MM-DD HH:mm:ss.SSS Z}</c> | <level>{extra[level_short]:<5}</level> | <w>{name}:{line}</w>]: <level>{message}</level>"
328
- colorize: true
329
296
  format_str: "[{time:YYYY-MM-DD HH:mm:ss.SSS Z} | {extra[level_short]:<5} | {name}:{line}]: {message}"
330
297
  file:
331
298
  logs_dir: "./logs"
@@ -333,12 +300,6 @@ logger:
333
300
  rotate_time: "00:00:00"
334
301
  retention: 90
335
302
  encoding: utf8
336
- plain:
337
- log_path: "{app_name}.all.log"
338
- err_path: "{app_name}.err.log"
339
- json:
340
- log_path: "json/{app_name}.json.all.log"
341
- err_path: "json/{app_name}.json.err.log"
342
303
  custom_serialize: false
343
304
  intercept:
344
305
  enabled: true
@@ -348,24 +309,30 @@ logger:
348
309
  mute_modules: []
349
310
  handlers:
350
311
  default.all.std_handler:
351
- type: STD
352
312
  enabled: true
313
+ h_type: STD
314
+ format: "[<c>{time:YYYY-MM-DD HH:mm:ss.SSS Z}</c> | <level>{extra[level_short]:<5}</level> | <w>{name}:{line}</w>]: <level>{message}</level>"
315
+ colorize: true
353
316
  default.all.file_handler:
354
- type: FILE
355
317
  enabled: false
318
+ h_type: FILE
319
+ sink: "{app_name}.all.log"
356
320
  default.err.file_handler:
357
- type: FILE
358
- error: true
359
321
  enabled: false
322
+ h_type: FILE
323
+ sink: "{app_name}.err.log"
324
+ error: true
360
325
  default.all.json_handler:
361
- type: FILE
362
- serialize: true
363
326
  enabled: false
327
+ h_type: FILE
328
+ sink: "json/{app_name}.all.json.log"
329
+ serialize: true
364
330
  default.err.json_handler:
365
- type: FILE
331
+ enabled: false
332
+ h_type: FILE
333
+ sink: "json/{app_name}.err.json.log"
366
334
  serialize: true
367
335
  error: true
368
- enabled: false
369
336
  extra:
370
337
  ```
371
338
 
@@ -418,7 +385,7 @@ To build the documentation, run the following command:
418
385
  pip install -r ./requirements/requirements.docs.txt
419
386
 
420
387
  # Serve documentation locally (for development):
421
- mkdocs serve -a 0.0.0.0:8000
388
+ mkdocs serve -a 0.0.0.0:8000 --livereload
422
389
  # Or use the docs script:
423
390
  ./scripts/docs.sh
424
391
 
@@ -0,0 +1,18 @@
1
+ beans_logging/__init__.py,sha256=evD0GgFDj9LjQPuJLP_9uEYBPAlU04-nD5Rq1n76Utg,405
2
+ beans_logging/__version__.py,sha256=SWqJTEDnx2fOon29wQowBCNjEkhyhMbbqVsSu4EpdWI,22
3
+ beans_logging/_builder.py,sha256=Pg9fXFPMCe4o-hl1xJPajSTmdglJ0Emofxdzuod_9xM,3935
4
+ beans_logging/_core.py,sha256=lG-wRvQ6vz4rS2Je74MAg80xmdHx2Iue9LHOh2S7zYc,9746
5
+ beans_logging/auto.py,sha256=MoNuQomiIFWQVpNTkOmFFVMo00HBlErfHC728GFOyqc,218
6
+ beans_logging/config.py,sha256=NpZo0wiwsYe25OyPMoHRtkbVG6UxuEHEfO3w7O1kbWM,6102
7
+ beans_logging/constants.py,sha256=Ztt08flQ-378TMYiasAI5pUvLxKJ3p0WEb0w71wXKsE,1169
8
+ beans_logging/filters.py,sha256=-Rys2rwuT7EUvuEA19jnhW6enIEkDuPzeGbAAz6RJSc,3720
9
+ beans_logging/formats.py,sha256=Vrr4RkCfiJl-oi6BLVxeR-k0WhTR0oBI4mpsWgBJBNE,1624
10
+ beans_logging/intercepters.py,sha256=9tgyNXE7d_OlHUl9IJ2yEeDmUWZBYGYCWXMT3r58_RM,3247
11
+ beans_logging/rotators.py,sha256=lzR31sdEPTZVDkyhC81FL4OnezIVKlElGJDRA2Svn2I,2121
12
+ beans_logging/schemas.py,sha256=7C8PKwWVnayX4NmPA-mKajB4Lrksgr0QUJGjbEU5mro,4360
13
+ beans_logging/sinks.py,sha256=7Guusg3N1S-28hLnRzuunP8lXnhexzny3aj-AR0HhuQ,482
14
+ beans_logging-8.0.0.dist-info/licenses/LICENSE.txt,sha256=CUTK-r0BWIg1r0bBiemAcMhakgV0N7HuRhw6rQ-A9A4,1074
15
+ beans_logging-8.0.0.dist-info/METADATA,sha256=P06jptdg47p2ea3XmKb-esErDJ17MZY-Xn0oVpNHYmI,12384
16
+ beans_logging-8.0.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
17
+ beans_logging-8.0.0.dist-info/top_level.txt,sha256=lx8JEqYGNha1sYbVrTtMo2Z01A7Shq8hX6bfsuKLTG8,14
18
+ beans_logging-8.0.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,30 +0,0 @@
1
- from enum import Enum
2
-
3
-
4
- class LogHandlerTypeEnum(str, Enum):
5
- STD = "STD"
6
- FILE = "FILE"
7
- SOCKET = "SOCKET"
8
- HTTP = "HTTP"
9
- SYSLOG = "SYSLOG"
10
- QUEUE = "QUEUE"
11
- MEMORY = "MEMORY"
12
- NULL = "NULL"
13
- CUSTOM = "CUSTOM"
14
- UNKNOWN = "UNKNOWN"
15
-
16
-
17
- class LogLevelEnum(str, Enum):
18
- TRACE = "TRACE"
19
- DEBUG = "DEBUG"
20
- INFO = "INFO"
21
- SUCCESS = "SUCCESS"
22
- WARNING = "WARNING"
23
- ERROR = "ERROR"
24
- CRITICAL = "CRITICAL"
25
-
26
-
27
- __all__ = [
28
- "LogHandlerTypeEnum",
29
- "LogLevelEnum",
30
- ]
@@ -1,18 +0,0 @@
1
- beans_logging/__init__.py,sha256=KOXpuCNTMsdlY9MF6ONwRjM5O1_JCkIzt_qetb2BFTw,261
2
- beans_logging/__version__.py,sha256=VgMOOqsYbyb60I1RmlZpqwqQ0C0IyT3R0c8_xX4pRGM,22
3
- beans_logging/_builder.py,sha256=KUHZLMj6AqyDQGpVVB4XGEP3xI_kkjNMG-pbV_PvtLE,5644
4
- beans_logging/_constants.py,sha256=rH9ZN-b7GXNXjbpOZUJfsft54Eiy8jnXm82jsFcMo3k,510
5
- beans_logging/_core.py,sha256=qkGl5NRKY7lKuVatwFmddwxeYS5viU5DDnfKucWK3Mo,9617
6
- beans_logging/_intercept.py,sha256=TeYze0eXRMVkOoC9Bl2qmaC7fSwExfQAmmGHz5KiuCU,3249
7
- beans_logging/auto.py,sha256=MoNuQomiIFWQVpNTkOmFFVMo00HBlErfHC728GFOyqc,218
8
- beans_logging/config.py,sha256=yDA-IbjhMIgP1DrFKa0ZDibNWAH_Ov8R7Hnqfggl71E,6172
9
- beans_logging/filters.py,sha256=-Rys2rwuT7EUvuEA19jnhW6enIEkDuPzeGbAAz6RJSc,3720
10
- beans_logging/formats.py,sha256=Vrr4RkCfiJl-oi6BLVxeR-k0WhTR0oBI4mpsWgBJBNE,1624
11
- beans_logging/rotators.py,sha256=lzR31sdEPTZVDkyhC81FL4OnezIVKlElGJDRA2Svn2I,2121
12
- beans_logging/schemas.py,sha256=b4igq8CkAzn7CGOBDc09hW0YTvWyuWRe97fpv_OaNdk,4444
13
- beans_logging/sinks.py,sha256=7Guusg3N1S-28hLnRzuunP8lXnhexzny3aj-AR0HhuQ,482
14
- beans_logging-7.0.0.dist-info/licenses/LICENSE.txt,sha256=CUTK-r0BWIg1r0bBiemAcMhakgV0N7HuRhw6rQ-A9A4,1074
15
- beans_logging-7.0.0.dist-info/METADATA,sha256=v6LwlP4Gc4ZnyvYnVHka9okW38UV9e2f2A_23-5Q9qs,13155
16
- beans_logging-7.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
- beans_logging-7.0.0.dist-info/top_level.txt,sha256=lx8JEqYGNha1sYbVrTtMo2Z01A7Shq8hX6bfsuKLTG8,14
18
- beans_logging-7.0.0.dist-info/RECORD,,