MackerelのカスタムメトリックをNew Relicに移行する時はNew Relic Flexという機能がおすすめ

システム開発部Misocaチームエンジニアの id:mizukmb です。

Misocaチームでは監視ツールとしてNew Relic Oneの採用を決定し、現在はインフラの監視に使用しているMackerelからの移行作業を進めています。

newrelic.com

Mackerelにはカスタムメトリックという独自のメトリック投稿機能がありますが、こちらをNew Relicに移行する方法について書きたいと思います。

Mackerelカスタムメトリックの代替候補

MackerelカスタムメトリックからNew Relicに移行するには 任意の数値をメトリックとしてNew Relicに送信できる 機能が必要です。私が調査した限りでは以下の機能が代替できそうでした。

  • Custom metrics
    • APMの機能。アプリケーションコード内で専用のメソッドが呼ばれる事でメトリックを送信できる
  • Metrics API
    • 専用のAPIエンドポイントにメトリックとして渡ししたい数値をJSONペイロードに入れてPOSTリクエストすると送信できる
  • New Relic Flex
    • New Relic Infrastructureエージェントに同梱された機能。専用のymlファイルを用意すると定期的にコマンドを実行し、標準出力で得られた値をNew Relicにメトリックとして送信できる

今回はMackerelのカスタムメトリックに機能的に最も近いNew Relic Flexを採用しました。

New Relic Flexの設定・動作確認方法について

New Relic FlexはInfrastructure agentがインストールされたサーバーであればすぐに使う事ができます。

docs.newrelic.com

github.com

/etc/newrelic-infrastructure/integrations.d/ 以下にNew Relic Flex用のymlファイルを置き、agentを再起動する事でメトリックの送信が開始されます。

基本的な使い方はGitHub READMEのbasic tutorial から読み始めると理解しやすいと思います。また、ymlファイルの設定については、 configureexamples が役立ちました。

動作確認には /var/db/newrelic-infra/newrelic-integrations/bin/nri-flex コマンドが便利です。このコマンドはInfrastructure agentがインストールされたサーバーであれば一緒にインストールされます。チュートリアルの4. How to add more Flex integrationsに使い方が記載されていますが、以下のようにymlファイルを指定する事でNew Relicにはメトリックを送信することなく、New Relicにどのような形式でメトリックが送信されるのか、意図した通りのメトリックになっているのかといった事が確認できます。

# myconfig.yml を対象に動作確認する。結果はJSON形式で標準出力として出力される
$ sudo /var/db/newrelic-infra/newrelic-integrations/bin/nri-flex --verbose --pretty --config_file ./myconfig.yml

例) delayed jobのキュー毎のジョブ数をカウントするメトリックを送信する

delayed jobはRailsアプリで非同期処理を実現するためのRuby gemです。RDBをバックエンドとして利用してジョブの登録や取り出しを行います。今回はこちらのキューに登録されたジョブ数をメトリックとしてNew Relic Flexを使ってNew Relicに送信する実装例を紹介します。

delayed jobキュー毎のジョブ数をRDBに問い合わせて標準出力に表示すれば良いので手段は複数考えられます (DBに接続して直接SQLを発行する、rakeタスクにする等) 。今回は実装を簡単にするため rails runner をシェルスクリプトから実行する方法にします。

#!/bin/bash

# ファイル名は delayed_job.sh とする

cd /path/to/rails_root

bundle exec rails runner '%w(default foo bar baz).each {|q| puts "#{q} #{Delayed::Job.where(queue: q).count}"}'

Rails runnerで実行するスクリプトは以下の内容を一行にまとめたものになっています。

# キュー名 `default`, `foo`, `bar`, `baz` に登録されたジョブ数をカウントして出力する
%w(default foo bar baz).each do |q|
  puts "#{q} #{Delayed::Job.where(queue: q).count}"
end

シェルスクリプトを実行するとキュー名とジョブ数がスペース区切りで出力されます。

default 10
foo 5
bar 0
baz 0

最後に設定用のymlファイルを用意します。さきほど作成したシェルスクリプトのファイルを指定しつつ、メトリック名や実行間隔もymlファイルに書いていきます。New Relic Flexでは得られた出力をどのようにパースするかを指定できます。今回はスペース区切りで出力しているのでそのようにymlファイルにも指定します。正規表現で指定することもできるみたいです。

# /etc/newrelic-infra/integrations.d/delayed_job.yml
integrations:
  - name: nri-flex
    interval: 5m # 実行間隔
    config:
      name: delayedJob
      apis:
        - name:  delayedJob # メトリック名
          commands:
            - run: ./delayed_job.sh # 実行するコマンド (今回はシェルスクリプトを実行)
              split: horizontal # 行指向で分割する
              set_header: [queueType, count] # 項目名
              split_by: \s # データをどのような文字で区切っているか。 \s はスペース区切りを意味している
              timeout: 30000 # タイムアウト (ms)

細かい設定項目については configureexamples を参照ください。

あとは New Relic Infrastructure のプロセスを再起動させれば上記ymlファイルが読み込まれメトリックの送信がはじまります。

メトリックは delayedjobSample という Sample サフィックス付きの名前で保存されます。以下はNRQLで実際に可視化させた例です。

f:id:mizukmb:20210405110818p:plain
New Relic Flexで送信したメトリックをNRQLで可視化した

おわりに

MackerelのカスタムメトリックをNew Relicに移行する時の方法としてNew Relic Flexを紹介しました。どのくらいニーズがあるかわからない内容でしたが参考になれば幸いです。

採用

弥生株式会社ではエンジニアを積極採用中です。

www.yayoi-kk.co.jp