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

2015年4月11日土曜日

fluentd-v2+elasticsearch+kibana3をEC2上で実施する

このエントリーをはてなブックマークに追加 はてなブックマーク - fluentd-v2+elasticsearch+kibana3をEC2上で実施する

nginxのアクセスログをfluentdを使ってelasticsearchに登録し、その情報をkinaba3を使って見れるようにした時のメモ

環境

  • Amazon Linux AMI 2015.03 (HVM), SSD Volume Type
  • td-agent 0.12.7
  • elasticsearch 1.3(最終的に1.4にアップグレード)
  • kibana3

td-agent2のインストール

最新のFluentd(td-agent2)ではAmazonLinuxもサポートとなったようなのでスクリプトからインストールします

td-agent2をAmazon Linuxで実行する

curl -L http://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sudo sh
$td-agent --version
td-agent 0.12.7
$sudo chkconfig td-agent on
$sudo chkconfig --list |grep td-agent

elastic-search1.3のインストール、起動

基本的には公式サイトに書いてあるように進めます。

elastic-search(YUM)

$sudo rpm --import https://packages.elasticsearch.org/GPG-KEY-elasticsearch
$sudo vi /etc/yum.repos.d/elasticsearch.repo

以下を記載します。

[elasticsearch-1.3]
name=Elasticsearch repository for 1.3.x packages
baseurl=http://packages.elasticsearch.org/elasticsearch/1.3/centos
gpgcheck=1
gpgkey=http://packages.elasticsearch.org/GPG-KEY-elasticsearch
enabled=1

インストールおよび自動起動登録、起動をします。

$sudo yum install elasticsearch
$sudo chkconfig --add elasticsearch
$sudo chkconfig --list |grep elasticsearch
$sudo service elasticsearch start

なお、起動時にメモリ量が確保出来なくてエラーになる場合があります。その場合には不要なプロセスをkillすればt2.microでも起動できました。もしくは/etc/elasticsearch/elasticsearch.ymlでメモリ量を記載することでも調整できるようです。

クラスタとノードの名前を確認

クラスタとノードの名前を確認します。 jqをインストールしていない人はyumでインストールしておくと便利だと思います。

# cluster
$curl -XGET http://localhost:9200/_cluster/health | jq .
{
  "cluster_name": "elasticsearch",
  "status": "green",
  "timed_out": false,
  "number_of_nodes": 1,
  "number_of_data_nodes": 1,
  "active_primary_shards": 0,
  "active_shards": 0,
  "relocating_shards": 0,
  "initializing_shards": 0,
  "unassigned_shards": 0
}

# node
$curl -XGET http://localhost:9200/ | jq .
{
  "status": 200,
  "name": "Sam Wilson",
  "version": {
    "number": "1.3.9",
    "build_hash": "0915c7306e6264ba21a6cb7609b93545ccc32ef1",
    "build_timestamp": "2015-02-19T12:34:48Z",
    "build_snapshot": false,
    "lucene_version": "4.9"
  },
  "tagline": "You Know, for Search"
}

デフォルトだとクラスタ名はelasticsearch、ノードは任意のマーベルコミックの人物になるようです。

クラスタの名前を変更する

クラスタ名とノード名を任意のものに変更します。本例ではクラスタ名をtest_cluster、ノード名をnode_1としました。

$sudo vi /etc/elasticsearch/elasticsearch.yml

cluster.name: test_cluster

node.name: "node_1"

設定後、サービスを再起動します。

$sudo service elasticsearch restart

変更を確認します。

# cluster
$curl -XGET http://localhost:9200/_cluster/health | jq .

# node
curl -XGET http://localhost:9200/ | jq .

どちらも変更されていることが確認できると思います。

nginxのインストール

$sudo yum install nginx
$sudo service nginx start
$sudo chkconfig nginx on
$chkconfig --list |grep nginx

fluentdのelastic-searchプラグインのインストール

fluentd経由でelastic-searchのプラグインをインストールします。事前に必要となるDevelopment toolscurl-develもインストールします。

$sudo yum groupinstall 'Development tools'
$sudo yum -y install curl-devel
$sudo /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-elasticsearch

nginxのアクセスログのフォーマットを確認する

nginxのログフォーマットを確認するためにFluentularというサイト上でFluentdのログフォーマットを確認できるサイトを使います。

上記サイトで実際に出力されるログとそのフォーマットが正しくできるまでを確認後、実際に設定ファイルに記載して内容を確認します。

まずは、標準出力に出すようにしています。

$sudo vi /etc/td-agent/td-agent.conf

以下のように記載します。

<source>
  type tail
  path /var/log/nginx/access.log
  format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<forward>[^\"]*)")?$/
  time_format %d/%b/%Y:%H:%M:%S %z
  pos_file /var/log/td-agent/nginx-access.log.pos
  tag nginx.access
</source>

<match nginx.access.**>
  type stdout
</match>

実際に動作が可能なやってみます。 今回はログがわかり易いようにflunetdをトレースモードで起動します。

$sudo td-agent -vv &

その後、実際にnginxにアクセスしてみます。

$wget http://localhost
--2015-04-11 02:53:04--  http://localhost/
localhost (localhost) をDNSに問いあわせています... 127.0.0.1
localhost (localhost)|127.0.0.1|:80 に接続しています... 接続しました。
2015-04-11 02:53:04 +0000 nginx.access: {"remote":"127.0.0.1","host":"-","user":"-","method":"GET","path":"/","code":"200","size":"3770","referer":"-","agent":"Wget/1.16.1 (linux-gnu)","forward":"-"}
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 3770 (3.7K) [text/html]
`index.html' に保存中

index.html          100%[=====================>]   3.68K  --.-KB/s 時間 0s

2015-04-11 02:53:04 (555 MB/s) - `index.html' へ保存完了 [3770/3770]

設定がうまくいっていれば、上記のメッセージの中にnginx.accessなどのように正しくfluentdがログをパースできているか確認できます。

上記、問題なければ一度fluentdを止めます。

$ps aux|grep ruby|awk ‘{ print $2 }’|sudo xargs kill -KILL

td-agentの設定ファイルを変更します。 デバッグ用にcopyプラグインを使って、標準出力もしつつ、ElasticSearchへの登録を行う設定に変更します。

$vi td-agent.conf

以下のように変更します。

<source>
  type tail
  path /var/log/nginx/access.log
  format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<forward>[^\"]*)")?$/
  time_format %d/%b/%Y:%H:%M:%S %z
  pos_file /var/log/td-agent/nginx-access.log.pos
  tag nginx.access
</source>

<match nginx.access.**>
  type copy

  <store>
    type stdout
  </store>

  <store>
    type elasticsearch
    host localhost
    port 9200
    type_name nginx_log
    include_tag_key true
    logstash_format true
    tag_key tag
  </store>
</match>

再起動後、nginxにリクエストを投げてアクセスログを更新します。

$td-agent -vv &
$wget http://localhost

先程と同じように標準出力にログがパースできているか確認し、問題なければ少し待つと以下のような出力がされます。

2015-04-11 04:19:50 +0000 [info]: plugin/out_elasticsearch.rb:67:client: Connection opened to Elasticsearch cluster => {:host=>"localhost", :port=>9200, :scheme=>"http"}

上記出力後、問題なければlogstash–2015.04.11というような今日の日付のインデックスができていると思うので全ての内容を取得します。

#データ取得(全件)
curl -XGET http://localhost:9200/logstash-2015.04.11/_search -d '
{
  "query": {
    "match_all" : {}
  }
}
' | jq .
{
"took": 44,
"timed_out": false,
"_shards": {
  "total": 5,
  "successful": 5,
  "failed": 0
},
"hits": {
  "total": 1,
  "max_score": 1,
  "hits": [
    {
      "_index": "logstash-2015.04.11",
      "_type": "nginx_log",
      "_id": "8w0OI32bRRObQna13HGcJQ",
      "_score": 1,
      "_source": {
        "remote": "127.0.0.1",
        "host": "-",
        "user": "-",
        "method": "GET",
        "path": "/",
        "code": "200",
        "size": "3770",
        "referer": "-",
        "agent": "Wget/1.16.1 (linux-gnu)",
        "forward": "-",
        "tag": "nginx.access",
        "@timestamp": "2015-04-11T04:18:57+00:00"
      }
    }
  ]
}
}

例えばsizeパラメーターが3000より大きいものみ取得したい場合には以下のようなリクエストを送ります。

curl -XGET http://localhost:9200/logstash-2015.04.11/_search -d '
{
  "query": {
    "query_string" : {
    "query" : "size:>3000"
   }
 }
}
' | jq .

kibanaのインストール

現在はKibana4がリリースされていますが、導入してみたところ、elasticsearch1.4.4以上である必要があったので今回はKinaba3で実施することにしました。

Kibana3.1.2

$wget https://download.elastic.co/kibana/kibana/kibana-3.1.2.tar.gz
$tar -zxvf kibana-3.1.2.tar.gz
$mv kibana-3.1.2 kibana
$sudo mv kibana /usr/share/nginx/html

nginxを再起動します。

$service nginx restart

上記の場合http://yourhost/kibanaとするとkibanaのサイトにアクセスできるようになっているかと思います。

ただし、Connection failedと表示されてelasticsearchとの接続がうまくできていないようでした。

上記原因の一つとしてまず、SecurityGroupの設定で9200ポートを開いていないことが問題の一つだったので、開けるように設定します。

また、上記を対応してもまだ接続エラーとなってしまい、色々探したのですが、利用が全くわからなかったのでelasticsearchのバージョンを1.3から1.4にあげて、設定を変えてみたところうまくいきました。

ElasticSearch–1.4-YUM

$sudo vi /etc/yum.repos.d/elasticsearch.repo

以下に変更。

[elasticsearch-1.4]
name=Elasticsearch repository for 1.4.x packages
baseurl=http://packages.elasticsearch.org/elasticsearch/1.4/centos
gpgcheck=1
gpgkey=http://packages.elasticsearch.org/GPG-KEY-elasticsearch

アップデート。

$sudo yum update

また、elasticsearch1.4からセキュリティ向上が目的で設定が追加で必要になったようで、それを追加します。

Kibana3+Elasticsearch1.4.1でConnection Failedと怒られる

$sudo vi /etc/elasticsearch/elasticsearch.yml 

以下を末尾に追記。

http.cors.allow-origin: "/.*/"
http.cors.enabled: true

サービスを再起動。

$sudo service elasticsearch restart
$sudo service nginx

この状態でアクセスするとうまくできました。

2015年2月20日金曜日

Fluentdを使ってApacheのログをRDS(Postgresql)に入れる

このエントリーをはてなブックマークに追加 はてなブックマーク - Fluentdを使ってApacheのログをRDS(Postgresql)に入れる

Fluentdを使ってApacheのログをRDS(Postgresql)に入れる対応をした時のメモ。

環境

  • AWS EC2 on Red Hat Enterprise Linux 6.6 (HVM)
  • RDS on PostgreSQL 9.3.5

EC2とRDS作成は省略。EC2とRDSは接続可能なようにネットワークとセキュリティグループの設定をしておくこと

Flunetdインストールの準備

Fluentdインストールの前にを参考に準備を行います。

NTP

こちらを参考に。

CentOSにntpサーバを入れて、日本標準時刻に自動的に合わせるためのメモ

まず、UTCからJST形式に変更します。

$cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

NTP自体はすでにインストールされていたので、設定ファイルを日本の設定に変更します。/etc/ntp.confを開いて

server 0.rhel.pool.ntp.org iburst
server 1.rhel.pool.ntp.org iburst
server 2.rhel.pool.ntp.org iburst
server 3.rhel.pool.ntp.org iburst

となっている部分を

server -4 ntp.nict.jp
server -4 ntp1.jst.mfeed.ad.jp
server -4 ntp2.jst.mfeed.ad.jp
server -4 ntp3.jst.mfeed.ad.jp

と変更。

サービスを起動します。

$sudo service ntpd start

確認。

$ntpq -p

自動起動ON。

 $sudo chkconfig ntpd on

ファイルディスクプリンタ

扱えるファイル数を増やすためにファイルディスクプリンタの設定をします。 /etc/security/limits.confを開いて、以下を末尾に追加します。

root soft nofile 65536
root hard nofile 65536
* soft nofile 65536
* hard nofile 65536

再起動。

$sudo shutdown -r now

確認。

$ulimit -n

ネットワーク関連のパラメータ変更

多分ここあたりの話が関係しているっぽい。

ぜんぶTIME_WAITのせいだ!

/etc/sysctl.confを開いて追記します。

net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 10240    65535

反映。

 $sudo sysctl -p

確認。

$sudo sysctl -a |grep -e recycle -e reuse -e port_range

Flunetdインストールのインストール

fluentd-インストールのページからインストール対象のディストリビューションを選んでインストール方法を確認します。 Redhatの場合、インストールスクリプトが用意されているのでそれを利用します。

$curl -L http://toolbelt.treasuredata.com/sh/install-redhat.sh | sh

これでインストールは完了です。

サービスが起動するか確認します。

$sudo /etc/init.d/td-agent start
Starting td-agent:                                         [  OK  ]

Fluent-catコマンドを使って挙動を確認する

fluentdの簡単な使い方、設定方法一覧

上記を参考にやってみました。 その他全体の概要についても詳しく書いてあり、参考になりました。

fluentdの設定を変更します。 /etc/td-agent/td-agent.confを以下のようにします。

<source>
  type forward
</source>
<match debug.**>
  type stdout
</match>

今回はわかりやすいようにtraceモードで起動したいので、一旦デーモンの方は停止させます。

$sudo /etc/init.d/td-agent stop

traceモードをバックグラウンドで起動します。

$td-agent -vv &

fluent-catコマンドを使って確認します。

$ echo '{"json":"message dayo"}' | /usr/lib64/fluent/ruby/bin/fluent-cat debug.test
2015-02-19 22:21:44 +0900 [trace]: plugin/in_forward.rb:189:initialize: accepted fluent socket from '127.0.0.1:23200': object_id=11839160
2015-02-19 22:21:44 +0900 debug.test: {"json":"message dayo"}
2015-02-19 22:21:44 +0900 [trace]: plugin/in_forward.rb:245:on_close: closed fluent socket object_id=11839160

debug.testというファイル名がマッチして表示されている事が確認できます。 試しに他のファイル名でやってみます。

$echo '{"json":"message dayo"}' | /usr/lib64/fluent/ruby/bin/fluent-cat debugaaaa.test
2015-02-19 22:23:56 +0900 [trace]: plugin/in_forward.rb:189:initialize: accepted fluent socket from '127.0.0.1:23201': object_id=70330928356440
2015-02-19 22:23:56 +0900 [warn]: fluent/engine.rb:330:emit: no patterns matched tag="debugaaaa.test"
2015-02-19 22:23:56 +0900 [trace]: plugin/in_forward.rb:245:on_close: closed fluent socket object_id=70330928356440

パターンにマッチしていない事が確認できます。

確認は終わったので、プロセスをkillします。

$ps aux|grep fluentd
$kill KILL hoge
$kill KILL fuga

Apacheのアクセスログをfluentdにかませてファイル出力する

RDSに入れる前にファイル出力が出来るか確認しました。 下記を参考にさせて頂きました。

fluentdを試してみた

まず、Apacheをインストールします。

$sudo yum install httpd -y

起動します。

$sudo service httpd start

また、td-agentがアクセスログの読み取りが出来るように権限を変更します。

$sudo chmod a+rx /var/log/httpd

fluentdの設定をApache用に変更します。 /etc/td-agent/td-agent.confを以下のようにします。

<source>
  type tail
  format apache
  path /var/log/httpd/access_log
  pos_file /var/log/td-agent/pos/apache.test.log.pos
  tag apache.access
</source>

<match apache.access>
  type file
  path /var/log/td-agent/access_log
</match>

posファイル用のディレクトリを作成します。

$sudo mkdir /var/log/td-agent/pos
$sudo chown -R td-agent:td-agent /var/log/td-agent/pos

デーモンを起動します。

$sudo service td-agent start

アクセスログが追加されるようにWebサーバーにアクセスします。

$wget http://localhost

うまく動作していれば/var/log/td-agent/access_log.20150219.b50f712d6139bb1bcという感じでファイルが出来ているかと思います。

ダメな場合、/var/log/td-agent/td-agent.logを確認するとエラーの原因が書いているかと思います。

RDSにApacheのアクセスログを送る

プラグインを追加して、RDSへ情報を送ります。

fluent-plugin-pgjson

まず、プラグインで必要なソフトウェア群をインストールします。

$sudo yum groupinstall "Development Tools" -y
$sudo yum install postgresql postgresql-devel -y

また、psqlコマンドを使ってEC2からアクセスできるか確認します。各パラメーターは自分の環境に変更してください。

$psql -U root -p 5432 -d testdb -h dbinstance.c0cdb3a3yekt.ap-northeast-1.rds.amazonaws.com

アクセス後、fluentd用のテーブルを作成します。

CREATE TABLE fluentd (
    tag Text
    ,time Timestamptz
    ,record Json
);

fluent-plugin-pgjsonを追加します。

$sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-pgjson

fluentdの設定ファイルを変更します。設定は適宜変更ください。

<source>
  type tail
  format apache
  path /var/log/httpd/access_log
  pos_file /var/log/td-agent/pos/apache.test.log.pos
  tag apache.access
</source>

<match apache.access>
  type pgjson
  host dbinstance.c0cdb3a3yekt.ap-northeast-1.rds.amazonaws.com
  port 5432
  database testdb
  table fluentd
  user root
  password PASSWORD
  time_col time
  tag_col tag
  record_col record
</match>

設定を反映するためにデーモンを再起動します。

 $sudo service td-agent restart

テーブルを確認するとログが登録されているのが確認できます。

testdb=> select * from fluentd;
apache.access | 2015-02-19 14:29:39+00 | {"host":"::1","user":"-","method":"GET
","path":"/","code":"403","size":"3985","referer":"-","agent":"Wget/1.12 (linux-
gnu)"}

自分でフォーマットを決める場合

今回、すでに用意されたapacheのフォーマットを利用しましたが、正規表現を用いて自分で定義することもできます。

例えばスペース区切りでcodeとsizeとkeyとする場合、以下のようにします。

<source> 
  type tail 
  path /var/log/foo/bar.log 
  pos_file /var/log/td-agent/foo-bar.log.pos 
  tag foo.bar 
  format /^(?<code>[^ ]*) (?<size>[^ ]*)$/ 
</source>

詳細や例は公式を見ると良いかと思います。

tailインプットプラグイン

また、以下のサイトで設定した正規表現がどのような挙動となるか確認できます。

Fluentular