Настройка логов сайта: мониторинг и анализ ошибок в 2026

Логи сайта — это как чёрный ящик самолёта: когда всё работает, на них мало кто обращает внимание, но когда случается сбой, именно они становятся единственным источником правды о том, что пошло не так. За 10+ лет работы я видел сотни ситуаций, когда правильно настроенные логи спасали проекты от многочасовых простоев.

Зачем нужны логи сайта и что они дают

Честно говоря, многие владельцы сайтов даже не знают о существовании логов. А зря. На моей практике был случай с интернет-магазином на Битриксе — клиент жаловался на странные проблемы с оплатой. Пользователи добавляли товары в корзину, но оплата периодически не проходила. Без логов мы бы искали проблему неделями.

Логи сайта — это детализированные записи всех событий, происходящих на сервере. Они фиксируют каждый запрос к сайту, каждую ошибку PHP, каждое обращение к базе данных. И вот что они дают в реальной работе:

У одного клиента на WordPress был интересный случай. Сайт периодически выдавал ошибку 500, но только для определённых страниц и только в определённое время. Оказалось, что плагин для бэкапов запускался каждые 6 часов и создавал такую нагрузку на базу данных, что некоторые запросы не успевали выполниться в отведённое время. Без логов мы бы никогда не связали эти события.

ℹ️
Важно: Логи потребляют дисковое пространство. На высоконагруженных проектах размер логов может достигать нескольких гигабайт в день. Обязательно настройте ротацию логов!

Типы логов веб-сервера и их назначение

В веб-разработке используется несколько типов логов, каждый из которых решает свои задачи. Я всегда настраиваю их все — лучше иметь больше информации, чем её недостаток.

Access логи (журнал доступа)

Это основной тип логов, который ведёт веб-сервер. В них записывается каждый HTTP-запрос к сайту. Стандартный формат для Apache выглядит так:

127.0.0.1 - - [25/Dec/2026:10:00:23 +0000] "GET /blog/nastroika-logov/ HTTP/1.1" 200 2048 "https://google.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"

Здесь видно IP-адрес, время запроса, URL, код ответа, размер ответа, реферер и user-agent. Эти данные золотая жила для анализа.

Error логи (журнал ошибок)

В error логах записываются все ошибки сервера: проблемы с конфигурацией, недоступные файлы, ошибки PHP. Пример записи:

[Wed Dec 25 10:00:23.123456 2026] [php7:error] [pid 12345] [client 192.168.1.100:54321] PHP Fatal error: Uncaught Error: Call to undefined function mysql_connect() in /var/www/html/old_script.php:15

На практике именно error логи помогают быстрее всего найти причину проблем. Когда клиент говорит "сайт не работает", я первым делом смотрю в error лог.

Логи приложений (PHP, MySQL, Redis)

Помимо веб-сервера, логи ведут и другие компоненты:

Был случай на Laravel-проекте — сайт стал тормозить после обновления с PHP 8.1 на 8.2. В логах PHP нашёл deprecated warnings, которые генерировались тысячами раз в минуту. Оказалось, что одна библиотека использовала устаревший синтаксис, и хотя сайт работал, каждое предупреждение записывалось в лог, создавая дополнительную нагрузку.

Настройка логов в Apache и Nginx

Грубо говоря, из коробки логи настроены плохо. Стандартные настройки подходят разве что для тестовых серверов. На продакшене я всегда переделываю конфигурацию под конкретные задачи.

Настройка логов в Apache

В Apache логи настраиваются через директивы в конфигурационном файле или в .htaccess. Вот моя рабочая конфигурация для виртуального хоста:

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html
    
    # Кастомный формат логов с дополнительной информацией
    LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" %D %{X-Forwarded-For}i" combined_custom
    
    # Access лог с ротацией по дням
    CustomLog "| /usr/bin/rotatelogs /var/log/apache2/example.com_access_%Y%m%d.log 86400" combined_custom
    
    # Error лог с уровнем детализации
    ErrorLog /var/log/apache2/example.com_error.log
    LogLevel warn
    
    # Отдельный лог для медленных запросов (>2 секунд)
    SetEnvIf Response-Time "^[2-9][0-9]{3}" slow_request
    CustomLog /var/log/apache2/example.com_slow.log combined_custom env=slow_request
</VirtualHost>

В этой конфигурации добавлен параметр %D, который показывает время выполнения запроса в микросекундах. Очень полезно для поиска узких мест.

Настройка логов в Nginx

В Nginx я предпочитаю более детальную настройку. Вот конфигурация, которую использую на большинстве проектов:

http {
    # Кастомный формат лога с временем выполнения
    log_format detailed '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" '
                       '$request_time $upstream_response_time '
                       '$http_x_forwarded_for';
    
    # Формат для API запросов
    log_format api_log '$remote_addr - [$time_local] "$request" '
                      '$status $body_bytes_sent $request_time '
                      '"$http_user_agent" "$request_body"';
    
    server {
        listen 80;
        server_name example.com;
        root /var/www/html;
        
        # Основной access лог
        access_log /var/log/nginx/example.com_access.log detailed;
        
        # Error лог с детализацией
        error_log /var/log/nginx/example.com_error.log warn;
        
        # Отдельные логи для API
        location /api/ {
            access_log /var/log/nginx/example.com_api.log api_log;
            proxy_pass http://backend;
        }
        
        # Исключаем статику из основного лога
        location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg)$ {
            access_log off;
            expires 1y;
        }
        
        # Отдельный лог для медленных запросов
        location / {
            if ($request_time >= 2) {
                access_log /var/log/nginx/example.com_slow.log detailed;
            }
        }
    }
}

Особенно важный момент — исключение статических файлов из логирования. На одном проекте лог раздулся до 50 ГБ за неделю только из-за запросов к CSS и JS файлам. А пользы от этого ноль.

💡
Совет: Используйте переменную $request_time в Nginx — она показывает полное время обработки запроса. Если видите значения больше 5 секунд, значит есть проблемы с производительностью.

Настройка логов PHP и MySQL

Логи веб-сервера — это только верхушка айсберга. Основные проблемы часто кроются глубже, в коде приложения или базе данных. Поэтому настройка логов PHP и MySQL критически важна.

PHP логи

В php.ini я всегда включаю детальное логирование ошибок:

; Включаем логирование ошибок
log_errors = On

; Путь к файлу логов
error_log = /var/log/php/php_errors.log

; Уровень детализации (все ошибки кроме notices в продакшене)
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED

; Не показываем ошибки пользователям
display_errors = Off

; Логируем даже повторяющиеся ошибки
ignore_repeated_errors = Off

; Максимальная длина сообщения об ошибке
log_errors_max_len = 1024

; Включаем логирование startup ошибок
log_errors_startup = On

А для разработки и дебага использую отдельные настройки с более детальным логированием:

; Для development окружения
error_reporting = E_ALL
display_errors = On
display_startup_errors = On
log_errors = On
error_log = /var/log/php/php_debug.log

; Включаем логирование всех уведомлений
; (полезно для отладки старого кода)
; error_reporting = E_ALL | E_STRICT

На одном проекте на Битриксе клиент жаловался на периодические "белые экраны". В PHP логах нашёл fatal error из-за превышения лимита памяти при импорте каталога. Оказалось, что скрипт импорта загружал в память весь XML-файл размером 200 МБ вместо построчной обработки.

MySQL логи

В MySQL самые важные логи — error log и slow query log. Вот моя стандартная конфигурация в my.cnf:

[mysqld]
# Error log
log-error = /var/log/mysql/error.log

# General query log (включаю только для отладки)
# general_log = 1
# general_log_file = /var/log/mysql/general.log

# Slow query log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2.0
log_queries_not_using_indexes = 1

# Binary log для репликации
log-bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 7
max_binlog_size = 100M

# Логирование соединений
log_warnings = 2

Параметр long_query_time = 2.0 означает, что в лог попадут все запросы, выполняющиеся дольше 2 секунд. На высоконагруженных проектах можно снизить до 0.5 или даже 0.1 секунды.

Был интересный случай с WordPress-сайтом. Клиент жаловался на медленную загрузку страниц товаров. В slow query log обнаружил, что запрос для получения похожих товаров выполняется по 15 секунд. Проблема была в отсутствии индекса на поле category_id в таблице wp_posts. После добавления индекса время выполнения сократилось до 0.02 секунды.

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

Анализировать логи вручную — задача неблагодарная. Особенно когда их объём исчисляется гигабайтами. За годы работы перепробовал десятки инструментов, остановился на нескольких проверенных решениях.

Консольные инструменты

Для быстрого анализа логов прямо на сервере использую стандартные Unix-утилиты. Вот мои любимые команды:

# Топ IP-адресов по количеству запросов
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

# Анализ кодов ответов
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr

# Поиск медленных запросов (время выполнения > 5 секунд)
awk '$NF > 5.0' /var/log/nginx/access.log

# Топ страниц по количеству ошибок 404
grep " 404 " /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -nr | head -10

# Анализ активности ботов
grep -E "(bot|spider|crawler)" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr

# Мониторинг ошибок PHP в реальном времени
tail -f /var/log/php/error.log | grep -E "(Fatal|Error)"

Эти команды выручают, когда нужно быстро понять, что происходит на сервере. Особенно полезно во время инцидентов.

ELK Stack (Elasticsearch + Logstash + Kibana)

Для серьёзных проектов ставлю ELK Stack. Да, настройка сложная, но результат того стоит. Logstash парсит логи и отправляет в Elasticsearch, а Kibana предоставляет красивые дашборды.

Вот пример конфигурации Logstash для парсинга Nginx логов:

input {
  file {
    path => "/var/log/nginx/access.log"
    start_position => "beginning"
    codec => "plain"
  }
}

filter {
  grok {
    match => { 
      "message" => "%{NGINXACCESS}" 
    }
  }
  
  date {
    match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
  }
  
  mutate {
    convert => { 
      "response" => "integer"
      "bytes" => "integer"
      "responsetime" => "float"
    }
  }
  
  if [response] >= 400 {
    mutate {
      add_tag => [ "error" ]
    }
  }
  
  if [responsetime] >= 2.0 {
    mutate {
      add_tag => [ "slow" ]
    }
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "nginx-logs-%{+YYYY.MM.dd}"
  }
}

Специализированные сервисы

Для небольших проектов использую облачные решения. Они проще в настройке и не требуют администрирования:

У одного клиента настроил Papertrail для мониторинга WordPress-сайта. Сервис автоматически отправляет уведомления в Slack при появлении ошибок 500. Это помогло сократить время реакции на проблемы с нескольких часов до нескольких минут.

⚠️
Внимание: Облачные сервисы получают доступ к вашим логам. Убедитесь, что в логах нет чувствительной информации (пароли, токены, персональные данные).

Настройка алертов и уведомлений

Логи полезны только тогда, когда их кто-то читает. А читать гигабайты логов каждый день нереально. Поэтому настройка автоматических алертов — это must have для любого серьёзного проекта.

Я использую несколько уровней алертов:

Алерты через Logwatch

Для базового мониторинга использую Logwatch — простую утилиту, которая анализирует логи и отправляет ежедневные отчёты:

# Установка на Ubuntu/Debian
sudo apt-get install logwatch

# Базовая конфигурация в /etc/logwatch/conf/logwatch.conf
MailTo = admin@example.com
MailFrom = server@example.com
TmpDir = /var/cache/logwatch
LogDir = /var/log
Range = Yesterday
Detail = Medium
Service = All

Можно создать кастомный сервис для анализа специфичных логов приложения:

#!/bin/bash
# /etc/logwatch/scripts/services/webapp

if [ -s /var/log/webapp/error.log ]; then
    echo "Web Application Errors:"
    echo "======================="
    
    # Подсчёт ошибок по типам
    grep "$(date --date='yesterday' '+%Y-%m-%d')" /var/log/webapp/error.log | \
    awk '{print $4}' | sort | uniq -c | sort -nr
    
    echo ""
    
    # Критические ошибки
    CRITICAL=$(grep -c "CRITICAL\|FATAL" /var/log/webapp/error.log)
    if [ $CRITICAL -gt 0 ]; then
        echo "!!! CRITICAL ERRORS FOUND: $CRITICAL !!!"
        grep "CRITICAL\|FATAL" /var/log/webapp/error.log | tail -5
    fi
fi

Real-time алерты с помощью скриптов

Для критических алертов настраиваю мониторинг в реальном времени. Вот скрипт, который отслеживает ошибки 500 и отправляет уведомления в Telegram:

#!/bin/bash
# /usr/local/bin/error500-monitor.sh

LOG_FILE="/var/log/nginx/access.log"
TELEGRAM_BOT_TOKEN="YOUR_BOT_TOKEN"
TELEGRAM_CHAT_ID="YOUR_CHAT_ID"
THRESHOLD=10  # Максимум ошибок 500 в минуту

send_telegram() {
    local message="$1"
    curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
         -d chat_id="${TELEGRAM_CHAT_ID}" \
         -d text="${message}" \
         -d parse_mode="HTML"
}

# Подсчёт ошибок 500 за последнюю минуту
ERRORS_COUNT=$(tail -n 1000 "$LOG_FILE" | \
    grep "$(date '+%d/%b/%Y:%H:%M')" | \
    grep " 500 " | wc -l)

if [ $ERRORS_COUNT -gt $THRESHOLD ]; then
    MESSAGE="🚨 CRITICAL ALERT
Server: $(hostname)
Errors 500 in last minute: $ERRORS_COUNT
Threshold: $THRESHOLD

Last errors:
$(tail -n 1000 "$LOG_FILE" | grep " 500 " | tail -3)"

    send_telegram "$MESSAGE"
fi

Этот скрипт запускаю через cron каждую минуту:

# В crontab
* * * * * /usr/local/bin/error500-monitor.sh

На практике такая настройка помогла предотвратить серьёзный инцидент. У клиента сломалась интеграция с платёжной системой, и все попытки оплаты стали возвращать ошибку 500. Благодаря алертам проблему обнаружили через 2 минуты вместо нескольких часов.

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

Логи — это не только инструмент для поиска ошибок, но и мощный способ анализа производительности. Я часто использую их для оптимизации сайтов, особенно когда стандартные инструменты не дают полной картины.

Анализ времени отклика

В логах Nginx время отклика записывается в переменной $request_time. Анализирую его с помощью простых скриптов:

# Топ самых медленных запросов
awk '$NF > 1.0 {print $NF, $7}' /var/log/nginx/access.log | \
sort -nr | head -20

# Средний время отклика по часам
awk '{print substr($4, 2, 11), $NF}' /var/log/nginx/access.log | \
awk '{sum[$1] += $2; count[$1]++} END {for (i in sum) print i, sum[i]/count[i]}' | \
sort

# Распределение времени отклика
awk '{
    if ($NF < 0.1) fast++
    else if ($NF < 0.5) normal++
    else if ($NF < 2.0) slow++
    else very_slow++
    total++
} END {
    print "Fast (<0.1s):", fast/total*100"%"
    print "Normal (0.1-0.5s):", normal/total*100"%"
    print "Slow (0.5-2s):", slow/total*100"%"
    print "Very slow (>2s):", very_slow/total*100"%"
}' /var/log/nginx/access.log

Был случай с Laravel-приложением — клиент жаловался на медленную работу админки. Анализ логов показал, что 90% запросов выполняются за 200-300 мс, но 5% запросов тормозят по 10-15 секунд. Оказалось, что проблема в запросах к API внешнего сервиса без таймаута. Добавили таймаут в 3 секунды и fallback-логику — проблема исчезла.

Анализ нагрузки по времени

Логи помогают понять паттерны нагрузки на сайт. Вот как я анализирую RPS (requests per second):

#!/bin/bash
# Анализ RPS по минутам

awk '{
    timestamp = substr($4, 2, 17)  # Извлекаем дату и время до минуты
    count[timestamp]++
} END {
    for (ts in count) {
        print ts, count[ts]/60  # Делим на 60 для получения RPS
    }
}' /var/log/nginx/access.log | sort

А этот скрипт показывает топ страниц по нагрузке:

# Топ URLs по количеству запросов и среднему времени отклика
awk '{
    url = $7
    time = $NF
    count[url]++
    total_time[url] += time
} END {
    for (url in count) {
        avg_time = total_time[url] / count[url]
        print count[url], avg_time, url
    }
}' /var/log/nginx/access.log | sort -nr | head -20

Анализ ошибок и их влияния на производительность

Иногда ошибки 404 или 500 создают дополнительную нагрузку на сервер. Анализирую это так:

# Соотношение успешных запросов к ошибкам по времени
awk '{
    hour = substr($4, 2, 14)  # Дата и час
    status = $9
    
    if (status >= 200 && status < 400) {
        success[hour]++
    } else {
        errors[hour]++
    }
    
    total[hour]++
} END {
    for (h in total) {
        error_rate = (errors[h] ? errors[h] : 0) / total[h] * 100
        printf "%s: %.2f%% errors (%d/%d)\n", h, error_rate, (errors[h] ? errors[h] : 0), total[h]
    }
}' /var/log/nginx/access.log | sort

У одного клиента на Битриксе обнаружил интересную проблему. Каждую ночь в 3:00 резко возрастало количество ошибок 404. Оказалось, что поисковый робот пытался индексировать старые URL после редизайна сайта. Настроили правильные редиректы 301, и нагрузка снизилась на 30%.

Безопасность и мониторинг атак

Логи — это первая линия обороны против хакеров. Анализируя их, можно обнаружить попытки взлома на ранней стадии и принять меры. За годы работы видел все виды атак, и у каждой есть свой "почерк" в логах.

Обнаружение брутфорс атак

Самый распространённый тип атак — перебор паролей. В логах это выглядит как множественные запросы к страницам авторизации с одного IP:

# Поиск подозрительной активности на страницах авторизации
grep -E "(wp-login|admin|login|auth)" /var/log/nginx/access.log | \
awk '{print $1}' | sort | uniq -c | sort -nr | head -10

# Детальный анализ попыток входа
awk '/wp-login.php/ && /POST/ {
    ip = $1
    time = $4
    status = $9
    
    attempts[ip]++
    
    if (status == 200) {
        success[ip]++
    }
} END {
    for (ip in attempts) {
        success_rate = (success[ip] ? success[ip] : 0) / attempts[ip] * 100
        if (attempts[ip] > 10) {
            printf "%s: %d attempts, %.1f%% success\n", ip, attempts[ip], success_rate
        }
    }
}' /var/log/nginx/access.log

Если видите IP с сотнями попыток входа и 0% успешности — это точно атака. Такие IP блокирую в firewall.

SQL-инъекции и XSS атаки

Эти атаки оставляют характерные следы в URL или POST-данных:

# Поиск попыток SQL-инъекций
grep -i -E "(union|select|insert|update|delete|drop|script|alert)" /var/log/nginx/access.log | \
grep -v -E "\.(css|js|jpg|png|gif)" | head -20

# Поиск XSS атак
grep -i -E "(<script|javascript:|onload=|onerror=)" /var/log/nginx/access.log

# Поиск попыток доступа к конфиденциальным файлам
grep -E "(\\.git|wp-config|database|backup|\.sql)" /var/log/nginx/access.log

Был случай с интернет-магазином — в логах обнаружил массу запросов с SQL-инъекциями. Атакующий пытался получить доступ к базе данных через уязвимость в поиске товаров. К счастью, правильно настроенная защита блокировала эти попытки, но инцидент показал важность мониторинга.

Автоматическое блокирование атакующих IP

Для автоматической защиты использую fail2ban. Вот конфигурация для блокировки брутфорс атак на WordPress:

# /etc/fail2ban/jail.local
[wordpress-auth]
enabled = true
filter = wordpress-auth
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 300
bantime = 3600
action = iptables[name=WordPress, port=http, protocol=tcp]

И соответствующий фильтр:

# /etc/fail2ban/filter.d/wordpress-auth.conf
[Definition]
failregex = ^<HOST>.*POST.*wp-login\.php.*HTTP/1\." (4|5)
ignoreregex =

Эта конфигурация блокирует IP на час после 5 неудачных попыток входа в течение 5 минут.

⚠️
Осторожно: Автоматическое блокирование может заблокировать легитимных пользователей. Всегда добавляйте в whitelist IP-адреса администраторов и офисов.

Оптимизация и ротация логов

На высоконагруженных проектах логи растут со скоростью несколько гигабайт в день. Без правильной настройки ротации диск переполнится за неделю. На моей практике были случаи, когда сайты падали именно из-за переполненного диска.

Настройка logrotate

Для ротации логов использую logrotate. Вот моя стандартная конфигурация:

# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 0644 www-data adm
    sharedscripts
    prerotate
        if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
            run-parts /etc/logrotate.d/httpd-prerotate; \
        fi \
    endscript
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

Для высоконагруженных проектов использую более агрессивную ротацию:

# Для проектов с большим трафиком
/var/log/nginx/access.log {
    hourly
    rotate 168  # 7 дней по 24 часа
    compress
    delaycompress
    missingok
    notifempty
    create 0644 www-data adm
    postrotate
        /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
    endscript
}

Оптимизация размера логов

Есть несколько способов уменьшить размер логов без потери важной информации:

  1. Исключение статических файлов — CSS, JS, изображения редко нужны в логах
  2. Сэмплирование — логирование только каждого N-го запроса
  3. Условное логирование — запись только ошибок и медленных запросов

Вот пример условного логирования в Nginx:

map $status $loggable {
    ~^[23]  0;  # Не логируем успешные ответы 2xx и 3xx
    default 1;  # Логируем все остальные
}

map $request_time $slow_request {
    ~^[0-1]\. 0;  # Не логируем быстрые запросы (<2 секунд)
    default 1;    # Логируем медленные
}

server {
    # Основной лог только для ошибок и медленных запросов
    access_log /var/log/nginx/access.log combined if=$loggable;
    access_log /var/log/nginx/slow.log combined if=$slow_request;
    
    # Отдельный лог для всех запросов (с быстрой ротацией)
    access_log /var/log/nginx/full.log combined;
}

Архивирование и долгосрочное хранение

Для соответствия требованиям безопасности или аудита часто нужно хранить логи месяцами. Настраиваю автоматическое архивирование старых логов:

#!/bin/bash
# /usr/local/bin/archive-logs.sh

LOGS_DIR="/var/log/nginx"
ARCHIVE_DIR="/backup/logs"
DAYS_TO_KEEP=7
ARCHIVE_DAYS=90

# Создаём директорию архива если её нет
mkdir -p "$ARCHIVE_DIR"

# Архивируем логи старше 7 дней
find "$LOGS_DIR" -name "*.log.*.gz" -mtime +$DAYS_TO_KEEP -exec mv {} "$ARCHIVE_DIR/" \;

# Удаляем архивы старше 90 дней
find "$ARCHIVE_DIR" -name "*.gz" -mtime +$ARCHIVE_DAYS -delete

# Отправляем старые логи в S3 (опционально)
# aws s3 sync "$ARCHIVE_DIR" s3://my-logs-bucket/$(hostname)/ --delete

Запускаю этот скрипт ежедневно через cron:

# В crontab
0 2 * * * /usr/local/bin/archive-logs.sh

Частые ошибки и их решение через логи

За годы работы накопил базу типичных проблем и способов их диагностики через логи. Поделюсь самыми частыми случаями — это поможет быстрее решать аналогичные проблемы.

Ошибки 500 — Internal Server Error

Самая частая и самая неинформативная ошибка для пользователей. Но в логах всегда есть детали:

# Поиск ошибок 500 с деталями
grep " 500 " /var/log/nginx/access.log | tail -10

# Коррелируем с PHP логами
tail -f /var/log/php/error.log | grep -E "(Fatal|Error)"

# Анализ причин ошибок 500
awk '/ 500 / {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr

Частые причины:

Медленная загрузка сайта

Когда клиенты жалуются на медленную работу, первым делом анализирую время отклика в логах:

# Топ медленных запросов за последний час
awk -v hour="$(date '+%d/%b/%Y:%H')" '$4 ~ hour && $NF > 2.0 {print $NF, $7}' \
/var/log/nginx/access.log | sort -nr | head -20

# Средний время отклика по типам файлов
awk '{
    if (match($7, /\.(php|html|htm)$/)) type="dynamic"
    else if (match($7, /\.(css|js|jpg|png|gif)$/)) type="static"
    else type="other"
    
    time[type] += $NF
    count[type]++
} END {
    for (t in time) {
        printf "%s: %.3f seconds average\n", t, time[t]/count[t]
    }
}' /var/log/nginx/access.log

Был интересный случай — клиент жаловался на медленный WordPress. Анализ показал, что проблема не в PHP, а в отдаче статических файлов. Оказалось, что на сервере не был включён gzip для CSS и JS файлов. После включения сжатия время загрузки сократилось в 3 раза.

Высокая нагрузка на сервер

Когда сервер начинает тормозить, важно понять источник нагрузки:

# Топ IP по количеству запросов за последний час
awk -v hour="$(date '+%d/%b/%Y:%H')" '$4 ~ hour {print $1}' \
/var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20

# Анализ User-Agent для выявления ботов
awk -F'"' '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

# Поиск необычных паттернов запросов
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -30

На одном проекте обнаружил, что 80% нагрузки создавал один агрессивный поисковый бот. Он делал по 50 запросов в секунду, игнорируя robots.txt. Пришлось блокировать его через .htaccess и обращаться в поддержку поисковика.

Проблемы с SSL-сертификатами

Ошибки SSL часто не очевидны для пользователей, но хорошо видны в логах:

# Поиск SSL ошибок в логах Nginx
grep -i ssl /var/log/nginx/error.log | tail -10

# Анализ запросов к HTTP вместо HTTPS
awk '$2 == "80" {print $1, $7}' /var/log/nginx/access.log | \
sort | uniq -c | sort -nr | head -20

Типичные SSL проблемы:

Для профилактики настраиваю мониторинг срока действия сертификатов и автоматическое продление через Let's Encrypt.

💡
Совет: Ведите журнал изменений на сервере. Когда появляется новая ошибка в логах, всегда можно сопоставить её с недавними изменениями в конфигурации или коде.

Правильно настроенные логи — это инвестиция в стабильность и безопасность сайта. Да, на первый взгляд это может показаться сложным, но поверьте — время, потраченное на настройку логирования, окупается многократно при первом же серьёзном инциденте. И помните: логи нужно не только собирать, но и регулярно анализировать. Только тогда они станут реальным инструментом для улучшения работы сайта.

Если вам нужна помощь с настройкой мониторинга или комплексным анализом проблем сайта, обращайтесь. На моей практике правильная диагностика через логи решает 90% технических проблем быстрее и эффективнее, чем попытки угадать причину.

Нужна помощь с настройкой мониторинга сайта?

Наши эксперты настроят систему логирования и мониторинга для вашего проекта.

П
Павел
Веб-разработчик · 10+ лет опыта · Bitrix, WordPress, Laravel

Читайте также

Как перенести сайт на другую CMS Настройка Google Analytics и Яндекс.Метрики на сайте Защита форм от спама без CAPTCHA