おはげようございます。
tl;dr
最近、個人的に Rundeck を触り始めている。
Rundeck の詳細については、以下の記事がとても参考になると思っているので、そちらをご一読頂くとして…
Rundeck の中身を知る一環として Plugin について調べていたら Logstash にジョブの結果を流すプラグインが既に在ったので…
そちらをパクらせて参考にさせて頂いて、同様にジョブの結果を flunetd に流す Rundeck Plugin を作ってみた。
あくまでも作ってみただけなので色々と雑になってしまっているのはすいません。
Logging Plugin について
参考
プラグインの種類
以下の三種類の Logging プラグインを作成することが出来る。
- Writer plugins
下図の通り Job の実行結果をログをストリームで書き出す。今回、作った Fluentd 用のプラグインはこの Write Plugin となる。
- Reader plugins
下図の通りログファイルをストリームで読み込む。
- Storage plugins
このタイプのプラグインに関しては具体的にどのような用途かちゃんと理解出来ていない。
Java か Groovy で実装する
Logging Plugin は Java と Groovy という言語で実装することが出来る。Java については特に言及は無い(言及するほどの知見は無い)が、Groovy に関しては JVM 上で動作する Java と親和性の高いスクリプト言語とのことで、Java よりは簡単に初められるのでは…(あくまでも個人的見解です…)という安易な気持ちでプラグイン作りに取り掛かった。
尚、Rundeck のプラグインには以下のような種類がある。(各プラグインの詳細についてはこちら)
- Node Executor Plugin
- Workflow Step Plugin
- File Copier Plugin
- Logging Plugin
- Notification Plugin
- Resource Model Source Plugin
- Model Format Parser and Generator Plugin
- Orchestrator Plugin
- Storage Converter Plugin
- Storage Plugin
幾つかのプラグインに関しては Java や Groovy 以外にシェルスクリプトで実装出来るプラグインもある。但し、Logging Plugin について Java と Groovy のみとなる。
何はともあれサンプルコード
全く知見の無い自分がうんちくを書くよりも以下のサンプルを見て頂いた方が百万倍良いと思う。
以下、ザックリポイント。
com.dtolabs.rundeck.plugins.logging.StreamingLogWriterPlugin
ライブラリをインポートrundeckPlugin
メソッドを利用
import com.dtolabs.rundeck.plugins.logging.StreamingLogWriterPlugin rundeckPlugin(StreamingLogWriterPlugin){ //plugin definition }
rundeckPlugin
メソッド内で以下のクロージャを定義する
configuration{ //property definitions go here... } // open { Map execution, Map config -> //open a stream for writing //return a map containing any context you want to maintain [mycounter: ..., mystream: ... ] } // addEvent { Map context, LogEvent event-> // write the event to my stream } // close { Map context -> // close my stream }
詳細はドキュメントをご一読を…。
rundeck-fluentd-plugin の使い方
インストール
インストールは FluentdPlugin.groovy を $RDECK_BASE/libext/ にコピーする。
$ sudo cp FluentdPlugin.groovy /var/lib/rundec/libext/
依存するライブラリの設置
とりあえず、以下のライブラリを設置することでプラグインが動作することを確認した。
$ sudo su - # cd /var/lib/rundeck/bootstrap # wget http://central.maven.org/maven2/org/msgpack/msgpack/0.6.12/msgpack-0.6.12.jar . # cp /var/lib/rundeck/exp/webapp/WEB-INF/lib/javassist-3.17.1-GA.jar .
※この方法が正しいかは解らないので正しい方法がマジでしりたひ
設定ファイル
以下のファイルの末尾に追記する。
- /etc/rundeck/rundeck-config.properties
rundeck.execution.logs.streamingWriterPlugins=FluentdPlugin
- /etc/rundeck/framework.properties
framework.plugin.StreamingLogWriter.FluentdPlugin.port=24224 framework.plugin.StreamingLogWriter.FluentdPlugin.host=localhost framework.plugin.StreamingLogWriter.FluentdPlugin.tag=rundeck.log
- /etc/rundeck/project.properties
project.plugin.StreamingLogWriter.FluentdPlugin.port=24224 project.plugin.StreamingLogWriter.FluentdPlugin.host=localhost project.plugin.StreamingLogWriter.FluentdPlugin.tag_prefix=rundeck.log
設定したら Rundeck のプロセスを再起動しておく。
fluentd の設定
お試しなので in_forward プラグインだけ。
type stdout
設定したら fluentd を以下の通り起動しておく。
$ fluentd -c test.conf -l debug.log &
ジョブを実行すると…
一分ごとに HelloWorld を Echo するジョブを走らせておくと…以下のようなログが debug.log に流れる。
2015-10-22 23:40:00 +0900 rundeck.log.hello-world: {"execution.loglevel":"INFO","execution.wasRetry":"false","execution.url":"http://xxx.xxx.xxx.xx:4440/project/hello-world/execution/follow/1389","execution.id":"fdf1cca5-e729-491b-a1fa-3d8fef373d46","execution.project":"hello-world","execution.username":"admin","execution.retryAttempt":"0","execution.user.name":"admin","execution.name":"hello-world","execution.serverUUID":null,"execution.group":null,"execution.execid":"1389","execution.serverUrl":"http://xxx.xxx.xxx.xx:4440/","event.stepctx":"1","event.step":"1","line":1,"datetime":1445524800447,"loglevel":"NORMAL","message":null,"eventType":"stepbegin"} 2015-10-22 23:40:00 +0900 rundeck.log.hello-world: {"execution.loglevel":"INFO","execution.wasRetry":"false","execution.url":"http://xxx.xxx.xxx.xx:4440/project/hello-world/execution/follow/1389","execution.id":"fdf1cca5-e729-491b-a1fa-3d8fef373d46","execution.project":"hello-world","execution.username":"admin","execution.retryAttempt":"0","execution.user.name":"admin","execution.name":"hello-world","execution.serverUUID":null,"execution.group":null,"execution.execid":"1389","execution.serverUrl":"http://xxx.xxx.xxx.xx:4440/","event.node":"localhost","event.stepctx":"1","event.user":"rundeck","event.step":"1","line":2,"datetime":1445524800458,"loglevel":"NORMAL","message":null,"eventType":"nodebegin"} 2015-10-22 23:40:00 +0900 rundeck.log.hello-world: {"execution.loglevel":"INFO","execution.wasRetry":"false","execution.url":"http://xxx.xxx.xxx.xx:4440/project/hello-world/execution/follow/1389","execution.id":"fdf1cca5-e729-491b-a1fa-3d8fef373d46","execution.project":"hello-world","execution.username":"admin","execution.retryAttempt":"0","execution.user.name":"admin","execution.name":"hello-world","execution.serverUUID":null,"execution.group":null,"execution.execid":"1389","execution.serverUrl":"http://xxx.xxx.xxx.xx:4440/","event.node":"localhost","event.stepctx":"1","event.user":"rundeck","event.step":"1","line":3,"datetime":1445524800869,"loglevel":"NORMAL","message":null,"eventType":"nodeend"} 2015-10-22 23:40:00 +0900 rundeck.log.hello-world: {"execution.loglevel":"INFO","execution.wasRetry":"false","execution.url":"http://xxx.xxx.xxx.xx:4440/project/hello-world/execution/follow/1389","execution.id":"fdf1cca5-e729-491b-a1fa-3d8fef373d46","execution.project":"hello-world","execution.username":"admin","execution.retryAttempt":"0","execution.user.name":"admin","execution.name":"hello-world","execution.serverUUID":null,"execution.group":null,"execution.execid":"1389","execution.serverUrl":"http://xxx.xxx.xxx.xx:4440/","event.stepctx":"1","event.step":"1","line":4,"datetime":1445524800870,"loglevel":"NORMAL","message":null,"eventType":"stepend"} 2015-10-22 23:40:00 +0900 rundeck.log.hello-world: {"execution.loglevel":"INFO","execution.wasRetry":"false","execution.url":"http://xxx.xxx.xxx.xx:4440/project/hello-world/execution/follow/1389","execution.id":"fdf1cca5-e729-491b-a1fa-3d8fef373d46","execution.project":"hello-world","execution.username":"admin","execution.retryAttempt":"0","execution.user.name":"admin","execution.name":"hello-world","execution.serverUUID":null,"execution.group":null,"execution.execid":"1389","execution.serverUrl":"http://xxx.xxx.xxx.xx:4440/","ending":true,"totallines":4,"message":"Execution null finished."}
ということで…
作る過程で得た知見
- Groovy って Ruby に似た側面もありそう
ということで、以下の記事が参考になる。
どの辺が具体的に似てるとかには言及する知見は無いが Ruby っぽい書き方も出来るだということを感じた。
- MessagePack と Fluentd について
例えば、[tag, time, record]
という配列を以下のようにしてシリアライズして Fluentd に投げる感じ。
MessagePack.pack([tag, time, record])
Enjoy Rundeck
Rundeck 道の入り口にやっと立てたのでこれからも精進したい。
以上。