Loki یک log aggregation system است که:
- ✅ لاگها را از Docker containers جمع میکند
- ✅ در Grafana قابل مشاهده است
- ✅ جستجو و فیلتر آسان است
- ✅ با Tempo و Prometheus یکپارچه است
Promtail یک log collector است که:
- ✅ لاگها را از Docker containers میخواند
- ✅ آنها را parse میکند (JSON)
- ✅ Labels را extract میکند
- ✅ لاگها را به Loki ارسال میکند
# راهاندازی تمام stack (شامل Loki)
make observability-upاین دستور تمام سرویسها را راهاندازی میکند:
- Tempo
- Jaeger
- Prometheus
- Loki
- Promtail
- Grafana
# راهاندازی Loki و Promtail
make loki-up
# راهاندازی Grafana (برای مشاهده logs)
make grafana-up- باز کردن: http://localhost:3000
- در منوی سمت چپ، روی "Explore" کلیک کنید (آیکون قطبنما)
- در بالای صفحه، dropdown "Data source" را باز کنید
- "Loki" را انتخاب کنید
در فیلد query، یکی از این query ها را بنویسید:
# تمام لاگهای container go-backend-api
{container="go-backend-api"}
# فقط error logs
{container="go-backend-api", level="error"}
# لاگهای یک correlation_id خاص
{container="go-backend-api", correlation_id="abc-123-def-456"}
# لاگهای یک trace_id خاص
{container="go-backend-api", trace_id="1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p"}
# لاگهای یک endpoint خاص
{container="go-backend-api", path="/hello"}
# لاگهای با status code 500
{container="go-backend-api", status_code="500"}
سپس روی "Run query" کلیک کنید.
# فیلتر بر اساس message
{container="go-backend-api"} |= "error"
# فیلتر بر اساس regex
{container="go-backend-api"} |~ ".*error.*"
# فقط error و warn logs
{container="go-backend-api"} | json | level=~"error|warn"
# لاگهای با latency بالا
{container="go-backend-api"} | json | latency_ms > 1000
# لاگهای یک method خاص
{container="go-backend-api"} | json | method="GET"
# ترکیب چند شرط
{container="go-backend-api"} | json | level="error" and status_code="500"
{container="go-backend-api", level="error"}
یا:
{container="go-backend-api"} | json | level="error"
# 1. ارسال request با correlation ID
CORRELATION_ID="debug-$(date +%s)"
curl -H "X-Correlation-ID: $CORRELATION_ID" http://localhost:8080/helloسپس در Grafana:
{container="go-backend-api", correlation_id="debug-1234567890"}
{container="go-backend-api"} | json | latency_ms > 1000
اگر Trace ID را میدانید:
{container="go-backend-api", trace_id="1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p"}
{container="go-backend-api", path="/hello"}
sum(rate({container="go-backend-api", level="error"}[5m]))
یکی از ویژگیهای قدرتمند Grafana، امکان رفتن از trace به logs مرتبط است.
- در Grafana Explore، Tempo datasource را انتخاب کنید
- یک trace را پیدا کنید
- روی trace کلیک کنید
- در بخش "Logs"، روی "Show logs" کلیک کنید
- لاگهای مرتبط با این trace نمایش داده میشوند
اگر Trace ID را میدانید:
- در Grafana Explore، Loki datasource را انتخاب کنید
- Query بنویسید:
{container="go-backend-api", trace_id="YOUR_TRACE_ID"}
# تمام لاگها
{container="go-backend-api"}
# با چند label
{container="go-backend-api", level="error", status_code="500"}
# فیلتر بر اساس message
{container="go-backend-api"} |= "error"
# فیلتر با regex
{container="go-backend-api"} |~ ".*error.*"
# فیلتر با JSON
{container="go-backend-api"} | json | level="error"
# Count logs
count_over_time({container="go-backend-api"}[5m])
# Rate of logs
rate({container="go-backend-api"}[5m])
# Sum by label
sum by (level) (count_over_time({container="go-backend-api"}[5m]))
Promtail به صورت خودکار این labels را از JSON logs extract میکند:
container: نام containercontainer_name: نام container بدون prefixlevel: log level (info, error, warn, etc.)correlation_id: correlation IDtrace_id: trace IDspan_id: span IDmethod: HTTP method (GET, POST, etc.)path: HTTP pathstatus_code: HTTP status codeapp: نام application (go-backend-service)service: نام service (از docker-compose)project: نام project (از docker-compose)
راه حل:
-
بررسی کنید که Loki در حال اجرا است:
docker ps | grep loki -
بررسی کنید که Promtail در حال اجرا است:
docker ps | grep promtail -
بررسی logs Promtail:
docker logs go-backend-promtail
-
بررسی logs Loki:
docker logs go-backend-loki
-
بررسی کنید که container API در حال اجرا است:
docker ps | grep go-backend-api -
بررسی کنید که لاگها تولید میشوند:
docker logs go-backend-api | tail -10 -
ارسال یک request تست:
curl http://localhost:8080/hello
-
بررسی بازه زمانی:
- اگر request را الان فرستادید، "Last 5 minutes" را انتخاب کنید
راه حل:
-
بررسی کنید که لاگها JSON format هستند:
docker logs go-backend-api | head -1 | jq .
-
بررسی Promtail config:
cat configs/promtail/promtail-config.yaml
-
Restart Promtail:
docker-compose -f docker-compose.observability.yml restart promtail
راه حل:
-
بررسی کنید که Grafana container در حال اجرا است:
docker ps | grep grafana -
بررسی logs Grafana:
docker logs go-backend-grafana | grep -i "loki\|datasource" | tail -20
-
بررسی فایل provisioning:
cat configs/grafana/provisioning/datasources/datasources.yml
-
Restart Grafana:
docker-compose -f docker-compose.observability.yml restart grafana
sum(rate({container="go-backend-api", level="error"}[1m]))
sum by (level) (count_over_time({container="go-backend-api"}[5m]))
avg_over_time({container="go-backend-api"} | json | latency_ms [5m])
topk(10,
sum by (path) (
{container="go-backend-api"} | json | latency_ms > 1000
)
)
sum by (path) (
rate({container="go-backend-api", level="error"}[5m])
)
# راهاندازی Loki
make loki-up
# مشاهده logs Loki
make loki-logs
# توقف Loki
make loki-down
# راهاندازی کامل stack
make observability-up# تمام لاگها
{container="go-backend-api"}
# فقط errors
{container="go-backend-api", level="error"}
# با correlation_id
{container="go-backend-api", correlation_id="abc-123"}
# با trace_id
{container="go-backend-api", trace_id="trace-id-here"}
# Slow requests
{container="go-backend-api"} | json | latency_ms > 1000
- Grafana: http://localhost:3000
- Grafana Explore: http://localhost:3000/explore
- Loki API: http://localhost:3100
⚠️ Loki خودش UI ندارد - همیشه از Grafana استفاده کنید⚠️ بازه زمانی مهم است - اگر request را 1 ساعت پیش فرستادید، باید بازه زمانی را تغییر دهید- ✅ Labels باید دقیق باشند - از Explore میتوانید labels موجود را ببینید
- ✅ LogQL syntax - برای جستجوی پیشرفته از LogQL استفاده کنید
- ✅ Trace-to-Logs - میتوانید از trace به logs مرتبط بروید