OSSログ管理比較:ELK Stack vs Loki vs Graylog でSplunkを脱却する
オープンソースラボ編集部 ・ 2026年6月13日
OSSログ管理比較:ELK Stack vs Loki vs Graylog でSplunkを脱却する
Splunk(月$150/GB〜)・Datadog Log Management(月$0.10/GB〜)・Sumo Logic(月$3/GB〜)に対して、ELK Stack(Elasticsearch + Logstash + Kibana)・Loki(Grafanaのログ集約)・Graylog(構造化ログ管理)はOSSでログ管理基盤を構築できます。
OSSログ管理を選ぶ理由
- コスト: Splunk 100GB/日=$15,000/月。Lokiセルフホストはストレージ代のみ
- データ主権: 本番ログに機密情報(認証トークン・個人情報)が含まれる場合に社内保持
- Grafana統合: Lokiはメトリクス(Prometheus)・トレース(Tempo)と同じGrafana UIで表示
- スケーラビリティ: LokiはS3にログを保存し、ほぼ無制限にスケール
主要ツールの概要
Loki(Grafana Loki)
2018年公開、Go製のOSSです。GitHubスター24k+。**「Prometheusのログ版」**として設計され、ログのインデックスはラベル(Kubernetes Pod名・サービス名等)のみを持ちます。Elasticsearchと比べてストレージコストが1/10〜1/50になる点が最大の特長です。
# docker-compose.yml - Grafana + Loki + Promtail スタック
version: '3.8'
services:
loki:
image: grafana/loki:2.9.4
restart: unless-stopped
ports:
- "3100:3100"
command: -config.file=/etc/loki/config.yaml
volumes:
- ./loki-config.yaml:/etc/loki/config.yaml
- loki_data:/loki
promtail:
image: grafana/promtail:2.9.4
restart: unless-stopped
volumes:
- /var/log:/var/log:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- ./promtail-config.yaml:/etc/promtail/config.yaml
command: -config.file=/etc/promtail/config.yaml
grafana:
image: grafana/grafana:10.4.0
restart: unless-stopped
ports:
- "3000:3000"
environment:
GF_SECURITY_ADMIN_PASSWORD: your-password
GF_FEATURE_TOGGLES_ENABLE: traceqlEditor
volumes:
- grafana_data:/var/lib/grafana
- ./grafana-provisioning:/etc/grafana/provisioning
volumes:
loki_data:
grafana_data:
# loki-config.yaml - Loki設定(ローカルストレージ)
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
common:
instance_addr: 127.0.0.1
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
schema_config:
configs:
- from: 2024-01-01
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
limits_config:
retention_period: 30d # 30日間保持
compactor:
working_directory: /loki/compactor
retention_enabled: true
# promtail-config.yaml - Dockerコンテナのログを収集
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:
# Dockerコンテナのログを自動収集
- job_name: docker
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
relabel_configs:
- source_labels: [__meta_docker_container_name]
target_label: container
- source_labels: [__meta_docker_container_log_stream]
target_label: logstream
- source_labels: [__meta_docker_container_label_com_docker_compose_service]
target_label: service
# アプリケーションログファイルを収集
- job_name: app-logs
static_configs:
- targets:
- localhost
labels:
job: myapp
env: production
__path__: /var/log/myapp/*.log
pipeline_stages:
- json:
expressions:
level: level
message: message
trace_id: trace_id
- labels:
level:
trace_id:
# LokiのHTTP APIでログをクエリ(Python)
import requests
from datetime import datetime, timezone, timedelta
LOKI_URL = 'http://localhost:3100'
def query_logs(
logql: str,
start: datetime = None,
end: datetime = None,
limit: int = 100,
) -> list:
'''LogQLクエリでLokiからログを取得'''
now = datetime.now(timezone.utc)
params = {
'query': logql,
'start': int((start or now - timedelta(hours=1)).timestamp() * 1e9),
'end': int((end or now).timestamp() * 1e9),
'limit': limit,
'direction': 'backward',
}
resp = requests.get(f'{LOKI_URL}/loki/api/v1/query_range', params=params)
resp.raise_for_status()
result = resp.json()
logs = []
for stream in result['data']['result']:
for ts, line in stream['values']:
logs.append({'timestamp': ts, 'log': line, 'labels': stream['stream']})
return logs
# 直近1時間のERRORログを取得
error_logs = query_logs(
logql='{service="myapp", env="production"} |= `ERROR` | json | level="error"',
limit=50,
)
print(f'{len(error_logs)}件のエラーログ:')
for log in error_logs[:5]:
print(f" {log['log'][:100]}")
# 特定のtrace_idのログを追跡(分散トレーシングと連携)
trace_logs = query_logs(
logql='{service=~".*"} | json | trace_id="abc123def456"',
)
print(f'トレース abc123def456: {len(trace_logs)}件のログスパン')
ELK Stack(Elasticsearch + Logstash + Kibana)
2012〜、Java/Node.js製のOSSです(Elasticsearch/Kibanaは2021年にライセンス変更、OSSフォークのOpenSearchも存在)。フルテキスト検索・複雑なログ集計・機械学習異常検知が必要な場合に選択されます。大量ログの分析ダッシュボードが充実しています。
# docker-compose.yml - ELK Stack(シンプル構成)
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.13.0
restart: unless-stopped
environment:
discovery.type: single-node
ES_JAVA_OPTS: -Xms1g -Xmx1g
xpack.security.enabled: "false"
volumes:
- es_data:/usr/share/elasticsearch/data
ports:
- "9200:9200"
logstash:
image: docker.elastic.co/logstash/logstash:8.13.0
restart: unless-stopped
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
kibana:
image: docker.elastic.co/kibana/kibana:8.13.0
restart: unless-stopped
ports:
- "5601:5601"
environment:
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
volumes:
es_data:
機能比較表
| 比較項目 | Loki | ELK Stack | Graylog |
|---|---|---|---|
| ストレージ効率 | ★★★(最高) | ★☆☆(高コスト) | ★★☆ |
| 検索性能 | ★★☆(ラベル検索) | ★★★(全文検索) | ★★☆ |
| Grafana統合 | ✅(ネイティブ) | △(プラグイン) | △ |
| 最小RAM | 512MB | 2GB〜 | 1GB〜 |
| GitHub Stars | 24k+ | 70k+(OpenSearch) | 8k+ |
ログ管理はDevOpsカテゴリ/categories/devopsのPrometheus・SigNozと組み合わせてメトリクス・ログ・トレースの3本柱のオブザーバビリティ基盤を構築します。セキュリティカテゴリ/categories/securityのWazuhとGraylogを統合してSIEM(セキュリティ情報イベント管理)基盤を構築するケースも多くあります。
FAQ
Q. LokiとElasticsearchのストレージコストの違いを具体的に教えてください。
A. 同じログ量(1GB/日)での比較: Elasticsearch: テキストのインデックス生成でRAWログの3〜5倍のストレージ消費→5GB/日、30日保持で150GB、AWS EBS $0.10/GB=$15/月。Loki: ラベルのみインデックス化→ログはgzip圧縮してS3に保存、圧縮後は原寸の10〜20%→200MB/日→30日=6GB、S3 $0.025/GB=$0.15/月。つまりLoki(S3)はElasticsearchの100倍以上コスト効率が良いケースがあります。ただしElasticsearchは任意のフィールドでの全文検索が可能で、Lokiは指定ラベル+grepのみ。非構造化ログのアドホック分析が多い場合はElasticsearchが向いています。
Q. Next.jsアプリのサーバーログをLokiに送るには?
A. Next.jsのAPIルートやServer Actionsのログは複数の方法で送れます。①winston + winston-loki: npm install winston winston-loki→winstonのTransportにLokiを追加(HTTP Push API)②Promtail: Next.jsをDockerで動かしている場合はコンテナのstdoutを自動収集③OpenTelemetry Logs: @opentelemetry/sdk-logs + @opentelemetry/exporter-logs-otlp-httpでLoki互換エンドポイントにPush。最もシンプルな方法: console.log(JSON.stringify({level:"info",message:"...",trace_id:"..."}))でJSON出力→PromtailのJSON pipelineでラベル抽出→Loki自動収集。
Q. Lokiのログ保存期間(Retention)を設定するには?
A. Lokiの設定ファイル(loki-config.yaml)のlimits_config.retention_periodで設定: 30d(30日)・90d(90日)。Compactorが自動で期限切れチャンクを削除します(compactor.retention_enabled: trueが必要)。S3バックエンドを使う場合はS3のライフサイクルポリシーでも制御可能(より安価に長期保存→Glacierへ移行)。注意: Lokiのretentionはグローバル設定のほか、Tenantごとにも設定できます(ruler_remote_write_headersでMulti-tenancy有効化)。
Q. GraylogをAD(Active Directory)と連携してログアクセスを制御するには?
A. Graylog → System → Authentication → Active Directory を選択。設定: AD/LDAPのホスト名・ポート・Base DN(DC=yourcompany,DC=com)・検索フィルタ((&(objectClass=user)(sAMAccountName=%s)))・管理者DNとパスワード。グループマッピング: ADのセキュリティグループ(例: GraylogAdmins・GraylogReaders)をGraylogのロールにマッピング。これで社員のADアカウントでGraylogにSSOログインでき、部門ごとにストリームへのアクセス権を制御できます。
まとめ
| ユースケース | 推奨ツール |
|---|---|
| コスト最適・Kubernetes・Grafana統合 | Loki |
| 全文検索・アドホック分析・ML異常検知 | ELK Stack(またはOpenSearch) |
| 構造化ログ・SIEM・AD認証 | Graylog |