fluentdでネストされたデータを扱いやすくする方法

前回の記事でJMXのメトリクスをfluentd経由で蓄積する方法を書きましたが、殆どの場合JMXのメトリクスは深い入れ子構造になっています。

$ curl -X POST -d '{"type":"read","mbean":"java.lang:type=Memory"}' http://localhost:8778/jolokia/ | python -mjson.tool

{
    "request": {
        "mbean": "java.lang:type=Memory",
        "type": "read"
    },
    "status": 200,
    "timestamp": 1389278295,
    "value": {
        "HeapMemoryUsage": {
            "committed": 133054464,
            "init": 16432320,
            "max": 518979584,
            "used": 67861272
        },
        "NonHeapMemoryUsage": {
            "committed": 46202880,
            "init": 24313856,
            "max": 251658240,
            "used": 45135144
        },
        "ObjectName": {
            "objectName": "java.lang:type=Memory"
        },
        "ObjectPendingFinalizationCount": 0,
        "Verbose": false
    }
}

こういったメトリクスの場合に蓄積先をTreasure Data DWHにするとネストされた部分は直接参照できず、get_json_objectというUDFを使う必要があり非常に面倒です。

# 蓄積されているデータを確認
$ td table:tail -n 1 -P glassfish memory
{
  "timestamp": 1389278845,
  "time": 1389278845,
  "status": 200,
  "request": {
    "mbean": "java.lang:type=Memory",
    "type": "read"
  },
  "value": {
    "Verbose": false,
    "ObjectPendingFinalizationCount": 0,
    "NonHeapMemoryUsage": {
      "max": 251658240,
      "committed": 46202880,
      "init": 24313856,
      "used": 45156080
    },
    "ObjectName": {
      "objectName": "java.lang:type=Memory"
    },
    "HeapMemoryUsage": {
      "max": 518979584,
      "committed": 133054464,
      "init": 16432320,
      "used": 59201544
    }
  }
}

# 直接参照できないためエラーとなる
$ td query -d glassfish -w "select v['value']['HeapMemoryUsage']['used'] from memory"

# このように参照する必要がある
$ td query -d glassfish -w "select get_json_object(v['value'], '$.HeapMemoryUsage.used') from memory"

今回はデータをフラットな形式に変換して蓄積することで、クエリを書きやすくする方法のご紹介です。

fluent-plugin-flatten-hash

fluent-plugin-flatten-hashという直球なプラグインがあります。fluent-plugin-flattenとは別物なので注意してください。GEMリポジトリに登録されているので、fluent-gemコマンドだけで簡単にインストールできます。

$ /usr/lib/fluent/ruby/bin/fluent-gem install fluent-plugin-flatten-hash

このプラグインを噛ますことで、データをフラットな形式に変換できます。/etc/td-agent/td-agent.confにJolokiaから取ってきたデータをフラット化してTDDWHに蓄積するには以下のように書きます。

<source>
  type jolokia
  tag jolokia.glassfish.memory
  jolokia_url http://localhost:8778/jolokia/
  jmx_bean java.lang:type=Memory
  run_interval 5s
</source>

<match jolokia.**>
  type flatten_hash

  # ネストの区切り文字
  separator _

  # jolokia.**というタグをtd.**に置換する
  remove_tag_prefix jolokia.
  add_tag_prefix td.
</match>

<match td.*.*>
  type tdlog
  apikey APIKEY

  auto_create_table
  buffer_type file
  buffer_path /var/log/td-agent/buffer/td
</match>

蓄積されたデータを見てみると、

$ td table:tail -n 1 -P glassfish memory
{
  "value_ObjectName_objectName": "java.lang:type=Memory",
  "value_HeapMemoryUsage_used": 45932528,
  "status": 200,
  "request_type": "read",
  "value_NonHeapMemoryUsage_max": 251658240,
  "value_NonHeapMemoryUsage_committed": 46202880,
  "value_HeapMemoryUsage_max": 518979584,
  "value_HeapMemoryUsage_committed": 133054464,
  "value_NonHeapMemoryUsage_used": 45178168,
  "timestamp": 1389280024,
  "time": 1389280024,
  "request_mbean": "java.lang:type=Memory",
  "value_Verbose": false,
  "value_NonHeapMemoryUsage_init": 24313856,
  "value_HeapMemoryUsage_init": 16432320,
  "value_ObjectPendingFinalizationCount": 0
}

このようにネストされたデータがアンダースコア区切りのフラットな形式で蓄積できるようになりました。これで各メトリクスの集計も簡単にできますね。お試しください!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>