【Windows Server2019】Grafana LokiとPromtailのインストールとセッティング、Grafanaとの連携

Pythonで作ったプログラムのログを収集し、Grafanaで見えるようにするにはどのようにしたらよいか?

Prometheusのエクスポータに「grok_exporter」というものがあるのですが、これを利用することでログ監視をすることは可能です。
ただし、grok_exporterをWindows機で利用するためにはクロスコンパイルしたもの(Windowsで使うために他のマシンのLinux上でコンパイルを行う)が必要となり、とても面倒です。
grok_exporterを利用するのではなく、別の手段を探したところ、「Grafana Loki」(ロギングエンジン)にてログ集約が行えるようなので、そちらで実現したいと思います。

・Grafana Loki
ログデータの収集、保存、クエリ、可視化を目的としたオープンソースのログ集約システムです。Lokiは、Prometheusと同じくCloud Native Computing Foundation(CNCF)のプロジェクトとして開発されています。
By chatGPT

ただし、ログの収集自体はできないため、推奨されている「Promtail」か「Fluentd」等を使用する必要があります。

1.Grafana Loki、Promtailのインストール

以下のページの下部にあるWindows用インストールファイルをダウンロードします。
https://github.com/grafana/loki/releases/
loki-windows-amd64.exe.zip
promtail-windows-amd64.exe.zip
※画面上に表示されていない場合は「Show all XX assets」を押下し、表示します。


2つのzipファイルを解凍し、適切な場所にフォルダを配置します。
例)C:\systemwatch\loki、C:\systemwatch\promtail
Loki実行ファイル:loki-windows-amd64.exe
Promtail実行ファイル:promtail-windows-amd64.exe

取得できるのは実行ファイル(EXEファイル)のみとなり、設定ファイルは別途用意する必要があります。
ブラウザを起動し、以下のURLにアクセスして設定ファイルをダウンロードします。
※ダウンロードできず、設定ファイルの中身がブラウザ画面に表示された場合は、
 その表示内容をコピーし、ローカルにアクセス先と同一名称のyamlファイルを作成し、内容のペーストを行う。
https://raw.githubusercontent.com/grafana/loki/main/cmd/loki/loki-local-config.yaml
https://raw.githubusercontent.com/grafana/loki/main/clients/cmd/promtail/promtail-local-config.yaml

ダウンロードした設定ファイルは、実行ファイルと同一のフォルダに格納します。

2.Loki設定ファイルの設定変更

設定ファイルに記載されているファイルパスは、Linuxに準拠した形で記載されています。
例えば「path_prefix: /tmp/loki」といった形で設定されていますが、実をいうとこのままでも動作は可能。
(その場合、C:¥の直下にtmpフォルダ以下が作成される)
フォルダパスについては、以下の様に実行フォルダ配下となるよう、絶対パスを指定する。
loki-local-config.yaml

path_prefix: /tmp/loki
↓
path_prefix: C:/systemwatch/loki/tmp/loki

chunks_directory: /tmp/loki/chunks
↓
chunks_directory: C:/systemwatch/loki/tmp/loki/chunks

rules_directory: /tmp/loki/rules
↓
rules_directory: C:/systemwatch/loki/tmp/loki/rules

3.Promtail設定ファイルの設定変更

Loki設定ファイルと同様、ファイルパスの変更を行います。
promtail-local-config.yaml

filename: /tmp/positions.yaml
↓
filename: C:/systemwatch/promtail/positions.yaml

また、ログ収集の対象となるファイルの指定は、この設定ファイル内で記載する必要があります。
「scrape_configs:」以下に、収集するログ毎に「-job_name」を記述します。
__path__にパスを設定します。アスタリスクによる指定も可能です。

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: C:/systemwatch/promtail/positions.yaml

clients:
  - url: http://localhost:3100/loki/api/v1/push

scrape_configs:
- job_name: logs
  static_configs:
  - targets:
      - localhost
    labels:
      job: logs
      __path__: C:/DataDirectory/logs/*.log

  pipeline_stages:
  - match:
      selector: '{job="logs"}'
      stages:
      - regex:
         expression: '^(?P<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\,\d{3}) .*$'
      - timestamp:
         source: time
         format: '2006-01-02 15:04:05.000'
         location: Asia/Tokyo

デフォルト設定では、Promtailで収集された日時がそのままタイムスタンプとして管理されます。
しかしその場合、Pythonのloggerで出力したログの中にも存在するログ出力時間と食い違いが発生してしまい、
Grafanaでのソート処理にて正常にソートされなくなってしまいます。
その対策として、ログ内にあるログ出力時間をPromtailのタイムスタンプと一致させるため、以下の対応を行います。
ログは「2023-06-26 16:59:38,646 [ERROR] エラー要因:TESTTEST」の形とします。

 ・pipeline_stages>match>stages>regexのexpression項にて、[time]という変数に正規表現(Google/RE2)を設定する。
 ・pipeline_stages>match>stages>timestampにて、regexで用意した[time]をsourceに指定し、
  formatをカスタム設定する。(カスタム設定の場合の設定値は参考欄のtimestampについてのURLを参照)
 ・正規表現については以下の通り
  ^:先頭を示す
  ?P

■参考
pipelinesについて:https://grafana.com/docs/loki/latest/clients/promtail/pipelines/
RE2:https://github.com/google/re2/wiki/Syntax
timestampについて:https://grafana.com/docs/loki/latest/clients/promtail/stages/timestamp/
設定の参考ブログ:https://blog.yiwkr.work/2020-09-01-promtail-timestamp


また、Windows Serverのイベントログを取得する場合は、設定ファイルに以下の内容を追加することでWindows Serverのイベントログを取得することが可能となります。

promtail-local-config.yaml

- job_name: windows
  windows_events:
    use_incoming_timestamp: false
    bookmark_path: "C:/systemwatch/promtail/bookmark.xml"
    eventlog_name: "Application"
    xpath_query: '*'
    labels:
      job: windows
  relabel_configs:
    - source_labels: ['computer']
      target_label: 'host'


■参考
https://grafana.com/docs/loki/latest/clients/promtail/scraping/#windows-event-log

4.Grafana Lokiの起動

PowerShellを実行し、実行ファイルがあるフォルダに移動後、以下のコマンド実行します。
※実行時に設定ファイルを指定する。
> cd C:\systemwatch\loki
> .\loki-windows-amd64.exe --config.file=loki-local-config.yaml

以下のメッセージがあれば起動が完了する。
level=info ts=2023-06-07T09:42:31.1513442Z caller=loki.go:499 msg="Loki started"
level=info ts=2023-06-07T09:42:34.0927708Z caller=scheduler.go:681 msg="this scheduler is in the ReplicationSet, will now accept requests."
level=info ts=2023-06-07T09:42:34.0927708Z caller=worker.go:209 msg="adding connection" addr=127.0.0.1:9096
level=info ts=2023-06-07T09:42:36.1515776Z caller=compactor.go:411 msg="this instance has been chosen to run the compactor, starting compactor"
level=info ts=2023-06-07T09:42:36.1515776Z caller=compactor.go:440 msg="waiting 10m0s for ring to stay stable and previous compactions to finish before starting compactor"

5.Promtailの起動

PowerShellを実行し、実行ファイルがあるフォルダに移動後、以下のコマンド実行します。
※実行時に設定ファイルを指定する。
> C:\systemwatch\promtail
> .\promtail-windows-amd64.exe --config.file=promtail-local-config.yaml

※実行時に「mapping values are not allowed in this context.」というエラーが出た場合、
インデントが誤っていたり、「項目: 設定値」の記述で、:の後ろに半角スペースが無いなどを確認する必要あり。
例)
○ job: aaa_logs
× job:aaa_logs


設定ファイルで指定したパスで該当するファイルを以下のURLから確認することが可能です。
ポート番号は、設定ファイルのhttp_listen_port項で指定しているポート番号となります。
http://localhost:9080/

6.Grafanaの設定

GrafanaのConnectionsにてデータソースとしてGrafana Lokiを設定し、連携させます。
やり方は以前取り上げた以下の記事を参照。
engetu21.hatenablog.com

URLの部分のポート番号は、Granafa Lokiの設定ファイルと同様のものを指定。デフォルトは3100。

ダッシュボードに移動し、新しくパネルを作ります。
Data sourceの欄に「Loki」が増えているため、それを選択。
Label Filtersを「job = logs」(logsは設定ファイルで設定したjob: logsの部分です)を選択。
右上のグラフの種類で「Logs」を選択し、[Run queries]を押下すれば、ログが表示されます。
※ログが表示されない場合は、ログが出力されているであろう時間帯にグラフを変更してください。
このままApplyを押下することで、ダッシュボードに反映されます。

7.蛇足

今回はPythonで出力したログファイルをPromtailで収集し、Grafana Lokiにて管理していますが、Python⇒Grafana Lokiに直接ログを送ることも可能なようです。
今回はその対応を行っていませんが、対応する場合は以下を参照し、Pythonでライブラリを導入することで対応が可能と思われます。(2023/6/29現在)
https://medium.com/geekculture/pushing-logs-to-loki-without-using-promtail-fc31dfdde3c6