Nature Remo Eを使って、消費電力をNew Relicに送信する

Hey, NewRelic Advent Calendar 2020 - Qiita, 15日目の記事だよ!時差があるのは気にしないで!

電力消費量が気になる季節がやってまいりました。ということで、Nature Remo Eを使って電力消費マネジメントの第一歩目である「計測せよ」にチャレンジしてみます。

Nature Remo Eを買う

買ってください

Nature API Tokenを取得する

Remo Eを良い感じにセットアップしていただいて、 https://home.nature.global/ にログインしたらなんとなくtokenが発行できます。

New Relicに情報を送る

電力消費情報をNew Relicに送ることで、アラートを設定して不測の事態に対応したり、パフォーマンスを可視化し、コストをコントロールするためのインサイトを得たりができるようになります。

New Relicに情報を送る方法はいくつかあります。Infrastructureエージェントを動かしているならnri-flex設定はシンプルなのでおすすめではありますが、せっかくなので2020年春あたりから整備されてきた新しいNew Relic Metrics APIを使って、情報を送ることにしましょう。

Nature APIから情報を持ってくる

go-remoeというライブラリがなんとすでにあるので、ありがたく使ってみることにします。解説のブログ記事を見た感じでは、以下2つが候補になります:

  • 瞬時消費電力: その瞬間の消費電力。スピードメーター的なもの。
  • 期間当り(たとえば1分当り)の消費電力: ある期間の消費電力を出すためには、期間終了時の積算消費電力から期間開始時の積算消費電力を良い感じに(正方向と逆方向を適当に)引く必要がある。

瞬時消費電力は扱いが簡単そうです。一方、期間の消費電力を扱うにはなんかちょっと計算をする必要があるようで、うーんなかなか難しい。とりあえず生のデータだけNew Relicに送っておいて、計算は後で考えることにしましょう。

計測・送信間隔は雰囲気的に1分毎を想定してみます。crontabで毎分実行させたり、現代的にはAWSCloudWatch Eventsを使って毎分Lambdaをinvokeさせるような想定です(Lambda Handlerへの実装は、読者の課題とする)。

New Relicに送る

New Relic Metrics APIを眺めてみると、Metrics APIを直接使う方法や、各言語のテレメトリSDK経由で送る方法にたどり着きます。そのあたりから、newrelic-telemetry-sdk-goにたどり着いてみましょう。

メトリックは3種類あると記載されています:

Basic type Aggregated type Description Example
Gauge(ゲージ) AggregatedGauge ある時点での単一の値 部屋の温度
Count(カウント) AggregatedCount 何らかのイベントが起こった回数を記録する エラーの発生回数
Summary(サマリー) AggregatedSummary ある時間間隔における、カウント、合計、最小、最大を記録する 1分あたりのHTTPリクエストのスループットやレスポンスタイムを記録する

Remo Eで取得できる値は、いずれもある瞬間での値なので、とりあえずゲージとして突っ込んでおきましょう。

コードはこうなりました。Nature API Token, New Relic Insert APIはそれぞれ、環境変数として設定しています。

package main

import (
    "context"
    "github.com/reeve0930/go-remoe"
    "github.com/newrelic/newrelic-telemetry-sdk-go/telemetry"
    "time"

    "os"
)

func main() {
    token := os.Getenv("NATURE_API_TOKEN")
    remoClient := remoe.NewClient(token)
    hervester, _ := telemetry.NewHarvester(telemetry.ConfigAPIKey(os.Getenv("NEW_RELIC_INSERT_API_KEY")))

    data, _ := remoClient.GetRawData()
    for _, d := range data {
        hervester.RecordMetric(telemetry.Gauge{
            Timestamp: time.Now(),
            Value:     float64(d.MeasuredInstantaneous),
            Name:      "remoe.MeasuredInstantaneous",
            Attributes: map[string]interface{}{
            "modelId": d.ModelID,
        },
        })
    }
    hervester.HarvestNow(context.Background())
}

New Relicで見てみる

New Relic Oneを開いて、右上のQuery Your Dataからメトリックの情報をクエリできます。Data Explorerから行っても良いですし、たとえばNRQLはこんな感じに発行してみましょう。

FROM Metric SELECT average(remoe.MeasuredInstantaneous) facet modelId TIMESERIES 

f:id:katzchang:20201216024445p:plain
データが良い感じに表示されている様子

データが突っ込まれましたね!

まとめ

こんな感じに、コンパクトなスクリプトでNew Relicにメトリック情報を放り込むことができるという例でした。コード全体はnewrelic-remoeで公開していますので、ご参考になれば幸いです。詳細が気になる方は@katzchangまでメンションなどいただければと思います。仕事だぜm,