Back to Blog
team@tinypod.app

Log Management for Self-Hosted Apps: Loki, Promtail, and Grafana

Application logs are your first debugging tool. Loki collects, stores, and lets you search logs from all your self-hosted applications.

logginglokigrafanaobservability

The Problem


Each container has its own logs. Debugging means SSH into the server, docker logs container-name, scroll through output. With 10 apps, this is painful.


The Solution: Centralized Logging


Collect all logs in one place. Search, filter, and correlate across applications.


The Loki Stack


Loki

The log database. Inspired by Prometheus but for logs. Indexes metadata (labels) but stores log lines as-is. Much more efficient than Elasticsearch for most use cases.


Promtail

The log collector. Runs on your server, reads container logs, and ships them to Loki.


Grafana

The dashboard. Query and visualize logs. You probably already have Grafana for metrics — Loki integrates seamlessly.


Why Loki over Elasticsearch?


Resource Usage

  • Loki: 512 MB RAM for moderate log volume
  • Elasticsearch: 4+ GB RAM minimum

  • Simplicity

  • Loki: Single binary, minimal configuration
  • Elasticsearch: JVM tuning, cluster management, index lifecycle

  • Cost

  • Loki: Stores compressed log lines efficiently
  • Elasticsearch: Full-text indexing uses 10-20x more disk

  • Trade-off

    Elasticsearch has faster full-text search. Loki is better for label-based filtering and recent log queries.


    Deployment


    1. Deploy Loki + Promtail on TinyPod

    2. Configure Promtail to read Docker/Podman logs

    3. Add Loki as a data source in Grafana

    4. Start querying logs


    Querying Logs


    Loki uses LogQL (similar to PromQL):


    All logs from the app container:

    {container="myapp"}


    Filter for errors:

    {container="myapp"} |= "error"


    Parse JSON logs:

    {container="myapp"} | json | status >= 500


    Best Practices


    Structured Logging

    Log in JSON format. Loki can parse fields for filtering:

    {"level": "error", "msg": "database connection failed", "service": "api"}


    Log Levels

    Use consistent levels: debug, info, warn, error, fatal. Filter by level in queries.


    Retention

    Keep logs for 30-90 days. Longer if compliance requires it. Configure Loki's retention policy to auto-delete old logs.


    Alerts on Logs

    Create Grafana alerts on log patterns:

  • Alert when error rate exceeds threshold
  • Alert on specific error messages
  • Alert when a service stops logging (might be crashed)