Логи сайта — это как чёрный ящик самолёта: когда всё работает, на них мало кто обращает внимание, но когда случается сбой, именно они становятся единственным источником правды о том, что пошло не так. За 10+ лет работы я видел сотни ситуаций, когда правильно настроенные логи спасали проекты от многочасовых простоев.
Зачем нужны логи сайта и что они дают
Честно говоря, многие владельцы сайтов даже не знают о существовании логов. А зря. На моей практике был случай с интернет-магазином на Битриксе — клиент жаловался на странные проблемы с оплатой. Пользователи добавляли товары в корзину, но оплата периодически не проходила. Без логов мы бы искали проблему неделями.
Логи сайта — это детализированные записи всех событий, происходящих на сервере. Они фиксируют каждый запрос к сайту, каждую ошибку PHP, каждое обращение к базе данных. И вот что они дают в реальной работе:
- Быстрое выявление проблем — вместо гадания на кофейной гуще получаем конкретные данные
- Анализ производительности — видим, какие скрипты тормозят сайт
- Мониторинг безопасности — отслеживаем попытки взлома и подозрительную активность
- SEO-оптимизация — анализируем, как поисковые боты обходят сайт
- Бизнес-аналитика — понимаем поведение пользователей на техническом уровне
У одного клиента на 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)
Помимо веб-сервера, логи ведут и другие компоненты:
- PHP error log — ошибки интерпретатора PHP
- MySQL error log — проблемы с базой данных
- Slow query log — медленные SQL-запросы
- Redis log — если используется кеширование
Был случай на 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 файлам. А пользы от этого ноль.
Настройка логов 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}"
}
}
Специализированные сервисы
Для небольших проектов использую облачные решения. Они проще в настройке и не требуют администрирования:
- Loggly — простой в настройке, хорошие возможности поиска
- Papertrail — отличный для real-time мониторинга
- DataDog — мощная аналитика, но дорогой
- New Relic — хорош для APM, логи как бонус
У одного клиента настроил Papertrail для мониторинга WordPress-сайта. Сервис автоматически отправляет уведомления в Slack при появлении ошибок 500. Это помогло сократить время реакции на проблемы с нескольких часов до нескольких минут.
Настройка алертов и уведомлений
Логи полезны только тогда, когда их кто-то читает. А читать гигабайты логов каждый день нереально. Поэтому настройка автоматических алертов — это must have для любого серьёзного проекта.
Я использую несколько уровней алертов:
- Критические — ошибки 500, недоступность сайта, ошибки базы данных
- Важные — превышение времени отклика, много ошибок 404, проблемы с SSL
- Информационные — необычная активность, новые источники трафика
Алерты через 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 минут.
Оптимизация и ротация логов
На высоконагруженных проектах логи растут со скоростью несколько гигабайт в день. Без правильной настройки ротации диск переполнится за неделю. На моей практике были случаи, когда сайты падали именно из-за переполненного диска.
Настройка 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
}
Оптимизация размера логов
Есть несколько способов уменьшить размер логов без потери важной информации:
- Исключение статических файлов — CSS, JS, изображения редко нужны в логах
- Сэмплирование — логирование только каждого N-го запроса
- Условное логирование — запись только ошибок и медленных запросов
Вот пример условного логирования в 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
Частые причины:
- Превышение лимита памяти PHP — в логах видно "Fatal error: Allowed memory size"
- Синтаксические ошибки в коде — "Parse error: syntax error"
- Недоступные файлы — "No such file or directory"
- Проблемы с правами доступа — "Permission denied"
Медленная загрузка сайта
Когда клиенты жалуются на медленную работу, первым делом анализирую время отклика в логах:
# Топ медленных запросов за последний час
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 проблемы:
- "SSL certificate problem: certificate has expired"
- "SSL certificate problem: self signed certificate"
- "SSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure"
Для профилактики настраиваю мониторинг срока действия сертификатов и автоматическое продление через Let's Encrypt.
Правильно настроенные логи — это инвестиция в стабильность и безопасность сайта. Да, на первый взгляд это может показаться сложным, но поверьте — время, потраченное на настройку логирования, окупается многократно при первом же серьёзном инциденте. И помните: логи нужно не только собирать, но и регулярно анализировать. Только тогда они станут реальным инструментом для улучшения работы сайта.
Если вам нужна помощь с настройкой мониторинга или комплексным анализом проблем сайта, обращайтесь. На моей практике правильная диагностика через логи решает 90% технических проблем быстрее и эффективнее, чем попытки угадать причину.
Нужна помощь с настройкой мониторинга сайта?
Наши эксперты настроят систему логирования и мониторинга для вашего проекта.