Apacheのアクセスログを、EmbulkでElasticsearchに叩き込む

# やりたいこと
* Apacheのアクセスログを、可視化・分析するための環境を作りたい

ということをお題に、

* すでにファイルとして存在するログを、Elasticsearchに放り込んで
* Kibanaで可視化するための準備を整える

ということをやってみたいと思います。

リアルタイムに出力されるログを対象にするのなら[Fluend](https://www.fluentd.org/)が通常だと思いますが、今回は「すでに存在するログ」を対象にするので、バルクローダーである[Embulk](https://github.com/embulk/embulk)を使ってみたいと思います。

# 対象のアクセスログ
ちょうど、Apacheのアクセスログが手元にありましてですね。そこそこの期間。

logrotatedで扱っていて、日付単位に`.gz`されています。

```shell
$ ls -1 accesslogs
access_log-20180602.gz
access_log-20180603.gz
access_log-20180604.gz
access_log-20180605.gz
access_log-20180606.gz
access_log-20180607.gz
access_log-20180608.gz
access_log-20180609.gz
access_log-20180610.gz
access_log-20180611.gz
access_log-20180612.gz
access_log-20180613.gz
access_log-20180614.gz

...

access_log-20181101.gz
access_log-20181102.gz
access_log-20181103.gz
access_log-20181104.gz
access_log-20181105.gz
access_log-20181106.gz
access_log-20181107.gz
access_log-20181108.gz
access_log-20181109.gz
access_log-20181110.gz
access_log-20181111.gz
access_log-20181112.gz
access_log-20181113.gz

...

access_log-20181201.gz
access_log-20181202.gz
access_log-20181203.gz
access_log-20181204.gz
access_log-20181205.gz
access_log-20181206.gz
access_log-20181207.gz
access_log-20181208.gz
access_log-20181209.gz
```

アクセスログの中身は、こんな感じです。

```
172.19.33.212 - - [30/Nov/2018:05:44:37 +0900] "GET /signin HTTP/1.1" 200 8276 9986 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
172.24.35.22 - - [30/Nov/2018:07:39:46 +0900] "GET /styles/style.css HTTP/1.1" 304 - 11265 "http://example.com/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
172.24.35.22 - - [30/Nov/2018:07:39:46 +0900] "GET /images/logo.svg HTTP/1.1" 304 - 11978 "http://example.com/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
```

これらのログファイルを、Embulkを使用してElasticsearchに放り込んでみましょう。

# 環境
今回の実行環境は、こちらです。

```shell
$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.1 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic


$ java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-0ubuntu0.18.04.1-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
```

Embulkは`172.17.0.2`、ElasticsearchとKibanaは`172.17.0.3`でSingle Nodeで動かすものとします。

# Embulkのインストール
Embulkの[Quick Start](https://github.com/embulk/embulk#quick-start)に沿って、インストールしてみます。

[Linux & Mac & BSD](https://github.com/embulk/embulk#linux--mac--bsd)

```shell
$ curl --create-dirs -o ~/.embulk/bin/embulk -L "https://dl.embulk.org/embulk-latest.jar"
$ chmod +x ~/.embulk/bin/embulk
$ echo 'export PATH="$HOME/.embulk/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
```

# ElasticsearchとKibanaのインストール
ElasticsearchとKibanaをインストールします。

それぞれ、ダウンロードページから取得して起動。

Elasticsearch。

```shell
$ $ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.5.3.tar.gz
$ tar xf elasticsearch-6.5.3.tar.gz
$ cd elasticsearch-6.5.3
$ vim config/elasticsearch.yml     # 設定変更
$ bin/elasticsearch
```

Elasticsearchは、Single Node向けに設定変更します。また、リモートホストからのアクセスも許可しておきます。

```yaml
network.host: 0.0.0.0
discovery.type: "single-node"
```

Kibana。

```shell
$ wget https://artifacts.elastic.co/downloads/kibana/kibana-6.5.3-linux-x86_64.tar.gz
$ tar xf kibana-6.5.3-linux-x86_64.tar.gz
$ cd kibana-6.5.3-linux-x86_64
$ vim config/kibana.yml      # 設定変更
$ bin/kibana
```

Kibanaは、リモートホストからのアクセスを許可しておきます。

```yaml
server.host: "0.0.0.0"
```

# Apacheのアクセスログを、Elasticsearchに放り込む
では、Apacheのアクセスログを、Embulkを使ってElasticsearchに投入したいと思います。

このパターンの場合、こちらのページを参考にするとよいでしょう。

[Scheduled bulk data loading to Elasticsearch + Kibana 5 from CSV files](http://www.embulk.org/docs/recipe/scheduled-csv-load-to-elasticsearch-kibana5.html)

EmbulkからElasticsearchのデータを投入するために、プラグインを追加します。

[Elasticsearch output plugin for Embulk](https://github.com/embulk/embulk-output-elasticsearch)

```shell
$ embulk gem install embulk-output-elasticsearch
```

次に、読み込むファイルが置かれたディレクトリと出力先の設定をシードとして作成します。

seed.yml

```yaml
in:
        type: file
        path_prefix: ./accesslogs
out:
        type: elasticsearch
        index: embulk
        index_type: embulk
        nodes:
          - host: 172.17.0.3
```

Elasticsearchのインデックス名およびタイプ名は、`embulk`とします。

このシードの設定を元に、「embulk guess」を実行して、設定ファイルを生成します。

```shell
$ embulk guess seed.yml -o config.yml
```

すると、中身がこのようになります。

config.yml

```yaml
in:
  type: file
  path_prefix: ./accesslogs
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: LF
    type: csv
    delimiter: ;
    quote: null
    trim_if_not_quoted: false
    skip_header_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: 'aaa.bbb.ccc.ddd - - [01/Nov/2018:03:13:14 +0900] "GET /index.html HTTP/1.1"
        200 164373 614058 "-" "User-Agent"', type: string}
out:
  type: elasticsearch
  index: embulk
  index_type: embulk
  nodes:
  - {host: 172.17.0.3}
```

`embulk guess`では、入力ファイルのフォーマット、圧縮形式などを推測してくれたりするのですが、フォーマットの点ではちょっと変なことになっています。

ところで、今回のアクセスログのフォーマットは、実はデフォルトから少し変えていたりします。

```
    LogFormat "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" combined
```

このパースには、次のプラグインを使ってパースしましょう。

[Apache CustomLog parser plugin for Embulk](https://github.com/jami-i/embulk-parser-apache-custom-log)

インストール。

```shell
$ embulk gem install embulk-parser-apache-custom-log
```

設定ファイルを、このように変更します。`format`には、ログフォーマットをそのまま記載。

config.yml

```yaml
in:
  type: file
  path_prefix: ./accesslogs
  decoders:
  - {type: gzip}
  parser:
    type: apache-custom-log
    format: "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\""
out:
  type: elasticsearch
  index: embulk
  index_type: embulk
  nodes:
  - {host: 172.17.0.3}
```

では、この設定ファイルを使って実行。

```shell
$ embulk run config.yml
```

Kibanaにデータが入ったので、「Discovery」でインデックスに対する定義を行い、表示。

![範囲を選択_007.png](https://qiita-image-store.s3.amazonaws.com/0/309669/1f2e253e-939d-5a49-df2b-3d3484a25d83.png)

時刻のフィールドは、`request-time`です。

![範囲を選択_008.png](https://qiita-image-store.s3.amazonaws.com/0/309669/500841d1-e488-668a-d545-82d134f3e659.png)

![範囲を選択_009.png](https://qiita-image-store.s3.amazonaws.com/0/309669/3346b13f-fa1f-ec32-17d9-7561e1508d10.png)

で、データが入りました、と。
※除外したいログが検索条件に入っていますが…

![範囲を選択_010.png](https://qiita-image-store.s3.amazonaws.com/0/309669/d689b8c7-05f5-c6eb-0149-a840a4fb168a.png)

こんな感じで、Fluendと似たステップでInput → Parse → Outputという流れでデータロードを実現できます。

プラグインには以下のような種類があり、入出力や加工などで活用しましょう。

* Input plugin
* Output plugin
* Filter plugin
* File parser plugin
* File decoder plugin
* File formatter plugin
* File encoder plugin
* Executor plugin

[Configuration / built in](http://www.embulk.org/docs/built-in.html)

[Embulk plugins](http://www.embulk.org/plugins/)