Grafana + Loki + FluentdでSyslog Viewerを作る

SyslogをWebUIで検索・閲覧する用途に最近では一般的にElasticsearchを利用しているケースが多いのだと思う。ただ特にクラスタ構成など必要ない小規模構成でもっと手軽に構築できれるものがほしいなと常々思っていたので早速自宅環境に導入してみた。[^1]
[^1]: 以前[Chronograf + Telegraf + InfluxDBによるSyslog Viewer](https://qiita.com/haccht/items/82e8694c57202135ae5e)を作ったが、普段はGrafanaを使うことが多くSyslog ViewerのためだけにChronografをインストールするのもなぁと思っていた。

![2020-05-08-140356_1330x932_scrot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16560/cab2d8c5-3b5d-1db8-b40d-8cb7f989674e.png)


Syslogの時系列ヒストグラム表示がある。SeverityやFacility、Hostnameでの絞り込みも可能。もちろん特定時間帯のログのみを抽出することもできる。

## 構成
server側で用意するのはclientからのsyslogを`514/udp`ポートで受けて`5514/tcp`ポートへ転送するためのRsyslogに加え、Grafana, Loki, Fluentdのみ。


```
                   +------------------------------------------------+
                   |                                                |
                   |   +---------+                         server   |
+--------+ 514/udp |   |         |                                  |
| client +------------->         |                                  |
+--------+         |   |         |                                  |
                   |   | rsyslog |                                  |
+--------+ 514/udp |   |         |                                  |
| client +------------->         |                                  |
+--------+         |   |         |                                  |
                   |   +----+----+                                  |
                   |        |                                       |
                   |        | 5514/tcp                              |
                   |        |                                       |
                   |   +----v-----+  +----------+  +------------+   |
                   |   | fluentd  +-->   loki   +-->  grafana   |   |
                   |   +----------+  +----------+  +------------+   |
                   |                                                |
                   +------------------------------------------------+

```

## 設定
[Grafana](https://grafana.com/docs/grafana/latest/installation/), [Loki](https://github.com/grafana/loki/blob/master/docs/installation/README.md)に加えて、Fluentdの安定配布版である[td-agent](https://docs.fluentd.org/installation)をそれぞれ手順通りにインストール＆サービス起動する。
Grafanaは`3000/tcp`で、 Lokiは`3100/tcp`で動作する。

```
sudo systemctl start grafana
sudo systemctl start loki
sudo systemctl start td-agent
```

またFluentdにはLokiへsyslogを転送するためのプラグインを追加インストールしておく必要がある。

```
sudo td-agent-gem install fluent-plugin-grafana-loki
```

Rsyslogはclientから`514/udp`ポートで受け取ったsyslogを`5514/tcp`ポートへ転送する。
`/etc/rsyslog.d/50-forward.conf`ファイルを作成し、以下の通り記述する。

```
$ModLoad imudp
$UDPServerRun 514

$ActionQueueType LinkedList # use asynchronous processing
$ActionQueueFileName srvrfwd # set file name, also enables disk mode
$ActionResumeRetryCount -1 # infinite retries on insert failure
$ActionQueueSaveOnShutdown on # save in-memory data if rsyslog shuts down

*.* @@127.0.0.1:5514;RSYSLOG_SyslogProtocol23Format
```

Fluentdは`5514/tcp`ポートで受け取ったsyslogをLokiへ転送する。
`/etc/td-agent/td-agent.conf`に以下を追記する。

```
<source>
  @type syslog
  @id syslog_in
  port 5514
  bind 0.0.0.0
  severity_key level
  facility_key facility
  tag syslog
  <transport tcp>
  </transport>
  <parse>
    message_format rfc5424
  </parse>
</source>

<match syslog.**>
  @type loki
  @id syslog_out
  url "http://localhost:3100"
  extra_labels {"app":"syslog"}
  <label>
    pid
    host
    level
    facility
  </label>
</match>
```


RsyslogとFluentdを再起動して設定を反映。

```
sudo systemctl restart rsyslog
sudo systemctl restart td-agent
```

以上で設定は終わり。非常に簡単。

## 操作方法

上記の設定により既にLokiにはログデータが蓄積されてはじめている。
`http://<サーバーのIPアドレス>:3000/` へアクセスし、Grafanaを起動して`Configuration > Data Sources`からLokiを選択・追加し、URLには　`http://localhost:3100`を記載する。

`Explorer`をクリックしてData SourceにLokiを選択。`Log labels`に`{app="syslog"}`を記載して`Run query`をクリックするとSyslogデータが表示される。

![2020-05-08-140444_1330x932_scrot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16560/fd8ecc52-484a-5194-aae1-0df112df5753.png)


ちなみに以下のコマンドでダミーログを飛ばしてきちんと受信・表示されていることを確認できるので、何もログが表示されない場合はこれで切り分けを。

```
logger -n <サーバーのIPアドレス> -d test
```

Fluentd転送時に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.
```

message検索など多少重さは感じるけど、対象時間帯を予め区切っておけばよいので別に問題はない。

以下は公式サイトからの引用。
こんな感じで色々絞り込みをしたり詳細の確認ができる。
![絞り込み](https://grafana.com/static/img/docs/v65/explore_log_details.gif)

楽しい！:v: