Loki でログを扱うとき、最初に悩むのがラベル設計です。ログを検索しやすくするために多くの値をラベルへ入れたくなりますが、入れすぎると stream が細かく分かれ、Loki の負荷や保存効率に影響します。反対に、ラベルを少なくしすぎると、毎回本文全体を検索することになり、運用時に必要なログへたどり着きにくくなります。
ラベルは、ログ本文に含まれる情報を何でも移す場所ではありません。検索の入口、集計の単位、ダッシュボードの変数として安定して使う値だけを置く場所です。IP アドレス、URL、ユーザー ID、リクエスト ID のように増え続ける値は、基本的にはラベルではなく本文や JSON フィールドとして扱う方が自然です。
この記事では、Loki のラベルに何を入れるべきかを、ModSecurity audit log、network syslog、Ubuntu journal、Ceph のようなログを例にしながら整理します。
ラベルは検索条件ではなく分割軸である
Loki のラベルは Prometheus のラベルに似ていますが、ログ本文そのものを置き換えるものではありません。ラベルの組み合わせによって stream が分かれ、その stream の中にログ行が入ります。つまり、ラベルはログをどの単位で分割して保存し、検索の入口にするかを決める設計要素です。
たとえば、source="modsecurity-audit"、host="proxy-rev.example.local"、job="modsecurity-audit" のようなラベルは、ログの種類や発生元を分けるために使いやすい値です。これらは比較的安定しており、ダッシュボードの変数にもできます。
一方で、リクエスト URL や送信元 IP アドレスをラベルにすると、値の種類が急速に増えます。検索したい値であっても、分割軸として安定していないものはラベルに向きません。
| 値 | ラベルに向くか | 理由 |
|---|---|---|
source | 向く | ログ種別を大きく分けられる |
job | 向く | 収集設定や処理系統を分けられる |
host | 条件付きで向く | 発生元を絞る軸として使いやすいが、短命な Pod 名は注意が必要 |
filename | 条件付きで向く | ファイル単位で意味がある場合は有効だが、パスが細かすぎると扱いにくい |
| 送信元 IP アドレス | 基本的に向かない | 値が増え続け、カーディナリティが高くなりやすい |
| URL | 基本的に向かない | パスやクエリ文字列の種類が多く、本文検索や JSON フィールドの方がよい |
| リクエスト ID | 向かない | ほぼログ行ごとに異なるため、ラベルにすると stream が分裂する |
高カーディナリティを避ける
Loki のラベル設計で避けるべきなのは、高カーディナリティです。カーディナリティとは、ラベル値の組み合わせがどれだけ多くなるかということです。値の種類が少なく、長期間安定しているラベルは扱いやすい一方、値が無数に増えるラベルは Loki の負荷や検索性に悪影響を与えます。
たとえば、source に入る値が modsecurity-audit、network-syslog、ubuntu-journal、ceph-cluster のように数種類であれば、ラベルとして扱いやすいです。しかし、remote_addr に世界中の送信元 IP アドレスを入れると、短時間で値が増え続けます。
検索したい値をラベルに入れれば便利に見えますが、便利さと保存構造は別です。送信元 IP アドレスや URL は、ログ本文や JSON フィールドとして保持し、必要なときに | json や文字列検索で絞る方がよい場合が多いです。
{source="modsecurity-audit", host="proxy-rev.example.local"}
| json
| response_status="403"
| request_request_line=~".*wp-login\\.php.*"この例では、source と host はラベルで絞り、response_status や request_request_line は JSON フィールドとして絞っています。ログを大きく分ける値と、ログ本文の中で検索する値を分けています。
ログ種別ごとに source を固定する
複数種類のログを Loki に集める場合、最初に決めたいのは source のようなログ種別ラベルです。これは、ログを読む人が最初に選ぶ入口になります。
| source | 対象ログ | 主な用途 |
|---|---|---|
modsecurity-audit | ModSecurity audit log | WAF の遮断理由、誤検知、攻撃傾向を見る |
network-syslog | ネットワーク機器の syslog | deny、drop、認証失敗、リンク状態を確認する |
ubuntu-journal | systemd journal | ホスト OS やサービス単位のログを見る |
ceph-cluster | Ceph cluster log | クラスター状態、警告、障害関連ログを見る |
source を固定しておくと、Grafana のダッシュボードを作るときに便利です。ModSecurity 用のダッシュボードは source="modsecurity-audit" を前提にできますし、network syslog 用のダッシュボードは source="network-syslog" を入口にできます。
ここで大事なのは、source を製品名だけにしないことです。たとえば apache という source では、access log、error log、ModSecurity audit log が混ざる可能性があります。ログの読み方が違うものは、分けた方が扱いやすくなります。
host は便利だが万能ではない
host は、ログの発生元を絞るために便利なラベルです。物理サーバー、仮想マシン、reverse proxy、ネットワーク機器のように、一定期間同じ名前で運用される対象であれば、host は有効な分割軸になります。
ただし、Kubernetes の Pod 名のように短期間で変わる値をそのまま host 相当のラベルに入れると、値が増えやすくなります。Pod 単位で調査したい場面はありますが、運用ダッシュボードの基本軸としては、namespace、app、container のような意味の安定した値を使う方が自然です。
| 対象 | ラベルとして使いやすい値 | 注意点 |
|---|---|---|
| 仮想マシン | host、service | 命名規則が安定していれば使いやすい |
| Kubernetes Pod | namespace、app、container | Pod 名を主軸にすると短命な値が増える |
| ネットワーク機器 | host、site、role | 機器名と設置場所を分けると集計しやすい |
| WAF / reverse proxy | host、source、job | リクエスト先 Host ヘッダーは本文側で扱う方がよいことが多い |
filename は収集経路の確認に使う
filename は、どのファイルから収集されたログかを確認するために有用です。特に、同じ host 上で複数のログファイルを収集する場合、/var/log/apache2/access.log、/var/log/apache2/error.log、/var/log/apache2/modsec_audit.json のように区別できます。
ただし、filename を運用上の主たる分類軸にしすぎると、ログローテーションやディレクトリ構成の変更に引っ張られます。ダッシュボードの基本軸は source や job に置き、filename は収集元の確認やトラブルシュート用に使う方が安定します。
本文に残すべき情報
ラベルに入れない情報は捨てるわけではありません。むしろ、本文や JSON フィールドとして残すことで、必要なときに詳細検索できます。WAF の audit log であれば、送信元 IP アドレス、request line、Host ヘッダー、response status、action message、anomaly score は本文側に残しておく価値があります。
この設計にすると、Grafana では最初にラベルで対象ログを絞り、その後に JSON フィールドで条件を追加できます。
topk(10,
sum by (request_request_line) (
count_over_time(
{source="modsecurity-audit"}
| json
| response_status="403"
[24h]
)
)
)このように、request_request_line はラベルにせず、JSON フィールドとして集計しています。URL や HTTP メソッドの種類は多くなりやすいため、ラベルではなく本文側に置いた方が扱いやすい典型例です。
メトリクスとログを同じ設計にしない
Prometheus のメトリクスと Loki のログは、どちらもラベルを持ちます。しかし、同じ感覚で設計すると失敗しやすくなります。メトリクスは時系列の値を集計するためのものであり、ログは出来事の説明を読むためのものです。
たとえば、Ceph の容量、PG 状態、I/O レートのような継続的な状態は、Prometheus のメトリクスで追う方が自然です。一方で、設定変更、エラー、例外的なイベント、WAF の遮断理由は、ログとして読む価値があります。正常状態を細かくログへ出し続けると、Loki 側の保存量や検索量が増え、重要なイベントが埋もれます。
ログ基盤の設計では、何を Loki に入れるかだけでなく、何をメトリクスへ任せるか、何を発生源で抑制するかも考える必要があります。
ダッシュボードから逆算する
ラベル設計は、収集設定だけを見て決めるものではありません。実際に Grafana でどう見るかから逆算すると、必要なラベルが見えやすくなります。
| 見たいもの | ラベルに欲しいもの | 本文側で十分なもの |
|---|---|---|
| ModSecurity の WAF ログだけを見る | source、job | request line、response status、action message |
| 特定 host の journal を見る | source、host、unit | message、PID、詳細なエラー文 |
| ネットワーク機器の syslog を見る | source、host、protocol | 送信元、宛先、deny 理由、interface 名 |
| ログ量の急増を調べる | source、host、job | 個別メッセージ、リクエスト ID |
ダッシュボードの変数に使う値はラベルに向きます。逆に、一覧表やログ詳細で読むだけの値は、本文側に残しておけば十分なことが多いです。
ラベル設計の判断基準
Loki のラベルに入れるか迷ったときは、次の基準で判断すると整理しやすくなります。
| 問い | ラベルに向く答え |
|---|---|
| 値の種類は少ないか | 数個から数十程度で安定している |
| 長期間変わりにくいか | 短命な ID やリクエストごとの値ではない |
| 最初の絞り込みに使うか | Grafana の変数やダッシュボードの入口になる |
| 集計単位として意味があるか | source、job、host、unit、namespace などで運用判断できる |
| 値が増え続けないか | IP アドレス、URL、ユーザー ID のように増殖しない |
この基準を満たさない値は、検索したい値であっても本文や JSON フィールドに置く方がよいです。ラベルは便利な検索キーではなく、ログ基盤の保存構造に影響する設計です。
参考資料
- Grafana Loki documentation: Labels
- Grafana Loki documentation: Label best practices
- Grafana Loki documentation: Log queries
参考書籍
Observability Engineering
ログ、メトリクス、トレースを含む observability の考え方を整理したい場合の参考書籍です。英語書籍であり、価格や在庫はリンク先で確認してください。
Amazon で見るこのリンクは Amazon アソシエイトリンクです。
関連する記事
まとめ
Loki のラベルは、ログ本文の情報を何でも移す場所ではありません。ログをどの単位で分割し、どの入口から検索し、どの単位でダッシュボード化するかを決める設計です。
source、job、安定した host のような値はラベルに向きます。一方で、IP アドレス、URL、リクエスト ID、ユーザー ID のように値が増え続けるものは、本文や JSON フィールドとして扱う方が安全です。
ログを検索しやすくすることと、ラベルを増やすことは同じではありません。Grafana でどう見るか、どの値で最初に絞るか、どの値は詳細検索に回すかを分けて考えることが、Loki のラベル設計では重要です。


