beans-logging 4.1.1__tar.gz → 6.0.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 (33) hide show
  1. {beans_logging-4.1.1 → beans_logging-6.0.0}/PKG-INFO +22 -164
  2. {beans_logging-4.1.1 → beans_logging-6.0.0}/README.md +17 -161
  3. beans_logging-6.0.0/beans_logging/__init__.py +16 -0
  4. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging/__version__.py +1 -1
  5. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging/_base.py +35 -10
  6. beans_logging-6.0.0/beans_logging/_consts.py +20 -0
  7. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging/_utils.py +36 -5
  8. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging/auto.py +11 -0
  9. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging/schemas.py +70 -53
  10. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging.egg-info/PKG-INFO +22 -164
  11. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging.egg-info/SOURCES.txt +1 -6
  12. beans_logging-6.0.0/beans_logging.egg-info/requires.txt +6 -0
  13. {beans_logging-4.1.1 → beans_logging-6.0.0}/setup.py +2 -1
  14. beans_logging-4.1.1/beans_logging/__init__.py +0 -6
  15. beans_logging-4.1.1/beans_logging/_const.py +0 -10
  16. beans_logging-4.1.1/beans_logging/fastapi/__init__.py +0 -6
  17. beans_logging-4.1.1/beans_logging/fastapi/_filters.py +0 -22
  18. beans_logging-4.1.1/beans_logging/fastapi/_formats.py +0 -49
  19. beans_logging-4.1.1/beans_logging/fastapi/_handlers.py +0 -74
  20. beans_logging-4.1.1/beans_logging/fastapi/_middlewares.py +0 -239
  21. beans_logging-4.1.1/beans_logging.egg-info/requires.txt +0 -3
  22. {beans_logging-4.1.1 → beans_logging-6.0.0}/LICENSE.txt +0 -0
  23. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging/_handlers.py +0 -0
  24. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging/filters.py +0 -0
  25. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging/formats.py +0 -0
  26. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging/rotation.py +0 -0
  27. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging/sinks.py +0 -0
  28. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging.egg-info/dependency_links.txt +0 -0
  29. {beans_logging-4.1.1 → beans_logging-6.0.0}/beans_logging.egg-info/top_level.txt +0 -0
  30. {beans_logging-4.1.1 → beans_logging-6.0.0}/setup.cfg +0 -0
  31. {beans_logging-4.1.1 → beans_logging-6.0.0}/tests/__init__.py +0 -0
  32. {beans_logging-4.1.1 → beans_logging-6.0.0}/tests/conftest.py +0 -0
  33. {beans_logging-4.1.1 → beans_logging-6.0.0}/tests/test_beans_logging.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: beans_logging
3
- Version: 4.1.1
3
+ Version: 6.0.0
4
4
  Summary: 'beans_logging' is a python package for simple logger and easily managing logging modules. It is a Loguru based custom logging package for python projects.
5
5
  Home-page: https://github.com/bybatkhuu/module.python-logging
6
- Download-URL: https://github.com/bybatkhuu/module.python-logging/archive/v4.1.1.tar.gz
6
+ Download-URL: https://github.com/bybatkhuu/module.python-logging/archive/v6.0.0.tar.gz
7
7
  Author: Batkhuu Byambajav
8
8
  Author-email: batkhuu10@gmail.com
9
9
  License: MIT
@@ -20,8 +20,10 @@ Requires-Python: >=3.8
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE.txt
22
22
  Requires-Dist: PyYAML<7.0,>=6.0
23
- Requires-Dist: pydantic<3.0.0,>=2.1.1
23
+ Requires-Dist: pydantic!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.10.0
24
24
  Requires-Dist: loguru<1.0.0,>=0.7.2
25
+ Provides-Extra: fastapi
26
+ Requires-Dist: beans-logging-fastapi<2.0.0,>=1.0.0; extra == "fastapi"
25
27
 
26
28
  # beans_logging
27
29
 
@@ -47,8 +49,8 @@ It is a `Loguru` based custom logging package for python projects.
47
49
  - Custom logging **formats**
48
50
  - **Multiprocess** compatibility (Linux, macOS - 'fork')
49
51
  - Add custom **handlers**
50
- - **FastAPI** HTTP access logging **middleware**
51
52
  - **Base** logging module
53
+ - Support **Pydantic-v1** and **Pydantic-v2**
52
54
 
53
55
  ---
54
56
 
@@ -206,16 +208,16 @@ python ./main.py
206
208
  **Output**:
207
209
 
208
210
  ```txt
209
- [2023-09-01 09:00:00.384 +09:00 | TRACE | beans_logging._base:478]: Intercepted modules: ['concurrent', 'concurrent.futures', 'asyncio']; Muted modules: [];
210
- [2023-09-01 09:00:00.384 +09:00 | TRACE | __main__:7]: Tracing...
211
- [2023-09-01 09:00:00.385 +09:00 | DEBUG | __main__:8]: Debugging...
212
- [2023-09-01 09:00:00.385 +09:00 | INFO | __main__:9]: Logging info.
213
- [2023-09-01 09:00:00.385 +09:00 | OK | __main__:10]: Success.
214
- [2023-09-01 09:00:00.385 +09:00 | WARN | __main__:11]: Warning something.
215
- [2023-09-01 09:00:00.385 +09:00 | ERROR | __main__:12]: Error occured.
216
- [2023-09-01 09:00:00.386 +09:00 | CRIT | __main__:13]: CRITICAL ERROR.
217
- [2023-09-01 09:00:00.386 +09:00 | ERROR | __main__:25]: division by zero
218
- [2023-09-01 09:00:00.386 +09:00 | ERROR | __main__:32]: Show me, what value is wrong:
211
+ [2023-09-01 00:00:00.000 +09:00 | TRACE | beans_logging._base:478]: Intercepted modules: ['concurrent', 'concurrent.futures', 'asyncio']; Muted modules: [];
212
+ [2023-09-01 00:00:00.000 +09:00 | TRACE | __main__:7]: Tracing...
213
+ [2023-09-01 00:00:00.000 +09:00 | DEBUG | __main__:8]: Debugging...
214
+ [2023-09-01 00:00:00.000 +09:00 | INFO | __main__:9]: Logging info.
215
+ [2023-09-01 00:00:00.000 +09:00 | OK | __main__:10]: Success.
216
+ [2023-09-01 00:00:00.000 +09:00 | WARN | __main__:11]: Warning something.
217
+ [2023-09-01 00:00:00.000 +09:00 | ERROR | __main__:12]: Error occured.
218
+ [2023-09-01 00:00:00.000 +09:00 | CRIT | __main__:13]: CRITICAL ERROR.
219
+ [2023-09-01 00:00:00.000 +09:00 | ERROR | __main__:25]: division by zero
220
+ [2023-09-01 00:00:00.000 +09:00 | ERROR | __main__:32]: Show me, what value is wrong:
219
221
  Traceback (most recent call last):
220
222
 
221
223
  > File "/home/user/workspaces/projects/beans_logging/examples/simple/./main.py", line 30, in <module>
@@ -235,157 +237,12 @@ Traceback (most recent call last):
235
237
  ZeroDivisionError: division by zero
236
238
  ```
237
239
 
238
- ### **Advanced (FastAPI)**
240
+ ### **FastAPI**
239
241
 
240
- [**`configs/logger.yml`**](https://github.com/bybatkhuu/module.python-logging/blob/main/examples/advanced/configs/logger.yml):
242
+ Checkout `beans_logging_fastapi` package: <https://github.com/bybatkhuu/module.fastapi-logging>
241
243
 
242
- ```yaml
243
- logger:
244
- app_name: "fastapi-app"
245
- level: "TRACE"
246
- use_diagnose: false
247
- stream:
248
- use_color: true
249
- use_icon: false
250
- format_str: "[<c>{time:YYYY-MM-DD HH:mm:ss.SSS Z}</c> | <level>{level_short:<5}</level> | <w>{name}:{line}</w>]: <level>{message}</level>"
251
- std_handler:
252
- enabled: true
253
- file:
254
- logs_dir: "./logs"
255
- rotate_size: 10000000 # 10MB
256
- rotate_time: "00:00:00"
257
- backup_count: 90
258
- log_handlers:
259
- enabled: true
260
- format_str: "[{time:YYYY-MM-DD HH:mm:ss.SSS Z} | {level_short:<5} | {name}:{line}]: {message}"
261
- log_path: "{app_name}.std.all.log"
262
- err_path: "{app_name}.std.err.log"
263
- json_handlers:
264
- enabled: true
265
- use_custom: false
266
- log_path: "json/{app_name}.json.all.log"
267
- err_path: "json/{app_name}.json.err.log"
268
- intercept:
269
- auto_load:
270
- enabled: true
271
- only_base: false
272
- ignore_modules: []
273
- include_modules: []
274
- mute_modules: ["uvicorn.access", "uvicorn.error"]
275
- extra:
276
- http_std_debug_format: '<n>[{request_id}]</n> {client_host} {user_id} "<u>{method} {url_path}</u> HTTP/{http_version}"'
277
- http_std_msg_format: '<n><w>[{request_id}]</w></n> {client_host} {user_id} "<u>{method} {url_path}</u> HTTP/{http_version}" {status_code} {content_length}B {response_time}ms'
278
- http_file_enabled: true
279
- http_log_path: "http/{app_name}.http.access.log"
280
- http_err_path: "http/{app_name}.http.err.log"
281
- http_json_enabled: true
282
- http_json_path: "json.http/{app_name}.json.http.access.log"
283
- http_json_err_path: "json.http/{app_name}.json.http.err.log"
284
- ```
285
-
286
- [**`.env`**](https://github.com/bybatkhuu/module.python-logging/blob/main/examples/advanced/.env):
287
-
288
- ```sh
289
- ENV=development
290
- DEBUG=true
291
- ```
292
-
293
- [**`logger.py`**](https://github.com/bybatkhuu/module.python-logging/blob/main/examples/advanced/logger.py):
294
-
295
- ```python
296
- from beans_logging import Logger, LoggerLoader
297
- from beans_logging.fastapi import add_http_file_handler, add_http_file_json_handler
298
-
299
-
300
- logger_loader = LoggerLoader()
301
- logger: Logger = logger_loader.load()
302
-
303
- if logger_loader.config.extra.http_file_enabled:
304
- add_http_file_handler(
305
- logger_loader=logger_loader,
306
- log_path=logger_loader.config.extra.http_log_path,
307
- err_path=logger_loader.config.extra.http_err_path,
308
- )
309
-
310
- if logger_loader.config.extra.http_json_enabled:
311
- add_http_file_json_handler(
312
- logger_loader=logger_loader,
313
- log_path=logger_loader.config.extra.http_json_path,
314
- err_path=logger_loader.config.extra.http_json_err_path,
315
- )
316
- ```
317
-
318
- [**`app.py`**](https://github.com/bybatkhuu/module.python-logging/blob/main/examples/advanced/app.py):
319
-
320
- ```python
321
- from typing import Union
322
- from contextlib import asynccontextmanager
323
-
324
- from dotenv import load_dotenv
325
- from fastapi import FastAPI, HTTPException
326
- from fastapi.responses import RedirectResponse
327
-
328
- load_dotenv()
329
-
330
- from beans_logging.fastapi import HttpAccessLogMiddleware
331
-
332
- from logger import logger, logger_loader
333
- from __version__ import __version__
334
-
335
-
336
- @asynccontextmanager
337
- async def lifespan(app: FastAPI):
338
- logger.info("Preparing to startup...")
339
- logger.success("Finished preparation to startup.")
340
- logger.info(f"API version: {__version__}")
341
-
342
- yield
343
- logger.info("Praparing to shutdown...")
344
- logger.success("Finished preparation to shutdown.")
345
-
346
- app = FastAPI(lifespan=lifespan, version=__version__)
347
- app.add_middleware(
348
- HttpAccessLogMiddleware,
349
- has_proxy_headers=True,
350
- debug_format=logger_loader.config.extra.http_std_debug_format,
351
- msg_format=logger_loader.config.extra.http_std_msg_format,
352
- )
353
-
354
- @app.get("/")
355
- def root():
356
- return {"Hello": "World"}
357
- ```
358
-
359
- Run the [**`examples/advanced`**](https://github.com/bybatkhuu/module.python-logging/tree/main/examples/advanced):
360
-
361
- ```sh
362
- cd ./examples/advanced
363
- # Install python dependencies for examples:
364
- pip install -r ./requirements.txt
365
-
366
- uvicorn app:app --host=0.0.0.0 --port=8000
367
- ```
368
-
369
- **Output**:
370
-
371
- ```txt
372
- [2023-09-01 12:37:38.569 +09:00 | TRACE | beans_logging._base:499]: Intercepted modules: ['watchfiles.watcher', 'asyncio', 'watchfiles', 'concurrent', 'dotenv', 'concurrent.futures', 'fastapi', 'dotenv.main', 'uvicorn', 'watchfiles.main']; Muted modules: ['uvicorn.error', 'uvicorn.access'];
373
- [2023-09-01 12:37:38.579 +09:00 | INFO | uvicorn.server:76]: Started server process [22599]
374
- [2023-09-01 12:37:38.579 +09:00 | INFO | uvicorn.lifespan.on:46]: Waiting for application startup.
375
- [2023-09-01 12:37:38.579 +09:00 | INFO | app:21]: Preparing to startup...
376
- [2023-09-01 12:37:38.580 +09:00 | OK | app:22]: Finished preparation to startup.
377
- [2023-09-01 12:37:38.580 +09:00 | INFO | app:23]: API version: 0.0.1-000000
378
- [2023-09-01 12:37:38.580 +09:00 | INFO | uvicorn.lifespan.on:60]: Application startup complete.
379
- [2023-09-01 12:37:38.582 +09:00 | INFO | uvicorn.server:218]: Uvicorn running on http://0.0.0.0:9000 (Press CTRL+C to quit)
380
- [2023-09-01 12:37:48.487 +09:00 | DEBUG | anyio._backends._asyncio:807]: [0b9f972939054a58ba10e7a39a12bd21] 127.0.0.1 - "GET / HTTP/1.1"
381
- [2023-09-01 12:37:48.488 +09:00 | OK | anyio._backends._asyncio:807]: [0b9f972939054a58ba10e7a39a12bd21] 127.0.0.1 - "GET / HTTP/1.1" 200 17B 0.5ms
382
- ^C[2023-09-01 12:37:51.845 +09:00 | INFO | uvicorn.server:264]: Shutting down
383
- [2023-09-01 12:37:51.949 +09:00 | INFO | uvicorn.lifespan.on:65]: Waiting for application shutdown.
384
- [2023-09-01 12:37:51.951 +09:00 | INFO | app:26]: Praparing to shutdown...
385
- [2023-09-01 12:37:51.952 +09:00 | OK | app:27]: Finished preparation to shutdown.
386
- [2023-09-01 12:37:51.952 +09:00 | INFO | uvicorn.lifespan.on:76]: Application shutdown complete.
387
- [2023-09-01 12:37:51.953 +09:00 | INFO | uvicorn.server:86]: Finished server process [22599]
388
- ```
244
+ - FastAPI HTTP access logging middleware
245
+ - Install with pip: `pip install -U beans-logging[fastapi]` or `pip install -U beans-logging-fastapi`
389
246
 
390
247
  ---
391
248
 
@@ -411,7 +268,7 @@ DEBUG=true
411
268
 
412
269
  BEANS_LOGGING_DISABLE_DEFAULT=false
413
270
  BEANS_LOGGING_CONFIG_PATH="./configs/logger.yml"
414
- BEANS_LOGGING_DIR="./logs"
271
+ BEANS_LOGGING_LOGS_DIR="./logs"
415
272
  ```
416
273
 
417
274
  ## Configuration
@@ -466,3 +323,4 @@ logger:
466
323
  - <https://github.com/Delgan/loguru>
467
324
  - <https://loguru.readthedocs.io/en/stable/api/logger.html>
468
325
  - <https://loguru.readthedocs.io/en/stable/resources/recipes.html>
326
+ - <https://github.com/bybatkhuu/module.fastapi-logging>
@@ -22,8 +22,8 @@ It is a `Loguru` based custom logging package for python projects.
22
22
  - Custom logging **formats**
23
23
  - **Multiprocess** compatibility (Linux, macOS - 'fork')
24
24
  - Add custom **handlers**
25
- - **FastAPI** HTTP access logging **middleware**
26
25
  - **Base** logging module
26
+ - Support **Pydantic-v1** and **Pydantic-v2**
27
27
 
28
28
  ---
29
29
 
@@ -181,16 +181,16 @@ python ./main.py
181
181
  **Output**:
182
182
 
183
183
  ```txt
184
- [2023-09-01 09:00:00.384 +09:00 | TRACE | beans_logging._base:478]: Intercepted modules: ['concurrent', 'concurrent.futures', 'asyncio']; Muted modules: [];
185
- [2023-09-01 09:00:00.384 +09:00 | TRACE | __main__:7]: Tracing...
186
- [2023-09-01 09:00:00.385 +09:00 | DEBUG | __main__:8]: Debugging...
187
- [2023-09-01 09:00:00.385 +09:00 | INFO | __main__:9]: Logging info.
188
- [2023-09-01 09:00:00.385 +09:00 | OK | __main__:10]: Success.
189
- [2023-09-01 09:00:00.385 +09:00 | WARN | __main__:11]: Warning something.
190
- [2023-09-01 09:00:00.385 +09:00 | ERROR | __main__:12]: Error occured.
191
- [2023-09-01 09:00:00.386 +09:00 | CRIT | __main__:13]: CRITICAL ERROR.
192
- [2023-09-01 09:00:00.386 +09:00 | ERROR | __main__:25]: division by zero
193
- [2023-09-01 09:00:00.386 +09:00 | ERROR | __main__:32]: Show me, what value is wrong:
184
+ [2023-09-01 00:00:00.000 +09:00 | TRACE | beans_logging._base:478]: Intercepted modules: ['concurrent', 'concurrent.futures', 'asyncio']; Muted modules: [];
185
+ [2023-09-01 00:00:00.000 +09:00 | TRACE | __main__:7]: Tracing...
186
+ [2023-09-01 00:00:00.000 +09:00 | DEBUG | __main__:8]: Debugging...
187
+ [2023-09-01 00:00:00.000 +09:00 | INFO | __main__:9]: Logging info.
188
+ [2023-09-01 00:00:00.000 +09:00 | OK | __main__:10]: Success.
189
+ [2023-09-01 00:00:00.000 +09:00 | WARN | __main__:11]: Warning something.
190
+ [2023-09-01 00:00:00.000 +09:00 | ERROR | __main__:12]: Error occured.
191
+ [2023-09-01 00:00:00.000 +09:00 | CRIT | __main__:13]: CRITICAL ERROR.
192
+ [2023-09-01 00:00:00.000 +09:00 | ERROR | __main__:25]: division by zero
193
+ [2023-09-01 00:00:00.000 +09:00 | ERROR | __main__:32]: Show me, what value is wrong:
194
194
  Traceback (most recent call last):
195
195
 
196
196
  > File "/home/user/workspaces/projects/beans_logging/examples/simple/./main.py", line 30, in <module>
@@ -210,157 +210,12 @@ Traceback (most recent call last):
210
210
  ZeroDivisionError: division by zero
211
211
  ```
212
212
 
213
- ### **Advanced (FastAPI)**
213
+ ### **FastAPI**
214
214
 
215
- [**`configs/logger.yml`**](https://github.com/bybatkhuu/module.python-logging/blob/main/examples/advanced/configs/logger.yml):
215
+ Checkout `beans_logging_fastapi` package: <https://github.com/bybatkhuu/module.fastapi-logging>
216
216
 
217
- ```yaml
218
- logger:
219
- app_name: "fastapi-app"
220
- level: "TRACE"
221
- use_diagnose: false
222
- stream:
223
- use_color: true
224
- use_icon: false
225
- format_str: "[<c>{time:YYYY-MM-DD HH:mm:ss.SSS Z}</c> | <level>{level_short:<5}</level> | <w>{name}:{line}</w>]: <level>{message}</level>"
226
- std_handler:
227
- enabled: true
228
- file:
229
- logs_dir: "./logs"
230
- rotate_size: 10000000 # 10MB
231
- rotate_time: "00:00:00"
232
- backup_count: 90
233
- log_handlers:
234
- enabled: true
235
- format_str: "[{time:YYYY-MM-DD HH:mm:ss.SSS Z} | {level_short:<5} | {name}:{line}]: {message}"
236
- log_path: "{app_name}.std.all.log"
237
- err_path: "{app_name}.std.err.log"
238
- json_handlers:
239
- enabled: true
240
- use_custom: false
241
- log_path: "json/{app_name}.json.all.log"
242
- err_path: "json/{app_name}.json.err.log"
243
- intercept:
244
- auto_load:
245
- enabled: true
246
- only_base: false
247
- ignore_modules: []
248
- include_modules: []
249
- mute_modules: ["uvicorn.access", "uvicorn.error"]
250
- extra:
251
- http_std_debug_format: '<n>[{request_id}]</n> {client_host} {user_id} "<u>{method} {url_path}</u> HTTP/{http_version}"'
252
- http_std_msg_format: '<n><w>[{request_id}]</w></n> {client_host} {user_id} "<u>{method} {url_path}</u> HTTP/{http_version}" {status_code} {content_length}B {response_time}ms'
253
- http_file_enabled: true
254
- http_log_path: "http/{app_name}.http.access.log"
255
- http_err_path: "http/{app_name}.http.err.log"
256
- http_json_enabled: true
257
- http_json_path: "json.http/{app_name}.json.http.access.log"
258
- http_json_err_path: "json.http/{app_name}.json.http.err.log"
259
- ```
260
-
261
- [**`.env`**](https://github.com/bybatkhuu/module.python-logging/blob/main/examples/advanced/.env):
262
-
263
- ```sh
264
- ENV=development
265
- DEBUG=true
266
- ```
267
-
268
- [**`logger.py`**](https://github.com/bybatkhuu/module.python-logging/blob/main/examples/advanced/logger.py):
269
-
270
- ```python
271
- from beans_logging import Logger, LoggerLoader
272
- from beans_logging.fastapi import add_http_file_handler, add_http_file_json_handler
273
-
274
-
275
- logger_loader = LoggerLoader()
276
- logger: Logger = logger_loader.load()
277
-
278
- if logger_loader.config.extra.http_file_enabled:
279
- add_http_file_handler(
280
- logger_loader=logger_loader,
281
- log_path=logger_loader.config.extra.http_log_path,
282
- err_path=logger_loader.config.extra.http_err_path,
283
- )
284
-
285
- if logger_loader.config.extra.http_json_enabled:
286
- add_http_file_json_handler(
287
- logger_loader=logger_loader,
288
- log_path=logger_loader.config.extra.http_json_path,
289
- err_path=logger_loader.config.extra.http_json_err_path,
290
- )
291
- ```
292
-
293
- [**`app.py`**](https://github.com/bybatkhuu/module.python-logging/blob/main/examples/advanced/app.py):
294
-
295
- ```python
296
- from typing import Union
297
- from contextlib import asynccontextmanager
298
-
299
- from dotenv import load_dotenv
300
- from fastapi import FastAPI, HTTPException
301
- from fastapi.responses import RedirectResponse
302
-
303
- load_dotenv()
304
-
305
- from beans_logging.fastapi import HttpAccessLogMiddleware
306
-
307
- from logger import logger, logger_loader
308
- from __version__ import __version__
309
-
310
-
311
- @asynccontextmanager
312
- async def lifespan(app: FastAPI):
313
- logger.info("Preparing to startup...")
314
- logger.success("Finished preparation to startup.")
315
- logger.info(f"API version: {__version__}")
316
-
317
- yield
318
- logger.info("Praparing to shutdown...")
319
- logger.success("Finished preparation to shutdown.")
320
-
321
- app = FastAPI(lifespan=lifespan, version=__version__)
322
- app.add_middleware(
323
- HttpAccessLogMiddleware,
324
- has_proxy_headers=True,
325
- debug_format=logger_loader.config.extra.http_std_debug_format,
326
- msg_format=logger_loader.config.extra.http_std_msg_format,
327
- )
328
-
329
- @app.get("/")
330
- def root():
331
- return {"Hello": "World"}
332
- ```
333
-
334
- Run the [**`examples/advanced`**](https://github.com/bybatkhuu/module.python-logging/tree/main/examples/advanced):
335
-
336
- ```sh
337
- cd ./examples/advanced
338
- # Install python dependencies for examples:
339
- pip install -r ./requirements.txt
340
-
341
- uvicorn app:app --host=0.0.0.0 --port=8000
342
- ```
343
-
344
- **Output**:
345
-
346
- ```txt
347
- [2023-09-01 12:37:38.569 +09:00 | TRACE | beans_logging._base:499]: Intercepted modules: ['watchfiles.watcher', 'asyncio', 'watchfiles', 'concurrent', 'dotenv', 'concurrent.futures', 'fastapi', 'dotenv.main', 'uvicorn', 'watchfiles.main']; Muted modules: ['uvicorn.error', 'uvicorn.access'];
348
- [2023-09-01 12:37:38.579 +09:00 | INFO | uvicorn.server:76]: Started server process [22599]
349
- [2023-09-01 12:37:38.579 +09:00 | INFO | uvicorn.lifespan.on:46]: Waiting for application startup.
350
- [2023-09-01 12:37:38.579 +09:00 | INFO | app:21]: Preparing to startup...
351
- [2023-09-01 12:37:38.580 +09:00 | OK | app:22]: Finished preparation to startup.
352
- [2023-09-01 12:37:38.580 +09:00 | INFO | app:23]: API version: 0.0.1-000000
353
- [2023-09-01 12:37:38.580 +09:00 | INFO | uvicorn.lifespan.on:60]: Application startup complete.
354
- [2023-09-01 12:37:38.582 +09:00 | INFO | uvicorn.server:218]: Uvicorn running on http://0.0.0.0:9000 (Press CTRL+C to quit)
355
- [2023-09-01 12:37:48.487 +09:00 | DEBUG | anyio._backends._asyncio:807]: [0b9f972939054a58ba10e7a39a12bd21] 127.0.0.1 - "GET / HTTP/1.1"
356
- [2023-09-01 12:37:48.488 +09:00 | OK | anyio._backends._asyncio:807]: [0b9f972939054a58ba10e7a39a12bd21] 127.0.0.1 - "GET / HTTP/1.1" 200 17B 0.5ms
357
- ^C[2023-09-01 12:37:51.845 +09:00 | INFO | uvicorn.server:264]: Shutting down
358
- [2023-09-01 12:37:51.949 +09:00 | INFO | uvicorn.lifespan.on:65]: Waiting for application shutdown.
359
- [2023-09-01 12:37:51.951 +09:00 | INFO | app:26]: Praparing to shutdown...
360
- [2023-09-01 12:37:51.952 +09:00 | OK | app:27]: Finished preparation to shutdown.
361
- [2023-09-01 12:37:51.952 +09:00 | INFO | uvicorn.lifespan.on:76]: Application shutdown complete.
362
- [2023-09-01 12:37:51.953 +09:00 | INFO | uvicorn.server:86]: Finished server process [22599]
363
- ```
217
+ - FastAPI HTTP access logging middleware
218
+ - Install with pip: `pip install -U beans-logging[fastapi]` or `pip install -U beans-logging-fastapi`
364
219
 
365
220
  ---
366
221
 
@@ -386,7 +241,7 @@ DEBUG=true
386
241
 
387
242
  BEANS_LOGGING_DISABLE_DEFAULT=false
388
243
  BEANS_LOGGING_CONFIG_PATH="./configs/logger.yml"
389
- BEANS_LOGGING_DIR="./logs"
244
+ BEANS_LOGGING_LOGS_DIR="./logs"
390
245
  ```
391
246
 
392
247
  ## Configuration
@@ -441,3 +296,4 @@ logger:
441
296
  - <https://github.com/Delgan/loguru>
442
297
  - <https://loguru.readthedocs.io/en/stable/api/logger.html>
443
298
  - <https://loguru.readthedocs.io/en/stable/resources/recipes.html>
299
+ - <https://github.com/bybatkhuu/module.fastapi-logging>
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from ._base import Logger, logger, LoggerLoader
4
+ from .schemas import LoggerConfigPM
5
+ from ._consts import WarnEnum
6
+ from .__version__ import __version__
7
+
8
+
9
+ __all__ = [
10
+ "Logger",
11
+ "logger",
12
+ "LoggerLoader",
13
+ "LoggerConfigPM",
14
+ "WarnEnum",
15
+ "__version__",
16
+ ]
@@ -1,3 +1,3 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- __version__ = "4.1.1"
3
+ __version__ = "6.0.0"
@@ -11,7 +11,12 @@ from typing import Union, Dict, Any
11
11
  import yaml
12
12
  from loguru import logger
13
13
  from loguru._logger import Logger
14
- from pydantic import validate_call
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
15
20
 
16
21
  ## Internal modules
17
22
  from ._utils import create_dir, deep_merge
@@ -168,7 +173,11 @@ class LoggerLoader:
168
173
  """
169
174
 
170
175
  if isinstance(config, dict):
171
- _config_dict = self.config.model_dump()
176
+ if "2.0.0" <= pydantic.__version__:
177
+ _config_dict = self.config.model_dump()
178
+ else:
179
+ _config_dict = self.config.dict()
180
+
172
181
  _merged_dict = deep_merge(_config_dict, config)
173
182
  try:
174
183
  self.config = LoggerConfigPM(**_merged_dict)
@@ -219,7 +228,11 @@ class LoggerLoader:
219
228
  return
220
229
 
221
230
  _new_config_dict = _new_config_dict["logger"]
222
- _config_dict = self.config.model_dump()
231
+ if "2.0.0" <= pydantic.__version__:
232
+ _config_dict = self.config.model_dump()
233
+ else:
234
+ _config_dict = self.config.dict()
235
+
223
236
  _merged_dict = deep_merge(_config_dict, _new_config_dict)
224
237
  self.config = LoggerConfigPM(**_merged_dict)
225
238
  except Exception:
@@ -240,7 +253,11 @@ class LoggerLoader:
240
253
  return
241
254
 
242
255
  _new_config_dict = _new_config_dict["logger"]
243
- _config_dict = self.config.model_dump()
256
+ if "2.0.0" <= pydantic.__version__:
257
+ _config_dict = self.config.model_dump()
258
+ else:
259
+ _config_dict = self.config.dict()
260
+
244
261
  _merged_dict = deep_merge(_config_dict, _new_config_dict)
245
262
  self.config = LoggerConfigPM(**_merged_dict)
246
263
  except Exception:
@@ -252,7 +269,9 @@ class LoggerLoader:
252
269
  # try:
253
270
  # import toml
254
271
 
255
- # with open(self.config_file_path, "r", encoding="utf-8") as _config_file:
272
+ # with open(
273
+ # self.config_file_path, "r", encoding="utf-8"
274
+ # ) as _config_file:
256
275
  # _new_config_dict = toml.load(_config_file) or {}
257
276
  # if "logger" not in _new_config_dict:
258
277
  # logger.warning(
@@ -261,7 +280,11 @@ class LoggerLoader:
261
280
  # return
262
281
 
263
282
  # _new_config_dict = _new_config_dict["logger"]
264
- # _config_dict = self.config.model_dump()
283
+ # if "2.0.0" <= pydantic.__version__:
284
+ # _config_dict = self.config.model_dump()
285
+ # else:
286
+ # _config_dict = self.config.dict()
287
+
265
288
  # _merged_dict = deep_merge(_config_dict, _new_config_dict)
266
289
  # self.config = LoggerConfigPM(**_merged_dict)
267
290
  # except Exception:
@@ -287,8 +310,8 @@ class LoggerLoader:
287
310
  if _is_debug and (self.config.level != "TRACE"):
288
311
  self.config.level = "DEBUG"
289
312
 
290
- if "BEANS_LOGGING_DIR" in os.environ:
291
- self.config.file.logs_dir = os.getenv("BEANS_LOGGING_DIR")
313
+ if "BEANS_LOGGING_LOGS_DIR" in os.environ:
314
+ self.config.file.logs_dir = os.getenv("BEANS_LOGGING_LOGS_DIR")
292
315
 
293
316
  # if self.config.stream.use_color:
294
317
  # ## Checking terminal could support xterm colors:
@@ -529,11 +552,13 @@ class LoggerLoader:
529
552
  ):
530
553
  _logger = logging.getLogger(_module_name)
531
554
  _logger.handlers = [_intercept_handler]
555
+ _logger.propagate = False
532
556
  _intercepted_modules.add(_module_name)
533
557
 
534
558
  for _include_module_name in self.config.intercept.include_modules:
535
559
  _logger = logging.getLogger(_include_module_name)
536
560
  _logger.handlers = [_intercept_handler]
561
+ logger.propagate = False
537
562
 
538
563
  if _include_module_name not in _intercepted_modules:
539
564
  _intercepted_modules.add(_include_module_name)
@@ -541,8 +566,8 @@ class LoggerLoader:
541
566
  for _mute_module_name in self.config.intercept.mute_modules:
542
567
  _logger = logging.getLogger(_mute_module_name)
543
568
  _logger.handlers = []
544
- # _logger.propagate = False
545
- # _logger.disabled = True
569
+ _logger.propagate = False
570
+ _logger.disabled = True
546
571
 
547
572
  if _mute_module_name in _intercepted_modules:
548
573
  _intercepted_modules.remove(_mute_module_name)
@@ -0,0 +1,20 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from enum import Enum
4
+
5
+
6
+ class WarnEnum(str, Enum):
7
+ ERROR = "ERROR"
8
+ ALWAYS = "ALWAYS"
9
+ DEBUG = "DEBUG"
10
+ IGNORE = "IGNORE"
11
+
12
+
13
+ class LogLevelEnum(str, Enum):
14
+ TRACE = "TRACE"
15
+ DEBUG = "DEBUG"
16
+ INFO = "INFO"
17
+ SUCCESS = "SUCCESS"
18
+ WARNING = "WARNING"
19
+ ERROR = "ERROR"
20
+ CRITICAL = "CRITICAL"
@@ -1,13 +1,19 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  import os
4
+ import sys
4
5
  import copy
5
6
  import errno
6
7
 
7
8
  from loguru import logger
8
- from pydantic import validate_call
9
+ import pydantic
9
10
 
10
- from ._const import WarnEnum
11
+ if "2.0.0" <= pydantic.__version__:
12
+ from pydantic import validate_call
13
+ else:
14
+ from pydantic import validate_arguments as validate_call
15
+
16
+ from ._consts import WarnEnum
11
17
 
12
18
 
13
19
  @validate_call
@@ -16,13 +22,13 @@ def create_dir(create_dir: str, warn_mode: WarnEnum = WarnEnum.DEBUG):
16
22
 
17
23
  Args:
18
24
  create_dir (str, required): Create directory path.
19
- warn_mode (str, optional): Warning message mode, for example: 'LOG', 'DEBUG', 'QUIET'. Defaults to "QUIET".
25
+ warn_mode (str, optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'. Defaults to "DEBUG".
20
26
  """
21
27
 
22
28
  if not os.path.isdir(create_dir):
23
29
  try:
24
30
  _message = f"Creaing '{create_dir}' directory..."
25
- if warn_mode == WarnEnum.LOG:
31
+ if warn_mode == WarnEnum.ALWAYS:
26
32
  logger.info(_message)
27
33
  elif warn_mode == WarnEnum.DEBUG:
28
34
  logger.debug(_message)
@@ -36,7 +42,7 @@ def create_dir(create_dir: str, warn_mode: WarnEnum = WarnEnum.DEBUG):
36
42
  raise
37
43
 
38
44
  _message = f"Successfully created '{create_dir}' directory."
39
- if warn_mode == WarnEnum.LOG:
45
+ if warn_mode == WarnEnum.ALWAYS:
40
46
  logger.success(_message)
41
47
  elif warn_mode == WarnEnum.DEBUG:
42
48
  logger.debug(_message)
@@ -67,3 +73,28 @@ def deep_merge(dict1: dict, dict2: dict) -> dict:
67
73
  _merged[_key] = copy.deepcopy(_val)
68
74
 
69
75
  return _merged
76
+
77
+
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
+
87
+
88
+ def get_app_name() -> str:
89
+ """Return application name (sys.argv[0]).
90
+
91
+ Returns:
92
+ str: Application name.
93
+ """
94
+
95
+ return (
96
+ os.path.splitext(os.path.basename(sys.argv[0]))[0]
97
+ .strip()
98
+ .replace(" ", "-")
99
+ .lower()
100
+ )