Ansible Tower(AWX)で実行したジョブの結果をELKで可視化しようとして、まずはジョブの実行結果をテーブルで表示させてみた時のメモです。
実行結果は動的に変わる部分があるのでpainlessを使ってコードを書いて表示してみます。
Logstash経由でElasticsearchへAnsible Towerのログを取り込む手順はAnsible Towerドキュメントを参照してください。
1. 目的
Ansible Towerで実行したジョブ結果(okやfailなど)をKibanaでPlaybook毎に可視化します。
イメージは以下の様な感じです。
時間 | Playbook | ok | fail |
---|---|---|---|
yyyyMMdd HH:mm:ss |
main.yml | 1 | 0 |
yyyyMMdd HH:mm:ss |
main2.yml | 0 | 1 |
2. 環境
項目 | バージョン |
---|---|
OS | RHEL7.5 |
ELK | 6.3.2-1 |
Ansible Tower | 3.2.5 |
3. ジョブ実行結果が入るフィールド
Ansible Towerでジョブを実行するとジョブのタスクを一つ実行する度に一つのログを出力します。
そのため、Kibanaでログを確認すると一つのジョブで数個記録されています。
その中の一つにジョブ結果を格納されているフィールドがあります。
それが event_data
です。
以下は、一つの例です。
(snip)
"event_data": {
"ok": {
"localhost": 1,
"192.168.0.236": 1
},
"playbook_uuid": "c867d20e-841a-44e7-b934-683dc0bad1d3",
"changed": {
"localhost": 1,
"192.168.0.236": 1
},
"playbook": "main.yml",
"skipped": {},
"processed": {
"localhost": 1,
"192.168.0.236": 1
},
"dark": {},
"failures": {},
"pid": 3
},
(snip)
event_data
はジョブに関連する各sourceに記録されていますが中身の構造が違ってきます。
結果は event_data
内に ok
playbook_uuid
changed
playbook
skipped
processed
dark
failures
pid
のキーがあります。
実行したホストやPlaybook数によって ok
や failures
などの中のキーや値が変わってきます。
そのため、まずは簡単に合計数を可視化するために painless
を使って可視化してみます。
4. Kibanaの設定
4-1. Scripted fieldsの作成
ここでは、以下4つのScripted fieldsをpainlessで作成します。
- task_skipped
- task_ok
- task_changed
- task_failures
Management
をクリックして Index Patterns
-> Scripted fields
へ移動し Add scripted field
をクリックして追加します。
ここでの対象indexは ansible_tower*
です。
4-1-1. task_skipped
int r = 0;
if(params._source.containsKey('event_data') && params._source.event_data.containsKey('skipped')) {
for (def key : params._source.event_data.skipped.keySet()) {
r = r + params._source.event_data.skipped[key];
}
}
return r;
4-1-2. task_ok
int r = 0;
if(params._source.containsKey('event_data') && params._source.event_data.containsKey('ok')) {
for (def key : params._source.event_data.ok.keySet()) {
r = r + params._source.event_data.ok[key];
}
}
return r;
4-1-3. task_changed
int r = 0;
if(params._source.containsKey('event_data') && params._source.event_data.containsKey('changed')) {
for (def key : params._source.event_data.changed.keySet()) {
r = r + params._source.event_data.changed[key];
}
}
return r;
4-1-4. task_failures
int r = 0;
if(params._source.containsKey('event_data') && params._source.event_data.containsKey('failures')) {
for (def key : params._source.event_data.failures.keySet()) {
r = r + params._source.event_data.failures[key];
}
}
return r;
4-2. 簡単に説明
キーのチェック(containsKey)に doc
を使わずに params._source
を使っている理由は可視化したい対象のデータが存在したりしなかったりするためです。
そのため doc
ではうまく動作しなかったので params._source
を直接使っています。
5. 可視化結果
こんな感じになります。
6. 課題
一応、このデータを元にグラフ化などもできますが params._source
を使っているソースなのでfilterが使えません。
そのため検索に難ありです。
Elasticsearchのindexに入れる前にデータを加工(フィールドを増やすなど)する必要があると思いました。
この事をTwitterで発言したところ @johtani
さんからIngestのアドバイスを頂いたので今後の検証で試していきたいと思います。
scripted fieldで表示時に変換するのではなく、登録時にIngestの機能で変換した方がいい気がします。https://t.co/9FDWfGgeyB
— Jun Ohtani (@johtani) 2018年8月10日
7. 参考
https://www.elastic.co/guide/en/elasticsearch/painless/master/painless-api-reference.html
https://www.elastic.co/guide/en/elasticsearch/reference/master/modules-scripting-fields.html