← 作品一覧

DATAAzure Functions / SQL / Blob Storage / Static Web Apps / Application Insights

Mod Insight

「たぶん伸びている」(これまで)

毎日の数字で確かめる(その後)

自分が Thunderstore と Nexus Mods で公開している mod 50 件のダウンロード数・評価・バージョンを、毎日自動で集めて履歴として残し、増え方をグラフで分析するダッシュボードです。扱っているのは、実際に使われている mod の数字です。

ダッシュボードは Azure の学生向けクレジットで動かしていて、いずれ止まる可能性があります。このページには画面と数字を載せてあるので、止まった後もこのまま読めます。

mod の数・取得時刻・費用は 2026-10-07 時点、表示時間は 2026-09-16 の計測(Mod-Insight の README と運用記録より)。

01課題

見えるのは「今の合計」だけ

Thunderstore の mod ページに出るのは、今の時点のダウンロード数の合計だけです。Nexus Mods とは数え方も画面も違うので、2 か所を並べて比べることもできません。

そのため、更新を出した後に増え方が変わったのか、どちらのサイトで伸びているのかは、毎日ページを見に行っても確かめられませんでした。

02ねらい

履歴を残して、同じ物差しで比べる

  1. 増え方を見る毎日同じ時刻に両サイトから取って履歴に残し、日ごとの増え方や更新の前後を見られるようにする。
  2. そろえて比べる2 つのサイトの数え方の違いをそろえて、同じ表とグラフで比べられるようにする。
  3. 対象を替えても使える「取得 → 保存 → 集計 API → 画面」の流れで作っておけば、EC の商品やアプリなど、API で数字が取れる別のものに替えても同じ作りで使える。

03設計

書き込みは 1 日 1 回、読み取りは DB を起こさない

書き込み1 日 1 回

  1. タイマー毎日 0:00(日本時間)に起動
  2. アダプターThunderstore/Nexus Mods の応答を共通の形に直す
  3. Azure SQL取得のたびに 1 行ずつ履歴を足す
  4. Blob画面が使う応答をすべて作り直して置く

読み取り開くたび

  1. ブラウザStatic Web Apps の HTML+Chart.js
  2. GET APIAzure Functions
  3. Blob最後の取得で作った応答をそのまま返す
  4. Azure SQLBlob が読めない時だけ
データは 1 日 1 回しか変わらないので、画面が使う応答は取得の直後にまとめて作り、Blob に置いておきます。黄色の Blob が、2 本の流れの接点です。配布サイトを増やす時は、共通の形を返すアダプターを 1 つ足すだけで、保存と API は変えません。

数字の作り方で決めたこと

日ごとの増加

取得回ごとの合計の差を「増加」にする(これまで)

mod ごとに前日との差を出してから足す(その後)

途中で mod が増えると、その mod のそれまでのダウンロード数がそのまま段差になります。Nexus Mods を追加した 9/15 は、合計の差だと +5,904、本当の増加は 348 でした。

取得の時刻

1 行ずつ保存した時刻を入れる(これまで)

1 回の取得で保存する行には、すべて同じ時刻を入れる(その後)

取得に数分かかっても時刻がばらけないので、時刻でまとめるだけで、配布サイトをまたいだ回ごとの合計が出ます。

2 サイトの違い

サイトごとに数え方が違うまま並べる(これまで)

「1 mod の 1 バージョンは 1 行」にそろえる(その後)

Thunderstore の一覧には総ダウンロード数の項目がないので、バージョンごとの数を足しています。Nexus Mods は同じバージョン番号のファイルが複数あるので、番号でまとめています。

取得した応答

表にある項目だけを保存する(これまで)

API の応答を丸ごと残しておく(その後)

あとからバージョン別の推移を見たくなった時、専用の表を作って、過去の分をこの保存データから埋め戻せました。

04実装

選んだ理由と、運用してから直したこと

全 mod の状況。合計ダウンロード数、期間内の増加、追跡中の mod 数と、合計の推移グラフ、mod ごとの一覧
全 mod の状況(2026-10-07)
mod ごとの詳細。ダウンロード数の推移にバージョン公開日の縦線、バージョン別の積み上げグラフ
mod ごとの推移とバージョン別の積み上げ
役割使っているもの選んだ理由
取得ジョブ・APIAzure Functions(Node.js)1 日 1 回のジョブと少量の API のために、サーバーを動かし続ける必要がない。Static Web Apps 付属の Functions はタイマー起動ができないので、独立した Function App にした
データベースAzure SQL Database(無料枠)mod・バージョン・時系列の関係がはっきりしていて、集計を JOIN とウィンドウ関数で書ける
読み取りキャッシュBlob Storage応答は 1 日 1 回しか変わらないので、JSON を置いておけば足りる。DB を止めたままにできる
画面HTML/JavaScript+Chart.js1 画面にグラフが数枚だけなので、ビルドの要らない作りにした
監視Application Insights+アラート「ジョブが動かなかった」「失敗した」をメールで知らせる
自動配置GitHub Actions+OpenID ConnectGitHub にパスワードを置かずに済む。main ブランチからの要求だけを受け付ける

運用してから直したこと

その日はじめての表示に約 50 秒

原因は Azure SQL(サーバーレス)の自動一時停止でした。しばらく使われないと止まり、次の接続で起きるまで約 1 分かかります。1 日 1 回の取得以外は人が開いた時しか DB を使わないので、ほぼ毎回「最初の 1 人が待つ」状態でした。

画面を開くたびに DB に問い合わせる(これまで)

取得の直後に応答を Blob に置き、API はそれを返す(その後)

最初の一覧の取得にかかる時間は、対策前の 47.7〜52.9 秒から 0.34 秒になりました(どちらも DB が止まっている状態で計測)。DB が起きるのは 1 日 1 回の取得の時だけです。

費用のほとんどが監視だった

ログ検索のアラートは、通知が出たかどうかに関係なく「本数 × 時間」で料金がかかります。3 本で月約 225 円になっていました。DB と Functions はどちらも 0 円で、費用のほとんどが監視でした。

取得の異常ごとにアラートを 1 本ずつ作る(これまで)

3 つの条件を 1 本のクエリにまとめ、問題の種類で分ける(その後)

監視の費用は月約 225 円から約 75 円になり、全体では月約 90 円です。1 本にしても、通知には何が起きたかが出ます。

調査の手順と計測の記録は 運用記録 にあります。

05反応

約 3 週間分のデータから分かったこと(2026-10-07 時点)

1 日の増加は、両サイトで同じ時期に約 4 割下がった

7 日平均は最初から Thunderstore で 44%、Nexus Mods で 43% 下がり、ほぼ同じ時期に戻り始めました。サイトごとの事情ではなく、ゲーム自体の遊ばれ方のような共通の要因を疑う材料になります。原因まではこのデータだけでは分かりません。

新しく増えるダウンロードの約 86% は Thunderstore です(1 日平均 199.3 対 33.1)。

日ごとの増加の棒グラフと 7 日平均の線

同じ更新でも、サイトによって反応が違う

BattleImprovements_fix 1.5.7 の公開前後 7 日を比べました。

公開前(1 日)公開後(1 日)新しい版の割合
Thunderstore19.324.01 日目 84.4%
Nexus Mods7.73.01 日目 75%

Thunderstore では公開後 2 日間だけ増え、新しい版が 1 日目から選ばれていました。増えた分には、mod マネージャーで更新した既存の利用者も入っていると考えています(更新もダウンロードとして数えられるため)。Nexus Mods は 1 日数件の規模なので、差が更新によるものかは判断できません。比べられる公開はまだ 1 回だけです。

公開の前後の表と、新しい版が占める割合の折れ線グラフ

Rummage は最初の 1 週間がいちばん伸びた

9/15 に公開した Rummage は、Thunderstore で 1 週目 +66、2 週目 +46、3 週目 +34 と増え方が落ち着いていきました。Nexus Mods の割合は約 18% で、全 mod の累計での割合とほぼ同じです。

まだ分からないこと