← 一覧に戻る

senrigan-observer

GitHub ↗ Python 最終push: 2026/4/26 16:22

WIP(現在進行中)

Work In Progress

このプロジェクトで現在進行中の作業と、過去のスナップショットを記録する。

現在の状況

ステータス: 運用フェーズに入った

  • 構成: AWS Lambda (senrigan-checker, Python 3.13) + EventBridge (rate 5min) + S3 静的ホスティング (senrigan.ikapps.com) + Route 53 Alias + SNS (SMS_Alert)
  • 監視対象(2件、いずれも稼働確認済):
    • oci-o40cs-bot: O40CS Discord用Bot鯖(OCI / 158.179.191.207)の tcp:22
    • 7channel-backend: 7ちゃんねるバックエンドの https://7channel.ikapps.com/v1/healthcheck
  • メール通知の全経路(Lambda → boto3 SNS → IAM Role → SNS → email)を S3 status.json 偽装→Lambda invoke で確認済。自分のApple Gmail と知人のGmail の2宛先に届く
  • 旧 Lightsail 構成は撤去済。Lightsail インスタンス自体と他サービス(7channel-server-v2, x-account-manager-ai, phpMyAdmin)は温存

次にやること: 当面なし。追加の監視対象が出てきたら checker/targets.json に追記して ./deploy/update-lambda.sh で反映する。

詰まっていること: なし


過去のWIPアーカイブ

(新しい「現在の状況」を書く前に、古いものをここに追記でアーカイブする。新しいものが上)

2026-04-26 14:31 時点のスナップショット

雛形のまま。プロジェクト発足直後。

ROADMAP(計画)

ロードマップ

今週

  • MVP実装(Lightsail相乗り構成)
  • OCI o40cs-bot を tcp:22 で監視
  • 7ちゃんねるバックエンドを HTTP healthcheck で監視
  • 状態遷移時に SNS でメール通知
  • AWS Lambda + S3 + EventBridge へ移行
  • Lightsail 側の千里眼関連を撤去

今月

(今月中にやりたいこと)

今四半期

  • 監視対象を必要に応じて追加していく(運用駆動)

いつか

  • HTTPS化(CloudFront + ACM)。今はオーバースペック判断で見送り
  • HTTP応答の本文/JSONフィールド検証(200だけでなく中身も見る)
  • チェック間隔を対象ごとに変えられるようにする(重要対象は1分、軽い対象は10分など)
  • 障害履歴の永続化(status.json は最新のみ。S3 に時系列ログを別途)
  • 通知先を Topic 単位ではなく対象ごとに振り分けられるようにする

DECISIONS(意思決定)

意思決定記録

このプロジェクトで下した重要な意思決定を記録する。 最新が上に来る。


2026-04-26: ホスティングを Lightsail から AWS Lambda+S3+EventBridge へ移行

背景: 監視対象の1つである Lightsail(多目的サーバー)に千里眼自身を相乗りさせていたため、Lightsail が落ちると監視も一緒に落ちて誰にも検知されない構成上のおかしさがあった。

決定: AWS Lambda + EventBridge + S3 + Route 53 Alias の構成に移行する。CloudFront は使わず HTTP のみで配信。

理由:

  • Lambda/EventBridge は永久無料枠の範囲内、S3 PUT/GET も微々たる額(月¥20〜50程度)でほぼタダ
  • watcher と watchee が分離され、Lightsail 障害でも監視が継続する
  • 既存 check.py が標準ライブラリ縛りで書かれていたため、lambda_handler 追加だけで再利用できた
  • HTTPSは Basic auth もないダッシュボードに必須ではないため CloudFront はオーバースペックと判断

2026-04-26: メール通知は状態遷移時のみ送る

背景: 5分毎の監視で「障害中ずっとメール送信」だと受信箱が埋まる。一方「失敗時1通だけ」だと復旧したか分からない。

決定: OK→NG(障害発生)と NG→OK(復旧)の状態遷移を検知したときのみ、それぞれ1通だけ SNS publish する。

理由:

  • スパム化を防ぎつつ、障害発生・解消の両方を把握できる
  • 実装は前回の status.json を読み比較するだけで簡潔

2026-04-26: 通知用 SNS Topic は既存の SMS_Alert を流用

背景: 既に AWS アカウントに複数の SNS Topic があり、新規作成は冗長。

決定: 既存 Topic arn:aws:sns:ap-northeast-1:776364707178:SMS_Alert を流用する。Topic 名は SMS だが実態は email subscription(自分のApple Gmail と知人のGmail の2件)。

理由:

  • 第三者である goda.takeshichan2@gmail.com も巻き込まれることは認識した上で、運用上問題ないと判断
  • 別 Topic を作るより既存運用に乗せる方が管理コストが低い

2026-04-26: ICMP は基本使わない

背景: OCI などクラウドVMのVCNはデフォルトでICMP echo(type 8)をブロックする。unreachable が誤検知の温床になる。

決定: クラウドVMの監視は tcp:<port> で代替する。icmp チェック種別自体は残すが、運用では原則使わない。

理由:

  • TCP疎通が通っていれば「VMもsshd等のサービスも生きている」と分かるため、ICMPより強い証拠になる
  • 監視のためだけに OCI Security List を緩めるのは最小権限から外れる
  • Lambda 移行後はそもそも raw socket が使えないため ICMP 不可

DEVLOG(作業ログ)

開発日誌

このプロジェクトでの作業を時系列で記録する。 最新のエントリが上に来る。


2026-04-26

14:30 - プロジェクト発足からLambda運用化まで一気通貫

やったこと:

  1. プロジェクト目的を確定

    • サーバー等の状態を定期チェックし、静的ページから一目で異常を確認できるダッシュボード
    • 名前は「千里眼」
  2. MVP実装(Lightsail相乗り構成) — commit 9bc0976

    • checker/check.py: 標準ライブラリのみで TCP / ICMP チェック
    • web/: ダーク基調の静的ダッシュボード(30秒で自動更新)
    • deploy/: Nginx 設定 と crontab 雛形
    • 初期監視対象: OCI VM 158.179.191.207(o40cs-bot)の tcp:22
    • ICMP は OCI のSecurity Listで弾かれるため TCP のみで代替する方針に
  3. Lightsail にデプロイ

    • private repo 用に deploy key 生成 → GitHub 登録 → SSH config(Host github.com-senrigan エイリアス)
    • /opt/senrigan-observer に clone、cron 5分毎、Nginx で senrigan.ikapps.com を配信
    • DNS: senrigan.ikapps.com13.230.63.19
  4. 監視対象とUIの細かい調整

    • 表示名を「O40CS Discord用Bot鯖(OCI)」へ → commit c665cbd
    • 7ちゃんねるバックエンド(https://7channel.ikapps.com/v1/healthcheck)をHTTP監視で追加。HTTPチェック種別を check.py に追加 → commit 82f818e
    • ページタイトルと見出しを「千里眼」に変更 → commit 554b2aa
  5. AWS SNS でメール通知 — commit edac50c

    • 既存 Topic SMS_Alert(既に2つemail subscription 入り)を流用
    • 専用 IAM User senrigan-publisher を最小権限(sns:Publish のみ)で作成
    • Lightsail に [senrigan] profile として access key を配置
    • 状態遷移(OK→NG / NG→OK)時のみ1通publishする実装
    • awscli を Lightsail に install して subprocess で叩く方式
  6. 「watcher と watchee 同居」問題の指摘 → 移行決断

    • 監視対象である Lightsail に監視自体を同居させる構成上のおかしさ
    • 移行先を Lambda+EventBridge+S3(ほぼ無料)に決定。CloudFront は不採用(HTTPS不要)
  7. AWS Lambda + S3 + EventBridge へ移行 — commit 0752543

    • check.py をリファクタし、CLI モードと Lambda モードの両対応に(lambda_handler 追加)
    • S3 バケット senrigan.ikapps.com 作成、静的ホスティング有効化、public read ポリシー
    • IAM Role senrigan-lambda-role(S3 RW + ListBucket + SNS Publish + Logs)
    • Lambda zip(check.py + targets.json)を senrigan-checker (Python 3.13) として作成
    • EventBridge senrigan-schedule を rate(5 minutes) で作成
    • Route 53 の senrigan.ikapps.com を S3 Website Endpoint への Alias に切替(権限不足のためユーザーに手動編集依頼)
    • deploy/ を Lambda/S3 デプロイスクリプトに置き換え(update-lambda.sh / update-web.sh
  8. Lightsail 側の千里眼関連だけ撤去(インスタンスや他サービスは温存)

    • crontab エントリ削除、Nginx 設定削除(nginx -t 通過後 reload)、/opt/senrigan-observer 削除
    • [senrigan] AWS profile 削除([default] は温存)、SSH キー / ~/.ssh/configgithub.com-senrigan ブロック削除
    • GitHub deploy key 削除、IAM User senrigan-publisher(access key 含む)削除
  9. メール通知の経路検証

    • S3 の status.json を偽装(oci-o40cs-bot の ok=false に書き換え)→ Lambda 手動invoke
    • 「前回ng / 今回ok」を検出し UP(復旧)メールが配信されるのを確認

気づき / メモ:

  • macOS と Linux で ping -W の単位が違う(macOS: ms / Linux: sec)。_ping_timeout_arg() で吸収済み
  • OCI のVCNはデフォルトでICMP echoをブロックしている。TCP疎通で代替するのが原則
  • SNS publish の --subject は ASCII 必須(本文は UTF-8 OK)
  • S3 で website hosting alias を Route 53 に張る場合、バケット名はDNS名と一致させる必要あり
  • Lambda は raw socket 非対応のため ICMP 不可。TCP/HTTP のみで設計したのが結果的に正解
  • 初回 Lambda 起動時に s3:ListBucket 権限不足で AccessDenied(S3はNoSuchKeyの代わりにAccessDeniedを返す)。policyに ListBucket 追加で解消

次回やること(あれば):

  • 当面なし。運用しながら必要な監視対象を追加していく

最近のコミット

README

senrigan-observer

サーバー等の状態を定期チェックし、静的ページから一目で異常を確認できる監視ダッシュボード。

公開URL: http://senrigan.ikapps.com/

構成

EventBridge (rate(5 minutes))
  ↓ invoke
Lambda: senrigan-checker (Python 3.13)
  ├─ checker/targets.json の対象に対して TCP / HTTP チェック
  ├─ S3 から前回の status.json を読み state 比較
  ├─ 状態遷移 (OK→NG / NG→OK) があれば SNS publish
  └─ 新 status.json を S3 へ書込み
        ↓
S3 バケット: senrigan.ikapps.com (静的ホスティング)
  ├─ index.html / style.css / app.js
  └─ data/status.json
        ↓
Route 53: senrigan.ikapps.com (Alias → S3 website endpoint)

ディレクトリ

senrigan-observer/
├── checker/
│   ├── check.py            # CLI と Lambda 両対応
│   └── targets.json        # 監視対象の定義
├── web/
│   ├── index.html
│   ├── style.css
│   └── app.js
└── deploy/
    ├── update-lambda.sh    # Lambda コード更新
    └── update-web.sh       # 静的ページ S3 同期

監視対象の追加

checker/targets.json に追記してから:

./deploy/update-lambda.sh

対応チェック種別:

spec 内容
tcp:<port> TCPポート疎通
http://... / https://... HTTP GET、2xxをOK判定
icmp Lambdaでは利用不可(raw socket非対応)

通知

OK→NG または NG→OK の遷移が起きたタイミングで、SNS Topic arn:aws:sns:ap-northeast-1:776364707178:SMS_Alert へ publish される。Topic の subscription 経由でメール等に届く。

通知先を変えたい場合は Lambda の環境変数 SNS_TOPIC_ARN を変更:

aws lambda update-function-configuration \
  --function-name senrigan-checker \
  --environment 'Variables={BUCKET_NAME=senrigan.ikapps.com,STATUS_KEY=data/status.json,SNS_TOPIC_ARN=<新ARN>}' \
  --region ap-northeast-1 --profile ichirokisanuki

ローカル開発

check.py は CLI モードもサポート。

python3 checker/check.py
cat web/data/status.json

ローカル CLI で SNS 通知をテストするには checker/notify.json を作る(gitignore済):

{
  "sns_topic_arn": "arn:aws:sns:...",
  "aws_profile": "default",
  "aws_region": "ap-northeast-1"
}

AWS リソース一覧

リソース 名前 リージョン
S3 Bucket senrigan.ikapps.com ap-northeast-1
Lambda Function senrigan-checker ap-northeast-1
IAM Role senrigan-lambda-role グローバル
EventBridge Rule senrigan-schedule ap-northeast-1
SNS Topic(共有) SMS_Alert ap-northeast-1
Route 53 senrigan.ikapps.com (A Alias → S3) グローバル

現在の監視対象

ID 対象 チェック
oci-o40cs-bot O40CS Discord用Bot鯖(OCI) (158.179.191.207) tcp:22
7channel-backend 7ちゃんねる バックエンド (7channel.ikapps.com) https://7channel.ikapps.com/v1/healthcheck