监控工具能告诉你服务器或网站什么时候宕机,但很多早期预警藏在日志里:磁盘每天都比前一天更满一点、同一个错误重复出现几百次、一波 SSH 暴力破解尝试、某个进程悄悄吃掉 CPU。很少有人每天早上去翻这些日志。本文每天收集一次关键数据,交给 Ollama 中的本地大模型整理成一份简短易读、附带排查建议的日报,并推送到 Telegram。由于模型运行在你自己的服务器上,日志不会离开服务器。
你需要按照使用 Ollama 部署本地大模型装好 Ollama 和一个小模型,另外还需要 jq 和 curl。在 Telegram 中通过 @BotFather 创建机器人,先给它发送任意一条消息,再查询你的 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'
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
请把机器人 Token 和 chat ID 替换成你自己的。由于脚本中包含 Token,因此设置为只有 root 能读取。num_ctx 让模型有足够的上下文容纳完整的数据清单,日报内容会被截断,以符合 Telegram 的单条消息长度限制。如果模型没有返回结果,你仍会收到原始数据。
/opt/aireport/report.sh
cat /opt/aireport/facts.txt # the data the model saw
首次运行需要加载模型,耗时会长一些。多对比几次日报和 facts.txt,判断摘要对你的服务器是否可靠;如果模型反应过度或不够敏感,请调整提示词。
echo '0 8 * * * root /opt/aireport/report.sh' > /etc/cron.d/aireport
timedatectl | grep "Time zone" # cron uses the server's time zone
在脚本的花括号代码块内添加更多段落,它们输出的所有内容都会成为数据的一部分。下面是一些实用的示例:
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 段。
不需要每台服务器都运行 Ollama。各台服务器只运行数据收集部分,再把 facts.txt 复制到装有 Ollama 的服务器(例如在 cron 中使用 SSH 密钥执行 scp),在那里统一生成所有日报。如果改为直接调用集中部署的 Ollama,请通过内网或 VPN 访问,切勿把 11434 端口开放到公网。
在 CPU 上模型输出较慢,对于每天运行一次的任务来说没有问题。如果想更快生成日报,可以换用 qwen2.5:3b 等更小的模型,或删除不需要的段落来精简数据清单。
技术上可以,但日志中包含 IP 地址、用户名、URL,有时还有客户数据。把这些数据发送给第三方会涉及隐私问题,并且必须遵守服务商的条款和支持地区。使用本地模型可以避免这些问题。
执行日报中建议的命令,并查看原始数据。如果发现未知进程占用大量 CPU 或出现异常登录,请按照如何判断 Linux 服务器是否被入侵进行排查。
如果按以上步骤操作后问题仍未解决,请提交工单联系 IMIDC 7×24 技术支持,并附上服务器 IP、系统版本、facts.txt 的内容以及你收到的日报,方便工程师快速定位。