Grafana + Loki + Vectorで実装するSyslogサーバー
はじめに
ログ集約・可視化・検索ツールとしてはELKスタックを利用するケースが多いが、これをLokiに置き換えることでより軽量にログを集約することができるようになる。
Grafana Lab社が開発したLokiは、ログのストリームに対してタグ付けし保存する仕組みを持つ。Prometheusと親和性がたかく、水平展開、高可用性、マルチテナントが可能。
実は以前にも、Grafana+LokiでSyslogサーバーを実装する同様の記事を作成していた。
この時は外部から受け取ったSyslogをLokiに流し込むため、Rsyslog+Fluentdを利用する構成としていた。今回はこれらをVectorという単一のツールで代替する。
VectorはRustで書かれた超軽量・高速なログ/メトリクス転送エージェント。
単一バイナリで動き、VRLという独自スクリプトで変換・フィルタして任意の宛先(Loki, S3, Elasticsearchなど)へ送れる。つまりFluentdやLogstashを現代設計で作り直したもの。
VectorはSources(入力)としてSyslogをサポートしており、RFC6587, RFC5424, RFC3164などのフォーマットの読み取りが可能。またSink(出力)としてLokiをネイティブでサポートしている。そのためVectorさえあれば、Rsyslogに依存しなくてよいということ。素晴らしい。
構成
各クライアントからのsyslogは514/udp
ポートで送信される。これをVectorで受けlokiへ転送する。
+--------------------------------+
| |
| +---------+ |
+--------+ 514/udp | | | |
| client +-------------> | |
+--------+ | | | |
| | Vector | |
+--------+ 514/udp | | | |
| client +-------------> | |
+--------+ | | | |
| +----+----+ |
| | |
| | 3100/tcp |
| | |
| +----v-----+ +----------+ |
| | loki +--> grafana | |
| +----------+ +----------+ |
| |
+--------------------------------+
設定
Grafana、Lokiに加え、Vectorをそれぞれインストールする。
sudo systemctl start grafana
sudo systemctl start loki
sudo systemctl start vector
各クライアントから514/udp
ポートで受け取ったsyslogを3100/tcp
ポートのLokiへ転送するため、/etc/vector/vector.yaml
ファイルを編集し、以下の通り設定する。
sources:
syslog:
type: syslog
mode: udp
address: '0.0.0.0:514'
sinks:
loki:
type: "loki"
inputs: ["syslog"]
endpoint: "http://127.0.0.1:3100"
labels:
app: "syslog"
hostname: "{{ hostname }}"
severity: "{{ severity }}"
facility: "{{ facility }}"
encoding:
codec: "json"
Vectorを再起動して設定を反映。
sudo systemctl restart vector
以上で設定は終わり。とっても簡単。
操作方法
上記の設定でLokiにはすでにsyslogが蓄積されてはじめている。
http://<サーバーのIPアドレス>:3000/
へアクセスし、Grafanaを起動してConfiguration > Data Sources
からLokiを選択、URLにhttp://127.0.0.1:3100
を記載する。
Explorer
をクリックしてData Source
にLokiを選択。Log labels
に{app="syslog"}
を記載してRun query
をクリックするとsyslogデータが表示される。
何もログが表示されない場合、サーバーにsyslogが到達しているかどうか切り分けるため、クライアントから以下のコマンドでダミーログを飛ばしてみればよい。
logger -n <サーバーのIPアドレス> -d test
syslogストリームにはseverityやfacility, hostnameなどラベル付けされているため、これらを用いたフィルタが可能。
ログメッセージによる検索は{severity="info"} |= "session closed"
のように、以下の記法を組み合わせて実現できる。
|= line contains string.
!= line doesn’t contain string.
|~ line matches regular expression.
!~ line does not match regular expression.
メッセージ検索には多少の重さを感じるが、事前に検索対象となる時間範囲を絞り込んでおけば問題ない程度であろう。
以下は公式サイトからの引用。
このような感じにログ絞り込みをしたり、ログ詳細が確認できる。
簡単楽しい!
Discussion