#!/bin/bash #каталог где nginx хранит логи logPath="/var/log/nginx/" #файл, где будем хранить переменные для следующего запуска varPathFile="/opt/check-log-nginx/var.tmp" #Lock файл, который будем провероять, если файл существует, значит скрипт запущен lockFile="/tmp/check-log-nginx.lock" #проверяем, если lock файл существует, то выходим из скрипта if [ -f "$lockFile" ] then exit 1 fi #создаем lock файл touch "$lockFile" #данные для телеграм бота botToken="1234567890:aaabbbeeecccdddB6WtSczDt_9DKpaf3-E" chatId="364640578" #подгружаем переменные из файла с прошлых запусков . $varPathFile 2> /dev/null #Проверяем переменные из файла с прошлых запусков, если переменных нет, то создаем их #Переменная, в которой хранится последняя проверяемая строка лога access.log при проверке if [ -z "$lineNumberAccess" ] then lineNumberAccess=0 fi #Переменная, в которой хранится последняя проверяемая строка лога error.log при проверке if [ -z "$lineNumberError" ] then lineNumberError=0 fi #Переменная, в которой хранится время последнней проверки, именно с этого времени, мы смотрим логи службы nginx. if [ -z "$lastChekDate" ] then lastChekDate=$(date -d "1 days ago" +"%Y-%m-%d %H:%M:%S") firstStart=1 fi #Переменная, в которой хранится дата создания файла access.log. if [ -z "$timestampCreateAccessLog" ] then timestampCreateAccessLog=9999999999 fi #Переменная, в которой хранится дата создания файла error.log. if [ -z "$timestampCreateErrorLog" ] then timestampCreateErrorLog=9999999999 fi #Проверяем дату создания файла access.log #если дата создания файла больше, чем мы сохраняли ранее, значит произолшла ротация логов и будем производить подсчет и с файла access.log.1 currentTimestampCreateAccessLog=$(stat -c '%W' "$logPath"access.log) if [ $timestampCreateAccessLog -lt $currentTimestampCreateAccessLog ] then topIpAddress=$(cat "$logPath"access.log <(tail -n +$lineNumberAccess "$logPath"access.log.1) |awk '{print $1}' | sort | uniq -c | sort -rn | head -10 | awk '{printf "%-80s %s \n", $2, $1" запросов" }') topUrl=$(cat "$logPath"access.log <(tail -n +$lineNumberAccess "$logPath"access.log.1) | awk -F'[ ?]' '{print $7}' | sort | uniq -c | sort -rn | head -10 | awk '{printf "%-80s %s \n", $2, $1 " запросов"}') returnAccessCode=$(cat "$logPath"access.log <(tail -n +$lineNumberAccess "$logPath"access.log.1) |awk '$9 >= 200 && $9 < 400 {print $9}' | sort | uniq -c | awk '{printf "%-80s %s \n","код " $2, $1" запросов" }') returnErrorCode=$(cat "$logPath"access.log <(tail -n +$lineNumberAccess "$logPath"access.log.1) |awk '$9 >= 400 && $9 < 600 {print $9}' | sort | uniq -c | awk '{printf "%-80s %s \n","код " $2, $1" запросов" }') else topIpAddress=$(tail -n +$lineNumberAccess "$logPath"access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10 | awk '{printf "%-80s %s \n", $2, $1" запросов" }') topUrl=$(tail -n +$lineNumberAccess "$logPath"access.log | awk -F'[ ?]' '{print $7}' | sort | uniq -c | sort -rn | head -10 | awk '{printf "%-80s %s \n", $2, $1 " запросов"}') returnAccessCode=$(tail -n +$lineNumberAccess "$logPath"access.log |awk '$9 >= 200 && $9 < 400 {print $9}' | sort | uniq -c | awk '{printf "%-80s %s \n","код " $2, $1" запросов" }') returnErrorCode=$(tail -n +$lineNumberAccess "$logPath"access.log |awk '$9 >= 400 && $9 < 600 {print $9}' | sort | uniq -c | awk '{printf "%-80s %s \n","код " $2, $1" запросов" }') fi #Проверяем дату создания файла error.log #если дата создания файла больше, чем мы сохраняли ранее, значит произолшла ротация логов и будем производить подсчет и с файла error.log.1 currentTimestampCreateErrorLog=$(stat -c '%W' "$logPath"error.log) #так как файл error.log тяжело распарсить, то будем просто подсчитывать число ошибок. if [ $timestampCreateErrorLog -lt $currentTimestampCreateErrorLog ] then lineAllErrorLog=$(cat "$logPath"error.log <(tail -n +$lineNumberError "$logPath"error.log.1) | wc -l) else lineAllErrorLog=$(tail -n +$lineNumberError "$logPath"error.log | wc -l) fi #Подготавливаем сообщение nginxStatisticMessenge=$(echo -e "=============Статистика Nginx=============" ) nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\n===Топ 10 ip адресов: ===" ) if [ "$topIpAddress" != "" ] then nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\n$topIpAddress" ) else nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\nНет новых запросов" ) fi nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\n===Топ 10 зпрашиваемых URL: ===" ) if [ "$topUrl" != "" ] then nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\n$topUrl" ) else nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\nНет новых запросов" ) fi nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\n===✅Удачные запросы: ===" ) if [ "$returnAccessCode" != "" ] then nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\n$returnAccessCode" ) else nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\nНет новых запросов" ) fi nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\n===❗️Неудачные запросы: ===" ) if [ "$returnErrorCode" != "" ] then nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\n$returnErrorCode" ) else nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\nНет новых запросов" ) fi nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\n===Журнал error.log===" ) if [ $lineAllErrorLog -gt 0 ] then nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\n❗️ Журнал содержит $lineAllErrorLog ошибок с момента последней проверки" ) else nginxStatisticMessenge=$(echo -e "$nginxStatisticMessenge\n\n✅ Журнал не содержит ошибок с момента последней проверки" ) fi #Получаем ошибки nginx в systemd с момента последнего запуска errorSystemd=$(journalctl --since "$lastChekDate" -p err -u nginx) systemdErrorMessenge=$(echo -e "=============Ошибки systemd=============" ) if [ "$errorSystemd" == "-- No entries --" ] then systemdErrorMessenge=$(echo -e "$systemdErrorMessenge\n\n✅С момента последней проверки, ошибок в systemd нет!" ) else #Считаем сколько всего ошибок в systemd lineAllMessengeSystemd=$(echo "$errorSystemd" | wc -l) #Берем последние 3 ошибки lastErrorSystemd=$(echo "$errorSystemd" | tail -n 3) #подготавливаем сообщение systemdErrorMessenge=$(echo -e "$systemdErrorMessenge\n\n❗️С момента последней прроверки в systemd накопилось ошибок - $lineAllMessengeSystemd" ) if [ $lineAllMessengeSystemd > 3 ] then systemdErrorMessenge=$(echo -e "$systemdErrorMessenge\n\nПоследние 3 ошибки:" ) systemdErrorMessenge=$(echo -e "$systemdErrorMessenge\n\n$lastErrorSystemd" ) systemdErrorMessenge=$(echo -e "$systemdErrorMessenge\n\nДля подробного просмотра требуется действия на сервере!" ) else systemdErrorMessenge=$(echo -e "$systemdErrorMessenge\nВозникшие ошибки:" ) systemdErrorMessenge=$(echo -e "$systemdErrorMessenge\n$lastErrorSystemd" ) fi fi #Время прошлого запуска if [ -z "$firstStart" ] then headMessenge="Статисктика из логов Nginx начиная с $lastChekDate по текущее время." else headMessenge="Первый запуск скрипта" fi if [ -z "$lineNumberAccess" ] then lineNumberAccess=0 fi #Подготавливаем сообщение messange=$(echo -e "$headMessenge\n\n$nginxStatisticMessenge\n\n$systemdErrorMessenge") # Формируем URL и данные url="https://api.telegram.org/bot$botToken/sendMessage" curlData="chat_id=$chatId&text=$messange&parse_mode=HTML" # Отправляем запрос curl -s -X POST "$url" -d "$curlData" > /dev/null #сохраняем переменные для будущих проверок echo -n '' > $varPathFile echo "lastChekDate=\"$(date +"%Y-%m-%d %H:%M:%S")"\" >> $varPathFile echo "lineNumberAccess=$(($(cat "$logPath"access.log | wc -l)+1))" >> $varPathFile echo "lineNumberError=$(($(cat "$logPath"error.log | wc -l)+1))" >> $varPathFile echo "timestampCreateAccessLog=$currentTimestampCreateAccessLog" >> $varPathFile echo "timestampCreateErrorLog=$currentTimestampCreateErrorLog" >> $varPathFile #удаляем lock файл rm -f "$lockFile"