Grafana Lokiがメジャーリリースされたのでログ収集からダッシュボード化まで試してみた


はじめに

現在の案件で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の流れとしては、

  1. ログ収集対象をdiscoveryし
  2. ログのストリームに対してラベルを付与し、
  3. Lokiインスタンスへ上記ログを送信する

というものになっています。

Grafanaとは

本記事の本題であるGrafana Lokiの親元のプロジェクトです。

Grafana LokiやPrometheusに格納されているログ・メトリクスをデータソースとして、ダッシュボードと呼ばれる画面で各情報を可視化します。

Promtail, Loki, Prometheus等で取得するデータのは人間にとって可読性の低いテキストデータでマシンリーダブルなので、Grafanaで可視化することでヒューマンリーダブルになります。

Promtail + Grafana Loki + Grafanaを使った基本構成

ここまでの構成をまとめ、Grafana Lokiを使ってログを取得し、Grafanaで可視化するための大まかなフローをまとめると以下の様になります。

  1. Promtailで特定のログをLokiに送信
  2. LokiがPromtailから送られたログを保存・処理し、
  3. Grafanaでログを取得・表示する という感じですね。

ハンズオン

それでは実際に手を動かして試してみましょう。

先に今回試した内容のdocker-composeファイルを記載しておきます。

順序としては、

  1. flogアプリケーションでダミーログを/var/log/flog.logへ出力し、
  2. Promtailの設定を追加し、上記flogのログを取得、Lokiへ送信するよう設定
  3. Loki側でPromtailから送信されるログを受け取り、
  4. 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でのログデータの可視化ができました!