ラベル fluentd の投稿を表示しています。 すべての投稿を表示
ラベル fluentd の投稿を表示しています。 すべての投稿を表示

2013年3月15日金曜日

nginx>fluentd>mongodb

スマートフォンからのアクセスをサービスのAPサーバに影響なく指標値として収集したくて、アクセスログやアプリケーションログを使おうと思って、まずは、nginxのアクセスログを保存する方法を検討して、fluentdmongodb を試してみました。

まず、fluentd に mongodb の plugin をインストールします。
[horiga@bin]: fluent-gem install fluent-plugin-mongo
Successfully installed fluent-plugin-mongo-0.6.13
1 gem installed
Installing ri documentation for fluent-plugin-mongo-0.6.13...
Installing RDoc documentation for fluent-plugin-mongo-0.6.13...
で、fluentd の設定ファイルを以下のようにしました。
<source>
 type tail
 path /usr/local/nginx/logs/access_heartbeat.log
 tag nginx.hb
 format /^(?<ipaddr>[^ ]*) \[(?<ts>[^\]]*)\] "(?<httpm>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<stat>[^ ]*) "(?<ua>[^\"]*)" (?<chid>[^ ]*)$/
 time_format %d/%b/%Y:%H:%M:%S %z
 pos_file /usr/local/fluent/logs/nginx_access_heartbeat.log.pos
</source>
<match nginx.**>
 type mongo
 database heartbeatdb
 collection heartbeat
 host localhost
 port 27017
 flush_interval 10s
</match>
そして、fluentd を起動しておきます。ext_bson とかいうpluginの警告ログがでますが、まぁBSONは使わないので無視しておきました。
次に、mongodb を起動します。とりあえずオプションなしのシングルモードで起動します。
defaultポートが27017で起動しました。fluent2mongo.conf に設定した port になりますね。
[horiga@bin]: ./mongod
./mongod --help for help and startup options
Fri Mar 15 21:03:56 [initandlisten] MongoDB starting : pid=51694 port=27017 dbpath=/data/db/ 64-bit host=hiroyuki-no-MacBook-Air.local
Fri Mar 15 21:03:56 [initandlisten] 
Fri Mar 15 21:03:56 [initandlisten] ** WARNING: soft rlimits too low. Number of files is 256, should be at least 1000
Fri Mar 15 21:03:56 [initandlisten] db version v2.2.2, pdfile version 4.5
Fri Mar 15 21:03:56 [initandlisten] git version: d1b43b61a5308c4ad0679d34b262c5af9d664267
Fri Mar 15 21:03:56 [initandlisten] build info: Darwin bs-osx-106-x86-64-1.local 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun  7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386 BOOST_LIB_VERSION=1_49
Fri Mar 15 21:03:56 [initandlisten] options: {}
Fri Mar 15 21:03:56 [initandlisten] journal dir=/data/db/journal
Fri Mar 15 21:03:56 [initandlisten] recover : no journal files present, no recovery needed
Fri Mar 15 21:03:56 [websvr] admin web console waiting for connections on port 28017
Fri Mar 15 21:03:56 [initandlisten] waiting for connections on port 27017
nginx の設定はとりあえず静的ファイルを変換するように以下のように設定
#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

 log_format fluent '$remote_addr [$time_local] "$request" $status "$http_user_agent" $http_x_test_chid'; 
    
 access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       9001;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

  location /hb/  {
    root html;
    index success.html;
    access_log logs/access_heartbeat.log fluent;
  }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
nginx を起動して、"http://localhost:9001/hb/?q=123" へアクセスしてみるとnginxのアクセスログに確かにアクセスログが残っていることを確認
[horiga@bin]: curl -H 'X-TEST-ChId:123456' http://localhost:9001/hb/?q=123
ok
[horiga@logs]: tail -F access_heartbeat.log 
127.0.0.1 [15/Mar/2013:21:15:25 +0900] "GET /hb/?q=123 HTTP/1.1" 200 "curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5" 123456
で、問題のmongodbにはどうか?
> use heartbeatdb 
> db.heartbeat.find();
{ "_id" : ObjectId("514310dc0840f7cb14000001"), "ipaddr" : "127.0.0.1", "ts" : "15/Mar/2013:21:14:27 +0900", "httpm" : "GET", "path" : "/hb/?q=123", "stat" : "200", "ua" : "curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5", "chid" : "123456", "time" : ISODate("2013-03-15T12:15:13Z") }
おおっ!!たしかにmongodbにも保存されてました。ここまで特にプログラミングなし、設定のみでできます。
あとは、このデータを使ってデータ分析だな。mongodb からデータを hdfs 上にもってきて分析結果をまた mongodb に格納するとか検討してみます。








2013年3月8日金曜日

fluent-logger-java を使ってみた

アプリケーションログを fluentd で収集して、アプリケーションエラーのログとかイベントログの収集してKPIとか集めたくてちょっとまとめます。
とりあえず、ローカル環境は MacOS ですが、fluentd のインストールについては割愛します。rubyやらなんやら入れる必要あります。
※ここら辺を参照

まずは、fluentd 側の設定。本家サイトの通りでおk


[horiga@fluent]: cat fluent4j.conf 
<source></source>
 type forward
 port 24224

<match fluentd.test.**>
 type stdout
</match>


で、起動コマンドはこんな感じで


[horiga@bin]: ./fluentd --config ../fluent4j.conf 


問題なく起動して、コンソールにログが出力されます

次はアプリケーション側。


<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://maven.apache.org/POM/4.0.0"
  xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelversion>4.0.0</modelversion>

 <groupid>com.blogspot.3agiroh.examples.fluentlogger</groupid>
 <artifactid>fluentlogger</artifactid>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>fluentlogger</name>
 <url>http://maven.apache.org</url>

 <properties>
  <project .build.sourceencoding="">UTF-8</project>
 </properties>

 <repositories>
  <repository>
   <id>fluentd.org</id>
   <name>Fluentd Maven2 Repository</name>
   <url>http://fluentd.org/maven2</url>
  </repository>
 </repositories>

 <dependencies>

  <dependency>
      <groupid>com.google.code.gson</groupid>
      <artifactid>gson</artifactid>
      <version>2.2.2</version>
      <scope>compile</scope>
    </dependency>
    
  <dependency>
   <groupid>org.fluentd</groupid>
   <artifactid>fluent-logger</artifactid>
   <version>0.2.6</version>
   
  </dependency>

  <dependency>
   <groupid>junit</groupid>
   <artifactid>junit</artifactid>
   <version>3.8.1</version>
   <scope>test</scope>
  </dependency>
 </dependencies>
</project>


今回テストしたのはJavaでこんなコードで実行しました
本家サイトにありますが、少しバージョンが古かったですね。Map に文字列だけでなく数字、bool型も


package com.blogspot.agiroh.examples.fluentlogger;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.fluentd.logger.FluentLogger;

import com.google.gson.Gson;

/**
 * This is Fluentd4 java test 
 */
public class App {

 static FluentLogger logger = FluentLogger.getLogger("fluentd.test");
 
 public static class Pojo {
  String str;
  int num;
  
  public String toString() {
   return new Gson().toJson(this);
  }
 }
 
 public static void main(String[] args) {
   Map<string object=""> data = new HashMap<string object="">();
   data.put("name", "hoge");
   data.put("age", 35);
   data.put("loggedin", true);
   long ts = new Date().getTime();
   data.put("ts", ts);
   
   Pojo pojo = new Pojo();
   pojo.str = "fuga";
   pojo.num = 100;
   data.put("pojo", pojo);
   
   // default timestamp is [sec]
   logger.log("fluent4j", data);
   
   // timestamp [millis]
   // logger.log("fluent4j", data, new Date().getTime());
 }
}


結果


[horiga@bin]: ./fluentd --config ../fluent4j.conf 
2013-03-08 20:05:11 +0900: starting fluentd-0.10.23
2013-03-08 20:05:11 +0900: reading config file path="../fluent4j.conf"
2013-03-08 20:05:11 +0900: adding source type="forward"
2013-03-08 20:05:11 +0900: adding match pattern="fluentd.test.**" type="stdout"
2013-03-08 20:05:11 +0900: listening fluent socket on 0.0.0.0:24224
2013-03-08 20:13:59 +0900 fluentd.test.fluent4j: {"ts":1362741239520,"loggedin":true,"age":35,"name":"hoge","pojo":"{\"str\":\"fuga\",\"num\":100}"}


おお!!無事に fluentd さんにイベントが転送されました。※本来ならこれを収集サーバに forward すればいいと思う。

でも、やっぱりvalueにpojoはだめか。まぁ複雑にしないでkey-valueの方が使いやすいからこれは問題ないかな。これで accesslog 以外にもいろいろ使えることはおk。実際のロジックと集計などは別に分離したいよね。