Initial commit: Message Gateway project

- FastAPI приложение для отправки мониторинговых алертов в мессенджеры
- Поддержка Telegram и MAX/VK
- Интеграция с Grafana, Zabbix, AlertManager
- Автоматическое создание тикетов в Jira
- Управление группами мессенджеров через API
- Декораторы для авторизации и скрытия эндпоинтов
- Подробная документация в папке docs/

Автор: Сергей Антропов
Сайт: https://devops.org.ru
This commit is contained in:
2025-11-12 20:25:11 +03:00
commit b90def35ed
72 changed files with 10609 additions and 0 deletions

0
app/common/__init__.py Normal file
View File

34
app/common/cors.py Normal file
View File

@@ -0,0 +1,34 @@
"""
Настройка CORS для приложения.
Автор: Сергей Антропов
Сайт: https://devops.org.ru
"""
import logging
from fastapi.middleware.cors import CORSMiddleware
from typing import List
from app.core.config import settings
logger = logging.getLogger(__name__)
def add(app):
"""
Добавить CORS middleware к приложению FastAPI.
Args:
app: Экземпляр приложения FastAPI.
"""
# Разрешаем все источники (можно настроить через переменные окружения)
allow_origins: List[str] = ["*"]
app.add_middleware(
CORSMiddleware,
allow_origins=allow_origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
logger.info("CORS middleware добавлен")

41
app/common/logger.py Normal file
View File

@@ -0,0 +1,41 @@
"""
Настройка логирования приложения.
Автор: Сергей Антропов
Сайт: https://devops.org.ru
"""
import logging
import os
from opentelemetry.instrumentation.logging import LoggingInstrumentor
# Настраиваем уровень логирования сначала
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Настройка логирования с поддержкой OpenTelemetry
try:
from app.core.config import settings
if settings.otel_enabled:
LoggingInstrumentor().instrument(
set_logging_format=True,
logging_format='%(levelname)s:\t %(message)s traceID=%(otelTraceID)s spanID=%(otelSpanID)s'
)
logger.info("OpenTelemetry логирование включено")
else:
LoggingInstrumentor().instrument(
set_logging_format=True,
logging_format='%(levelname)s:\t %(message)s'
)
except Exception as e:
logger.warning(f"Ошибка настройки OpenTelemetry логирования: {e}")
# Используем базовое логирование
LoggingInstrumentor().instrument(
set_logging_format=True,
logging_format='%(levelname)s:\t %(message)s'
)

32
app/common/metrics.py Normal file
View File

@@ -0,0 +1,32 @@
from prometheus_client import make_asgi_app, Counter, Gauge, CollectorRegistry, push_to_gateway # Добавляем метрики для прометея
from fastapi import Request
import os
#def add_middleware(app):
# # Обьявляем метрики, которые будем собирать
# registry = getMetricsRegistry()
# all_requests = Counter('tg_monitoring_gateway_all_requests_counter', 'Счетчик запросов', registry=registry)
# # Запускаем счетчик запросов
# @app.middleware("request_count")
# def request_count(request: Request, call_next):
# all_requests.inc()
# pushMetricsRegistry(registry, all_requests)
# response = call_next(request)
# return response
#def getMetricsRegistry():
# registry = CollectorRegistry()
# return(registry)
#def pushMetricsRegistry(registry, metric):
# pushgateway_url = os.getenv('PUSHGATEWAY_URL')
# pushgateway_job = os.getenv('PUSHGATEWAY_JOB')
# push_to_gateway(pushgateway_url, job=pushgateway_job, registry=registry)
# return(metric)
#def requestsCount(registry, endpoint):
# all_requests = Counter('tg_monitoring_gateway_api_requests_counter', 'Счетчик запросов к API', labelnames=['endpoint'], registry=registry)
# all_requests.labels(endpoint=endpoint).inc()
# pushMetricsRegistry(registry, all_requests)
# return(endpoint)

69
app/common/telemetry.py Normal file
View File

@@ -0,0 +1,69 @@
"""
Настройка телеметрии OpenTelemetry.
Автор: Сергей Антропов
Сайт: https://devops.org.ru
"""
import logging
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource, SERVICE_NAME
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.sampling import TraceIdRatioBased
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
logger = logging.getLogger(__name__)
def setup_telemetry():
"""
Настройка провайдера телеметрии OpenTelemetry.
Returns:
TracerProvider: Провайдер трейсинга.
"""
from app.core.config import settings
resource = Resource(attributes={SERVICE_NAME: settings.otel_service_name})
sampler = TraceIdRatioBased(1.0) # 100% семплирование
# Настройка экспортера OTLP
exporter_config = {}
if settings.otel_exporter_otlp_endpoint:
exporter_config['endpoint'] = settings.otel_exporter_otlp_endpoint
exporter_config['insecure'] = settings.otel_exporter_otlp_insecure
exporter = OTLPSpanExporter(**exporter_config)
provider = TracerProvider(sampler=sampler, resource=resource)
processor = SimpleSpanProcessor(exporter)
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
logger.info(f"Telemetry настроен для сервиса: {settings.otel_service_name}")
return provider
def add(app):
"""
Добавить инструментацию OpenTelemetry к приложению FastAPI.
Args:
app: Экземпляр приложения FastAPI.
"""
from app.core.config import settings
if settings.otel_enabled:
try:
tracer_provider = setup_telemetry()
FastAPIInstrumentor.instrument_app(
app,
tracer_provider=tracer_provider,
excluded_urls="/openapi.json,/docs,/redoc"
)
logger.info("OpenTelemetry инструментация добавлена")
except Exception as e:
logger.error(f"Ошибка настройки OpenTelemetry: {e}")
else:
logger.info("OpenTelemetry отключен")