6.7 KiB
6.7 KiB
📋 Логирование
Стек технологий
| Компонент | Технология |
|---|---|
| Фасад | SLF4J (org.slf4j.Logger) |
| Реализация | Logback (поставляется с spring-boot-starter-web) |
| Конфигурация | Стандартная Spring Boot (без кастомного logback.xml) |
| Экспорт (прод) | OpenTelemetry Java Agent → OTLP → SigNoz |
| Контекст тенанта | SLF4J MDC (tenant.id) |
Архитектура
graph LR
Code["Java-код<br/>log.info(...)"] --> SLF4J["SLF4J API"]
SLF4J --> Logback["Logback"]
Logback -->|"Локальная разработка"| Console["stdout / stderr"]
Logback -->|"Продакшн"| OTelAgent["OTel Java Agent<br/>(Logback Appender)"]
OTelAgent -->|"OTLP HTTP"| SigNoz["SigNoz"]
Локальная разработка
Логи выводятся в stdout контейнера в стандартном формате Spring Boot:
2026-03-22 12:00:00.123 INFO 1 --- [main] c.m.app.config.DataInitializer : Initializing databases for 1 tenant(s)...
Просмотр логов:
docker compose logs -f backend
Продакшн (Kubernetes)
OpenTelemetry Java Agent подключается как -javaagent в Dockerfile и автоматически перехватывает логи Logback, экспортируя их в SigNoz по OTLP.
ENTRYPOINT ["java", "-javaagent:opentelemetry-javaagent.jar", "-jar", "app.jar"]
Конфигурация агента задаётся через переменные окружения в backend.yaml:
| Переменная | Значение | Назначение |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT |
http://192.168.1.100:4318 |
Адрес SigNoz Collector |
OTEL_SERVICE_NAME |
magistr-backend |
Имя сервиса в SigNoz |
OTEL_RESOURCE_ATTRIBUTES |
deployment.environment=default |
Окружение |
OTEL_LOGS_EXPORTER |
otlp |
Экспорт логов через OTLP |
OTEL_METRICS_EXPORTER |
otlp |
Экспорт метрик через OTLP |
OTEL_TRACES_EXPORTER |
otlp |
Экспорт трейсов через OTLP |
OTEL_INSTRUMENTATION_LOGBACK_APPENDER_EXPERIMENTAL_CAPTURE_MDC_ATTRIBUTES |
tenant.id |
Захват MDC-атрибута в логи |
Note
В локальной разработке OpenTelemetry Agent также встроен в Docker-образ, но без переменных
OTEL_*он работает в режиме noop — логи идут только в stdout.
Мультитенантный контекст (MDC)
Каждый HTTP-запрос обогащается tenant ID через TenantInterceptor:
// preHandle — при входе запроса
MDC.put("tenant.id", tenant);
Span.current().setAttribute("tenant.id", tenant);
// afterCompletion — после завершения
MDC.remove("tenant.id");
Это позволяет:
- Фильтровать логи по тенанту в SigNoz
- Коррелировать логи с трейсами через Span-атрибуты
- Идентифицировать, к какому университету относится каждая запись
Использование в коде
Классы с логированием
| Класс | Уровни | Что логируется |
|---|---|---|
TenantInterceptor |
DEBUG, WARN | Резолвинг тенанта, неизвестный тенант (404) |
TenantDataSourceConfig |
INFO, WARN, ERROR | Загрузка тенантов, fallback на H2 |
TenantRoutingDataSource |
INFO, WARN | Добавление/удаление тенантов, тест соединения |
TenantConfigWatcher |
INFO, ERROR, WARN | Изменения ConfigMap, Flyway миграции |
ConfigMapUpdater |
INFO, WARN, ERROR | Обновление ConfigMap в K8s |
DataInitializer |
INFO | Инициализация БД при старте |
LessonsController |
INFO, DEBUG, ERROR | CRUD-операции с занятиями, валидация |
Паттерн использования
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyClass {
private static final Logger log = LoggerFactory.getLogger(MyClass.class);
public void doSomething() {
log.info("Операция выполнена: param={}", value);
log.error("Ошибка: {}", e.getMessage(), e); // со стектрейсом
}
}
Рекомендации по уровням
| Уровень | Когда использовать |
|---|---|
ERROR |
Необработанные ошибки, сбои подключения к БД, провалы миграций |
WARN |
Неизвестный тенант, нет конфигурации, fallback-сценарии |
INFO |
Успешные операции, CRUD-действия, старт/стоп компонентов |
DEBUG |
Детали резолвинга тенанта, ping-запросы |
Настройка уровня логирования
В application.properties (по умолчанию закомментировано):
# Включить DEBUG для всего приложения
#logging.level.root=DEBUG
# Только для пакета приложения
logging.level.com.magistr.app=DEBUG
# Только для конкретного класса
logging.level.com.magistr.app.config.tenant.TenantInterceptor=DEBUG
Также можно задавать через переменные окружения:
LOGGING_LEVEL_ROOT=DEBUG
LOGGING_LEVEL_COM_MAGISTR_APP=DEBUG
Просмотр логов
Локально (Docker Compose)
# Все логи backend
docker compose logs -f backend
# Фильтрация по ключевому слову
docker compose logs -f backend | grep "tenant"
Продакшн (SigNoz)
Логи доступны в веб-интерфейсе SigNoz → раздел Logs:
- Фильтрация по
service.name = magistr-backend - Фильтрация по
tenant.id(из MDC) - Корреляция с трейсами через общий
trace_id