lsyncd ってのは?
Linux上で動作するlsyncdは,ファイルシステムのイベント(作成・削除・移動/リネーム・属性変更などなど)を通知してくれるLinuxカーネルAPIを利用し,ほぼリアルタイムにファイルの同期等を行ってくれる超便利なソフトウェアです.
変更のあったファイルやディレクトリ内容をrsyncを利用して別サーバや別ディレクトリにコピー/削除する,という使い方がスタンダード(?)かと思いますが,ファイル変更時にコマンドを起動することも可能なので,画像ファイルのサムネイルを作成/削除する,などの設定例もドキュメントに記載されています.
fluentd ってのは?
「データコレクタ」「データログ収集ツール」などと呼ばれる,ログを始めとしたデータの集約・転送などを簡単に,安全に行ってくれる,これまた超便利なソフトウェアです.
input・output・filterなどといった入出力・フィルタリング機能はプラグイン式になっており,様々なデータソース・データストアに対応したプラグインが公開されていますし,いざとなれば自分で作ることも可能です.
やりたいこと
- 特定のディレクトリに追加されたファイルの情報をプログラムに渡したい
- 全ての処理が完了した段階でファイルを削除・または移動/リネームしたい
やってみる
lsyncd の設定は全て lua という言語で記述されています.
もしかして,lua 自体にsocketやhttp-requestみたいな機能があるんじゃね?と思って調べてみると,ありました.
Lua にSMTP,HTTP,FTP 等のネットワーク機能を追加してくれる拡張ライブラリです.
lsyncdとLuaSocketのインストール
今回はDebian系OSだったので,apt-getで一発インストールでした.
$ sudo apt-get install lsyncd liblua5.1-socket2
LuaSocketのファイル群は /usr/share/lua/5.1/ 配下に展開されていました.
$ ls /usr/share/lua/5.1/
ltn12.lua mime.lua socket/ socket.lua
lsyncd の設定
環境変数の設定
インストールしたLuaSocketを読み込めるよう,環境変数でパス等を指定してやります
$ sudo vi /etc/defaults/lsyncd
#
LUA_INIT=
LUA_PATH='/usr/share/lua/5.1/?.lua;?.lua'
LUA_CPATH='/usr/share/lua/5.1/?.so;?.so'
設定ファイル lsyncd.conf.lua
では,おもむろに lsyncd 設定ファイルを記述していきます.
今回は
- 監視するディレクトリ : /test/data/
- 新規作成イベントのみ監視
- fluentd は
- host : 127.0.0.1
- port : 8888
- tag : inotify.<ディレクトリ毎の識別子>
- jsondata
- dirpath : 監視ディレクトリパス
- filename : 追加ファイル名
ということにします.
-- LuaSocketのhttpライブラリを読み込み
http = require("socket.http")
settings = {
-- 省略
}
--
-- function 定義
-- 追加されたファイル情報を fluentd に通知する
--
-- @param tag 振り分け用タグ(必須)
-- @param dir 監視ディレクトリパス
-- @param path 追加されたファイル名
-- @return true 通知成功(HTTPステータスコードが200) / false 通知失敗
--
fluentlog = function(tag, dir, path)
local url = "http://127.0.0.1:8888/inotify.".. tag
local json = 'json={"dirpath":"'.. dir ..'","filename":"'.. path ..'"}'
local d, c, h, s = http.request(url, json)
-- HTTPステータスが200であればtrue,それ以外は失敗としてfalseを返却する
if c == 200 then
return true
else
return false
end
end
--
-- action 定義
-- ディレクトリを監視し,追加されたファイル情報を通知する
--
fluentnotify = {
maxProcesses = 1,
delay = 1,
action = function(inlet)
local event = inlet.getEvent()
if event.isdir then
-- ディレクトリは処理対象外
inlet.discardEvent(event)
return
end
if event.etype == "Create" then
local config = inlet.getConfig()
local path = event.pathname
if fluentlog(config.tag, event.source, path) then
inlet.discardEvent(event)
return
else
return "again"
end
end
inlet.discardEvent(event)
end,
}
--
- 監視すべきディレクトリとタグを指定
--
sync {
fluentnotify, -- actionを指定
source="/test/data", -- 監視するディレクトリ
tag="testdata", -- fluent へのタグ
recursive=false, -- 下位ディレクトリは監視しない
}
fluentd 側の設定例
こんな感じでしょうか.
実際には,これからさらにmongo_tail とか out_exec などのプラグインを使って処理を行わせています.
: 中略
#
# HTTP input source は必須.これが無いと受け止められない
# http://localhost:8888/<tag>?json=<json>
<source>
@type http
@id http_input
bind 127.0.0.1
port 8888
</source>
: 中略
<match inotify.**>
@type copy # ストリームを2つにコピー
<store>
@type file # 1つはファイルに保存
path /var/log/fluentd/inotify.log
compress gz
</store>
<store>
@type mongo # もう1つはMongoDBに保存
database testdb
collection testdatas
host mongohost
port 27017
</store>
</match>
最後に
ご覧いただきありがとうございます,何かのお役に立てたら幸いです.
間違い等ありましたらご指摘くださいm(_ _)m