#!/usr/bin/env python3 """ Мониторинг Redis Trigger в n8n Проверяет наличие подписчиков на канале ticket_form:description и отправляет алерт если подписчиков нет """ import redis import time import logging from datetime import datetime import sys # Настройки REDIS_HOST = "crm.clientright.ru" REDIS_PORT = 6379 REDIS_PASSWORD = "CRM_Redis_Pass_2025_Secure!" CHANNEL = "ticket_form:description" CHECK_INTERVAL = 60 # Проверка каждую минуту ALERT_THRESHOLD = 0 # Если подписчиков меньше этого значения - алерт logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('/var/www/fastuser/data/www/crm.clientright.ru/ticket_form/logs/n8n_redis_monitor.log'), logging.StreamHandler(sys.stdout) ] ) logger = logging.getLogger(__name__) def check_subscribers(): """Проверка количества подписчиков на канале""" try: r = redis.Redis( host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD, decode_responses=True, socket_connect_timeout=5, socket_timeout=5 ) # Проверка подключения r.ping() # Проверка подписчиков numsub = r.pubsub_numsub(CHANNEL) subscribers = numsub[0][1] if numsub else 0 logger.info(f"📊 Канал {CHANNEL}: {subscribers} подписчиков") if subscribers <= ALERT_THRESHOLD: logger.warning( f"⚠️ ВНИМАНИЕ: На канале {CHANNEL} нет подписчиков! " f"n8n workflow может быть неактивен или завис." ) return False return True except redis.ConnectionError as e: logger.error(f"❌ Ошибка подключения к Redis: {e}") return False except Exception as e: logger.error(f"❌ Неожиданная ошибка: {e}") return False finally: try: r.close() except: pass def send_test_message(): """Отправка тестового сообщения для проверки""" try: r = redis.Redis( host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD, decode_responses=True, socket_connect_timeout=5, socket_timeout=5 ) test_message = { "type": "test", "session_id": "monitor_test", "timestamp": datetime.utcnow().isoformat(), "message": "Health check from monitor script" } import json subscribers = r.publish(CHANNEL, json.dumps(test_message)) logger.info(f"📤 Тестовое сообщение отправлено. Получено подписчиками: {subscribers}") r.close() return subscribers > 0 except Exception as e: logger.error(f"❌ Ошибка отправки тестового сообщения: {e}") return False def main(): """Основной цикл мониторинга""" logger.info("🚀 Запуск мониторинга Redis Trigger для n8n") logger.info(f"📡 Канал: {CHANNEL}") logger.info(f"⏱️ Интервал проверки: {CHECK_INTERVAL} секунд") consecutive_failures = 0 max_failures = 3 # После 3 неудачных проверок подряд - критический алерт while True: try: is_ok = check_subscribers() if is_ok: consecutive_failures = 0 else: consecutive_failures += 1 if consecutive_failures >= max_failures: logger.critical( f"🚨 КРИТИЧЕСКОЕ СОСТОЯНИЕ: " f"Канал {CHANNEL} не имеет подписчиков уже {consecutive_failures} проверок подряд! " f"Требуется перезапуск n8n workflow!" ) # Можно добавить отправку уведомления (email, telegram, etc.) time.sleep(CHECK_INTERVAL) except KeyboardInterrupt: logger.info("⏹️ Остановка мониторинга по запросу пользователя") break except Exception as e: logger.error(f"❌ Критическая ошибка в цикле мониторинга: {e}") time.sleep(CHECK_INTERVAL) if __name__ == "__main__": main()