[New Relic] NRQLで文字列を整形して、ほしいデータを取得する

Tech

2024.12.24

Topics

はじめに

こんにちは、tkgです。

最近、New Relicで Dashboardを作っていました。
NRQLでほしいデータを収集・可視化していくのですが、NRDBにInsertされているデータではほしい情報に余分なものが付与されていたので、NRQLのドキュメントとにらめっこしてなんとかした、という状況がありました。
Insertするデータを整形できれば一番良いと思いますが、そうできない場合も稀にあるとは思います。そういったときに利用できる関数の使い方を解説をしたいと思います。

テーブル

今回は AWSの Network LoadBalancerのデータを用います。
JSON表記にしていますが、次のようなカラムが存在しています。

{
  "aws.Arn": "arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/env01-nlb-web-http-tg/1234567890abcdef",
  "aws.MetricStreamArn": "arn:aws:cloudwatch:ap-northeast-1:123456789012:metric-stream/NewRelic-Metric-Stream-ap-northeast-1",
  "aws.Namespace": "AWS/NetworkELB",
  "aws.accountId": "123456789012",
  "aws.networkelb.AvailabilityZone": "ap-northeast-1c",
  "aws.networkelb.LoadBalancer": "net/env01-nlb-web/1234567890abcdef",
  "aws.networkelb.TargetGroup": "targetgroup/env01-nlb-web-http-tg/1234567890abcdef",
  "aws.networkelb.UnHealthyHostCount": {
    "type": "summary",
    "count": 60,
    "sum": 0,
    "min": 0,
    "max": 0
  },
  "aws.region": "ap-northeast-1",
  "collector.name": "cloudwatch-metric-streams",
  "displayName": "targetgroup/env01-nlb-web-http-tg/1234567890abcdef",
  "endTimestamp": 1735009200000,
  "entity.guid": "1234567890asdfghjklqwertyuiop",
  "entity.id": "-1234567890abcdef",
  "entity.name": "targetgroup/env01-nlb-web-http-tg/1234567890abcdef",
  "entity.type": "AWS_NLB_TARGET_GROUP",
  "entityName": "targetgroup/env01-nlb-web-http-tg/1234567890abcdef",
  "instrumentation.provider": "aws",
  "metricName": "aws.networkelb.UnHealthyHostCount",
  "newrelic.cloudIntegrations.providerAccountId": "123456",
  "newrelic.cloudIntegrations.providerAccountName": "Prod_123456789012",
  "newrelic.cloudIntegrations.providerExternalId": "123456789012",
  "newrelic.source": "metricAPI",
  "timestamp": 1735005600000
}

substring()で文字列の一部を取得する

文字列を抽出する関数です。
substring(抽出する文字列, どこから開始するか, 何文字目まで抽出するか) という書式になります。

もし、entity.nametargetgroup という文字列を抜き出したいときは次のようになります。

FROM Metric 
SELECT substring(entity.name, 0, 11)
WHERE aws.Namespace = 'AWS/NetworkELB'

position()で文字列の位置を取得する

指定文字列が何文字目に存在しているか を取得する関数です。

FROM Metric 
SELECT position(entity.name, '/', 0)
WHERE aws.Namespace = 'AWS/NetworkELB'

上記データの場合では entity.name targetgroup/env01-nlb-web-http-tg/1234567890abcdef の 最初の “/” を検出し、0始まりの 11 を返します。
position(entity.name, '/', 1) とすることで 0始まりの 2番目、 つまり33 の値を返してもらうことも可能です。

substring()とposition()を応用して、目当ての文字列を抜き出す

文字列を抽出する関数と 文字列の位置を特定する関数が利用できるということは、
特定の文字列に挟まれている文字列を抽出することが可能であるということです。
entity.name を例とすると、1番目の ‘/’ と 2番目の ‘/’ の間の文字列を抜き出すことで ターゲットグループの名前のみを抜き出す ということが可能となります。

FROM Metric 
SELECT substring(entity.name, position(entity.name, '/', 0) + 1, position(entity.name, '/', 1) - position(entity.name, '/', 0) - 1 ) AS entityName
WHERE aws.Namespace = 'AWS/NetworkELB'

WITH … AS

WITH AS を利用して、クエリ内で事前に環境変数を定義することが可能です。
上記応用のクエリはかなり読みずらいものでしたが、次のようにすることで可読性の向上に繋がります。

FROM Metric 
WITH position(entity.name, '/', 0) + 1 AS FIRSTSLASH,
     position(entity.name, '/', 1) - position(entity.name, '/', 0) - 1 AS SECONDSLASH
SELECT substring(entity.name, FIRSTSLASH, SECONDSLASH) AS entityName
WHERE aws.Namespace = 'AWS/NetworkELB'

まとめ

上記のような整形を行える関数を利用することで、Insertされた構造データ内にほしい情報が無くて困ったときなどに整形して対応する という選択肢が生まれるかなと思います。
他のメトリクスとのかみ合わせが悪いときに整形して対応するなど、応用が効く関数のため理解しておくと思ったより使い所はあるのではないでしょうか。
自分への戒めも含めですが、公式ドキュメントに他の関数も含め記述がありますので、一度眺めた上で身近なデータで触ってみると理解度向上に繋がりそうです。

テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!

tkg

2016年入社のインフラエンジニアです。 写真が趣味。防湿庫からはレンズが生え、押入れには機材が生えます。 2D/3DCG方面に触れていた時期もありました。

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら