Slack Metricsのローカル環境とstg環境がどうつながり、どこで取り違えが起きたのかを、実際のAPI・SQS・CloudWatchログに沿って整理します。結論は、Wi‑Fiよりも「入口のURL」「DBごとのID」「キューを読むWorker」の3点です。
workspace_id はチャンネル番号ではなく、DB内のSlackワークスペース管理番号。Slackのチャンネル番号ではなく、アプリがワークスペースを管理するためのDB主キーです。
| 項目 | 意味 | 例 |
|---|---|---|
| workspaces.id | アプリDB内のワークスペース管理番号 | ローカル=1 / stg=3 |
| channels.workspace_id | どのワークスペースに属するか | 3 |
| channels.source_id | Slack側のチャンネルID | Cから始まるID |
X-WORKSPACE-ID: 123 は「3番チャンネルを同期」ではなく、「stg RDSの workspaces.id=3 に紐づくSlack全体を同期」という指定です。
内部IDは環境ごとのDBで別々に採番されます。名前が同じでも番号は共有されません。
| APIの入口 | 参照DB | 使うID |
|---|---|---|
| localhost:8080 | ローカルPostgreSQL | 1 |
| api.stg.example.com | stg RDS | 3 |
環境とIDはセット。 localhostから送ったid=1をstg Workerが処理すると、stg RDSにid=1がないため not found になります。
入口から保存先まで、すべてstg側へ揃えると迷いません。
curl --request POST \ 'https://api.stg.example.com/api/workspace-sync?from=2026-08-12&to=2026-08-13' \ --header 'X-WORKSPACE-ID: 123'
POST /api/workspace-syncReceived messageSuccessfully handled messageWi‑Fiが原因とは確認されていません。 最初のcurlで確認できた直接原因は、HTTPの80番へ接続した一方、ALBにはHTTPS 443しかなかったことです。
同じAWSキューを見ていれば、ECS Workerとの競合Consumerになります。
| 受信したWorker | 参照先 | 起こり得る結果 |
|---|---|---|
| ECS Worker | stg RDS | stgのIDなら正常処理 |
| ローカルWorker | ローカルPostgreSQL | stgのIDがなくnot foundになる可能性 |
stg動作確認中はローカルの MODE=sqs go run main.go を停止し、ECS WorkerだけをConsumerにするのが最も分かりやすい運用です。
ここは推測と事実を分ける。 ローカルWorkerが起動していれば競合し得ます。ただしCloudWatchの /ecs/slack-metrics-worker-stg に出たfailはECS Workerのログです。ローカル標準出力が自動転送されたわけではありません。
成功と失敗は同じ処理ではなく、メッセージIDが異なる別々の仕事でした。
| 出来事 | 確認結果 | 判定 |
|---|---|---|
| http://ALBへcurl | ポート80にリスナーなし | API到達前に失敗 |
| message 14690a72-… / id=3 | Successfully handled message | stg同期成功 |
| message 7669f475-… / id=1 | WorkspaceRepo.Load: not found | 古い別メッセージが失敗 |
message_id を見る。同じIDの Received message と Successfully handled message を1組として追う。