~ M O N G O D B 使 っ ち ゃ う ぞ ! ~
(Nginx+)Fluentd+MongoDB
&Groovy+MongoDB
目次
1. Fluentdって?
2. wajaでの採用理由
3. Nginx+Fluentd+MongoDB設定
4. 使えそうなシチュエーション
5. Groovyって?
6. Groovy+MongoDB
1. Fluentdって?
 Open Source Log Management
 日本人開発者 & Ruby(コアはC, thin Ruby wrapper)
 インプット、アウトプットをつなぐ「パイプ」
 ログの入出力が一番分かりやすい使い方だったのでしょう
 JSON
 プラグインメカニズム
 入力
 ファイル、ストリーム、etc…
 出力
 ファイル、メール、ストリーム、DB、etc…
2. wajaでの採用理由
 ログ解析の要望
 Analyticsだけでは知ることが難しい(設定が複雑になる)タイプ
 商品一覧ページから商品詳細ページへの遷移数(APサーバ毎)
 調査の効率化
 毎回毎回ログファイルにgrep/awk。。。
 解析対象のログファイルをDBに入れられたら、、
 専用アプリ作るための工数。。
 現行のPostgreSQL(というかDBサーバ)は使いたくない
 全部まるっとすべて一気に解決!
3. Nginx+Fluentd+MongoDB
Nginx
Fluentd
Tomcat
Nginx
Fluentd
Tomcat
Fluentd
MongoDB
wajaweb01
wajaweb02
wajalog01
Fluentd(wajaweb01, wajaweb02)
- Nginxのログファイルをtail監視(入力)
- wajalog01のFluentdにストリーム転送(出力)
Fluentd(wajalog01)
- ストリームから入力
- MongoDBに出力
MongoDB
- 要求に従って書込
3. Nginx+Fluentd+MongoDB
 Nginx
 取りたいログを追加するのみ
 $remote_addr, $remote_user, $time_local, $request, $status,
$body_bytes_sent, $http_referer, $http_user_agent,
$request_time
 $http_x_forwarded_for ※リバースプロキシ(ロードバランサ)環境
 $upstream_addr ※どのAPサーバに処理を振ったか
 $upstream_response_time ※APサーバからの応答時間
 $cookie_JSESSIONID ※COOKIEのセッションID
3. Nginx+Fluentd+MongoDB
 Fluentd(wajaweb01, wajaweb02)
<source>
type tail
path /var/log/nginx/waja.access.log
format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) [(?<time>[^]]*)]
“(?<method>S+)(?: +(?<path>[^ ]*) +S*)?” (?<status>[^ ]*) … (中略)/
time_format %d/%b/%Y:%H:%M:%S %z
tag nginx.waja.access
pos_file /var/log/td-agent/nginx.waja.access.pos
</source>
(ログファイル分設定)
<match nginx.**>
type forward
buffer_chunk_limit 10m
<server>
host wajalog01
</server>
</match>
入力
出力
3. Nginx+Fluentd+MongoDB
 Fluentd(wajalog01)
<source>
type forward
port 24224
</source>
<match nginx.**>
type mongo
host localhost
database nginx
tag_mapped
remove_tag_prefix nginx.
flush_interval 10s
buffer_chunk_limit 10m
</match>
入力
出力
3. Nginx+Fluentd+MongoDB
 MongoDB
$ mongo
MongoDB shell version: 2.4.4
connecting to: test
> show dbs
admin (empty)
local 0.078125GB
nginx 19.9443359375GB
> use nginx
switched to db nginx
> show tables
reason.access
ssl.waja.access
system.indexes
waja.access
3. Nginx+Fluentd+MongoDB
 まとめ
 FluentdがJSONベースなので、MongoDBとの親和性が高い
 というかプラグイン任せなのですが。。
 MongoDBがスキーマレス
 MongoDBの設定(スキーマ定義など)は何もしていない。
 取りたいログ属性を増やしたい場合、Nginx、Fluentdの設定変更のみ
 MongoDBがシャーディング
 解析処理をハードに行うようになった場合
 ログがどんどん増えた場合
 Capped Collectionを使う、という選択肢もあり
 総じて「カンタン」
4. 使えそうなシチュエーション
 とにかくログを突っ込みまくる
 Tomcat, PostgreSQLのログだって入れちゃえる
 きっと誰かプラグインを書いてるのでは。。正規表現頑張りたくない。。
 ログデータを一括管理することで、調査を簡易化
 MongoDBをキャッシュサーバに
 オンメモリや、ファイル、memcachedなどの代替
5. Groovyって?
 Javaを拡張する言語
 Javaの痒いところに手が届く感じ
 スクリプトとしても使える
 Closure, AST, 型推論などの仕組み
 より「簡潔に」Javaが書ける
5. Groovyって?
 ある日付を設定したい by Java
 キィィィィーーーーーーーーーーーーーーーー!
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2013);
cal.set(Calendar.MONTH, 1); // 2月
cal.set(Calendar.DATE, 15);
cal.set(Calendar.HOUR_OF_DAY, 13);
cal.set(Calendar.MINUTE, 27);
cal.set(Calendar.SECOND, 30);
cal.set(Calendar.MILLISECOND, 999);
cal.add(Calendar.DATE, 2); // 2日後
Date plus2 = cal.getTime();
5. Groovyって?
 ある日付を設定したい by Groovy
 ス、スッキリーー!
Calendar cal = Calendar.getInstance()
cal.with {
set(YEAR, 2013)
set(MONTH, FEBRUALY) // 2月
set(DATE, 15)
set(HOUR_OF_DAY, 13)
set(MINUTE, 27)
set(SECOND, 30)
set(MILLISECOND, 999)
}
def now = new Date()
def plus2 = now + 2
6. Groovy+MongoDB
 DBと接続
def mongo = new Mongo("localhost", 27017)
def db = mongo.getDB("crawler")
def collection = db.getCollection("sites")
6. Groovy+MongoDB
 ドキュメントを挿入
def doc = [
url: "org.mongodb",
tags:
["database", "open-source"],
attrs: [
["lastAccess", new Date()],
["pingtime", 20]
]
] as BasicDBObject
collection.insert(doc)
6. Groovy+MongoDB
 ドキュメントを表示
collection.find().each { obj ->
println "objs : " + obj
}

Fluentd+MongoDB+Groovy

  • 1.
    ~ M ON G O D B 使 っ ち ゃ う ぞ ! ~ (Nginx+)Fluentd+MongoDB &Groovy+MongoDB
  • 2.
    目次 1. Fluentdって? 2. wajaでの採用理由 3.Nginx+Fluentd+MongoDB設定 4. 使えそうなシチュエーション 5. Groovyって? 6. Groovy+MongoDB
  • 3.
    1. Fluentdって?  OpenSource Log Management  日本人開発者 & Ruby(コアはC, thin Ruby wrapper)  インプット、アウトプットをつなぐ「パイプ」  ログの入出力が一番分かりやすい使い方だったのでしょう  JSON  プラグインメカニズム  入力  ファイル、ストリーム、etc…  出力  ファイル、メール、ストリーム、DB、etc…
  • 4.
    2. wajaでの採用理由  ログ解析の要望 Analyticsだけでは知ることが難しい(設定が複雑になる)タイプ  商品一覧ページから商品詳細ページへの遷移数(APサーバ毎)  調査の効率化  毎回毎回ログファイルにgrep/awk。。。  解析対象のログファイルをDBに入れられたら、、  専用アプリ作るための工数。。  現行のPostgreSQL(というかDBサーバ)は使いたくない  全部まるっとすべて一気に解決!
  • 5.
    3. Nginx+Fluentd+MongoDB Nginx Fluentd Tomcat Nginx Fluentd Tomcat Fluentd MongoDB wajaweb01 wajaweb02 wajalog01 Fluentd(wajaweb01, wajaweb02) -Nginxのログファイルをtail監視(入力) - wajalog01のFluentdにストリーム転送(出力) Fluentd(wajalog01) - ストリームから入力 - MongoDBに出力 MongoDB - 要求に従って書込
  • 6.
    3. Nginx+Fluentd+MongoDB  Nginx 取りたいログを追加するのみ  $remote_addr, $remote_user, $time_local, $request, $status, $body_bytes_sent, $http_referer, $http_user_agent, $request_time  $http_x_forwarded_for ※リバースプロキシ(ロードバランサ)環境  $upstream_addr ※どのAPサーバに処理を振ったか  $upstream_response_time ※APサーバからの応答時間  $cookie_JSESSIONID ※COOKIEのセッションID
  • 7.
    3. Nginx+Fluentd+MongoDB  Fluentd(wajaweb01,wajaweb02) <source> type tail path /var/log/nginx/waja.access.log format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) [(?<time>[^]]*)] “(?<method>S+)(?: +(?<path>[^ ]*) +S*)?” (?<status>[^ ]*) … (中略)/ time_format %d/%b/%Y:%H:%M:%S %z tag nginx.waja.access pos_file /var/log/td-agent/nginx.waja.access.pos </source> (ログファイル分設定) <match nginx.**> type forward buffer_chunk_limit 10m <server> host wajalog01 </server> </match> 入力 出力
  • 8.
    3. Nginx+Fluentd+MongoDB  Fluentd(wajalog01) <source> typeforward port 24224 </source> <match nginx.**> type mongo host localhost database nginx tag_mapped remove_tag_prefix nginx. flush_interval 10s buffer_chunk_limit 10m </match> 入力 出力
  • 9.
    3. Nginx+Fluentd+MongoDB  MongoDB $mongo MongoDB shell version: 2.4.4 connecting to: test > show dbs admin (empty) local 0.078125GB nginx 19.9443359375GB > use nginx switched to db nginx > show tables reason.access ssl.waja.access system.indexes waja.access
  • 10.
    3. Nginx+Fluentd+MongoDB  まとめ FluentdがJSONベースなので、MongoDBとの親和性が高い  というかプラグイン任せなのですが。。  MongoDBがスキーマレス  MongoDBの設定(スキーマ定義など)は何もしていない。  取りたいログ属性を増やしたい場合、Nginx、Fluentdの設定変更のみ  MongoDBがシャーディング  解析処理をハードに行うようになった場合  ログがどんどん増えた場合  Capped Collectionを使う、という選択肢もあり  総じて「カンタン」
  • 11.
    4. 使えそうなシチュエーション  とにかくログを突っ込みまくる Tomcat, PostgreSQLのログだって入れちゃえる  きっと誰かプラグインを書いてるのでは。。正規表現頑張りたくない。。  ログデータを一括管理することで、調査を簡易化  MongoDBをキャッシュサーバに  オンメモリや、ファイル、memcachedなどの代替
  • 12.
    5. Groovyって?  Javaを拡張する言語 Javaの痒いところに手が届く感じ  スクリプトとしても使える  Closure, AST, 型推論などの仕組み  より「簡潔に」Javaが書ける
  • 13.
    5. Groovyって?  ある日付を設定したいby Java  キィィィィーーーーーーーーーーーーーーーー! Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, 2013); cal.set(Calendar.MONTH, 1); // 2月 cal.set(Calendar.DATE, 15); cal.set(Calendar.HOUR_OF_DAY, 13); cal.set(Calendar.MINUTE, 27); cal.set(Calendar.SECOND, 30); cal.set(Calendar.MILLISECOND, 999); cal.add(Calendar.DATE, 2); // 2日後 Date plus2 = cal.getTime();
  • 14.
    5. Groovyって?  ある日付を設定したいby Groovy  ス、スッキリーー! Calendar cal = Calendar.getInstance() cal.with { set(YEAR, 2013) set(MONTH, FEBRUALY) // 2月 set(DATE, 15) set(HOUR_OF_DAY, 13) set(MINUTE, 27) set(SECOND, 30) set(MILLISECOND, 999) } def now = new Date() def plus2 = now + 2
  • 15.
    6. Groovy+MongoDB  DBと接続 defmongo = new Mongo("localhost", 27017) def db = mongo.getDB("crawler") def collection = db.getCollection("sites")
  • 16.
    6. Groovy+MongoDB  ドキュメントを挿入 defdoc = [ url: "org.mongodb", tags: ["database", "open-source"], attrs: [ ["lastAccess", new Date()], ["pingtime", 20] ] ] as BasicDBObject collection.insert(doc)
  • 17.