← Назад к вопросам

С чего начнешь осмотр лога

2.3 Middle🔥 171 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Методология анализа логов в Java приложениях

Осмотр логов — это критичный навык для debug и troubleshooting в production. Правильный подход экономит часы времени. Разберём систематический процесс.

Шаг 1: Определение временного окна (Time Window)

Сначала нужно понять, когда произошла проблема.

# Ищем ERROR логи
grep ERROR app.log | head -20

# Смотрим последние логи
tail -100 app.log

# Логи в определённом временном диапазоне
grep "2024-03-22 14:3[0-9]" app.log

Вопросы для себя:

  • Когда произошла ошибка?
  • Это недавнее явление или долгое время?
  • Есть ли паттерн? (каждый час, случайно, после деплоя?)

Шаг 2: Уровни логирования (ERROR -> WARN -> INFO -> DEBUG)

# Сначала смотрим только ERRORS - это критичные проблемы
grep "ERROR" app.log | tail -50

# Затем добавляем WARNING для полной картины
grep -E "ERROR|WARN" app.log | tail -100

# Потом смотрим INFO для контекста
grep -E "ERROR|WARN|INFO" app.log

# DEBUG только если нужна очень детальная информация
grep "DEBUG" app.log

Иерархия критичности:

ERROR (критично) > WARN (предупреждение) > INFO (информация) > DEBUG (детали)

Шаг 3: Stack trace анализ

Stack trace содержит самую ценную информацию.

# Выводим стек трейс с контекстом
grep -A 20 "Exception" app.log

# Ищем конкретное исключение
grep "NullPointerException" app.log -A 10
grep "OutOfMemoryError" app.log -A 5
grep "SQLException" app.log -A 15

Что анализировать в stack trace:

java.lang.NullPointerException: Cannot read field "value" because "obj" is null
    at com.example.UserService.processUser(UserService.java:42)
    at com.example.UserController.handleRequest(UserController.java:15)
    at java.lang.Thread.run(Thread.java:834)
  1. Тип исключения — NullPointerException
  2. Сообщение об ошибке — "Cannot read field..."
  3. Место возникновения — UserService.java:42 (самое важное!)
  4. Цепочка вызовов — откуда была вызвана функция

Шаг 4: Контекст вокруг ошибки

# Смотрим логи ДО ошибки для контекста
grep -B 20 "ERROR" app.log | tail -30

# Ищем первый признак проблемы
grep -B 10 -A 10 "java.lang.OutOfMemoryError" app.log

Ищите:

  • Какой запрос был обработан до ошибки?
  • Какое состояние приложения?
  • Есть ли предупреждения (WARN) перед ошибкой?

Шаг 5: Поиск паттернов и повторений

# Считаем количество конкретных ошибок
grep "SQLException" app.log | wc -l
grep "ConnectionTimeout" app.log | wc -l

# Смотрим, какие ошибки встречаются чаще всего
grep "ERROR" app.log | cut -d':' -f2 | sort | uniq -c | sort -rn

# Ищем повторяющиеся паттерны
grep "Transaction rolled back" app.log

Шаг 6: Анализ производительности через логи

# Ищем медленные запросы
grep "executed in [0-9][0-9][0-9][0-9]ms" app.log

# Ищем запросы дольше 5 секунд
grep -E "executed in [0-9]{4,}ms" app.log

# Анализируем утечки памяти
grep "GC overhead limit exceeded" app.log
grep "Full garbage collection" app.log

Практический пример анализа

# 1. Смотрим последние 100 строк
tail -100 app.log

# 2. Видим ERROR - смотрим стек трейс
grep -A 15 "2024-03-22 14:35:42" app.log

# 3. Находим NullPointerException в UserService.java:42
# 4. Смотрим исходный код строки 42
vim src/main/java/com/example/UserService.java +42

# 5. Анализируем логику - видим, что obj может быть null
# 6. Смотрим логи ДО ошибки для контекста
grep -B 30 "NullPointerException" app.log

# 7. Находим, что перед ошибкой был запрос с пустым параметром
# 8. Исправляем код - добавляем null check

if (obj == null) {
    logger.warn("Object is null, skipping processing");
    return;
}

Шаг 7: Связь с БД и внешними сервисами

# Ищем ошибки БД
grep "SQLException\|Connection refused\|Connection timeout" app.log

# Анализируем проблемы сетевого взаимодействия
grep "IOException\|SocketTimeoutException\|ConnectException" app.log

# Ищем проблемы с внешними API
grep "HTTP 500\|HTTP 503\|Connection refused" app.log

Шаг 8: Проверка конфигурации

# Смотрим, какие конфигурации были загружены
grep "Configuration loaded\|Property:" app.log

# Проверяем переменные окружения
grep "Environment:" app.log

# Ищем WARNING о неправильной конфигурации
grep "WARN.*Configuration" app.log

Инструменты для анализа логов

Command-line инструменты:

# grep - поиск
grep "ERROR" app.log

# tail/head - начало/конец файла
tail -f app.log  # real-time логи

# awk - обработка строк
awk -F'\\[' '{print $2}' app.log | sort | uniq -c

# sed - поиск и замена
sed -n '100,200p' app.log  # строки 100-200

# wc - счёт
grep "ERROR" app.log | wc -l

Специализированные инструменты:

  • ELK Stack (Elasticsearch, Logstash, Kibana) — для распределённого логирования
  • Splunk — коммерческий анализ логов
  • Datadog — мониторинг и анализ
  • Graylog — центральный репозиторий логов
  • AWK, Sed — для Unix обработки

Чеклист анализа логов

[ ] Определил точное время проблемы
[ ] Нашёл ERROR/EXCEPTION в логах
[ ] Прочитал полный stack trace
[ ] Определил точный файл и строку кода
[ ] Посмотрел логи ДО ошибки для контекста
[ ] Проверил, повторяется ли ошибка
[ ] Проанализировал логи БД и внешних сервисов
[ ] Проверил конфигурацию
[ ] Смотрел производительность (GC, memory, slow queries)
[ ] Воспроизвел проблему локально

Типичные ошибки при анализе логов

  1. Смотришь только окончание лога — нужен контекст ДО ошибки
  2. Игнорируешь WARN — часто это предупреждение о проблеме
  3. Не ищешь корневую причину — stack trace показывает следствие
  4. Не проверяешь конфигурацию — неправильные env переменные частая причина
  5. Не анализируешь производительность — OutOfMemory часто предшествуют другие признаки

Систематический подход к анализу логов превращает хаос непонятных ошибок в чёткую цепь причин и следствий. Главное — начинать с ERROR, смотреть stack trace, анализировать контекст и всегда искать корневую причину, а не симптом.