Linux-сервер

Ежедневный отчёт о сервере: анализ логов с ИИ (локальная LLM в Ollama) и отправка в Telegram

6 шагов 16 мин чтения 20 просмотров 0
Содержание

Системы мониторинга сообщают, когда сервер или сайт недоступен, но ранние признаки проблем прячутся в логах: диск, который каждый день заполняется ещё немного, ошибка, повторяющаяся сотни раз, волна попыток подбора пароля SSH, процесс, который незаметно съедает CPU. Мало кто читает эти логи каждое утро. В этой статье мы раз в сутки собираем ключевые данные, поручаем локальной языковой модели в Ollama превратить их в короткий понятный отчёт с рекомендуемыми проверками и отправляем его в Telegram. Поскольку модель работает на вашем собственном сервере, логи не покидают его.

ИИ-отчёт — это ежедневный обзор, а не мониторинг в реальном времени и не средство защиты. Сохраните полноценные оповещения о недоступности (см. статью о мониторинге с Uptime Kuma и оповещениях в Telegram) и сами проверяйте всё, на что указывает отчёт: языковые модели могут неверно истолковать данные.

Шаг 1: Подготовка Ollama, jq и Telegram-бота

Понадобится Ollama с небольшой моделью, настроенная, как описано в статье о запуске локальной LLM с Ollama, а также jq и curl. Создайте бота через @BotFather в Telegram, отправьте ему любое сообщение и узнайте ID своего чата:

apt install -y jq curl
ollama pull qwen2.5:7b

# Send any message to your bot first, then:
curl -s "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates" | jq '.result[].message.chat.id'

Шаг 2: Создание скрипта отчёта

mkdir -p /opt/aireport
cat > /opt/aireport/report.sh <<'EOF2'
#!/bin/bash
# Daily AI server report: collect facts, summarise them with Ollama, send to Telegram
MODEL="qwen2.5:7b"
LANGUAGE="Simplified Chinese"                 # language of the report
TG_TOKEN="123456789:replace-with-your-bot-token"
TG_CHAT="123456789"
FACTS=/opt/aireport/facts.txt

{
  echo "Host: $(hostname)  Uptime: $(uptime -p)"
  echo "Load average 1/5/15 min: $(cut -d' ' -f1-3 /proc/loadavg)  CPU cores: $(nproc)"
  echo; echo "## Memory"; free -h
  echo; echo "## Disk usage"; df -h -x tmpfs -x devtmpfs -x overlay
  echo; echo "## Failed systemd units"; systemctl --failed --no-legend
  echo; echo "## Most frequent error messages in the last 24 hours"
  journalctl --since "24 hours ago" -p err --no-pager -o cat | sort | uniq -c | sort -rn | head -20
  echo; echo "## Failed SSH password logins in the last 24 hours (count, then top source IPs)"
  journalctl --since "24 hours ago" --no-pager -o cat | grep -c "Failed password"
  journalctl --since "24 hours ago" --no-pager -o cat | grep -oP "Failed password .* from \K[0-9a-fA-F.:]+" | sort | uniq -c | sort -rn | head -5
  if [ -f /var/log/nginx/access.log ]; then
    echo; echo "## Nginx HTTP status codes since the last log rotation"
    awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -8
    echo; echo "## URLs with the most 5xx errors"
    awk '$9 ~ /^5/ {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -5
  fi
  echo; echo "## Top processes by CPU"
  ps -eo user,pid,%cpu,%mem,etime,comm --sort=-%cpu | head -8
} > "$FACTS" 2>&1

PROMPT="You are an experienced Linux operations engineer. Below are today's facts from a server.
Write a short daily report in $LANGUAGE for the server owner:
1. First line: overall status, one of OK / ATTENTION / PROBLEM.
2. Then at most 5 bullet points about anything unusual, each with the likely cause and one command to check it.
3. If everything looks normal, say so in one sentence.
Only use the facts below. Do not invent numbers.

$(head -c 12000 "$FACTS")"

REPORT=$(jq -n --arg m "$MODEL" --arg p "$PROMPT" \
  '{model: $m, prompt: $p, stream: false, options: {temperature: 0.2, num_ctx: 8192}}' \
  | curl -s --max-time 900 http://127.0.0.1:11434/api/generate -d @- | jq -r '.response // empty')
[ -z "$REPORT" ] && REPORT="AI summary failed. Raw facts:
$(head -c 3000 "$FACTS")"

curl -s -X POST "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
  --data-urlencode "chat_id=${TG_CHAT}" \
  --data-urlencode "text=[$(hostname)] daily report
${REPORT:0:3800}" > /dev/null
EOF2
chmod 700 /opt/aireport/report.sh

Замените токен бота и ID чата, а в переменной LANGUAGE при необходимости укажите нужный язык отчёта, например Russian. Скрипт доступен для чтения только root, так как содержит токен. Параметр num_ctx даёт модели достаточно контекста для всей сводки данных, а отчёт обрезается под ограничение длины сообщения в Telegram. Если модель не ответит, вы всё равно получите исходные данные.

Шаг 3: Проверка

/opt/aireport/report.sh
cat /opt/aireport/facts.txt      # the data the model saw

Первый запуск длится дольше, пока загружается модель. Несколько раз сравните отчёт с facts.txt, чтобы оценить, насколько надёжны сводки для ваших серверов, и скорректируйте промпт, если модель реагирует слишком остро или, наоборот, пропускает важное.

Шаг 4: Расписание ежедневного отчёта

echo '0 8 * * * root /opt/aireport/report.sh' > /etc/cron.d/aireport
timedatectl | grep "Time zone"     # cron uses the server's time zone

Шаг 5: Добавьте важные для вас проверки

Добавляйте новые разделы внутри фигурных скобок в скрипте: всё, что они выводят, попадает в сводку данных. Несколько полезных примеров:

  echo; echo "## Fail2ban"; fail2ban-client status sshd | grep -E "Currently banned|Total banned"
  echo; echo "## Stopped Docker containers"; docker ps -a --filter status=exited --format "{{.Names}}: {{.Status}}"
  echo; echo "## Certificates"; for c in /etc/letsencrypt/live/*/cert.pem; do echo "$c $(openssl x509 -enddate -noout -in "$c")"; done
  echo; echo "## Last backup file"; ls -lt /backup | head -3

Связанные статьи: Fail2ban для SSH и Nginx, бесплатные SSL-сертификаты и их продление, а для IP-блоков — автоматический мониторинг арендованного блока IP.

Шаг 6: Несколько серверов

Ollama не обязательно запускать на каждом сервере. Оставьте на каждом сервере только сбор данных, копируйте facts.txt на сервер с Ollama (например, через scp из cron с SSH-ключом) и формируйте все отчёты там. Если же вы обращаетесь к центральному Ollama напрямую, делайте это через частную сеть или VPN, а не открывая порт 11434 в интернет.

Частые вопросы

Отчёт формируется несколько минут

На CPU модель пишет медленно, но для ежедневной задачи это нормально. Чтобы ускорить отчёты, используйте модель поменьше, например qwen2.5:3b, или сократите сводку, убрав ненужные разделы.

Можно ли вместо локальной модели использовать облачный ИИ API?

Технически да, но логи содержат IP-адреса, имена пользователей, URL, а иногда и данные клиентов. Передача их третьей стороне затрагивает вопросы конфиденциальности и должна соответствовать условиям провайдера и поддерживаемым им регионам. Локальная модель снимает этот вопрос.

В отчёте сказано, что что-то не так. Что делать?

Выполните предложенную команду и посмотрите исходные данные. Если вы видите неизвестные процессы с высокой нагрузкой на CPU или неожиданные входы в систему, действуйте по статье о том, как проверить, не взломан ли Linux-сервер.

Если проблема не решена, создайте тикет — техническая поддержка IMIDC работает 24/7. Укажите IP сервера, версию ОС, содержимое facts.txt и полученный отчёт, чтобы мы быстрее нашли причину.

Помог ли вам данный ответ?

Похожие руководства