fluentdを利用してawsのs3にwindowsアプリからログをアップする

Windowsベースの基幹システム開発に携わっている巷で話題のゴルフおじさんこと菊池です。

今回はログ収集ツールとして巷で話題のfluetd!SanwaSystemTechBlogでも一度取り上げられています。

これなら基幹システムからのログを賢く収集・運用できるのではないかと喜んだのもつかの間

私たちの基幹システムはWindows、しかしfluentdはWindowsに対応していない。

そこを強引に収集すべく色々やってみたいと思います。

今回の構成

fluentdのin側にhttp、out側にs3プラグインを使用して。 アプリからhttpで送信し、s3に保存してもらおうという構成です。

既にfluentdはAWSに構築したlinuxにインストールしてあります。 そのあたりはSanwaSystemTechBlog平尾さんの記事に詳しく書いてあるので見てください。

複数WEBサーバのログを、一か所に集めて見やすくしよう! - Sanwa Systems Tech Blog

s3の準備

とりあえずテスト用のバケットを作成します。

f:id:apollo_13:20150312110907j:plain

アクセスするための認証キーを取得します。

f:id:apollo_13:20150313164112p:plain

f:id:apollo_13:20150313164121p:plain

アクセスキーを取得する詳しい方法はこちらから↓。

アクセスキー ID と秘密アクセスキーの取得 - Amazon Simple Queue Service

fluentdの設定

fluentdのコンフィグファイルにs3出力用の設定をします。

こんな感じで

<match s3.**>
 type s3
 aws_key_id ※上で取得したAccess Key ID
 aws_sec_key ※上で取得したSecret Access Key
 check_apikey_on_start false
 s3_bucket test-sanwasystem ※上で作ったバケット名
 s3_region ap-northeast-1
 path logs/
 buffer_path /var/log/td-agent/buffer/s3
 time_slice_format %Y%m%d/%Y%m%d-%H
 time_slice_wait 5m
</match>

こちらは入力側の設定。httpでの入力を受け付けるようにします。 今回は既にある設定を使います。

<source>
  type http
  port 8888
</source>

処理してもらいたいデータはjson形式にして下記のように送信します。

POST http://localhost:8888/<tag>?json=<json>

<tag>に当たる部分が、<match>の設定に合致したとき処理が行われます。

今回、s3用の設定は <match s3.**> なので

http://localhost:8888/s3

となります。

アプリ側

アプリ側にfluentdへの送信を行う部分を作成します。こちらはC#で書いてます。

とはいってもただPOSTしているだけですが。 送信するJSON形式のデータを作成するところでDynamicJsonというライブラリを使用しています。

string url = "http://xx.xx.xx.xx:8888/s3"
Encoding enc = Encoding.UTF8;
string postData = "json=" + HttpUtility.UrlEncode(DynamicJson.Serialize(logData), enc);

byte[] data = Encoding.ASCII.GetBytes(postData);

HttpWebRequest http = (HttpWebRequest)HttpWebRequest.Create(url);
http.ContentType = "application/x-www-form-urlencoded";
http.Method = "POST";
http.ContentLength = postData.Length;

Stream reqStream = http.GetRequestStream();
reqStream.Write(data, 0, data.Length);
reqStream.Close();

HttpWebResponse res = (HttpWebResponse)http.GetResponse();

Stream resStream = res.GetResponseStream();

StreamReader sr = new StreamReader(resStream, enc);
Console.WriteLine(sr.ReadToEnd());

sr.Close();
resStream.Close();

実行すると。。。。

f:id:apollo_13:20150312110534j:plain

s3にファイルが作成されました。

fluentdのmatch ..*の部分は URLに対応するので、fluentdに送信するときにあらかじめログ情報を分類しておきURLを変えてあげることによってそれぞれの処理内容を変更させることもできます。

サービス毎やログレベルなどによって分割したりして、わかりやすく格納していけるかなと思います。 この辺りは実際に運用してみてベストな方法を考えたいと思います。

ここまで色々できるとどんどんやりたいことが出てきてしまいますね。 次回はslackに連携してみたいと思います。