はじめに
現在の案件でPrometheus + Grafana(+ Alertmanager + Consul)を使って監視環境を運用しているのですが、ログ監視については現場内製のツールを使用しています。
しかしせっかくなので今使用しているCNCF公認のアプリケーションと連携して、よりモダンなログ監視ができないかを調査していました。
パッと思いつくのはElasticSearch + Fluentd + KibanaのEFKスタックですが、ゼロからその環境を構築するのは結構コストがかかります。
他に代替策がないかなと考えながらCNCF Landscapeを見ていたところ、Grafana Lokiが目にとまりました。
このGrafana LokiのGitHubの概要の部分には、
Like Prometheus, but for logs.
と書いてあり、今のGrafanaとの相性が良さそうだと感じ試してみることにしました。本記事はその際のメモを記載したものです。
各関連プロジェクト、概念について解説
Grafana Lokiとは
GitHubのdescriptionに書かれている様に、Prometheusのメトリクスのログバージョンのプロジェクトです。
後述のPromtailから送られるログを特定のストレージに保存し、Grafanaなどに連携して利用します。
Promtail
PromtailはLokiに対してログを送るエージェントです。
取得したいログがあるアプリケーションのインスタンスに対してデプロイし、ログを取得・送信させます。
Promtailの流れとしては、
- ログ収集対象をdiscoveryし
- ログのストリームに対してラベルを付与し、
- Lokiインスタンスへ上記ログを送信する
というものになっています。
Grafanaとは
本記事の本題であるGrafana Lokiの親元のプロジェクトです。
Grafana LokiやPrometheusに格納されているログ・メトリクスをデータソースとして、ダッシュボードと呼ばれる画面で各情報を可視化します。
Promtail, Loki, Prometheus等で取得するデータのは人間にとって可読性の低いテキストデータでマシンリーダブルなので、Grafanaで可視化することでヒューマンリーダブルになります。
Promtail + Grafana Loki + Grafanaを使った基本構成
ここまでの構成をまとめ、Grafana Lokiを使ってログを取得し、Grafanaで可視化するための大まかなフローをまとめると以下の様になります。
- Promtailで特定のログをLokiに送信
- LokiがPromtailから送られたログを保存・処理し、
- Grafanaでログを取得・表示する
という感じですね。
ハンズオン
それでは実際に手を動かして試してみましょう。
先に今回試した内容のdocker-composeファイルを記載しておきます。
順序としては、
- flogアプリケーションでダミーログを
/var/log/flog.log
へ出力し、 - Promtailの設定を追加し、上記flogのログを取得、Lokiへ送信するよう設定
- Loki側でPromtailから送信されるログを受け取り、
- GrafanaでLokiをデータソースとして追加し、ダッシュボードとして可視化する
というものになっています。
version: '3.7'
networks:
grafana:
services:
grafana:
image: grafana/grafana
environment:
GF_EXPLORE_ENABLED=true
ports:
3000:3000
networks:
grafana
loki:
image: grafana/loki
ports:
3100:3100
networks:
grafana
promtail:
image: grafana/promtail
ports:
9080:9080
command: -config.file=/etc/promtail/flog-config.yaml
volumes:
./etc/promtail:/etc/promtail
./var/log:/var/log
networks:
grafana
flog-logger:
image: mingrammer/flog
command: -n 5 -d 5 -t log -w -o /var/log/flog.log -l
volumes:
./var/log:/var/log
networks:
grafana
ダミーログ生成アプリケーションを立ち上げて、ログを生成する
まずはLokiで管理するためのログの生成から行なっていきます。
Docker imageでランダムなログを出力してくれるmingrammer/flog
というimageがあったので、こちらを利用することにしました。
単純にdocker runを行うと標準出力へログを送信してくれますが、Promtailで取得しやすくするために/var/log/flog.log
というファイルへ出力するようオプションを調節し、docker-composeの起動時に実行するように設定を行いました。
例として下記にdocker run
したときの出力を記載しておきます。いい感じの出力になっていますね。
$ docker run mingrammer/flog
160.42.94.201 hettinger6406 [08/12/2019:08:06:47 +0000] "DELETE /bricks-and-clicks" 501 8708
216.202.164.184 schumm2546 [08/12/2019:08:06:47 +0000] "DELETE /harness" 502 8144
127.193.172.88 [08/12/2019:08:06:47 +0000] "DELETE /cross-media" 501 10036
35.157.101.153 [08/12/2019:08:06:47 +0000] "DELETE /facilitate" 404 26412
70.73.208.218 [08/12/2019:08:06:47 +0000] "HEAD /communities/b2c/morph" 500 6639
189.108.176.231 erdman6222 [08/12/2019:08:06:47 +0000] "HEAD /best-of-breed/real-time/implement" 301 9151
100.181.144.136 hane3425 [08/12/2019:08:06:47 +0000] "DELETE /orchestrate/transform" 205 25930
(...)
Promtailを立ち上げログを収集する
ログの生成ができたので、次にPromtailにログを取得させ、かつLokiへ送信させます。
Promtail containerからflog containerへ取得を行い、Loki containerのAPIへリクエストする設定を記述し、起動時に利用することを明示します。
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
url: http://loki:3100/loki/api/v1/push
scrape_configs:
job_name: flog-logger
static_configs:
targets:
flog-logger
labels:
job: flog
__path__: /var/log/flog.log
起動ができたら http://localhost:9080/targets をブラウザで開くことでPromtailの起動と、ログの取得ができていることが確認できます。
Grafana Lokiを立ち上げPromtailからのpushを受ける
Promtail側からLokiへログを送信する設定が適切に行えていれば、Loki側ではログが自動で保存されます。
それを確認するためには、Lokiに対してREST APIでリクエストを送ることで、格納されているログを取得することができます。
例えば/loki/api/v1/query
へGETリクエストを送信すると、下記の様な結果を受け取ることができます。
$ curl -G -s "http://localhost:3100/loki/api/v1/query" --data-urlencode 'query={job="flog"}' | jq
{
"status": "success",
"data": {
"resultType": "streams",
"result": [
{
"stream": {
"filename": "/var/log/flog.log",
"job": "flog"
},
"values": [
[
"1575790467377181386",
"15.152.22.86 - pacocha1603 [08/12/2019:07:33:47 +0000] \"POST /mission-critical\" 203 12036"
],
[
"1575790462309234273",
"132.100.60.192 - white7155 [08/12/2019:07:33:47 +0000] \"HEAD /envisioneer/morph/matrix/compelling\" 501 19202"
],
(...)
]
}
]
}
}
これで生成されたログがPromtailから取得され、Lokiに送信されていることが分かりました。
では次にGrafanaを使ってこのログデータを可視化することにしましょう。
GrafanaでLokiをデータソースに設定し、Explorerで可視化する
localhost:3000
をブラウザで開くことで、Grafanaを開くことができます。
ログインの認証はadmin/admin
で可能です。
Grafanaが起動、usernameとpasswordは両方adminを入力することでログインが可能です。
ログインができたら次に可視化を行うデータ元である、データソースを指定する必要があります。
下記の様な画面がログイン後に表示されると思いますので、"Add data source"を選択しましょう。
次にどのアプリケーションをデータソースとして使うか選択する画面に移動します。
"Logging & document databases"の項目にあるLokiを選びましょう。
そうすると接続情報を入力する画面に移動します。
今の場合はローカルのLokiを接続先として設定するので、URLのinputにhttp://loki:3100
を入力し、"Save & Test"をクリックして緑色のアラートが出れば接続完了です。
設定が完了したら、今度は左メニューのExplorerを選択します。
ここでは簡易的なダッシュボードを作成することができるので、画面中の"Log Labels"からfilenameを選択すれば、下記の様なグラフとログの一覧が表示されます。
以上で簡単ではありますが、アプリケーションによるログ出力、Promtailによるログ取得、Lokiでのログ管理、そしてGrafanaでのログデータの可視化ができました!