diff --git a/backup.py b/backup.py
index 4ad4433b..27839beb 100644
--- a/backup.py
+++ b/backup.py
@@ -3,9 +3,9 @@ import subprocess
from datetime import datetime
from aiogram.types import BufferedInputFile
-from loguru import logger
from config import ADMIN_ID, BACK_DIR, DB_NAME, DB_PASSWORD, DB_USER
+from logger import logger
async def backup_database():
diff --git a/client.py b/client.py
index fd82c4bb..f0b1e0ff 100644
--- a/client.py
+++ b/client.py
@@ -1,7 +1,7 @@
import py3xui
-from loguru import logger
from config import TOTAL_GB
+from logger import logger
async def add_client(
@@ -72,7 +72,7 @@ async def extend_client_key(
client.sub_id = email
client.total_gb = total_gb
client.enable = True
- client.limit_ip = 1
+ client.limit_ip = 1
await xui.client.update(client.id, client)
logger.info(
diff --git a/database.py b/database.py
index c1fcc078..186c77ea 100644
--- a/database.py
+++ b/database.py
@@ -1,9 +1,9 @@
from datetime import datetime
import asyncpg
-from loguru import logger
from config import BONUS_PERCENT, DATABASE_URL
+from logger import logger
async def init_db():
diff --git a/handlers/admin/admin_commands.py b/handlers/admin/admin_commands.py
index af783e57..7be9694a 100644
--- a/handlers/admin/admin_commands.py
+++ b/handlers/admin/admin_commands.py
@@ -3,13 +3,13 @@ from aiogram import Router, types
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
-from loguru import logger
from bot import bot
from config import DATABASE_URL
from database import add_balance_to_client, check_connection_exists
from filters.admin import IsAdminFilter
from handlers.texts import TRIAL
+from logger import logger
router = Router()
diff --git a/handlers/admin/admin_coupons.py b/handlers/admin/admin_coupons.py
index 00764539..86f581b1 100644
--- a/handlers/admin/admin_coupons.py
+++ b/handlers/admin/admin_coupons.py
@@ -3,9 +3,9 @@ from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
-from loguru import logger
from database import create_coupon, delete_coupon_from_db, get_all_coupons
+from logger import logger
class AdminCouponsState(StatesGroup):
diff --git a/handlers/admin/admin_user_editor.py b/handlers/admin/admin_user_editor.py
index 5c7ff475..6e157034 100644
--- a/handlers/admin/admin_user_editor.py
+++ b/handlers/admin/admin_user_editor.py
@@ -7,7 +7,6 @@ from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import CallbackQuery, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
-from loguru import logger
from bot import bot
from config import CLUSTERS, DATABASE_URL, TOTAL_GB
@@ -16,6 +15,7 @@ from filters.admin import IsAdminFilter
from handlers.admin.admin_panel import back_to_admin_menu
from handlers.keys.key_utils import delete_key_from_cluster, renew_key_in_cluster
from handlers.utils import sanitize_key_name
+from logger import logger
router = Router()
diff --git a/handlers/coupons.py b/handlers/coupons.py
index 1c145d92..9c9064e3 100644
--- a/handlers/coupons.py
+++ b/handlers/coupons.py
@@ -6,10 +6,10 @@ from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
-from loguru import logger
from config import DATABASE_URL
from database import update_balance
+from logger import logger
class CouponActivationState(StatesGroup):
diff --git a/handlers/donate.py b/handlers/donate.py
index 41c5004a..407d1211 100644
--- a/handlers/donate.py
+++ b/handlers/donate.py
@@ -3,10 +3,10 @@ from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import InlineKeyboardButton, LabeledPrice, PreCheckoutQuery
from aiogram.utils.keyboard import InlineKeyboardBuilder
-from loguru import logger
from bot import bot
from config import RUB_TO_XTR
+from logger import logger
class DonateState(StatesGroup):
diff --git a/handlers/instructions/instructions.py b/handlers/instructions/instructions.py
index f67fc887..458af5b5 100644
--- a/handlers/instructions/instructions.py
+++ b/handlers/instructions/instructions.py
@@ -2,11 +2,11 @@ import os
from aiogram import F, Router, types
from aiogram.types import BufferedInputFile, InlineKeyboardButton, InlineKeyboardMarkup
-from loguru import logger
from bot import bot
from config import CONNECT_WINDOWS, SUPPORT_CHAT_URL
from handlers.texts import INSTRUCTION_PC, INSTRUCTIONS, KEY_MESSAGE
+from logger import logger
router = Router()
diff --git a/handlers/keys/key_management.py b/handlers/keys/key_management.py
index 1a069c4f..de856809 100644
--- a/handlers/keys/key_management.py
+++ b/handlers/keys/key_management.py
@@ -7,7 +7,6 @@ from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message
-from loguru import logger
from bot import bot, dp
from config import CONNECT_ANDROID, CONNECT_IOS, DATABASE_URL, DOWNLOAD_ANDROID, DOWNLOAD_IOS, PUBLIC_LINK
@@ -17,6 +16,7 @@ from handlers.keys.key_utils import create_key_on_cluster
from handlers.profile import process_callback_view_profile
from handlers.texts import KEY, KEY_TRIAL, NULL_BALANCE, RENEWAL_PLANS, key_message_success
from handlers.utils import get_least_loaded_cluster, sanitize_key_name
+from logger import logger
router = Router()
diff --git a/handlers/keys/key_utils.py b/handlers/keys/key_utils.py
index 676b0f43..44da28c6 100644
--- a/handlers/keys/key_utils.py
+++ b/handlers/keys/key_utils.py
@@ -1,11 +1,11 @@
import asyncio
import asyncpg
-from loguru import logger
from py3xui import AsyncApi
from client import add_client, delete_client, extend_client_key
from config import ADMIN_PASSWORD, ADMIN_USERNAME, CLUSTERS, DATABASE_URL, TOTAL_GB
+from logger import logger
async def create_key_on_cluster(cluster_id, tg_id, client_id, email, expiry_timestamp):
diff --git a/handlers/keys/keys.py b/handlers/keys/keys.py
index b2cdce02..e458fb1a 100644
--- a/handlers/keys/keys.py
+++ b/handlers/keys/keys.py
@@ -6,7 +6,6 @@ from datetime import datetime, timedelta
import asyncpg
from aiogram import F, Router, types
from aiogram.types import BufferedInputFile
-from loguru import logger
from bot import bot
from config import CLUSTERS, CONNECT_ANDROID, CONNECT_IOS, DATABASE_URL, DOWNLOAD_ANDROID, DOWNLOAD_IOS, PUBLIC_LINK, TOTAL_GB
@@ -14,6 +13,7 @@ from database import delete_key, get_balance, store_key, update_balance, update_
from handlers.keys.key_utils import delete_key_from_cluster, delete_key_from_db, renew_key_in_cluster, update_key_on_cluster
from handlers.texts import INSUFFICIENT_FUNDS_MSG, KEY_NOT_FOUND_MSG, NO_KEYS, PLAN_SELECTION_MSG, RENEWAL_PLANS, SUCCESS_RENEWAL_MSG, key_message
from handlers.utils import get_least_loaded_cluster, handle_error
+from logger import logger
locale.setlocale(locale.LC_TIME, "ru_RU.UTF-8")
diff --git a/handlers/keys/subscriptions.py b/handlers/keys/subscriptions.py
index c49fc5e9..553db553 100644
--- a/handlers/keys/subscriptions.py
+++ b/handlers/keys/subscriptions.py
@@ -2,9 +2,9 @@ import base64
import aiohttp
from aiohttp import web
-from loguru import logger
from config import CLUSTERS
+from logger import logger
async def fetch_url_content(url):
diff --git a/handlers/notifications.py b/handlers/notifications.py
index 7354dca4..56e2d2b6 100644
--- a/handlers/notifications.py
+++ b/handlers/notifications.py
@@ -3,7 +3,6 @@ from datetime import datetime, timedelta
import asyncpg
from aiogram import Bot, Router, types
-from loguru import logger
from py3xui import AsyncApi
from client import delete_client
@@ -11,6 +10,7 @@ from config import ADMIN_PASSWORD, ADMIN_USERNAME, CLUSTERS, DATABASE_URL, TOTAL
from database import delete_key, get_balance, update_balance, update_key_expiry
from handlers.keys.key_utils import renew_key_in_cluster
from handlers.texts import KEY_EXPIRY_10H, KEY_EXPIRY_24H, KEY_RENEWED, RENEWAL_PLANS
+from logger import logger
router = Router()
diff --git a/handlers/payments/cryprobot_pay.py b/handlers/payments/cryprobot_pay.py
index 9f95bc2f..44f9c691 100644
--- a/handlers/payments/cryprobot_pay.py
+++ b/handlers/payments/cryprobot_pay.py
@@ -5,12 +5,12 @@ from aiogram.fsm.state import State, StatesGroup
from aiogram.types import InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiohttp import web
-from loguru import logger
from bot import bot
from config import CRYPTO_BOT_ENABLE, CRYPTO_BOT_TOKEN, RUB_TO_USDT
from database import add_connection, check_connection_exists, get_key_count, update_balance
from handlers.texts import PAYMENT_OPTIONS
+from logger import logger
router = Router()
diff --git a/handlers/payments/robokassa_pay.py b/handlers/payments/robokassa_pay.py
index db6d3762..c2559faa 100644
--- a/handlers/payments/robokassa_pay.py
+++ b/handlers/payments/robokassa_pay.py
@@ -7,12 +7,12 @@ from aiogram.fsm.state import State, StatesGroup
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiohttp import web
-from loguru import logger
from bot import bot
from config import ROBOKASSA_LOGIN, ROBOKASSA_PASSWORD1, ROBOKASSA_PASSWORD2, ROBOKASSA_TEST_MODE
from database import add_connection, check_connection_exists, get_key_count, update_balance
from handlers.texts import PAYMENT_OPTIONS
+from logger import logger
router = Router()
diff --git a/handlers/payments/stars_pay.py b/handlers/payments/stars_pay.py
index 2cde3805..a628d3b0 100644
--- a/handlers/payments/stars_pay.py
+++ b/handlers/payments/stars_pay.py
@@ -3,12 +3,12 @@ from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import InlineKeyboardButton, LabeledPrice, PreCheckoutQuery
from aiogram.utils.keyboard import InlineKeyboardBuilder
-from loguru import logger
from bot import bot
from config import RUB_TO_XTR
from database import add_connection, check_connection_exists, get_key_count, update_balance
from handlers.texts import PAYMENT_OPTIONS
+from logger import logger
router = Router()
diff --git a/handlers/payments/yookassa_pay.py b/handlers/payments/yookassa_pay.py
index dd9788b6..0a3d8056 100644
--- a/handlers/payments/yookassa_pay.py
+++ b/handlers/payments/yookassa_pay.py
@@ -6,13 +6,13 @@ from aiogram.fsm.state import State, StatesGroup
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiohttp import web
-from loguru import logger
from yookassa import Configuration, Payment
from bot import bot
from config import YOOKASSA_ENABLE, YOOKASSA_SECRET_KEY, YOOKASSA_SHOP_ID
from database import add_connection, check_connection_exists, get_key_count, update_balance
from handlers.texts import PAYMENT_OPTIONS
+from logger import logger
router = Router()
diff --git a/handlers/profile.py b/handlers/profile.py
index 0bf5bc39..7958a5b5 100644
--- a/handlers/profile.py
+++ b/handlers/profile.py
@@ -4,12 +4,12 @@ from aiogram import F, Router, types
from aiogram.fsm.context import FSMContext
from aiogram.types import BufferedInputFile, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
-from loguru import logger
from bot import bot
from config import CHANNEL_URL
from database import get_balance, get_key_count, get_referral_stats
from handlers.texts import get_referral_link, invite_message_send, profile_message_send
+from logger import logger
router = Router()
diff --git a/handlers/start.py b/handlers/start.py
index 19408545..09e19d6f 100644
--- a/handlers/start.py
+++ b/handlers/start.py
@@ -4,13 +4,13 @@ from aiogram import F, Router
from aiogram.filters import Command
from aiogram.types import BufferedInputFile, CallbackQuery, InlineKeyboardButton, Message
from aiogram.utils.keyboard import InlineKeyboardBuilder
-from loguru import logger
from bot import bot
from config import CHANNEL_URL, CONNECT_ANDROID, CONNECT_IOS, DOWNLOAD_ANDROID, DOWNLOAD_IOS, SUPPORT_CHAT_URL
from database import add_connection, add_referral, check_connection_exists, get_trial
from handlers.keys.trial_key import create_trial_key
from handlers.texts import INSTRUCTIONS_TRIAL, WELCOME_TEXT, get_about_vpn
+from logger import logger
router = Router()
diff --git a/handlers/utils.py b/handlers/utils.py
index 98c9145e..a4cafd30 100644
--- a/handlers/utils.py
+++ b/handlers/utils.py
@@ -2,10 +2,10 @@ import random
import re
import asyncpg
-from loguru import logger
from bot import bot
from config import CLUSTERS, DATABASE_URL
+from logger import logger
def sanitize_key_name(key_name: str) -> str:
diff --git a/logger.py b/logger.py
new file mode 100644
index 00000000..cef0cba7
--- /dev/null
+++ b/logger.py
@@ -0,0 +1,47 @@
+import logging
+import sys
+
+from loguru import logger
+
+logger.remove()
+
+
+level_mapping = {
+ 50: "CRITICAL",
+ 40: "ERROR",
+ 30: "WARNING",
+ 20: "INFO",
+ 10: "DEBUG",
+ 0: "NOTSET",
+}
+
+
+class InterceptHandler(logging.Handler):
+ def emit(self, record):
+ logger_opt = logger.opt(depth=6, exception=record.exc_info)
+ message = record.getMessage()
+ logger_opt.log(level_mapping.get(record.levelno, "INFO"), message)
+
+
+logging.basicConfig(handlers=[InterceptHandler()], level=0)
+logging.getLogger("httpcore").setLevel(logging.WARNING)
+logging.getLogger("httpx").setLevel(logging.WARNING)
+
+# Настройка вывода в консоль
+logger.add(
+ sys.stderr,
+ level="INFO",
+ format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {module}:{function}:{line} | {message}",
+ colorize=True,
+)
+
+# Настройка записи в файл
+logger.add(
+ "logging.log",
+ level="DEBUG",
+ format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {module}:{function}:{line} | {message}",
+ rotation="60 minute",
+ retention=24,
+)
+
+logger = logger
diff --git a/middlewares/logging.py b/middlewares/logging.py
index 22c57362..9325a555 100644
--- a/middlewares/logging.py
+++ b/middlewares/logging.py
@@ -1,9 +1,9 @@
-import logging
from typing import Any, Awaitable, Callable, Dict
from aiogram import BaseMiddleware
from aiogram.types import CallbackQuery, Message, TelegramObject
-from loguru import logger
+
+from logger import logger
class LoggingMiddleware(BaseMiddleware):
@@ -32,23 +32,4 @@ class LoggingMiddleware(BaseMiddleware):
f"Имя пользователя: {username}, "
f"Действие: {action}"
)
-
return await handler(event, data)
-
-
-class InterceptHandler(logging.Handler):
- def emit(self, record):
- try:
- level = logger.level(record.levelname).name
- except ValueError:
- level = "INFO"
-
- logger.log(level, record.getMessage())
-
-
-logging.basicConfig(handlers=[InterceptHandler()], level=0)
-
-logging.getLogger("httpcore").setLevel(logging.WARNING)
-logging.getLogger("httpx").setLevel(logging.WARNING)
-
-logger.add("logs/app.log", level="INFO", rotation="10 MB", compression="zip")