今回はVectorと言うpipelineツールについて自社での事例(少しだけ)を交えながら紹介します。
Vectorとは
一言で言うとRust製の超速く軽量なパイプラインツールです。
類似のツールで言うとfluendやlogstashがこれにあたります。
公式サイトを見てもらうのが一番わかりやすいと思いますが簡単に説明するため概要を説明していきます。
自作のプラグインを使うのは現段階ではまだ難しそうなのでそういうケースではfluentdなどを選択するのが良さそうです。
※以下の画像は公式サイトから引用しています。
概念図
- Sources
- Transforms
- Sinks
という3つのセクションに分かれてます。
Sources
Sourcesはファイル、標準出力、HTTP、外部のクラウドサービスなどを監視してVector上のデータとして入力します。
Transforms
Transformsはその名の通りSourcesで取り込んだデータを加工します。
フィルタをかけたりログをパースしてJSONに変換したりタグを追加したり削除したりできます。
正規表現をサポートしているのでアプリケーションで実装されているオリジナルログもパースして個別のパラメータとして扱えます。
Sinks
SinksはTransformsで加工したデータを様々なDBに保存したりファイルに保存することを行います。
一通りのDBに対応しているのとinfluxdb2.0やclickhouseに対応しているのが良いですね。
他ツールとの比較
ファイルの監視については一通りの機能を揃えています。
パフォーマンスについて
https://vector.dev/#performance
CPU
Memory
I/O
File To TCP、TCP To Backhole、TCP To HTTPでのI/Oは一位です。
CPUはそこそこですがMemoryについても上位に入っています。
全体的な傾向としては省メモリでI/O性能が高いようです。
インストール方法
各OS向けにパッケージ化されていて簡単にインストールできます。(以下はUbuntuの例)
Ubuntuの場合はdebパッケージがあるのでそれを登録してインストールするだけです。
サンプルとしてansibleのtaskを載せておきます。
- 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のセクションに分かれており簡単に設定することが出来ます。
Link-Uでの事例
nginxのアクセスログ(ltsv形式)をinfluxdb2.0に保存します。
nginx
ltsvの設定は以下のような感じです。
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
[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の場合当時それが必要だった為。)
[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のテンプレートで設定ファイルは管理しているので一部変数化されています。
[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の平均レスポンス速度や最速、最遅タイムを出すなどアクセスログに存在しているパラメータから数字を出すことができます。
Vectorを使うと手間をかけずに簡単にデータを可視化することが出来ます。
fluentdを使っているところは多そうですが、省メモリという点でこれからはVectorも選択肢に挙がってくるかもしれません。