Files
crm.clientright.ru/ticket_form/monitor_n8n_redis_trigger.py
Fedor 52fe013375 feat(ticket_form): unified_id/contact_id передача, исправлен мерж сессии, новая сессия для жалобы
- Добавлены unified_id и contact_id в TicketFormDescriptionRequest
- Исправлен CODE_MERGE_PROJECT_TO_SESSION.js - теперь сохраняются ВСЕ данные из body.other
- Добавлен fallback на получение other из Webhook напрямую
- Генерация новой session_id при создании новой жалобы (сохраняя авторизацию)
- Добавлен SQL_SELECT_CONTACT_WITH_CUSTOM_FIELDS.sql для CRM контактов
- Создан SESSION_LOG_2025-11-25.md с документацией сессии
2025-11-25 20:02:21 +03:00

145 lines
5.0 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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()