Linux Server

AI Daily Server Report: Summarise Logs with a Local LLM (Ollama) and Send It to Telegram

6 steps 15 min read 57 views 0
On this page

Monitoring tools tell you when a server or website is down, but early warnings hide in the logs: a disk that fills up a little more every day, an error that repeats hundreds of times, a wave of SSH brute-force attempts, a process that quietly eats the CPU. Few people read those logs every morning. This guide collects the key facts once a day, lets a local language model in Ollama turn them into a short, readable report with suggested checks, and sends it to Telegram. Because the model runs on your own server, the logs never leave it.

The AI report is a daily overview, not real-time monitoring and not a security tool. Keep proper alerts for downtime (see monitoring with Uptime Kuma and Telegram alerts) and check anything the report flags yourself: language models can misread data.

Step 1: Prepare Ollama, jq and a Telegram Bot

You need Ollama with a small model, set up as in running a local LLM with Ollama, plus jq and curl. Create a bot with @BotFather in Telegram, send it any message, then read your chat 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'

Step 2: Create the Report Script

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

Replace the bot token and chat ID. The script is readable only by root because it contains the token. num_ctx gives the model enough context for the whole fact sheet, and the report is cut to fit Telegram's message limit. If the model does not answer, you still receive the raw facts.

Step 3: Test It

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

The first run takes longer while the model loads. Compare the report with facts.txt a few times to judge how reliable the summaries are for your servers, and adjust the prompt if it over- or under-reacts.

Step 4: Schedule the Daily Report

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

Step 5: Add the Checks That Matter to You

Add more sections inside the braces of the script; everything they print becomes part of the facts. Some useful examples:

  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

Related guides: Fail2ban for SSH and Nginx, free SSL certificates and renewal, and for IP blocks, monitoring a rented IP block automatically.

Step 6: Several Servers

Ollama does not need to run on every server. Run only the data-collection part on each server, copy facts.txt to the server with Ollama (for example with scp from cron, using an SSH key), and generate all reports there. If you call a central Ollama directly instead, do it over a private network or VPN, never by opening port 11434 to the internet.

FAQ

The report takes several minutes

On CPU the model writes slowly, which is fine for a daily job. For faster reports use a smaller model such as qwen2.5:3b or shorten the fact sheet by removing sections you do not need.

Can I use a cloud AI API instead of a local model?

Technically yes, but logs contain IP addresses, user names, URLs and sometimes customer data. Sending them to a third party has privacy implications and must follow the provider's terms and supported regions. A local model avoids this.

The report says something looks wrong. What now?

Run the suggested command and look at the raw facts. If you see unknown processes using a lot of CPU or unexpected logins, follow checking whether a Linux server is hacked.

Still stuck after following these steps? Open a support ticket and the IMIDC 24/7 technical team will help. Include the server IP, OS version, the contents of facts.txt and the report you received so we can pinpoint the issue faster.

Was this answer helpful?

Related Tutorials