Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Куда отправлялись логи в PROD
Логирование в Production: общая архитектура
В production окружении логирование — это критический компонент системы мониторинга, позволяющий отслеживать проблемы, отлаживать ошибки и анализировать поведение приложения. Логи отправляются в специализированные системы хранения и анализа.
Типичная архитектура логирования в PROD
┌─────────────────┐
│ Java приложение │
│ (SLF4J) │
└────────┬─────────┘
│
┌────┴──────┬──────────┬─────────┐
│ │ │ │
▼ ▼ ▼ ▼
┌────────┐ ┌────────┐ ┌───────┐ ┌─────────┐
│ Console │ │Logback │ │Syslog │ │ HTTP │
└────────┘ └────────┘ └───────┘ └─────────┘
│ │ │ │
│ └────┬─────┘ │
│ │ │
│ ┌───────▼────────┐ │
│ │ Logstash / ELK │ │
│ │ (обработка) │ │
│ └────────┬───────┘ │
│ │ │
│ ┌─────────────┼──────────┐ │
│ │ │ │ │
▼ ▼ ▼ ▼ │
┌──────────────────────────────────┐ │
│ Elasticsearch (хранение индексов) │ │
│ Logstash (обработка) │ │
│ Kibana (визуализация) │ │
└──────────────────────────────────┘ │
│
┌─────────────────────────────────┘
│
▼
┌──────────────┐
│ CloudWatch │
│ (AWS) │
└──────────────┘
1. ELK Stack (Elasticsearch, Logstash, Kibana)
Это самая распространенная система логирования в production
// Конфигурация логирования с Logback
// logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS}
[%thread]
%-5level
%logger{36}
- %msg%n
</pattern>
</encoder>
</appender>
<!-- JSON appender для логстеша -->
<appender name="LOGSTASH"
class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>logstash.example.com:5000</destination>
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>
Процесс:
- Логи отправляются из приложения на Logstash
- Logstash обрабатывает, парсит и обогащает логи
- Логи сохраняются в Elasticsearch
- Kibana используется для поиска и анализа
- Alerting срабатывает при ошибках
// Использование в коде
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RestController
public class OrderController {
private static final Logger logger =
LoggerFactory.getLogger(OrderController.class);
@PostMapping("/orders")
public ResponseEntity<Order> createOrder(@RequestBody Order order) {
logger.info("Creating order with id: {}", order.getId());
try {
Order saved = orderService.save(order);
logger.info("Order created successfully: {}", saved.getId());
return ResponseEntity.ok(saved);
} catch (Exception e) {
logger.error("Error creating order: {}", order.getId(), e);
throw new RuntimeException(e);
}
}
}
2. Cloudwatch (AWS)
Для приложений, развернутых на AWS, логи отправляются в CloudWatch:
// Зависимость для AWS CloudWatch
// pom.xml
<dependency>
<groupId>software.amazon.awslogs</groupId>
<artifactId>aws-java-log-runtime-library</artifactId>
<version>1.0.0</version>
</dependency>
// logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="AWS_CLOUDWATCH"
class="software.amazon.awslogs.logback.LoggingEventAppender">
<logGroupName>/aws/ecs/my-app</logGroupName>
<logStreamName>production</logStreamName>
<region>eu-west-1</region>
</appender>
<root level="INFO">
<appender-ref ref="AWS_CLOUDWATCH"/>
</root>
</configuration>
Процесс:
- Приложение отправляет логи в CloudWatch
- CloudWatch группирует логи по логирующим группам
- Можно искать логи через AWS консоль
- Cloudwatch Logs Insights для анализа
- CloudWatch Alarms срабатывают при ошибках
3. Google Cloud Logging (GCP)
// logback-spring.xml для GCP
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CLOUD_LOGGING_APPENDER"
class="com.google.cloud.logging.logback.CloudLoggingAppender">
<projectId>my-gcp-project</projectId>
<resourceType>gae_app</resourceType>
<log>projects/my-gcp-project/logs/my-app</log>
</appender>
<root level="INFO">
<appender-ref ref="CLOUD_LOGGING_APPENDER"/>
</root>
</configuration>
4. Splunk
Enterprise решение для больших объемов данных
// Logback configuration для Splunk
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="SPLUNK"
class="com.splunk.logging.HttpEventCollectorLogbackAppender">
<token>YOUR_HEC_TOKEN</token>
<url>https://splunk.example.com:8088</url>
<host>myapp-01</host>
<source>java-application</source>
<sourcetype>java</sourcetype>
</appender>
<root level="INFO">
<appender-ref ref="SPLUNK"/>
</root>
</configuration>
5. Prometheus + Loki
Современный стек для микросервисов
// Конфигурация для отправки метрик в Prometheus
public class MetricsConfiguration {
@Bean
public MeterRegistry meterRegistry() {
return new PrometheusMeterRegistry(
PrometheusConfig.DEFAULT
);
}
}
// Использование
@Component
public class OrderMetrics {
private final MeterRegistry meterRegistry;
public OrderMetrics(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
public void recordOrderCreated() {
meterRegistry.counter("orders.created").increment();
}
}
6. Syslog
Классический протокол для системных логов
// logback-spring.xml с Syslog
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="SYSLOG"
class="ch.qos.logback.classic.net.SyslogAppender">
<syslogHost>syslog.example.com</syslogHost>
<port>514</port>
<facility>LOCAL7</facility>
<suffixPattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg</suffixPattern>
</appender>
<root level="INFO">
<appender-ref ref="SYSLOG"/>
</root>
</configuration>
Таблица популярных решений
| Система | Компания | Использование | Масштаб | Стоимость |
|---|---|---|---|---|
| ELK Stack | Elastic | Самостоящая | Маленькие/средние | Бесплатно |
| CloudWatch | AWS | На AWS инстансах | Любой | Per GB |
| Cloud Logging | GCP | На GCP инстансах | Любой | Per GB |
| Azure Monitor | Microsoft | На Azure | Любой | Per GB |
| Splunk | Splunk | Enterprise | Очень крупные | Дорого |
| Sumologic | Sumo Logic | Cloud | Средние/крупные | SaaS |
| Datadog | Datadog | Cloud + metrics | Средние/крупные | SaaS |
| Loki | Grafana | На K8s | Маленькие/средние | Бесплатно |
Пример полной конфигурации Spring Boot
// application-prod.yml
logging:
level:
root: INFO
com.myapp: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
file:
name: /var/log/myapp/app.log
max-size: 100MB
max-history: 30
spring:
application:
name: my-app
profiles:
active: prod
// logback-spring-prod.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<springProfile name="prod">
<!-- Файловый логгер -->
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/var/log/myapp/app.log</file>
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS}
[%thread]
%-5level
%logger{36}
- %msg%n
</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
/var/log/myapp/app-%d{yyyy-MM-dd}.%i.log.gz
</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<!-- Logstash JSON appender -->
<appender name="LOGSTASH"
class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${LOGSTASH_HOST:logstash}:5000</destination>
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>
<root level="INFO">
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</springProfile>
</configuration>
Лучшие практики
public class LoggingBestPractices {
private static final Logger logger =
LoggerFactory.getLogger(LoggingBestPractices.class);
// ✅ Правильное логирование
public void goodLogging() {
logger.debug("Processing order: {}", orderId);
logger.info("Order processed successfully");
logger.warn("Order delay: {}ms", delayTime);
logger.error("Order processing failed", exception);
}
// ❌ Неправильное логирование
public void badLogging() {
// Не используй строковую конкатенацию
// logger.debug("Processing order: " + orderId);
// Не логируй конфиденциальные данные
// logger.info("User password: " + password);
// Не логируй слишком много информации
// logger.info(entireObject.toString());
}
}
Заключение
В production окружении логи отправляются в специализированные системы хранения:
- ELK Stack — самый популярный выбор для самостоящих решений
- CloudWatch — если приложение на AWS
- Google Cloud Logging — если приложение на GCP
- Splunk — для очень крупных систем с большими объемами
- Loki + Prometheus — для Kubernetes окружений
Основной принцип: логи никогда не остаются только на диске приложения — они отправляются в централизованное хранилище для анализа, поиска и мониторинга. Это позволяет:
- Отслеживать проблемы в реальном времени
- Анализировать логи с разных инстансов вместе
- Устанавливать алерты при ошибках
- Хранить логи дольше, чем на самом сервере