Bot

開発記録#167(2025/4/3)「論文ベースのbot開発フローpart.29 Bot Ops Full Stack“運用フルスタック”を構築する方法」

2025年4月3日

前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。

本記事では「暗号通貨のパンプ&ダンプスキームの検出」に関する論文をベースにbot開発の過程をまとめていきます。

Bot Ops Full Stack

# ✅ Kubernetes Deployment Template for Multi-Bot
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bot-{{PAIR}}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: bot-{{PAIR}}
  template:
    metadata:
      labels:
        app: bot-{{PAIR}}
    spec:
      restartPolicy: Always
      containers:
      - name: bot
        image: your_dockerhub_user/crypto-bot:latest
        args: ["bots/{{PAIR}}/config.yaml"]
        env:
        - name: PAIR
          value: "{{PAIR}}"
        resources:
          limits:
            memory: "1Gi"
            cpu: "500m"
---
# ✅ Slack Alert Script (send_slack.py)
import requests

def send_slack_alert(message):
    url = "https://hooks.slack.com/services/XXXX/XXXX/XXXX"
    payload = {"text": f"\ud83d\udea8 {message}"}
    requests.post(url, json=payload)
---
# ✅ Logger Utility (logger.py)
import logging
from datetime import datetime

def get_logger(name, log_file=None):
    logger = logging.getLogger(name)
    logger.setLevel(logging.INFO)
    if not logger.handlers:
        formatter = logging.Formatter("[%(asctime)s] %(levelname)s - %(message)s", "%Y-%m-%d %H:%M:%S")
        log_file = log_file or f"./logs/{name}_{datetime.now().strftime('%Y%m%d')}.log"
        file_handler = logging.FileHandler(log_file)
        console_handler = logging.StreamHandler()
        file_handler.setFormatter(formatter)
        console_handler.setFormatter(formatter)
        logger.addHandler(file_handler)
        logger.addHandler(console_handler)
    return logger
---
# ✅ Retry With Alert (retry_with_alert.py)
import time
from send_slack import send_slack_alert

def retry_with_alert(task_func, retries=3, delay=5, task_name=""):
    for attempt in range(1, retries + 1):
        try:
            return task_func()
        except Exception as e:
            if attempt == retries:
                send_slack_alert(f"{task_name} \u306f {retries} \u56de\u9023\u7d9a\u5931\u6557\u3057\u307e\u3057\u305f: {e}")
            time.sleep(delay)
---
# ✅ Backup Script (backup_script.py)
import boto3
import os
from datetime import datetime

AWS_ACCESS_KEY = "YOUR_ACCESS"
AWS_SECRET_KEY = "YOUR_SECRET"
BUCKET_NAME = "crypto-bot-backups"

def backup_to_s3():
    s3 = boto3.client('s3', aws_access_key_id=AWS_ACCESS_KEY, aws_secret_access_key=AWS_SECRET_KEY)
    for folder in ["./logs", "./models"]:
        for root, _, files in os.walk(folder):
            for f in files:
                local_path = os.path.join(root, f)
                s3_key = f"{datetime.now().strftime('%Y-%m-%d')}/{f}"
                s3.upload_file(local_path, BUCKET_NAME, s3_key)
                print(f"\u2705 {f} \u3092 S3 \u306b\u30d0\u30c3\u30af\u30a2\u30c3\u30d7")

if __name__ == "__main__":
    backup_to_s3()
---
# ✅ Monitor & Backup Executor (monitor.py)
from retry_with_alert import retry_with_alert
from backup_script import backup_to_s3
from send_slack import send_slack_alert

# placeholder for resource checks

def monitor():
    try:
        # ここでPrometheus値の監視などに置換可能
        print("\U0001f9e0 モニタリング中...")
    except Exception as e:
        send_slack_alert(f"\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u30a8\u30e9\u30fc: {e}")

if __name__ == "__main__":
    monitor()
    backup_to_s3()

Bot運用の安定化・監視・通知・バックアップすべてを網羅したテンプレート一式です ✅
このファイルは以下の内容を含んでいます:


📦 セット内容

ファイル名内容
deployment-template.yaml通貨ペアごとのKubernetes Deployment定義(テンプレート形式)
send_slack.pySlack通知機能(Webhook連携)
logger.py共通ロガーユーティリティ
retry_with_alert.py異常時リトライ+Slack通知
backup_script.pyS3バックアップ用スクリプト(logs, models)
monitor.pyモニタリング & バックアップの自動実行用

コードの解説

上記のコードを複数通貨ペア対応の自動取引BotをKubernetes上で安定的に運用するためのテンプレート一式として、それぞれのコードの役割と実装意図を解説します。


🧱 構成の全体像

このテンプレートは、次の機能を網羅しています:

  • ✅ 各通貨ペアBotを個別にKubernetesでデプロイ可能(テンプレート対応)
  • ✅ エラー検知時の Slack通知連携
  • ✅ ログのローカル保存と S3へのバックアップ
  • monitor.py による簡易 モニタリング&バックアップ自動実行
  • ✅ 共通ユーティリティ:ログ記録・リトライ機構

1️⃣ Kubernetes Deployment テンプレート

apiVersion: apps/v1
kind: Deployment
metadata:
  name: bot-{{PAIR}}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: bot-{{PAIR}}
  template:
    metadata:
      labels:
        app: bot-{{PAIR}}
    spec:
      restartPolicy: Always
      containers:
      - name: bot
        image: your_dockerhub_user/crypto-bot:latest
        args: ["bots/{{PAIR}}/config.yaml"]
        env:
        - name: PAIR
          value: "{{PAIR}}"
        resources:
          limits:
            memory: "1Gi"
            cpu: "500m"

🔍 解説

  • {{PAIR}} の部分に btcusdtethusdt を入れることで、複数通貨のBotをテンプレートから自動展開可能。
  • restartPolicy: Always によりBotが異常終了しても自動復旧。
  • コンテナのリソース上限(CPU/メモリ)も制限済みで安全。

2️⃣ Slack通知スクリプト:send_slack.py

import requests

def send_slack_alert(message):
    url = "https://hooks.slack.com/services/XXXX/XXXX/XXXX"
    payload = {"text": f"🚨 {message}"}
    requests.post(url, json=payload)

🔍 解説

  • 異常検出時にSlackへリアルタイム通知を送る仕組み。
  • send_slack_alert() はどのモジュールからも呼び出せる汎用関数です。

3️⃣ ロガーユーティリティ:logger.py

import logging
from datetime import datetime

def get_logger(name, log_file=None):
    ...

🔍 解説

  • 標準出力(コンソール)とログファイルの両方に同時出力
  • ログファイルは自動的に日付付きのファイル名で保存されます。

4️⃣ エラー時のリトライ+通知:retry_with_alert.py

from send_slack import send_slack_alert

def retry_with_alert(task_func, retries=3, delay=5, task_name=""):
    ...

🔍 解説

  • 指定関数を最大retries回まで実行。
  • 最終失敗時にSlack通知を飛ばすため、重要なAPIコールやファイル操作時に安全

5️⃣ S3へのバックアップスクリプト:backup_script.py

import boto3
import os
from datetime import datetime

def backup_to_s3():
    ...

🔍 解説

  • ./logs./models ディレクトリ配下のファイルを AWS S3 に日付フォルダ付きでアップロード。
  • ログ保持・モデル保存に最適で、バックアップ漏れを防ぎます。

AWS S3をざっくり解説

Botテンプレートで出てきた “S3 バックアップ”──この S3 は Amazon Web Services の “Simple Storage Service” のこと。超シンプルにポイントだけ押さえます。


1️⃣ 何が “Simple” なのか?

  • オブジェクトストレージ:ファイルを “オブジェクト” として丸ごと保存。
  • フォルダ階層もサーバ管理も不要PUT で置き、GET で取り出すだけ。
  • スケール自動:数ファイルでも数十億ファイルでも、運用者は容量を気にしなくてOK。

2️⃣ S3 を使うメリット

  1. 高耐久
    • 公式値 99.999999999%(イレブンナイン)。同一リージョン内で自動多重化。
  2. アクセス制御が柔軟
    • IAMロールやプリサインURLで、Botだけ・人間だけなど細かく権限設定。
  3. コスト最適化
    • 使った分だけ課金。古いログは Glacier に自動移行して激安保管も可。
  4. エコシステムが豊富
    • boto3(Python SDK)/CLI/GUI、どれでも操作可。
    • AthenaでSQL検索、Lambdaで自動処理…後々の拡張がラク。

3️⃣ Bot 運用での典型パターン

  • logs/models/日付フォルダで S3 にアップロード。
  • インスタンスを潰しても履歴はクラウドに残る。
  • 別環境への復旧やモデルロールバックも 1コマンドでダウンロードして完了。

【まとめ】
S3=“ほぼ壊れず、ほぼ無限”のネット上の金庫
Bot開発では “転ばぬ先のバックアップ先” として覚えておけば十分です。


6️⃣ 簡易モニタリング&定期バックアップ実行:monitor.py

from retry_with_alert import retry_with_alert
from backup_script import backup_to_s3
from send_slack import send_slack_alert

def monitor():
    print("🧠 モニタリング中...")

🔍 解説

  • monitor():将来的には CPU/メモリ監視やPrometheusとの連携も追加可能。
  • backup_to_s3():毎回呼び出されるため、Cronから実行すれば自動化も可能。

⏰ Cron への組み込み例

# 毎日3:00にmonitor.pyを実行し、S3にバックアップ
0 3 * * * /usr/bin/python3 /app/monitor.py >> /var/log/monitor.log 2>&1

✅ まとめ:このテンプレートが解決する課題

課題解決方法
Botの異常停止に気づけないSlack通知 + 自動再起動
ログがローカルにしか残らないS3へのバックアップ導入
デプロイが手動で面倒{{PAIR}} テンプレート化で自動展開
管理が分散する共通ユーティリティで一元化

🔜 次にやりたいこと

  • 📈 Grafana用のPrometheus連携テンプレート
  • 🧠 ML戦略の追加と切り替えロジック
  • 🐳 Helmによる複数Botの一括管理化
  • 🌐 Slack通知テンプレートのカスタマイズ(チャートURLや絵文字など)

🔜 次にできること

  • 実運用に合わせて config.yamlPAIR を指定して起動
  • モニタリング対象を Prometheus に拡張(ご希望あれば対応可)
  • Slack通知テンプレートのカスタマイズ(チャートURLやハイライト付き)
  • 各通貨ペアごとのPodを Helm で一括展開する仕組みへ拡張

必要に応じて、自動デプロイ化 / ダッシュボード連携 / 複数戦略統合などもサポートできます。

Yodaka

次回は「自動デプロイ化 / ダッシュボード連携 / 複数戦略統合のための方法」を詳しく説明します。

関連
開発記録#168(2025/4/3)「論文ベースのbot開発フローpart.30 Bot運用の自動化と統合」

続きを見る

👇ラジオで話したこと

テンプレート一括運用―Bot Ops(Operations) Full Stack
タイトル:テンプレートで全部回す!“運用フルスタック”を構築する方法



こんにちは、よだかです。
今回は「Bot Ops Full Stack」、つまり運用・監視・通知・バックアップまでをテンプレート一式で一気に整える方法を解説します。
このセットさえ導入すれば、複数通貨ペアBotをKubernetesで安全に走らせつつ、エラーもバックアップも自動化できます。初心者でも実装イメージがつかめるよう、コードの狙いと役割を順に見ていきましょう。


セクション1|全体像とゴール

今日触れるファイルは6つ。

ファイル役割
deployment-template.yamlK8sでBotを展開する雛形
send_slack.py異常をSlackへ通知
logger.pyコンソール+ファイルへ同時ログ出力
retry_with_alert.py処理失敗時にリトライ&Slack告知
backup_script.pylogs/modelsをS3へ転送
monitor.pyモニタ & 定期バックアップ実行

目標は「Botが落ちない・気づける・データが飛ばない」の三拍子を、テンプレートだけで担保することです。


セクション2|Kubernetes Deploymentテンプレート

まずは deployment-template.yaml

containers:
- name: bot
  image: your_dockerhub_user/crypto-bot:latest
  args: ["bots/{{PAIR}}/config.yaml"]
  resources:
    limits:
      memory: "1Gi"
      cpu: "500m"
restartPolicy: Always
  • {{PAIR}}btcusdtethusdt を流し込めば、通貨ペアごとにPodを量産。
  • restartPolicy: Always でクラッシュ時も自動再起動。
  • CPU / メモリを絞り、ほかのBotと奪い合わないようにします。

これをHelmやKustomizeから呼び出せば、一行コマンドで全ペア展開が可能です。


セクション3|通知スタック

1. send_slack.py

def send_slack_alert(message):
    payload = {"text": f"🚨 {message}"}
    requests.post(WEBHOOK_URL, json=payload)
  • Webhook URL さえ入れ替えれば即使える。
  • どのモジュールでも send_slack_alert() を呼べば通知完了。

2. retry_with_alert.py

def retry_with_alert(task_func, retries=3, delay=5, task_name=""):
    ...
  • 重要処理を包むだけで、最大3回まで自動リトライ
  • 連続失敗したらSlackへ警告。
  • 例:API発注、S3転送、DB書き込みなどで活躍。

セクション4|ロギングとバックアップ|

1. logger.py

  • get_logger("BTCUSDT")日付付きファイル+コンソールに同時出力。
  • 日々のトラブルシュートが数段ラクになります。

2. backup_script.py

for folder in ["./logs", "./models"]:
    ...
    s3.upload_file(local_path, BUCKET_NAME, s3_key)
  • logs/models/ を日付フォルダでS3に保管。
  • インスタンスが死んでも履歴は雲の上に残る——安心感が段違い。

セクション5|monitor.py で自動実行

def monitor():
    print("🧠 モニタリング中...")
  • ここに将来 Prometheusメトリクス を取り込めば、CPUやメモリ閾値で即Slack通知可能。
  • ファイル最後で backup_to_s3() を呼ぶため、cronの一行登録で「監視+バックアップ」を定期実行できます。
0 3 * * * python /app/monitor.py >> /var/log/monitor.log 2>&1

セクション6|このテンプレートが解決する課題

課題テンプレートでの解決
Bot停止に気づけないSlack通知+K8s自動再起動
ログ喪失・モデル紛失S3バックアップ
手動デプロイが面倒{{PAIR}} テンプレ化で一括展開
エラー原因が散在共通ロガー&リトライで一元管理

導入後は運用タスクが「見る・考える」だけになります。開発者は戦略ロジックに集中でき、Opsに追われにくくなるわけです。


ラストセクション|まとめと次回予告

  • Deploymentテンプレで多通貨Botを量産
  • Slack通知 + 自動再起動で“落ちても起きる”設計
  • ログ & モデルは毎日S3へ自動バックアップ
  • monitor.pyは“監視+バックアップ”の司令塔

このセットがそろえば、Bot運用はほぼ放置でOKレベルに近づきます。


🔜 次回は

「自動デプロイ化・ダッシュボード連携・複数戦略統合」
を具体的に深掘りします。Helmチャート化、GitOpsによるCDパイプライン、Grafana統合──運用を“押すだけデプロイ”に進化させる方法をお届け予定です。

🎙️おまけトーク|専業botter の“リアルな日常”



さて本編はテンプレートで運用をフルスタック化する話でしたが──
「じゃあ、そのあと botter の生活って実際どうなるの?」
今日は “夢と現実” をまぜつつ、リアルな日常をお届けします。


1️⃣ フルスタック Ops 後の平日ルーティン

4 : 30 起床 → Slack を開く

  • まず見るのは “アラート未読ゼロ” の緑バッジ。
  • 夜間に Restart → 正常復帰していれば 👀 で確認→2 秒で閉じる

5 : 00 ダッシュボード巡回(30 分)

  • Grafanaで 勝率・PnL・リソース負荷 を俯瞰。
  • 異常値がなければ終わり。あっても Prometheus→Podログ で5 分診断。

午前中 空いた時間は“攻め”

  • 新戦略リサーチ or パラメータ AB テスト
  • 実装は GitHub PR、マージ ➜ CI が自動ビルド ➜ テンプレ Helm で即反映。

午後〜夜 ほぼ自由時間

  • モニタリングは Slack 通知まかせ。
  • 月に一度、モデル更新とバックアップ世代整理を 1 時間で済ませるだけ。

感覚としては 「運用 1:開発・研究 4:自由 5」
Botが稼働しつつ自分は“浮いた時間”で次のエッジを掘る──これが理想形です。


2️⃣ クラウド請求書のリアル

ところが 夢のように見えても、お金はシビア

項目月コスト(目安)
2vCPU×3ノード(スポット)$55
S3 標準 50 GB$1.5
Prometheus + Grafana PV$4
合計約 $60/月
  • Botが 月$300 以上 利益を生むならまず黒字。
  • 収支トントン期は 「CPU 500 m → 200 m」 のように限界まで資源を絞る。
  • 無料枠+スポットインスタンス活用で コスト 40 % 圧縮 も可能です。

3️⃣ 深夜 3 時のアラート対応

実例:BTCUSDT Bot が OOMKilled → 自動再起動失敗

  1. 3 : 02 Slack🚨「Restart 3 回失敗」
  2. ベッドでスマホから Grafana → Pod log を Check
    • エラーは “メモリ上限到達” と判明
  3. k9s(モバイルSSH)で kubectl edit → memory 1 Gi → 1.5 Gi
  4. 3 : 07 Pod再起動 → OK
  5. 朝イチに Post-mortem 作成
    • 原因:NY時間急騰で取引量 4 倍
    • 対策:requests/limits 自動スケーリング を次スプリントへ登録

ポイントは「30 秒で状況把握 → 5 分で応急処置」「翌朝ドキュメント化で再発防止」。
Ops が自動化されていても、“最後は人間が判断する場面” はゼロになりません。


まとめ

  • Ops フルスタック=自由時間が増える
  • とはいえ クラウド請求と夜間アラート はリアルに存在
  • 小さく始めて、資源もタスクも 数字を見ながら段階拡張──これが稼いでいる botter の現実的スタンスです

ここからは、自動デプロイ化やダッシュボード連携をさらに深掘りして、
“押すだけデプロイ”の世界 を目指します。お楽しみに!

それでは、良き開発と堅牢なOpsを。よだかでした!

-Bot