読者です 読者をやめる 読者になる 読者になる

銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

HTTP API を使って C# で New Relic Pluginを作る (1)

前回のめとべや東京でも話題に出した通り、New Relic はSaaS形式の監視サービスの神ツールなわけですが、

実はプラグインでさらにいろいろなものを監視することができます。すでに公開されているPluginを使うことができるのですが、自分でPluginを作ることもできます。ちょうどPerformance Monitorの値をPlugin経由で監視したくなり、C# でPlugin(の元)を作ったので紹介したいと思います。 ちなみに、無償枠のアカウントでもプラグインの作成と動作確認ができました。

まず、New Relic のPlugin開発については、「Developing Plugins」を一通り軽く目を通しておきましょう。さて、そもそも 「Choosing a development language for your plugin」 にあるように、JavaとRubyであればSDKが提供されています。それでも、今回C# から HTTP APIを叩くようにしたのは、パフォーマンスモニターの値を取得したかったからです。もちろん、JavaやRubyからコマンドライン経由で取得することができますが、C# のコードから直接叩けるようにした方がなにかと都合がよさそうだったので、HTTP API を叩くことにしました。

今回はまず適当な乱数を送信するPluginを作ってみましょう。APIの仕様は Metric data for the HTTP Plugin API にあります。 JSONで送信するので、JSON.NET をNugetに入れた上で、サンプルコードは次のようになります。

まず、NewRelicにログインして、ライセンスキー(NewRelic Agentとかのインストールで使うやつ)をコピーっておきます。これを、 X-License-Key ヘッダーにつけて送信します。 HTTP APIの制限で1分間に1回までしか送信できないので、1分間ごとに実行するようにwhile文で書いています。また、duration で前回送信からの時間を送信するので、 last 変数を使っています。 payload 変数に格納しているものが、APIに送信するJSONのデータになります。今回は匿名型で書いてます。agent のホストとpidは仕様なのでそのまま送っていますが、これは測定データとしては表示されません。

肝心のデータはcomponents の方で、まず、guid はPluginで一意になる値で、Java のパッケージ名的な命名規約が推奨されています。ピリオド区切りで最後の単語がデフォルトでプラグインの名前として表示されるようです。そして、name ですが、これはプラグインの性質により都合のいい名前をつけるのがいいかと思われます。後から画面を出しますが、Componentごとにグラフを表示するので、(今回のケースだと)サーバーの名前を表示するのがわかりやすくなります。今回はホスト名をそのまま名前にしています。

最後にMetricsですが、これはJSONのキーがそのままMetricsの名前になります。Component/<pluginの名前>/<測定値> という形式になります。単位も測定値のあとにいれるのがいいのですが、これは次回以降に説明したいと思います。 あとは、指定されたURLにPOSTするだけ、ということで割と簡単にPluginができてしまいました。実行してみましょう。 (Mainメソッド中で実行することを想定しているので、非同期メソッドをResultで受けて同期的に待機しています) ログを見て正常に送信できていそうだったら、NewRelicの画面を見ます。(送信完了後、数十秒もすれば画面に反映されました)

f:id:tanaka733:20130921110648p:plain

左側のタブ一覧に、プラグインの名前が追加されているはずです。それを選択すると、Componentの名前一覧が表示されます。 これを選択するとダッシュボードが表示され、うまく送信されているようならデフォルトでその値のグラフが表示されています。

f:id:tanaka733:20130921110706p:plain

まあ、乱数なので何の面白味もありませんね。

さて、1分間隔の測定値しか送信できないのか、という疑問を持たれた方もいるかもしれません。 1分間(もしくはそれ以上の時間間隔)の平均、最小、最大、和、平方和を送信してデータ処理する仕組みがNewRelic側にあるので、負荷の心配が少ない Perfmon の項目であれば1秒おきにデータを取得して、NewRelic側には1分おきにデータ送信する、という仕掛けが考えられます。 このあたりの実際にPerfmon のデータを送信する処理はまた次回紹介したいと思います。Rxの出番になります。