Skip to content

Commit a64d884

Browse files
committed
feat: Настройка логирования по записи в файл
С помощью bind и фильтра каждый логер будет писать в свой файл
1 parent 71ce8bb commit a64d884

File tree

5 files changed

+66
-11
lines changed

5 files changed

+66
-11
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
fill_db:
2+
poetry shell
23
python scripts/add_records_in_db.py
34
deploy:
45
python scripts/dokku/deploy.py

config.py

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
import inspect
2+
import logging
13
import os
4+
import sys
5+
from typing import Optional, Union
26

37
from dotenv import find_dotenv, load_dotenv
48
from loguru import logger
@@ -7,24 +11,65 @@
711
basedir = os.path.abspath(os.path.dirname(__file__))
812

913

14+
class InterceptHandler(logging.Handler):
15+
"""
16+
Обработчик (из документации `loguru`) ловит все сообщения от стандартного `logging` и передаёт их в `loguru`.
17+
"""
18+
19+
def emit(self, record: logging.LogRecord) -> None:
20+
# Get corresponding Loguru level if it exists.
21+
level: Union[str, int]
22+
try:
23+
level = logger.level(record.levelname).name
24+
except ValueError:
25+
level = record.levelno
26+
27+
# Find caller from where originated the logged message.
28+
frame, depth = inspect.currentframe(), 0
29+
while frame and (depth == 0 or frame.f_code.co_filename == logging.__file__):
30+
frame = frame.f_back
31+
depth += 1
32+
33+
logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())
34+
35+
1036
def get_config():
1137
"""Получение настроек проекта."""
1238
env = os.getenv('FLASK_ENV', 'production')
39+
logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
1340
if env == 'development':
14-
return DevelopConfig
41+
return DevelopConfig()
1542
else:
16-
return ProductionConfig
43+
return ProductionConfig()
1744

1845

1946
class LoggerConfig:
2047
logger = logger
2148

22-
def __init__(self, file_name) -> None:
49+
def custom_filter(self, record: dict):
50+
"""
51+
Фильтрация записи в файл.
52+
"""
53+
return True if self.file_name == record.get('extra').get('logger') else False
54+
55+
def __init__(
56+
self,
57+
file_name,
58+
extra_format='{extra[logger]} {message}',
59+
) -> None:
60+
self.file_name = file_name
61+
62+
custom_filter = self.custom_filter
63+
2364
self.logger.add(
2465
f'logs/{file_name}.log',
2566
backtrace=True,
2667
diagnose=True,
2768
rotation='20 MB',
69+
retention=5,
70+
format=extra_format,
71+
filter=custom_filter,
72+
enqueue=True,
2873
)
2974

3075

@@ -56,12 +101,14 @@ class DevelopConfig:
56101

57102
BOT_TOKEN = os.getenv('token')
58103
URL_ADMIN = os.getenv('URL_ADMIN')
59-
web_logger = LoggerConfig('test-web').logger
60-
bot_logger = LoggerConfig('test-bot').logger
61104

62105
def __name__(self):
63106
return 'DevelopConfig'
64107

108+
def __init__(self) -> None:
109+
self.web_logger = LoggerConfig('web', '{extra[logger]} {message}').logger.bind(logger='web')
110+
self.bot_logger = LoggerConfig('bot', '{extra[logger]} {message}').logger.bind(logger='bot')
111+
65112

66113
class ProductionConfig:
67114
DASHBOARD_EXPENSE = os.getenv('DASHBOARD_EXPENSE')
@@ -76,11 +123,12 @@ class ProductionConfig:
76123
BOT_TOKEN = os.getenv('token')
77124
URL_ADMIN = os.getenv('URL_ADMIN')
78125

79-
web_logger = LoggerConfig('web').logger
80-
bot_logger = LoggerConfig('bot').logger
81-
82126
def __name__(self):
83127
return 'ProductionConfig'
84128

129+
def __init__(self) -> None:
130+
self.web_logger = LoggerConfig('web', '{extra[logger]} {message}').logger.bind(logger='web')
131+
self.bot_logger = LoggerConfig('bot', '{extra[logger]} {message}').logger.bind(logger='bot')
132+
85133

86134
settings = get_config()

main.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import subprocess
22
from concurrent.futures import ProcessPoolExecutor
33

4+
from config import settings
5+
6+
web_logger = settings.web_logger
7+
bot_logger = settings.bot_logger
8+
49

510
def start_web():
611
subprocess.call(['gunicorn', '--bind', '0.0.0.0:5000', '-w 4', 'web_app:app'])
@@ -13,7 +18,9 @@ def start_bot():
1318
def main():
1419
with ProcessPoolExecutor() as pool:
1520
pool.submit(start_bot)
21+
bot_logger.info('🔘 Запуск бота')
1622
pool.submit(start_web)
23+
web_logger.info('🌐 Запуск админки')
1724

1825

1926
if __name__ == '__main__':

src/telegram/handlers/weight.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ async def root_weight_menu(callback: types.CallbackQuery, state: FSMContext):
2222
weight_manager = WeightTelegramService(callback)
2323
result = await weight_manager.check_note()
2424
presence_of_record = True if result else False
25-
msg = f'Твой вес сегодня: <b>{result.value}</b>' if result else 'Журнал веса'
25+
msg = f'Твой вес сегодня: <b>{result.value}</b>' if result else 'Журнал веса на сегодня пуст'
2626

2727
if presence_of_record:
2828
await state.set_data({'weight_note_id': result.id})

src/webapp/dashbords/weight.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@
1313
from src.services.weight import WeightDashbordService
1414
from src.webapp.dashbords.base import DashboardManager, StyleDash
1515

16-
logger = settings.bot_logger
16+
logger = settings.web_logger
1717

1818

1919
def get_weight_analytics(current_flask_app):
2020
def show_content():
2121
"""Получение и отрисовка данных."""
2222
weight_manager = WeightDashbordService(current_user.telegram_id)
23-
2423
data_weight = weight_manager.get_all_weight_by_telegram_id()
2524
list_timestamp = sorted(set([i[1] for i in data_weight]))
2625

0 commit comments

Comments
 (0)