go-check-css-selector — CSS セレクタで要素の存在をチェックする Mackerel チェックプラグインを作った

2 年前くらいに作っていたけどどこにも書いてなかったのでちょっと整備してブログに書いておく。CRE になって数ヶ月した頃に「そういえば仕組みは理解してるけど自分で Mackerel のチェックプラグインを作ったことがなかったな」と思い立ち作ってみたもの。

github.com

go-check-css-selector は指定された URL にアクセスし、HTML 内に指定した CSS セレクタにマッチする要素が存在するかをチェックするシンプルなプラグイン。セレクタで指定した要素が見つかれば OK、見つからなければ CRITICAL、URL へのアクセスや HTML のパースでエラーが発生したら UNKNOWN を返す。

使い方は以下のような感じ。

[plugin.checks.check-css-selector-sample]
command = ["go-check-css-selector", "-U", "https://example.com", "-S", "div.content"]

実装としては素朴で GET した HTML をパースして要素を探しているだけ。もうちょっと高度なことをやろうとするとヘッドレスブラウザを使う必要が出てきそう。というのはすでにチームメンバーの id:kmuto が Playwright と mkr wrap の組み合わせでやっていた。

Go のアプリケーションとしてチェックプラグインを書く場合は checkers パッケージを使うと本当に簡単に書ける。チェック結果のステータスやメッセージの生成、標準出力への出力も全部やってくれるので、実装はチェックロジックに集中できる。

年末にリポジトリの棚卸しをしていてこのプラグインの存在を思い出したので記事を書いてみている。久しぶりに見返してみたらコードに TODO コメントが残っていたり、GitHub のリリース周りの設定もそういえばしたことがなかったのでついでに整備した。goreleaser はドキュメントを見つつ設定したら特に詰まるところもなかった。今回は tag は手で打ったけど、リリースワークフローをもうちょっと整備すればさらに楽になりそう。Immutable Releases ってやつを有効にするといいと見たのでついでに有効にしてみた。

ものづくりと AI

プログラミングを覚えたてのころ、狂ったように Greasemonkey スクリプトを書いていた。自分の生活を便利にするためのアイデアをシュッと形にできて、ブログに公開するとフィードバックをもらえるというのがうれしかった。greasemonkey カテゴリ の記事を見ると当時の様子が伺える(はてなダイアリーの時のログもそのまま残っていて便利ですね)

現代では AI と一緒にコードを書くことが当たり前になり、高速にアイデアを形にできるようになった。AI にとっかかりのアイデアを形にしてもらってそのコードを読み書きして改良したり、そこからさらに AI に手伝ってもらってアイデアを膨らませつつ物を作っていくという工程を楽しんでいるうちに、これは冒頭に書いたアイデアを形にしていく楽しさに近いなと感じるようになった。いわゆる Vibe Coding と呼ばれるようなアプローチで、AI が書いたコードを読んで理解し手直しする対話の中にも学びがあるし、何より技術的な壁が下がって「作りたいもの」に集中できるのがうれしい。

そんな風にアイデアを形にして作ったものを紹介する。

Mackerel Pricing Calculator

Mackerelの料金を計算するためのツール1。Mackerel の課金体系は、基本部分は従量課金性でわかりやすいのだけど細かい部分で無料枠があったり最低利用料金があったりする。もともとスプレッドシートで料金計算ツールを作っていたりしたけど、より手軽に使えるように Web アプリにしてみたもの。

最初のロジックを作るところから Claude Code に料金ページを読ませて全部任せてから、実際に触ってみて計算ロジックに間違いがないかを確認しつつ手直しを続けている。細かいところが色々間違っていたのだけど、AI の解釈に問題があるという可能性がある一方で、料金ページの方にも曖昧なところがあるということだとも思うので、それはフィードバックしたい。ペライチ HTML かつライブラリを使わずに作るという方針にしているので本当に素朴なコードになっている。

はてなブログ アイキャッチビルダー

はてなブログには有料プランの機能として、自動生成されるアイキャッチ画像を HTML を書くことでカスタマイズできる機能がある。この時に設定する HTML は、はてなブログの管理画面からもプレビューができるのだけど、Web 上に埋め込まれたエディタを使わないといけない。これをローカルでプレビューできるようにするためのツールを作っている。

とりあえず動くところまではできているけど、そもそもの構成が回りくどくなっていたり追加したい機能もあるので改善していきたい。

おまけ: Radar Chart as a Service

任意の軸と点数を設定してレーダーチャートを共有できるサービス。昔同僚の誰かが欲しいと言ってたよなというのを思い出して作ったんだけど、それ以上は特になし。

***

特にアイキャッチビルダーなどは、気づいたら遅い時間までコードをいじっていたという体験を久しぶりにするくらいアイデアを形にすることが楽しかった。新しい技術を学ぶことも好きだが、それは手段であって、作りたいものを形にすることが出発点だ。とりあえず動くものを作って改良していく。AI エージェントのおかげでものづくりに集中できるようになった。


この記事ははてなエンジニア Advent Calendar 2025 33日目の記事です。


  1. 筆者は Mackerel の CRE をしているが、これは個人活動で作った非公式のツール

Cloudflare AI Search で Mackerel ドキュメントを検索するチャットボットを作った

この記事は Mackerel Advent Calendar 2025 20日目の記事です。


最近は日々の生活を便利にするサイトやスクリプトを動かすために Cloudflare の Workers や Cron Triggers を使っている。CLI ツールである Wrangler を使うと気軽にデプロイやリソースの操作ができて便利だし、いい感じにエコシステムが整っていて KV(Key-Value ストア)、D1(SQL データベース)、R2(オブジェクトストレージ)あたりとの連携も簡単にできる。そんな Cloudflare を使い今回は Mackerel のドキュメントを検索できるチャットボットを作ってみた。

コードは以下のリポジトリにありますが、Cloudflare と Slack での Web コンソール上の設定も必要なため、そのまますぐに動作する状態にはなっていません。

github.com

仕組みを簡単に説明するとこんな感じ。

  • Mackerel のドキュメントを R2 に保存
    • 加工などはせず公開されている Markdown をそのまま同期。お試しということで定期実行の仕組みまでは作らず素朴に手元から同期している
  • AI Search のデータソースとして上記 R2 を指定
    • ベクトル化やインデックス作成は AI Search が自動的にやってくれる。こちらもお試しということでベクトル化や回答生成のモデルはデフォルトのものを使っている
  • Workers でエンドポイントを実装し Slack の slash command からのリクエストを受け、AI Search にクエリを投げて回答を生成

構成
構成

動作イメージはこんな感じ。

サバオ

モデル選定やシステムプロンプトの調整は行っていないため、回答品質の評価はまだできていない。一方で、未使用だった Cloudflare の機能を試す良い機会にはなった。ただし、ドキュメント検索と回答生成は AI Search に任せきりで、その部分は素振りになっていないので精度のチューニングをしつつ学んでいきたい。

Claude Code CLI と Mackerel MCP サーバーで Web アプリケーションの課題を解決してみる

Mackerel の MCP サーバーがリリースされたので、Mackerel のトレーシング機能のハンズオンの Web アプリケーションを題材に、課題の分析とコードの修正ができるか試してみた。

目次

Claude Code CLI の MCP サーバー設定

MCP サーバーの設定

まず Claude Code CLI に MCP サーバーを追加する。これは claude mcp add コマンドでできる。設定は --scope オプションによって保存される場所が変わる。また、下記のようなオプションにすると、MACKEREL_APIKEY が展開されて保存されることに注意。

claude mcp add mackerel --scope local  --env MACKEREL_APIKEY="${MACKEREL_APIKEY}" -- npx -y @mackerel/mcp-server

動作確認

Claude Code CLI を起動して、MCP サーバーが正しく設定されているか確認する

> /mcp
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Manage MCP servers                                                                                                               │
│                                                                                                                                  │
│ ❯ 1. mackerel            ✔ connected · Enter to view details                                                                     │
│                                                                                                                                  │
│ MCP Config locations (by scope):                                                                                                 │
│  • User config (available in all your projects):                                                                                 │
│    • /Users/kga/.claude.json                                                                                                     │
│  • Project config (shared via .mcp.json):                                                                                        │
│    • /Users/kga/ghq/github.com/mackerelio/mackerel-handson/tracing/demo/sample-app/ruby/.mcp.json (file does not exist)          │
│  • Local config (private to you in this project):                                                                                │
│    • /Users/kga/.claude.json [project: /Users/kga/ghq/github.com/mackerelio/mackerel-handson/tracing/demo/sample-app/ruby]       │
│                                                                                                                                  │
│ For help configuring MCP servers, see: https://docs.claude.com/en/docs/claude-code/mcp                                           │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

Claude が Mackerel API を呼び出せていれば成功。

> Mackerel に登録されているホストの数を教えて

⏺ Mackerel に登録されているホストの数を確認します。
  ⎿  {
       "hosts": [
         {
     … +750 lines (ctrl+o to expand)

⏺ 4台

トレーシングハンズオンの事前準備

準備のドキュメントを参考に、起動のための事前準備や Mackerel にトレースをエクスポートするための API キーの設定を済ませる。

また、本来のハンズオンでは、コード中に課題の改善のためのコメントが含まれているがカンニングされないようにこれを削除しておく。

Mackerel MCP サーバーを使った課題の解決

ハンズオンのアプリケーションには以下のような課題が含まれている。

  • エラーが発生する
  • 処理時間が遅い
  • N+1 問題が起きている

これを解決させてみる。

手順

2 と 3 を繰り返す。

  1. ハンズオンアプリケーションを立ち上げる
  2. エンドポイント(/products)にアクセスし、Mackerel にトレースをエクスポートする
  3. Mackerel のトレース詳細画面からトレースIDをコピーし Claude に課題解決を依頼する

課題解決の様子

Claude に以下のように依頼する

このディレクトリに含まれるアプリケーションにはいくつか問題が含まれています。
トレースID 1c8263e7dd735d7b68dcb22f62a37a81 のトレースを Mackerel から取得しその問題を修正してください

エラーが起きているとか、エンドポイントが遅いのような具体的な課題については触れなかったが、まずはエラーを発見し直してくれた。あと、typo も見つけてくれた(試したハンズオンのバージョンが古かった。既に直っています)。

トレースデータから、以下の問題を検出しました:

#### 検出された問題

**問題1: RuntimeError が発生**
- ファイル: `app/controllers/product_controller.rb:32`
- エラー内容: `RuntimeError: Sleep time is too long: 3`
- 原因: `method_sample` メソッドで `n > 2` の場合に例外を発生させている

**問題2: JSON レスポンスのキーにタイポ**
- ファイル: `app/controllers/product_controller.rb:8`
- 誤: `prirce`
- 正: `price`

次のイテレーション

修正を入れたトレースはこれです。さらに改善案を提案してください
a5be924c50c529fbf887596fb3a15c14
**問題1: N+1 クエリ問題(重大)**
- 100個の商品それぞれに対して、個別にカテゴリを取得
- トレースに100個の `SELECT "categories".* FROM "categories" WHERE "categories"."id" = ? LIMIT ?` クエリが存在
- 影響: データベースへの不要なクエリが大量発生し、パフォーマンスが大幅に低下

**問題2: 不要な sleep 処理(中)**
- `method_sample` メソッドで1秒、2秒、3秒の sleep を実行(合計6秒)
- 影響: レスポンス時間が6秒以上増加

**レスポンス時間の内訳**
- リクエスト全体: 約6.3秒
  - 初期クエリ: 約0.12秒
  - Category N+1 クエリ: 約0.15秒
  - method_sample sleep: 6秒

まとめ

**✅ 改善された点**
1. **N+1 クエリが解消**
   - カテゴリクエリが1回のみ: `SELECT "categories".* FROM "categories" WHERE "categories"."id" IN (...)`
   - 100個のIDをまとめて取得(IN句使用)

2. **レスポンス時間が大幅改善**
   - 全体: 約 **46ms**
   - 以前: 6.3秒 → **約137倍の高速化!**

3. **DBクエリ数の削減**
   - 商品クエリ: 1回
   - カテゴリクエリ: 1回
   - 合計: **2回**(以前は102回)

ということで、Claude Code CLI と Mackerel MCP サーバーを組み合わせることで、トレースの内容を取得し様々な課題解決を LLM にやってもらうことができた。トレースの一覧やエラーDBパフォーマンスHTTPパフォーマンスなども MCP サーバーから取得できるようになるとさらに夢が広がりそう。