Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Ответ
Как осмотреть логи в Java приложении
Логирование критично для отладки и мониторинга. Рассмотрю инструменты, форматы и стратегии анализа логов.
1. Структура лога — что смотреть
2024-03-22 10:45:32.123 [main] INFO com.example.UserService - User registered: user123
└─ Timestamp └─ Thread └─ Level └─ Logger Name └─ Message
В каждом логе содержится:
- Timestamp — когда произошло
- Thread — в каком потоке
- Level — критичность (TRACE, DEBUG, INFO, WARN, ERROR, FATAL)
- Logger name — откуда логируется (класс)
- Message — что произошло
- Exception — стек трассировки ошибки (если есть)
2. Файлы логов — где их найти
# Spring Boot приложение
/var/log/myapp.log # На production сервере
logs/spring.log # В директории приложения
# Docker контейнер
docker logs <container-id> # Выводит логи контейнера
docker logs -f <container-id> # Следить за логами в реальном времени
# Kubernetes pod
kubectl logs <pod-name> # Логи пода
kubectl logs -f <pod-name> # Tail логи
kubectl logs --previous <pod-name> # Логи предыдущего пода (если переставал работать)
3. Чтение логов — команды Linux
# Показать последние 50 строк
tail -n 50 myapp.log
# Следить за логами в реальном времени
tail -f myapp.log
# Показать последние 100 строк по времени
tail -f myapp.log | grep "2024-03-22 10:45"
# Поиск по уровню логирования
grep "ERROR" myapp.log
grep "WARN" myapp.log
# Поиск по классу
grep "com.example.UserService" myapp.log
# Показать ошибки за последний час
grep "ERROR" myapp.log | tail -100
# Просмотр стека ошибки
grep -A 20 "Exception" myapp.log # -A 20: 20 строк после совпадения
# Подсчёт ошибок
grep -c "ERROR" myapp.log
4. Анализ ошибок — типичные паттерны
# NullPointerException
grep "NullPointerException" myapp.log
# Ищем что привело: обычно строка перед исключением
grep -B 5 "NullPointerException" myapp.log
# Database connection errors
grep -i "connection" myapp.log | grep "ERROR"
# Out of Memory
grep "OutOfMemoryError" myapp.log
# Timeout errors
grep -i "timeout\|timed out" myapp.log
# HTTP errors
grep "500\|503\|502" myapp.log # Server errors
grep "404\|401\|403" myapp.log # Client errors
5. Программное чтение логов в Java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Service
public class UserService {
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
public void registerUser(User user) {
logger.info("Starting user registration: {}", user.getEmail());
try {
userRepository.save(user);
logger.info("User registered successfully: {}", user.getId());
} catch (Exception e) {
logger.error("Failed to register user: {}", user.getEmail(), e);
// e — исключение автоматически добавит stack trace
}
}
}
Вывод:
2024-03-22 10:45:32 INFO com.example.UserService - Starting user registration: user@example.com
2024-03-22 10:45:33 INFO com.example.UserService - User registered successfully: 123
# Если ошибка:
2024-03-22 10:46:00 ERROR com.example.UserService - Failed to register user: other@example.com
java.sql.SQLException: Connection timeout
at com.example.db.Database.connect(Database.java:45)
at com.example.repo.UserRepository.save(UserRepository.java:32)
...
6. Логирование на разных уровнях
public class ApplicationService {
private static final Logger logger = LoggerFactory.getLogger(ApplicationService.class);
public void processOrder(Order order) {
// TRACE — самый подробный (обычно отключен)
logger.trace("Entering processOrder with order: {}", order);
// DEBUG — для разработчиков при отладке
logger.debug("Order validation started");
if (order.isValid()) {
// INFO — важные события
logger.info("Order processed successfully: orderId={}", order.getId());
} else {
// WARN — что-то неправильно, но приложение продолжает работу
logger.warn("Order validation failed: orderId={}, reason={}",
order.getId(), order.getValidationErrors());
}
try {
saveOrder(order);
} catch (DatabaseException e) {
// ERROR — ошибка, которая повлияет на функциональность
logger.error("Failed to save order: orderId={}", order.getId(), e);
}
}
}
7. Конфигурация уровней логирования (logback.xml)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_FILE" value="logs/application.log"/>
<!-- Appender: куда писать логи -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}</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>${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<!-- Console appender для разработки -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Уровни логирования по пакетам -->
<logger name="com.example.myapp" level="DEBUG"/>
<logger name="org.springframework" level="INFO"/>
<logger name="org.hibernate" level="WARN"/>
<root level="INFO">
<appender-ref ref="FILE"/>
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
8. Поиск проблем в логах — стратегия
# 1. Поиск по времени проблемы
# Пользователь сообщил об ошибке в 10:45
grep "2024-03-22 10:4[0-5]" myapp.log | grep "ERROR"
# 2. Поиск связанных логов (trace ID)
# Современные системы используют trace ID
grep "traceId=abc123def456" myapp.log
# 3. Поиск истории пользователя
grep "userId=123" myapp.log
# 4. Полный стек ошибки
grep -A 30 "java.lang.NullPointerException" myapp.log
# 5. Периодические ошибки
grep "Timeout" myapp.log | wc -l # Количество ошибок
grep "Timeout" myapp.log | tail -20 # Последние 20
9. Best Practices для логирования
// ✅ ПРАВИЛЬНО
logger.info("Order created: orderId={}, userId={}, amount={}",
order.getId(), order.getUserId(), order.getAmount());
// ✅ Используй placeholders вместо конкатенации
logger.debug("Processing user: {}", user);
// ❌ НЕ ДЕЛАЙ
logger.info("Order created: " + order.getId()); // Строка создаётся всегда
logger.debug("Debug: " + expensiveFunction()); // Вызывается даже если DEBUG отключен
// ✅ Ленивое вычисление для дорогих операций
if (logger.isDebugEnabled()) {
logger.debug("Data: {}", expensiveOperation());
}
// ✅ Логируй исключения
try {
doSomething();
} catch (Exception e) {
logger.error("Failed to do something", e); // e добавит stack trace
}
10. Инструменты для анализа логов
| Инструмент | Использование |
|---|---|
| grep | Поиск по паттерну (быстро) |
| tail -f | Следить за логами в реальном времени |
| ELK Stack | Elasticsearch + Logstash + Kibana (большие приложения) |
| Splunk | Централизованный анализ логов |
| DataDog | Мониторинг логов и метрик |
| CloudWatch | AWS логи |
| awk/sed | Обработка и фильтрация логов |
Краткая стратегия:
- Найди временной период проблемы
- Ищи ERROR/WARN в этом диапазоне
- Посмотри на исключения и stack trace
- Проследи цепочку событий перед ошибкой
- Проверь конфигурацию и ресурсы сервера