Goでアプリケーションのメトリクスを操作する

1408

こんにちは。インターンの木村です。
今回は、「現在のアクセス数」などのアプリケーションのメトリクスをGoで操作する方法を紹介します。

メトリクスの登録、公開

Goでメトリクスを操作するときは、expvarパッケージを使います。今回は「現在の接続数」を例にして説明します。

まず、testAPPのメトリクス用に以下のようにパッケージを作ります。

package metrics

import (
  "expvar"
)

var (
  MetricsMap               = expvar.NewMap("testApp") // testApp用のMapを用意
  MetricsCurrentConnection = new(expvar.Int) // Mapに入れる値。(接続数など)
)

func init() {
// init()でMetricsMapに値を登録
  MetricsMap.Set("current_connection", MetricsConnectionCount)
}

このパッケージをtestAppのソースでimportすることで、http://testAppURL/debug/varsにJSONフォーマットで公開されます。

testAppソース内では、メトリクスの値の更新を行います。ユーザーが接続してきて、値を増やしたいときは、以下のようにします。

metrics.MetricsCurrentConnection.Add(1)
逆に接続が終わって接続数を減らしたいときは、単純に、

metrics.MetricsCurrentConnection.Add(-1)
として値を減らします。

このようにして操作した結果、http://testAppURL/debug/varsにアクセスすることで以下のようなその時点の値を見ることができます。

"testApp": {"current_connection": 0}

コード内でメトリクスを取得する

さて、上記のようにしてhttp://testAppURL/debug/varsにアクセスすればメトリクスを取得できるようになりました。
でも、コード内からも値を取得したいですよね?その方法を紹介します。

例えば、metricsパッケージ内にメトリクスを取得する関数を作ったときは、以下のように値を取得します。

//Interface{}型で取得したtestAppのメトリクスを*expvar.Map型に変換
testAppMetrics := expvar.Get("testApp").(*expvar.Map) 
//testAppMetricsから"current_connection"の値をinterface{}型で取得し、*expvar.Int型に変換
currentConnection := testAppMetrics.Get("current_connection").(*expvar.Int) 
//値を標準のfloat64型に変換
val := float64(currentConnection.Value()) 

expvarのGetメソッドで値を取得できるのですが、戻り値はinterface{}なので実際にこの値を使って色々したいときは型アサーションします。
この例では、”testApp”メトリクスを最初に作ったMapとして取得し、その中身である”current_connection”の値を取得してfloat64型に変換しました。

今回はGoによるメトリクス操作のお話でした。

参考

https://qiita.com/methane/items/8f56f663d6da4dee9f64