From a1b961ae207583d8c11a5ed8bdb19c4c08f55f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=BB=D0=B0=D0=B4=20=D0=97=D0=B2=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=B2?= Date: Thu, 19 Sep 2024 15:21:52 +0500 Subject: [PATCH] Small cleanup code --- log_manager.py | 45 ++++++++++- telezab.py | 214 +++++++++++++++++++------------------------------ 2 files changed, 125 insertions(+), 134 deletions(-) diff --git a/log_manager.py b/log_manager.py index d517fbb..708d373 100644 --- a/log_manager.py +++ b/log_manager.py @@ -29,6 +29,7 @@ class LogManager: 'flask_error': os.path.join(self.log_dir, 'flask_error.log'), 'app': os.path.join(self.log_dir, 'app.log'), 'app_error': os.path.join(self.log_dir, 'app_error.log'), + 'debug': os.path.join(self.log_dir, 'debug.log'), } # Ensure the log directory exists @@ -49,6 +50,12 @@ class LogManager: 'error': { 'format': '[%(asctime)s] %(levelname)s %(module)s: %(message)s', }, + 'werkzeug': { + 'format': '[%(asctime)s] %(levelname)s %(message)s' + }, + 'debug': { + 'format': '[%(asctime)s] %(levelname)s %(module)s [%(funcName)s:%(lineno)d]: %(message)s' + } }, 'handlers': { 'telebot_console': { @@ -59,14 +66,14 @@ class LogManager: 'flask_console': { 'class': 'log_manager.UTF8StreamHandler', 'stream': 'ext://sys.stdout', - 'formatter': 'default', + 'formatter': 'werkzeug', }, 'flask_file': { 'class': 'logging.handlers.TimedRotatingFileHandler', 'filename': self.log_files['flask'], 'when': 'midnight', 'backupCount': self.retention_days, - 'formatter': 'default', + 'formatter': 'werkzeug', 'encoding': 'utf-8', }, 'flask_error_file': { @@ -74,7 +81,7 @@ class LogManager: 'filename': self.log_files['flask_error'], 'when': 'midnight', 'backupCount': self.retention_days, - 'formatter': 'error', + 'formatter': 'werkzeug', 'encoding': 'utf-8', 'level': 'ERROR', }, @@ -95,6 +102,15 @@ class LogManager: 'encoding': 'utf-8', 'level': 'ERROR', }, + 'debug_file': { + 'class': 'logging.handlers.TimedRotatingFileHandler', + 'filename': self.log_files['debug'], + 'when': 'midnight', + 'backupCount': self.retention_days, + 'formatter': 'debug', + 'encoding': 'utf-8', + 'level': 'DEBUG', + }, }, 'loggers': { 'flask': { @@ -107,6 +123,16 @@ class LogManager: 'handlers': ['app_file', 'app_error_file', 'telebot_console'], 'propagate': False, }, + 'werkzeug': { + 'level': 'INFO', + 'handlers': ['flask_file', 'flask_error_file', 'flask_console'], + 'propagate': False, + }, + 'debug': { + 'level': 'DEBUG', + 'handlers': ['debug_file'], + 'propagate': False, + }, } # 'root': { # 'level': 'DEBUG', @@ -134,6 +160,19 @@ class LogManager: # Clean up old archives self.cleanup_old_archives() + def configure_werkzeug_logging(self): + """Отключаем встроенный логгер Werkzeug и задаём собственные настройки логирования.""" + werkzeug_logger = logging.getLogger('werkzeug') + werkzeug_logger.handlers = [] # Удаляем существующие обработчики + + # Добавляем кастомный обработчик для форматирования логов + handler = TimedRotatingFileHandler(self.log_files['flask'], when='midnight', backupCount=self.retention_days, encoding='utf-8') + handler.setFormatter(logging.Formatter('[%(asctime)s] %(levelname)s %(message)s')) + werkzeug_logger.addHandler(handler) + + # Отключаем дублирование логов + werkzeug_logger.propagate = False + def cleanup_old_archives(self): """Deletes archived logs older than retention_days.""" now = datetime.now() diff --git a/telezab.py b/telezab.py index b333992..5c2a574 100644 --- a/telezab.py +++ b/telezab.py @@ -42,25 +42,25 @@ def load_value_from_file(file_name): # Функция для получения переменной из окружения или файла -def get_variable_value(variable_name): - # Попытка получить значение из окружения - value = os.getenv(variable_name) - - # Если переменная окружения не установлена, попробуем загрузить из файла - if not value: - file_value = "file_" + variable_name - value = os.getenv(file_value) - with open(value, 'r') as file: - value = file.read() - return value - return value +# def get_variable_value(variable_name): +# # Попытка получить значение из окружения +# value = os.getenv(variable_name) +# +# # Если переменная окружения не установлена, попробуем загрузить из файла +# if not value: +# file_value = "file_" + variable_name +# value = os.getenv(file_value) +# with open(value, 'r') as file: +# value = file.read() +# return value +# return value # -DEV = get_variable_value('DEV') +DEV = os.getenv('DEV') # Загрузка переменных окружения или значений из файлов -TOKEN = get_variable_value('TELEGRAM_TOKEN') -ZABBIX_API_TOKEN = get_variable_value('ZABBIX_API_TOKEN') -ZABBIX_URL = get_variable_value('ZABBIX_URL') +TOKEN = os.getenv('TELEGRAM_TOKEN') +ZABBIX_API_TOKEN = os.getenv('ZABBIX_API_TOKEN') +ZABBIX_URL = os.getenv('ZABBIX_URL') DB_PATH = 'db/telezab.db' SUPPORT_EMAIL = "shiftsupport-rtmis@rtmis.ru" BASE_URL = '/telezab' @@ -70,7 +70,7 @@ region_api = RegionAPI(DB_PATH) user_state_manager = UserStateManager() # Initialize Flask application -app = Flask(__name__, template_folder='templates') +app = Flask(__name__,static_url_path='/static', template_folder='templates') # Инициализация LogManager log_manager = LogManager(log_dir='logs', retention_days=30) @@ -233,16 +233,6 @@ def get_admins(): conn.close() return admins -# # Get list of regions -# def get_regions(): -# with db_lock: -# conn = sqlite3.connect(DB_PATH) -# cursor = conn.cursor() -# cursor.execute('SELECT region_id, region_name FROM regions WHERE active = TRUE ORDER BY region_id') -# regions = cursor.fetchall() -# conn.close() -# return regions - def get_sorted_regions(): with db_lock: @@ -251,12 +241,10 @@ def get_sorted_regions(): cursor.execute('SELECT region_id, region_name FROM regions WHERE active = TRUE') regions = cursor.fetchall() conn.close() - # Сортируем регионы по числовому значению region_id regions.sort(key=lambda x: int(x[0])) return regions - # Check if region exists def region_exists(region_id): with db_lock: @@ -267,7 +255,6 @@ def region_exists(region_id): conn.close() return count > 0 - # Get list of regions a user is subscribed to def get_user_subscribed_regions(chat_id): with db_lock: @@ -282,11 +269,10 @@ def get_user_subscribed_regions(chat_id): ''', (chat_id,)) regions = cursor.fetchall() conn.close() + # Сортируем регионы по числовому значению region_id + regions.sort(key=lambda x: int(x[0])) return regions - - - # Check if user is subscribed to a region def is_subscribed(chat_id, region_id): with db_lock: @@ -301,7 +287,6 @@ def is_subscribed(chat_id, region_id): conn.close() return count > 0 - # Format regions list def format_regions_list(regions): return '\n'.join([f"{region_id} - {region_name}" for region_id, region_name in regions]) @@ -327,8 +312,6 @@ def log_user_event(chat_id, username, action): NOTIFICATION_MODE = 1 SETTINGS_MODE = 2 - - # Handle /help command to provide instructions @bot.message_handler(commands=['help']) def handle_help(message): @@ -339,13 +322,12 @@ def handle_help(message): help_text = ( '/start - Показать меню бота\n' 'Настройки - Перейти в режим настроек и управления подписками\n' - 'Активные события - Получение всех нерешённых событий мониторинга по выбранным сервисам в выбранного региона\n' + 'Активные события - Получение всех нерешённых событий мониторинга по выбранным сервисам выбранного региона\n' 'Помощь - Описание всех возможностей бота' ) bot.send_message(message.chat.id, help_text, parse_mode="html") show_main_menu(message.chat.id) - # Handle /register command for new user registration def handle_register(message): chat_id = message.chat.id @@ -363,12 +345,12 @@ def handle_register(message): bot.send_message(chat_id,text,parse_mode="HTML") log_user_event(chat_id, username, "Requested registration") - # Handle /start command @bot.message_handler(commands=['start']) def handle_start(message): show_main_menu(message.chat.id) + def show_main_menu(chat_id): markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True) if is_whitelisted(chat_id): @@ -377,7 +359,6 @@ def show_main_menu(chat_id): else: user_state_manager.set_state(chat_id, "REGISTRATION") markup.add('Регистрация') - bot.send_message(chat_id, "Выберите действие:", reply_markup=markup) @@ -385,8 +366,7 @@ def create_settings_keyboard(chat_id, admins_list): markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True) # Линия 1: "Подписаться", "Отписаться" markup.row('Подписаться','Отписаться') - markup.row('Мои подписки') - markup.row('Режим уведомлений') + markup.row('Мои подписки','Режим уведомлений') if DEV == '1': if chat_id in admins_list: markup.row('Активные регионы') @@ -394,17 +374,14 @@ def create_settings_keyboard(chat_id, admins_list): markup.row('Назад') return markup - # Settings menu for users def show_settings_menu(chat_id): if not is_whitelisted(chat_id): user_state_manager.set_state(chat_id, "REGISTRATION") bot.send_message(chat_id, "Вы неавторизованы для использования этого бота") return - admins_list = get_admins() markup = create_settings_keyboard(chat_id, admins_list) - bot.send_message(chat_id, "Вы находитесь в режиме настроек. Выберите действие:", reply_markup=markup) # Основной обработчик меню @@ -413,15 +390,12 @@ def handle_menu_selection(message): chat_id = message.chat.id text = message.text.strip() username = message.from_user.username - # Проверка авторизации if not is_whitelisted(chat_id) and text != 'Регистрация': bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.") return - # Получаем текущее состояние пользователя current_state = user_state_manager.get_state(chat_id) - # Обработка команд в зависимости от состояния if current_state == "MAIN_MENU": handle_main_menu(message, chat_id, text) @@ -462,7 +436,6 @@ def handle_main_menu(message, chat_id, text): def handle_settings_menu(message, chat_id, text): """Обработка команд в меню настроек.""" admins_list = get_admins() - if text.lower() == 'подписаться': user_state_manager.set_state(chat_id, "SUBSCRIBE") handle_subscribe_button(message) @@ -494,83 +467,58 @@ def handle_subscribe_button(message): if not is_whitelisted(chat_id): bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.") return - username = message.from_user.username if username: username = f"@{username}" else: username = "N/A" regions_list = format_regions_list(get_sorted_regions()) + markup = telebot.types.InlineKeyboardMarkup() markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data=f"cancel_action")) bot.send_message(chat_id, f"Отправьте номера регионов через запятую:\n{regions_list}\n",reply_markup=markup) - # Сохраняем ID сообщения с клавиатурой для последующего редактирования - # user_state_manager.set_state(chat_id, "WAITING_FOR_INPUT", - # extra_data={"cancel_message_id": sent_message.message_id}) bot.register_next_step_handler_by_chat_id(chat_id, process_subscription_button, chat_id, username) def process_subscription_button(message, chat_id, username): subbed_regions = [] invalid_regions = [] - if message.text.lower() == 'отмена': bot.send_message(chat_id, "Действие отменено.") user_state_manager.set_state(chat_id, "SETTINGS_MENU") return show_settings_menu(chat_id) - if not all(part.strip().isdigit() for part in message.text.split(',')): markup = telebot.types.InlineKeyboardMarkup() markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data=f"cancel_action")) bot.send_message(chat_id, "Неверный формат данных. Введите номер или номера регионов через запятую.", reply_markup=markup) - - # # Сохраняем ID сообщения с клавиатурой для последующего редактирования - # user_state_manager.set_state(chat_id, "WAITING_FOR_INPUT", extra_data={"cancel_message_id": sent_message.message_id}) - - bot.register_next_step_handler_by_chat_id(chat_id, process_subscription_button, chat_id, username) return - region_ids = message.text.split(',') valid_region_ids = [region[0] for region in get_sorted_regions()] - with db_lock: conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() - for region_id in region_ids: region_id = region_id.strip() if region_id not in valid_region_ids: invalid_regions.append(region_id) continue - cursor.execute('INSERT OR IGNORE INTO subscriptions (chat_id, region_id, username, active) VALUES (?, ?, ?, TRUE)', (chat_id, region_id, username)) if cursor.rowcount == 0: cursor.execute('UPDATE subscriptions SET active = TRUE WHERE chat_id = ? AND region_id = ?', (chat_id, region_id)) subbed_regions.append(region_id) conn.commit() - - # # Получаем ID сообщения с клавиатурой "Отмена" и скрываем её - # state_data = user_state_manager.get_state(chat_id) - # cancel_message_id = state_data.get("cancel_message_id") - # - # if cancel_message_id: - # try: - # bot.edit_message_reply_markup(chat_id, cancel_message_id, reply_markup=None) - # except telebot.apihelper.ApiTelegramException as e: - # telebot.logger.error(f"Failed to edit message: {e}") - if len(invalid_regions) > 0: bot.send_message(chat_id, f"Регион с ID {', '.join(invalid_regions)} не существует. Введите корректные номера или 'отмена'.") - bot.send_message(chat_id, f"Подписка на регионы: {', '.join(subbed_regions)} оформлена.") log_user_event(chat_id, username, f"Subscribed to regions: {', '.join(subbed_regions)}") user_state_manager.set_state(chat_id, "SETTINGS_MENU") show_settings_menu(chat_id) + def handle_unsubscribe_button(message): chat_id = message.chat.id if not is_whitelisted(chat_id): @@ -578,27 +526,22 @@ def handle_unsubscribe_button(message): telebot.logger.info(f"Unauthorized access attempt by {chat_id}") user_state_manager.set_state(chat_id, "REGISTRATION") return show_main_menu(chat_id) - username = message.from_user.username if username: username = f"@{username}" else: username = "N/A" - # Получаем список подписок пользователя user_regions = get_user_subscribed_regions(chat_id) + if not user_regions: bot.send_message(chat_id, "Вы не подписаны ни на один регион.") user_state_manager.set_state(chat_id, "SETTINGS_MENU") return show_settings_menu(chat_id) - regions_list = format_regions_list(user_regions) markup = telebot.types.InlineKeyboardMarkup() - markup.add(telebot.types.InlineKeyboardButton(text="Отмена", - callback_data=f"cancel_action")) + markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data=f"cancel_action")) bot.send_message(chat_id, f"Отправьте номер или номера регионов, от которых хотите отписаться (через запятую):\n{regions_list}\n",reply_markup=markup) - # user_state_manager.set_state(chat_id, "WAITING_FOR_INPUT", - # extra_data={"cancel_message_id": sent_message.message_id}) bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription_button, chat_id, username) @@ -606,51 +549,31 @@ def process_unsubscription_button(message, chat_id, username): unsubbed_regions = [] invalid_regions = [] markup = telebot.types.InlineKeyboardMarkup() - markup.add(telebot.types.InlineKeyboardButton(text="Отмена", - callback_data=f"cancel_action")) + markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data=f"cancel_action")) if message.text.lower() == 'отмена': bot.send_message(chat_id, "Действие отменено.") user_state_manager.set_state(chat_id, "SETTINGS_MENU") return show_settings_menu(chat_id) - # Проверка, что введённая строка содержит только цифры и запятые if not all(part.strip().isdigit() for part in message.text.split(',')): bot.send_message(chat_id, "Некорректный формат. Введите номера регионов через запятую.", reply_markup=markup) - # user_state_manager.set_state(chat_id, "WAITING_FOR_INPUT", - # extra_data={"cancel_message_id": sent_message.message_id}) bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription_button, chat_id, username) return - region_ids = message.text.split(',') valid_region_ids = [region[0] for region in get_user_subscribed_regions(chat_id)] - with db_lock: conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() - for region_id in region_ids: region_id = region_id.strip() - if region_id not in valid_region_ids: invalid_regions.append(region_id) continue - # Удаление подписки query = 'UPDATE subscriptions SET active = FALSE WHERE chat_id = ? AND region_id = ?' cursor.execute(query, (chat_id, region_id)) unsubbed_regions.append(region_id) conn.commit() - - # # Получаем ID сообщения с клавиатурой "Отмена" и скрываем её - # state_data = user_state_manager.get_state(chat_id) - # cancel_message_id = state_data.get_extra_data(chat_id) - - # if cancel_message_id: - # try: - # bot.edit_message_reply_markup(chat_id, cancel_message_id, reply_markup=None) - # except telebot.apihelper.ApiTelegramException as e: - # telebot.logger.error(f"Failed to edit message: {e}") - if len(invalid_regions) > 0: bot.send_message(chat_id, f"Регион с ID {', '.join(invalid_regions)} не найден в ваших подписках.") bot.send_message(chat_id, f"Отписка от регионов: {', '.join(unsubbed_regions)} выполнена.") @@ -670,6 +593,7 @@ def handle_cancel_action(call): show_settings_menu(chat_id) return + @bot.callback_query_handler(func=lambda call: call.data == "cancel_active_triggers") def handle_cancel_active_triggers(call): chat_id = call.message.chat.id @@ -680,13 +604,9 @@ def handle_cancel_active_triggers(call): user_state_manager.set_state(chat_id, "MAIN_MENU") show_main_menu(chat_id) return - ###################################################################################################################### -## help_Region_Manager -## -###################################################################################################################### - # Handle admin region management commands +###################################################################################################################### def handle_region_manager(chat_id: int, action: str): if action == 'add': bot.send_message(chat_id, "Введите ID и название региона в формате:\n ") @@ -694,10 +614,8 @@ def handle_region_manager(chat_id: int, action: str): elif action == 'remove': bot.send_message(chat_id, "Введите ID региона, который хотите сделать неактивным") bot.register_next_step_handler_by_chat_id(chat_id, process_remove_region) - ###################################################################################################################### -## help_Region_Manager -## +# Handle admin region management commands ###################################################################################################################### class RegionManager: def __init__(self, db_path): @@ -812,6 +730,7 @@ def handle_region_action(call): bot.send_message(chat_id, f"Регион {region_id} обновлен до {region_name} и активирован.") region_manager.log_event(chat_id, username, f"Admin replaced and reactivated region {region_id} - {region_name}") + telebot.logger.info(f"Admin {username} replaced and reactivated region {region_id} - {region_name}") user_state_manager.set_state(chat_id, "SETTINGS_MENU") @@ -819,11 +738,12 @@ def handle_region_action(call): region_manager.add_region(region_id, region_name) bot.send_message(chat_id, f"Регион {region_id} активирован.") region_manager.log_event(chat_id, username, f"Admin reactivated region {region_id} - {region_name}") + telebot.logger.info(f"Admin {username} activate {region_id} - {region_name}") user_state_manager.set_state(chat_id, "SETTINGS_MENU") elif action == "cancel_region": bot.send_message(chat_id, "Действие отменено.") - telebot.logger.info(f"Admin {username} canceled region action.") + telebot.logger.info(f"Admin {username} canceled region actions.") user_state_manager.set_state(chat_id, "SETTINGS_MENU") bot.edit_message_reply_markup(chat_id=chat_id, message_id=call.message.message_id, reply_markup=None) bot.answer_callback_query(call.id) @@ -840,6 +760,7 @@ def process_remove_region(message): if success: bot.send_message(chat_id, f"Регион {region_id} теперь неактивен, и все активные подписки обновлены.") region_manager.log_event(chat_id, username, f"Admin {username} deactivated region {region_id}") + telebot.logger.info(f"Admin {username} deactivated region {region_id}") user_state_manager.set_state(chat_id, "SETTINGS_MENU") show_settings_menu(chat_id) @@ -860,27 +781,31 @@ def process_remove_region(message): # Handle displaying active subscriptions for a user def handle_my_subscriptions_button(message): chat_id = message.chat.id + username = f"@{message.from_user.username}" if message.from_user.username else "N/A" if not is_whitelisted(chat_id): bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.") - telebot.logger.info(f"Unauthorized access attempt by {chat_id}") + telebot.logger.info(f"Unauthorized access attempt by {username} {chat_id}") return user_regions = get_user_subscribed_regions(chat_id) if not user_regions: bot.send_message(chat_id, "Вы не подписаны ни на один регион.") + telebot.logger.debug(f"Запрашиваем {user_regions} for {username} {chat_id}") else: user_regions.sort(key=lambda x: int(x[0])) # Сортировка по числовому значению region_id regions_list = format_regions_list(user_regions) bot.send_message(chat_id, f"Ваши активные подписки:\n{regions_list}") + telebot.logger.debug(f"Запрашиваем {user_regions} for {username} {chat_id}") show_settings_menu(chat_id) # Handle displaying all active regions def handle_active_regions_button(message): chat_id = message.chat.id + username = f"@{message.from_user.username}" if message.from_user.username else "N/A" if not is_whitelisted(chat_id): bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.") - telebot.logger.info(f"Unauthorized access attempt by {chat_id}") + telebot.logger.info(f"Unauthorized access attempt by {username} {chat_id}") return regions = get_sorted_regions() # Используем функцию для получения отсортированных регионов @@ -1010,18 +935,30 @@ def extract_region_number(host): def handle_notification_mode_button(message): chat_id = message.chat.id + username = f"@{message.from_user.username}" if message.from_user.username else "N/A" + + telebot.logger.debug(f"Handling notification mode button for user {username} ({chat_id}).") + if not is_whitelisted(chat_id): bot.send_message(chat_id, "Вы неавторизованы для использования этого бота") + telebot.logger.warning(f"Unauthorized access attempt by {username} ({chat_id})") return + # Логируем успешное авторизованное использование бота + telebot.logger.info(f"User {username} ({chat_id}) is authorized and is selecting a notification mode.") + + # Отправляем клавиатуру выбора режима уведомлений markup = types.InlineKeyboardMarkup() markup.add(types.InlineKeyboardButton(text="Критические события", callback_data="notification_mode_disaster")) markup.add(types.InlineKeyboardButton(text="Все события", callback_data="notification_mode_all")) - bot.send_message(chat_id, "Выберите уровень событий мониторинга, уведомление о которых хотите получать:\n" - '1. Критические события (приоритет "DISASTER") - события, являющиеся потенциальными авариями и требующие оперативного решения.\nВ Zabbix обязательно имеют тег "CALL" для оперативного привлечения инженеров к устранению.\n\n' - '2. Все события (По умолчанию) - критические события, а также события Zabbix высокого ("HIGH") приоритета, имеющие потенциально значительное влияние на сервис и требующее устранение в плановом порядке.', - reply_markup=markup,parse_mode="HTML") + bot.send_message(chat_id, + "Выберите уровень событий мониторинга, уведомление о которых хотите получать:\n" + '1. Критические события (приоритет "DISASTER") - события, являющиеся потенциальными авариями и требующие оперативного решения.\nВ Zabbix обязательно имеют тег "CALL" для оперативного привлечения инженеров к устранению.\n\n' + '2. Все события (По умолчанию) - критические события, а также события Zabbix высокого ("HIGH") приоритета, имеющие потенциально значительное влияние на сервис и требующее устранение в плановом порядке.', + reply_markup=markup, parse_mode="HTML") + + telebot.logger.info(f"Sent notification mode selection message to {username} ({chat_id}).") @bot.callback_query_handler(func=lambda call: call.data.startswith("notification_mode_")) @@ -1030,13 +967,17 @@ def handle_notification_mode_selection(call): message_id = call.message.message_id mode = call.data.split("_")[2] + telebot.logger.debug(f"User ({chat_id}) selected notification mode: {mode}.") + # Убираем клавиатуру bot.edit_message_reply_markup(chat_id=chat_id, message_id=message_id, reply_markup=None) + telebot.logger.debug(f"Removed inline keyboard for user ({chat_id}).") # Обновляем режим уведомлений disaster_only = True if mode == "disaster" else False try: + telebot.logger.debug(f"Attempting to update notification mode in the database for user {chat_id}.") with db_lock: conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() @@ -1046,15 +987,25 @@ def handle_notification_mode_selection(call): mode_text = "Критические события" if disaster_only else "Все события" bot.send_message(chat_id, f"Режим уведомлений успешно изменён на: {mode_text}") + telebot.logger.info(f"Notification mode for user ({chat_id}) updated to: {mode_text}") + + # Логируем изменение состояния пользователя user_state_manager.set_state(chat_id, "SETTINGS_MENU") + telebot.logger.debug(f"User state for {chat_id} set to SETTINGS_MENU.") + + # Показываем меню настроек show_settings_menu(chat_id) + telebot.logger.debug(f"Displayed settings menu to {chat_id}.") except Exception as e: telebot.logger.error(f"Error updating notification mode for {chat_id}: {e}") bot.send_message(chat_id, "Произошла ошибка при изменении режима уведомлений.") finally: conn.close() + telebot.logger.debug(f"Database connection closed for user {chat_id}.") + # Логируем успешный ответ callback-запроса bot.answer_callback_query(call.id) + telebot.logger.debug(f"Callback query for user ({chat_id}) answered.") @@ -1349,7 +1300,7 @@ def webhook(): if region_id is None: app.logger.error(f"Не удалось извлечь номер региона из host: {data.get('host')}") return jsonify({"status": "error", "message": "Invalid host format"}), 400 - app.logger.info(f"Извлечён номер региона: {region_id}") + app.logger.debug(f"Извлечён номер региона: {region_id}") # Запрос подписчиков для отправки уведомления в зависимости от уровня опасности if data['severity'] == '5': # Авария @@ -1361,7 +1312,7 @@ def webhook(): cursor.execute(query, (region_id,)) results = cursor.fetchall() - app.logger.info(f"Найдено подписчиков: {len(results)} для региона {region_id}") + app.logger.debug(f"Найдено подписчиков: {len(results)} для региона {region_id}") # Проверка статуса региона (активен или нет) query = 'SELECT active FROM regions WHERE region_id = ?' @@ -1369,7 +1320,7 @@ def webhook(): region_row = cursor.fetchone() if region_row and region_row[0]: # Если регион активен - app.logger.info(f"Регион {region_id} активен. Начинаем рассылку сообщений.") + app.logger.debug(f"Регион {region_id} активен. Начинаем рассылку сообщений.") message = format_message(data) undelivered = False @@ -1379,7 +1330,7 @@ def webhook(): app.logger.info(f"Отправка сообщения пользователю @{username} (chat_id={chat_id}) [{formatted_message}]") try: send_to_queue({'chat_id': chat_id, 'username': username, 'message': message}) - app.logger.info(f"Сообщение поставлено в очередь для {chat_id} (@{username})") + app.logger.debug(f"Сообщение поставлено в очередь для {chat_id} (@{username})") except Exception as e: app.logger.error(f"Ошибка при отправке сообщения для {chat_id} (@{username}): {e}") undelivered = True @@ -1392,7 +1343,7 @@ def webhook(): # Коммитим изменения в базе данных conn.commit() - app.logger.info("Изменения в базе данных успешно сохранены.") + app.logger.debug("Изменения в базе данных успешно сохранены.") conn.close() # Возвращаем успешный ответ @@ -1415,19 +1366,20 @@ def webhook(): def format_message(data): try: priority_map = { - '4': 'Высокая', - '5': 'Авария' + 'High': '⚠️', + 'Disaster': '⛔️' } - priority = priority_map.get(data['severity'], 'Неизвестно') + priority = priority_map.get(data['severity']) if data['status'].upper() == "PROBLEM": message = ( - f"⚠️ {data['host']} ({data['ip']})\n" + f"{priority} {data['host']} ({data['ip']})\n" f"Описание: {data['msg']}\n" - f"Критичность: {data['severity']}" + f"Критичность: {data['severity']}\n" + f"Время возникновения проблемы: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(data['date_reception'])))} Мск\n" ) if 'link' in data: - message += f'\nURL: Ссылка на график' + message += f'URL: Ссылка на график' return message else: message = ( @@ -1435,7 +1387,7 @@ def format_message(data): f"Описание: {data['msg']}\n" f"Критичность: {data['severity']}\n" f"Проблема устранена!\n" - f"Время устранения проблемы: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(data['date_reception'])))}\n" + f"Время устранения проблемы: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(data['date_reception'])))} Мск\n" ) if 'link' in data: message += f'URL: Ссылка на график'