Vectorの紹介（おまけでinfluxdb2.0との連携）

今回はVectorと言うpipelineツールについて自社での事例（少しだけ）を交えながら紹介します。

# Vectorとは

[https://vector.dev/](https://vector.dev/)

一言で言うとRust製の超速く軽量なパイプラインツールです。
類似のツールで言うとfluendやlogstashがこれにあたります。
公式サイトを見てもらうのが一番わかりやすいと思いますが簡単に説明するため概要を説明していきます。

自作のプラグインを使うのは現段階ではまだ難しそうなのでそういうケースではfluentdなどを選択するのが良さそうです。

※以下の画像は公式サイトから引用しています。

# 概念図

![スクリーンショット 2020-12-07 11.18.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11796/bc64949b-3166-1830-56ee-d4d8879fc941.png)

* Sources
* Transforms
* Sinks

という３つのセクションに分かれてます。

## Sources

Sourcesはファイル、標準出力、HTTP、外部のクラウドサービスなどを監視してVector上のデータとして入力します。

## Transforms

Transformsはその名の通りSourcesで取り込んだデータを加工します。
フィルタをかけたりログをパースしてJSONに変換したりタグを追加したり削除したりできます。
正規表現をサポートしているのでアプリケーションで実装されているオリジナルログもパースして個別のパラメータとして扱えます。

## Sinks

SinksはTransformsで加工したデータを様々なDBに保存したりファイルに保存することを行います。
一通りのDBに対応しているのとinfluxdb2.0やclickhouseに対応しているのが良いですね。

# 他ツールとの比較

![スクリーンショット 2020-12-07 11.16.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11796/b86fdb10-79e2-072e-7f34-7e2a55250c83.png)

ファイルの監視については一通りの機能を揃えています。

# パフォーマンスについて

[https://vector.dev/#performance](https://vector.dev/#performance)

## CPU
![スクリーンショット 2020-12-07 11.08.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11796/86176f5c-03e0-cdcb-0a57-e615571015c4.png)

## Memory
![スクリーンショット 2020-12-07 11.08.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11796/c605af8a-37cc-836b-f430-89fa91237c44.png)

## I/O
![スクリーンショット 2020-12-07 11.08.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11796/671a2d7d-171d-47e7-7234-b1f596903fa4.png)

File To TCP、TCP To Backhole、TCP To HTTPでのI/Oは一位です。
CPUはそこそこですがMemoryについても上位に入っています。
全体的な傾向としては省メモリでI/O性能が高いようです。

# インストール方法

各OS向けにパッケージ化されていて簡単にインストールできます。（以下はUbuntuの例）

Ubuntuの場合はdebパッケージがあるのでそれを登録してインストールするだけです。

サンプルとしてansibleのtaskを載せておきます。

```yaml
- name: Download .deb package
  get_url:
    url: https://packages.timber.io/vector/0.10.X/vector-amd64.deb
    dest: /tmp/vector-amd64.deb
  tags:
    - install

- name: Install package
  apt:
    deb: /tmp/vector-amd64.deb
  tags:
    - install

- name: put config template
  template:
    src: vector.toml.j2  # 後述します
    dest: /etc/vector/vector.toml
  notify:
    - Reload vector  # handlersに設定する必要あり

- name: add adm group to vector user
  user:
    name: vector
    groups: adm
    append: yes  # nginxのログを監視するため

- name: Start Vector
  systemd:
    name: vector
    state: started
    enabled: yes
```

# 設定ファイルについて

toml形式で設定します。
最初に説明したSources, Transforms, Sinksのセクションに分かれており簡単に設定することが出来ます。

![スクリーンショット 2020-12-07 11.28.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11796/6b77e789-6614-5b6f-d516-b31c648c55bd.png)

## Link-Uでの事例

nginxのアクセスログ（ltsv形式）をinfluxdb2.0に保存します。

### nginx

ltsvの設定は以下のような感じです。

```conf
log_format ltsv 'time:$time_iso8601\t'
                'status:$status\t'
                'remote_addr:$remote_addr\t'
                'request_method:$request_method\t'
                'request_uri:$request_uri\t'
                'host:$host\t'
                'request_time:$request_time\t'
                'bytes_sent:$bytes_sent\t'
                'referer:$http_referer\t'
                'useragent:$http_user_agent\t'
                'app_info:$upstream_http_x_app_info';
```

app_infoはアプリケーションから返すパラメータを出力する設定で入れています。

### Sources

```toml
[sources.nginx_log_api]
  # General
  type = "file" # required
  ignore_older = 86400 # optional, no default, seconds
  include = ["/var/log/nginx/api.log"] # required
  exclude = ["/var/log/nginx/error.log", "/var/log/nginx/*.log-*"] # required
  start_at_beginning = false # optional, default
```

includeで特定のファイルを指定しているのでexcludeの中身は不要ですが説明の為に入れています。

### Transforms

ltsv形式をパースするため正規表現を頑張って書きます。
Typesでは想定する型を指定します。
（metricに変換しているのは当時influxdbの場合当時それが必要だった為。）

```toml
[transforms.nginx_parser_api]
  type = "regex_parser"
  inputs = ["nginx_log_api"]
  regex = "^time:(?P<timestamp>[^\\t]+)\\tstatus:(?P<status>\\d+)\\tremote_addr:(?P<remote_addr>[^\\t]+)\\trequest_method:(?P<request_method>\\w+)\\trequest_uri:(?P<request_uri>[^\\t]+)\\thost:(?P<host>[^\\t]+)\\trequest_time:(?P<request_time>[^\\t]+)\\tbytes_sent:(?P<bytes_sent>[^\\t]+)\\treferer:(?P<referer>[^\\t]+)\\tuseragent(?P<useragent>[^\\t]+)\\tapp_info:(?P<app_info>[^\\t]+)$"
  drop_field = true
  field = "message"

  # Types
  types.timestamp = "timestamp|%Y-%m-%dT%H:%M:%S%z"
  types.status = "int"
  types.remote_addr = "string"
  types.request_method = "string"
  types.request_uri = "string"
  types.host = "string"
  types.request_time = "float"
  types.bytes_sent = "int"
  types.referer = "string"
  types.useragent = "string"

[transforms.nginx_parser_to_metric]
  type = "log_to_metric"
  inputs = ["nginx_parser_api"]

  [[transforms.nginx_parser_to_metric.metrics]]
    type = "gauge"
    field = "request_time"
    tags.status = "{% raw %}{{status}}{% endraw %}"
    tags.host = "{% raw %}{{remote_addr}}{% endraw %}"
    tags.request_method = "{% raw %}{{request_method}}{% endraw %}"
    tags.request_uri = "{% raw %}{{request_uri}}{% endraw %}"
    tags.host = "{% raw %}{{host}}{% endraw %}"
    tags.referer = "{% raw %}{{referer}}{% endraw %}"
    tags.useragent = "{% raw %}{{useragent}}{% endraw %}"

```

### Sinks

ansibleのテンプレートで設定ファイルは管理しているので一部変数化されています。

```toml
[sinks.influxdb]
  # General
  type = "influxdb_metrics"
  inputs = ["nginx_parser_to_metric"]
  endpoint = "http://{{ influxdb_endpoint }}:8086"
  namespace = "nginx"
  bucket = "{{ influxdb_bucket_name }}"
  healthcheck = true

  # Auth
  org = "Link-U"
  token = "{{ influxdb_auth_token }}"
```

# まとめ

以下の図は一時間毎に叩かれたAPIの数です。
サンプルデータの為グラフの変化が少ないですがinfluxdb2.0で可視化した場合API単位で数を出すことができます。
他にも時間単位別のAPIの平均レスポンス速度や最速、最遅タイムを出すなどアクセスログに存在しているパラメータから数字を出すことができます。

![スクリーンショット 2020-12-07 11.46.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11796/4ab2f38e-f13f-3a56-f0d2-88cfaba3a051.png)

Vectorを使うと手間をかけずに簡単にデータを可視化することが出来ます。
fluentdを使っているところは多そうですが、省メモリという点でこれからはVectorも選択肢に挙がってくるかもしれません。