ansibleのログをfluentdに流す¶
Chef のログを Fluentd に流す という記事を読みました。Ansibleにもそのための機能があるにも関わらず、あ まり情報がないのでまとめてみました。
callback plugin¶
Ansibleにはmoduleとは別にpluginという機構があります。例えば "{{lookup('file', '/etc/foo.txt') }}" というように使うlookup pluginがあり ます。他にもconnectionやvarsのpluginがありますが、そのうちの一つに、 callback pluginがあります。
callback pluginはその名の通り、いろいろなイベントが発生した時に自動的に 呼び出されるcallbackを登録するためのpluginです。イベントの例としては、
playbookの開始時
taskの開始時
task成功時
task失敗時
playbook終了時
などがあります。
例: fluentdへと送るplugin¶
moduleは各種言語で実装できるansibleなのですが、pluginは残念ながら現状 pythonでしか実装できません。
ということで、callback pluginを実装してみた結果が以下のコードです。 callbackの関数を実装すればいいということが分かると思います。
ただ、登録できるハンドラが多すぎてここには一部だけしか載せていません。 gist にあげておきましたので、 そちらもご覧ください。どういう時に呼び出されるかは関数名から雰囲気で察 してください。(このあたり公式にもドキュメントがないので、コードを読むし かないのです)
import json
import urllib
import urllib2
url = 'http://localhost:8888/ansible'
def post(category, data):
data['category'] = category
invocation = data.pop('invocation', None)
if invocation:
data['module_name'] = invocation['module_name']
data['module_args'] = invocation['module_args']
values = {'json': json.dumps(data)}
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
urllib2.urlopen(req)
class CallbackModule(object):
def on_any(self, *args, **kwargs):
pass
def runner_on_failed(self, host, res, ignore_errors=False):
res["host"] = host
post(host, 'FAILED', res)
def runner_on_ok(self, host, res):
res["host"] = host
post('OK', res)
def runner_on_error(self, host, msg):
post('ERROR', {"host": host, 'error': msg})
def runner_on_skipped(self, host, item=""):
post('SKIPPED', {"host": host, "item": item})
これをin_http経由でfluentdに流し、out_fileで書きだした結果が以下の通りです。
2014-02-16T00:18:04+09:00 ansible {"category":"Play_on_start"}
2014-02-16T00:18:05+09:00 ansible {"category":"Play_start"}
2014-02-16T00:18:10+09:00 ansible {"category":"OK","changed":true,"end":"2014-02-1515:18:10.810734","stdout":"Sat Feb 15 15:18:10 UTC 2014","cmd":["date"],"rc":0,"start":"2014-02-1515:18:10.808307","host":"docker","stderr":"","delta":"0:00:00.002427","module_name":"command","module_args":"date"}
2014-02-16T00:18:11+09:00 ansible {"verbose_always":true,"category":"OK","host":"docker","msg":"Sat Feb 15 15:18:10 UTC 2014","module_name":"debug","module_args":"msg=\"Sat Feb 15 15:18:10 UTC 2014\""}
ちょっと分かりにくいですが、3行目のtaskの結果("OK")に、start(開始時刻)、 end(終了時刻)、そしてdeltaという実行時間が入っています。ログに取るので あれば、deltaはかなり有用ではないでしょうか。もちろんstdoutという標準出 力もとれています。
ちなみに実行したtaskは以下の通りです。
tasks:
- name: get date
command: date
register: date
- name: debug
debug: msg="{{ date.stdout }}"
導入方法¶
callback pluginを使うには以下の3つの方法があります。
inventoryファイルと同じ階層に callback_plugins というディレクトリを作成し、その中にpluginファイルを置く。
デフォルトでは /usr/share/ansible/plugins 以下にある、callback_pluginの下に置く
ansible.cfgでcallback_pluginを置いてあるディレクトリを指定する
callback_plugins = /usr/share/ansible_plugins/callback_plugins
いずれも単にpythonファイルを置くだけで使えるようになります。逆に言うと、 不用意に置くと勝手に実行されてしまう点には気をつけてください。
なお、複数のcallback pluginがディレクトリにあるとそれらすべてが実行されます。
まとめ¶
ansibleの実行結果を得るcallback pluginを紹介し、一例としてfluentdへと送 るpluginを実装しました。
fluentdに限らず例えばfailした時にnagiosに飛ばしたりhipchatに飛ばしたりと、 いろいろ役に立つと思います。
Comments
comments powered by Disqus