背景:なぜVector、DeepSeek、Telegramの3点セットを選んだのか?
マイクロサービスを半年以上運用して、ある悪夢に直面しました。毎日50GB以上のログが生成されますが、その99%は無意味なデータです。以前のエラー対応プロセスは非常に手動でした。まず通知を受け取り、サーバーにSSHでログインしてログをgrepし、最後にChatGPTにコピペする。このやり方は、特に深夜2時にトラブルが発生したときには、心底疲れ果てるものでした。
代替案を探す際、ELK Stackも検討しました。しかし、ELKは起動するだけで数GBのRAMを消費するため、中小規模のサーバークラスターには重すぎます。最終的に選んだのはVectorです。これはRustで書かれたログ収集ツールで、非常に軽量(RAM消費量はわずか20-30MB程度)です。これに、推論能力で話題のDeepSeek-R1とTelegramを組み合わせることで、24時間365日稼働する「オンコール助手」を作り上げました。
DeepSeek-R1の最大の利点は、ログの文脈を理解する能力です。単に無機質なInternal Server Errorを報告するだけではありません。「データベースの接続プールが溢れています。max_connectionsを増やすか、接続リークを確認してください」といったように, 原因を具体的に指摘してくれます。そのおかげで、チームの障害復旧時間(MTTR)を70%短縮することができました。
コアコンポーネントのセットアップ
1. Vectorのインストール
Vectorはデータの「運び屋」としての役割を担います。ファイルやDockerコンテナからログを集め、AI側に送り出します。Linuxなら、30秒ほどで素早くインストールできます。
curl --proto '=https' --tlsv1.2 -sSf https://sh.vector.dev | sh
2. Ollama経由でDeepSeek-R1をローカル実行する
データのセキュリティを確保し、機密ログのクラウド流出を防ぐため、DeepSeek-R1を社内サーバーで直接実行しています。サーバーにGPUがない場合は、7Bまたは14Bモデルを使用すればCPUでもスムーズに動作します。
# Ollamaのインストール
curl -fsSL https://ollama.com/install.sh | sh
# DeepSeek-R1モデルをプルする
ollama run deepseek-r1:7b
3. Telegram Botの設定
@BotFatherとチャットして**Bot Token**を取得するだけです。その後、@userinfobotを使って個人の**Chat ID**を取得します。これが、リアルタイムでエラー分析レポートを受け取るチャンネルになります。
分析システムの構成
システムの心臓部はvector.yamlファイルにあります。すべてのログを送信してリソースを無駄にするのではなく、ERRORまたはCRITICALレベルのログのみをフィルタリングします。
ステップ1:ログのフィルタリングとフォーマット
以下の設定では、ログファイルを監視し、AIに送信する前に不要な情報を削除します。
sources:
app_logs:
type: "file"
include:
- "/var/log/myapp/*.log"
read_from: "beginning"
transforms:
error_filter:
type: "filter"
inputs:
- "app_logs"
condition: |
includes(["ERROR", "CRITICAL", "EXCEPTION"], upcase!(string!(.message) ?? ""))
log_formatter:
type: "remap"
inputs:
- "error_filter"
source: |
.content = "以下のエラーが発生しました: " + .message
del(.file)
del(.host)
ステップ2:AIブリッジの構築
現時点では、Vectorは対話形式でOllamaを直接呼び出す機能をサポートしていません。そのため、仲介役として小さなPythonスクリプトを作成しました。このスクリプトはログを受け取り、DeepSeek-R1に問い合わせ、その結果をTelegramに送信します。
import requests
from flask import Flask, request
app = Flask(__name__)
OLLAMA_URL = "http://localhost:11434/api/generate"
TELEGRAM_TOKEN = "YOUR_BOT_TOKEN"
CHAT_ID = "YOUR_CHAT_ID"
def ask_deepseek(log_content):
# あなたはDevOpsのエキスパートです。以下のエラーを分析し、原因と解決策を簡潔に提示してください
prompt = f"Bạn là chuyên gia DevOps. Hãy phân tích lỗi sau và đưa ra nguyên nhân, cách khắc phục ngắn gọn: {log_content}"
payload = {"model": "deepseek-r1:7b", "prompt": prompt, "stream": False}
response = requests.post(OLLAMA_URL, json=payload)
return response.json().get("response", "エラーを分析できませんでした。")
@app.route('/alert', methods=['POST'])
def handle_log():
log_data = request.json
analysis = ask_deepseek(log_data.get("content", ""))
# 🚨 システムエラー警告
# 📝 ログ:
# 💡 分析結果:
msg = f"🚨 *システムエラー警告*\n\n📝 *ログ:* {log_data['content']}\n\n💡 *分析結果:*\n{analysis}"
requests.post(f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage",
data={"chat_id": CHAT_ID, "text": msg, "parse_mode": "Markdown"})
return "OK", 200
if __name__ == '__main__':
app.run(port=5000)
実際の成果
検証のために、以下のコマンドでデータベース接続エラーをシミュレートしてみます。
echo "2024-05-20 15:30:00 ERROR: Connection timeout to database 10.0.0.5:5432" >> /var/log/myapp/app.log
5秒も経たないうちに、Telegramに新しいメッセージが届きました。内容は非常に詳細です:
🚨 システムエラー警告
📝 ログ: Connection timeout to database 10.0.0.5:5432
💡 分析結果:
原因はファイアウォールがポート5432をブロックしているか、データベースサーバーがハングアップしている可能性があります。`nc -zv 10.0.0.5 5432`コマンドを実行してネットワーク接続を確認することをお勧めします。
実務上の経験から、DeepSeek-R1は思考プロセス(<think>タグ)がかなり長くなる傾向があります。AIが最終的な結果のみに集中するようにプロンプトを調整することをお勧めします。また、Vectorのsinkでrate_limitを設定してください。これにより、連鎖的なエラーが発生した際のメッセージの「スパム」状態を防ぐことができます。
このシステムは半年間安定して稼働しており、少人数のチームにとって本当に救世主となりました。皆さんの構築が成功することを願っています!

