はじめに
この記事はCiscoの有志によるCisco Systems Japan Advent Calendar 2018の18日目です。
この記事では、拙作のfluent-plugin-telemetry-iosxe
を紹介します。
fluent-plugin-telemetry-iosxe
は、その名前から推測できるとおり、IOS XEのModel Driven TelemetryのためのFluentdのInputプラグインです。
[Github] tetsusat/fluent-plugin-telemetry-iosxe
https://github.com/tetsusat/fluent-plugin-telemetry-iosxe
昨年のAdvent Calenderの頃に公開したプラグインですが、今回の投稿を執筆するにあたって、以下の機能拡張を行ってます。
- Chunked Framingに対応 (https://tools.ietf.org/html/rfc6242#section-4.2)
- 複数サブスクリプションのサポート
そもそもIOS XEのModel Driven Telemetry?
IOS XEのModel Driven Telemetryは、現在、IETF Telemetryのプレスタンダード版draft-ietf-netconf-yang-push
に準拠してます。
IOS XEのModel Driven Telemetry自体については、昨年のCisco Advent Calenderのために執筆した以下の記事を参考にしてください。
[Qiita] IOS XEのModel Driven Telemetryを試してみた
https://qiita.com/tetsusat/items/eae0f79f445e54ef662f
デバイスの設定
デバイス側の設定は超簡単です。
まずは、YANGに対応したNETCONFを有効にします。
Router(config)#netconf-yang
加えて、NETCONFでアクセスするためのアカウントを作成します。privilege
レベルは15
にする必要があります。
Router(config)#username admin privilege 15 password admin
これだけです。
fluent-plugin-telemetry-iosxeの設定
まずは、標準出力に出力する例です。
<source>
@type telemetry_iosxe
server 192.0.2.1
port 830
user admin
password admin
xpath_filters /process-cpu-ios-xe-oper:cpu-usage/cpu-utilization/five-seconds
tag cpu-usage-five-seconds
period 500
@label @telemetry
</source>
<label @telemetry>
<match **>
@type stdout
</match>
</label>
TelemetryのNotificationを受けると、以下のような感じで標準出力に出力されます。
2018-12-14 03:30:54.000000000 +0000 cpu-usage-five-seconds: {"cpu_usage":{"cpu_utilization":{"five_seconds":1}}}
2018-12-14 03:30:59.000000000 +0000 cpu-usage-five-seconds: {"cpu_usage":{"cpu_utilization":{"five_seconds":2}}}
2018-12-14 03:31:04.000000000 +0000 cpu-usage-five-seconds: {"cpu_usage":{"cpu_utilization":{"five_seconds":1}}}
...
次に、InfluxDBに出力する例です。
InfluxDBに出力するためにfluent-plugin-influxdb
を使います。
それと、Grafanaで可視化することを想定して、fluent-plugin-flatten-hash
で階層化されたデータをフラット化しておきます。
[Github] fangli/fluent-plugin-influxdb
https://github.com/fangli/fluent-plugin-influxdb
[Github] kazegusuri/fluent-plugin-flatten-hash
https://github.com/kazegusuri/fluent-plugin-flatten-hash
fluent-plugin-telemetry-iosxe
の解説からは脱線しますが、fluent-plugin-influxdb
の設定でauto_tags
をtrue
にしておくと、値が文字列なフィールドをタグにしてくれます。そうすると、GrafanaのクエリーでWHERE
によるフィルタやGROUP BY
による集約に使えるようになります。
<source>
@type telemetry_iosxe
server 192.0.2.1
port 830
xpath_filters /process-cpu-ios-xe-oper:cpu-usage/cpu-utilization/five-seconds
user admin
password admin
tag cpu-usage-five-seconds
period 500
@label @telemetry
</source>
<label @telemetry>
<filter **>
@type flatten_hash
separator .
</filter>
<match **>
@type influxdb
host localhost
port 8086
dbname telemetry
user admin
password admin
time_precision s
auto_tags true
</match>
</label>
すると、以下のような感じでInfluxDBにレコードができます。
> select * from "cpu-usage-five-seconds" limit 5
name: cpu-usage-five-seconds
time cpu_usage.cpu_utilization.five_seconds
---- --------------------------------------
1544759262000000000 1
1544759267000000000 2
1544759272000000000 1
1544759277000000000 2
1544759282000000000 1
応用
およそ1年前にこのプラグインを公開して以来、複数の対象にサブスクライブするにはどうしたらいいのか、ということをしばしば聞かれました。
2つやり方があります。
1つ目のやり方は、xpath_filters
におけるXPathの指定にユニオンオペレータ(|)を使います。こうすると、一つのサブスクリプションで複数の対象にサブスクライブできます。
<source>
@type telemetry_iosxe
...
xpath_filters /interfaces/interface[name="GigabitEthernet1"]/statistics/in-octets|/interfaces/interface[name="GigabitEthernet1"]/statistics/out-octets
....
</source>
この場合、一つのNotificationに集約されて通知されてきます。
2018-12-14 04:02:34.000000000 +0000 interface-stats: {"interfaces":{"interface":{"name":"GigabitEthernet1","statistics":{"in_octets":7935445674,"out_octets":27392586}}}}
2018-12-14 04:02:39.000000000 +0000 interface-stats: {"interfaces":{"interface":{"name":"GigabitEthernet1","statistics":{"in_octets":7935459283,"out_octets":27458631}}}}
2018-12-14 04:02:44.000000000 +0000 interface-stats: {"interfaces":{"interface":{"name":"GigabitEthernet1","statistics":{"in_octets":7935472426,"out_octets":27459313}}}}
...
もう一つのやり方は、xpath_filters
において対象を配列として指定します。こうすると、複数のサブスクリプションで複数の対象にサブスクライブできます。
<source>
@type telemetry_iosxe
...
xpath_filters [
"/interfaces/interface[name=\"GigabitEthernet1\"]/statistics/in-octets",
"/interfaces/interface[name=\"GigabitEthernet1\"]/statistics/out-octets"
]
....
</source>
この場合、サブスクリプションが複数なので、複数のNotificationが通知されてきます。
2018-12-14 04:19:53.000000000 +0000 interface-stats: {"interfaces":{"interface":{"name":"GigabitEthernet1","statistics":{"in_octets":7937904353}}}}
2018-12-14 04:19:53.000000000 +0000 interface-stats: {"interfaces":{"interface":{"name":"GigabitEthernet1","statistics":{"out_octets":27901067}}}}
2018-12-14 04:19:58.000000000 +0000 interface-stats: {"interfaces":{"interface":{"name":"GigabitEthernet1","statistics":{"in_octets":7937919099}}}}
2018-12-14 04:19:58.000000000 +0000 interface-stats: {"interfaces":{"interface":{"name":"GigabitEthernet1","statistics":{"out_octets":27968448}}}}
2018-12-14 04:20:03.000000000 +0000 interface-stats: {"interfaces":{"interface":{"name":"GigabitEthernet1","statistics":{"in_octets":7937933134}}}}
2018-12-14 04:20:03.000000000 +0000 interface-stats: {"interfaces":{"interface":{"name":"GigabitEthernet1","statistics":{"out_octets":27970140}}}}
...
おしまい