Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Lambda+Elasticsearch(Amazon Elasticsearch Service)でELBのログをサーバーレスでKibanaで可視化する

More than 5 years have passed since last update.

AmazonのマネージドサービスとしてElasticsearch+Kiban4が使えるAmazon Elasticsearch Serviceが発表されました。

【AWS発表】Amazon Elasticsearch Service

以前fluentdを使ってELBのログをElasticsearchに取り込むことをやってみたのですが、その場合、fluentdを動かすサーバーが必要です。

ELBのアクセスログをfluentd(fluent-plugin-elb-access-log)+Elasticsearch+kibanaで可視化する

今であればLambdaがTokyoリージョンにあって使えるのでS3へのELBアクセスログのアップロードをイベントにして、Lambdaで処理してElasticsearchに登録することでサーバーレスで可視化ができそうだと思い、やってみたのでメモ。

Lambda用のロール作成

IAMでLambda用のS3へのアクセス及びElasticsearchへの登録ができるロールを予め作成しておきます。

Elasticsearchの作成

マネージメントコンソールなどからElasticsearchの新規ドメインを作成しておきます。

また、先ほど作成したロールからElasticsearchを操作できるようにします。

作成後、作成したドメインのエンドポイントをメモしておきてください。

Lambdaのコード作成

LambdaからElasticsearchへ登録するコードを書く必要があります。
と、思ったのですが、以下にLambdaによってS3からapacheのログをElasticsearchに登録するAWS公式のサンプルがありました。

amazon-elasticsearch-lambda-samples/src/s3_lambda_es.js

ログファイルのパース部分がapache/nginx用のものを使っているようなので、ELB用のパースに変えれば良さげです。
apache/nginxで利用されているものを参考にELBのアクセスログをパースするnpmを作ってみました。

elb-log-parser

今回はこれと既存のものを利用して少しのコード変更で実現します。もし、パース部分をもっと細かくする場合も同様にparserを作って登録する部分は既存のものを使ってやると簡単にできるかと思います。

まず、適当な所でAmazon公式のリポジトリからs3からElasticsearchへ登録するコードを取得します。

$git clone https://github.com/awslabs/amazon-elasticsearch-lambda-samples.git

次に今回利用する用のLambdaのプロジェクトを作成します。

# プロジェクト作成
$mkdir es-elb-log
$cd es-elb-log
$cp ../amazon-elasticsearch-lambda-samples/src/s3_lambda_es.js index.js

# 依存ライブラリのインストール。bylineはStreamを1行ごとに取り出せる
$npm install aws-sdk byline elb-log-parser

次に少しファイルを変更します。{your-es-endpoint}は先ほど作成したElasticsearchのエンドポイントにしてください。

index.js
- var parse = require('clf-parser');
+ var parse = require('elb-log-parser');

- endpoint: 'my-search-endpoint.amazonaws.com',
+ endpoint: {your-es-endpoint},
- region: 'my-region',
+ region: 'ap-northeast-1',
- doctype: 'apache',
+ doctype: 'elb',

ZIPで圧縮します。

$zip -r es-elb-log.zip index.js node_modules

これでコードができたのであとはLambdaFunctionをマネジーメントコンソールなどから作成し、作成したZIPファイルをアップロードします。

Handlerにはindex.handlerを指定し、Roleには最初に作成したロールを指定してください。また、ログの量によると思いますが、Timeoutの時間は少し長めにしておくと良いかもしれません。

やってみる

準備ができたので以下を行い、Lambda経由でアクセスログが登録できるか確認します。

  • EC2を起動し、Webサーバーを起動
  • ELBを作成し、EC2にトラフィックが流れるようにする
  • ELBのアクセスログを任意のS3バケットに登録するように設定。アクセスログの間隔を5分にすると結果が早く分かります。
  • LambdaのEventSourcesでELBのアクセスログを配置するバケット、EventTypeとしてObject Created(All)を指定します。

Screen Shot 2015-10-12 at 6.32.21 PM.png

あとは適当にELBにアクセスし、ログが出力されるのを待ちます。

設定が無事できていればS3へアクセスログがアップロードされたタイミングでLambdaが実行され、Elasticsearchへログ情報が登録されます。Elasticsearhをマネージメントコンソールで確認すると以下のようにレコードが登録されているのが確認できるかと思います。

Screen Shot 2015-10-12 at 5.23.49 PM.png

CloudwatchLogsでLambdaのログも確認できます。

Screen Shot 2015-10-12 at 6.39.52 PM.png

また、Elasticsearchのアクセスポリシーを変更し、利用している環境のIPからの接続を許可することでKinabaにアクセスし、以下のようにログ情報を見ることができます。

Screen Shot 2015-10-12 at 5.35.36 PM.png

サーバー管理なしでここまでできるのはかなりいい感じです!

toshihirock
こちらは個人の意見で会社とは関係ありません。お約束です。
http://toshihirock.blogspot.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away