[ GUIDE ]

Self-hosted Laravel log aggregation

Three credible patterns — Loki, OpenSearch, and BYOD Postgres — with Monolog config and honest ops tradeoffs.

QUICK ANSWER

How do I self-host log aggregation for Laravel?

Three patterns: Grafana Loki + Promtail is the modern OSS default — lightweight, scales well, Grafana UI. OpenSearch + Filebeat is heavier but familiar if you've run Elasticsearch. NightOwl's BYOD Postgres writes Laravel logs alongside your APM data in a database you already own — zero extra infrastructure. Pick Loki for log-only workloads, NightOwl when logs are one signal among request, query, and job telemetry.

Updated · 2026-04-13

Step 1 — Log JSON, not plain text

Before you pick an aggregator, make your logs structured. Every aggregator's value is indexing fields, not substring-matching free text.

config/logging.php

php
'channels' => [
    'stack' => [
        'driver' => 'stack',
        'channels' => ['json'],
        'ignore_exceptions' => false,
    ],

    'json' => [
        'driver' => 'daily',
        'path' => storage_path('logs/laravel.log'),
        'formatter' => Monolog\Formatter\JsonFormatter::class,
        'level' => env('LOG_LEVEL', 'debug'),
        'days' => 14,
    ],
],

Attach per-request context globally so every log line has a correlation ID:

app/Http/Middleware/LogContext.php

php
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

public function handle($request, Closure $next)
{
    $requestId = $request->header('X-Request-Id', Str::uuid()->toString());

    Log::withContext([
        'request_id' => $requestId,
        'user_id' => auth()->id(),
        'env' => config('app.env'),
    ]);

    return $next($request);
}

Option A — Grafana Loki + Promtail

Loki is Grafana's log aggregation database. Indexes metadata (labels), not log content — cheap to run, fast at filter queries, scales horizontally. Promtail tails your log files and ships them.

promtail-config.yaml

yaml
server:
  http_listen_port: 9080

positions:
  filename: /tmp/positions.yaml

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

scrape_configs:
  - job_name: laravel
    static_configs:
      - targets: [localhost]
        labels:
          job: laravel
          env: production
          __path__: /var/www/storage/logs/*.log
    pipeline_stages:
      - json:
          expressions:
            level: level
            message: message
            request_id: request_id
      - labels:
          level:
          request_id:

Run Loki + Promtail + Grafana via Docker Compose. Expect $10-40/mo of VPS for small-to-moderate apps. Loki scales to large volume but needs object storage (S3) for the big tiers.

Option B — OpenSearch + Filebeat

OpenSearch is the Apache-licensed Elasticsearch fork. Familiar if you've used ELK. Full-text indexing of log content — expensive on storage but powerful at arbitrary search. Filebeat is the log shipper.

filebeat.yml

yaml
filebeat.inputs:
  - type: filestream
    paths:
      - /var/www/storage/logs/*.log
    parsers:
      - ndjson:
          overwrite_keys: true
          add_error_key: true

output.elasticsearch:
  hosts: ["https://opensearch:9200"]
  username: "filebeat"
  password: "${FILEBEAT_PASSWORD}"
  index: "laravel-%{+yyyy.MM.dd}"

Heavier than Loki. Expect 8GB+ RAM for a production OpenSearch node. Worth it if you need full-text search across every log byte, not just labels. Not worth it for most Laravel apps.

Option C — BYOD Postgres (NightOwl)

If you already run PostgreSQL, logs as another table is the lowest-ops option. NightOwl ships a Laravel logs watcher that writes every log record with context into your own PostgreSQL — alongside request, query, and job telemetry.

bash
composer require nightowl/agent
php artisan nightowl:install
# logs start streaming to your Postgres immediately

You get structured logs in a database you already know how to query, back up, and scale. Works for teams that don't want to run a separate log stack. Not right for teams doing ingest volumes Postgres can't handle — that's typically 100+ GB/day territory.

How to pick

If you want Pick
Fully open-source, log-only, scales horizontallyGrafana Loki + Promtail
Full-text search across every log byteOpenSearch + Filebeat
Logs alongside request/query/job APM data, zero extra infrastructureNightOwl (BYOD Postgres)
Cheapest SaaS (not self-hosted)Papertrail from $5/mo

THE EASY WAY

Skip the separate log stack

NightOwl ingests Laravel logs — structured, with full request context — into a PostgreSQL database you own. You get log aggregation, request traces, query groupings, and job monitoring in one place. No separate Loki or OpenSearch cluster to operate.

Data stays in your PostgreSQL. From $5/month flat.

Frequently asked questions

What's the best self-hosted Laravel log aggregation option?

Three credible setups: (1) Grafana Loki + Promtail — modern, OSS, scales well, works for log-only use cases; (2) OpenSearch + Filebeat — Elasticsearch fork, heavyweight but familiar; (3) NightOwl's BYOD Postgres — writes Laravel logs into a PostgreSQL database you own alongside request/query/job telemetry, so you don't run a separate log stack. Pick Loki for pure log aggregation, NightOwl when logs are one signal among many.

Can I use Laravel's default log channels for aggregation?

Partially. Laravel's single or daily channels write to local files — fine for a single-server app. Once you run 2+ servers, local files break because logs are scattered. Switch to the papertrail, syslog, or custom Monolog channels to forward logs to a central location, or use an agent (Filebeat, Promtail, Fluent Bit) to tail the files and ship them.

How do I ship Laravel logs to Grafana Loki?

Two patterns. File-tailing: Promtail agent tails storage/logs/laravel.log and ships lines to Loki. Direct push: a custom Monolog handler pushes JSON-structured log records directly to Loki's HTTP API. The direct approach adds a dependency on Loki's availability from the app; file-tailing is more resilient but loses structure unless you log JSON.

Is self-hosted log aggregation cheaper than SaaS?

At low volume, SaaS is cheaper once you value your time. Papertrail starts at $5/mo for small apps; Better Stack starts around $29/mo per Responder (annual). At moderate-to-high volume (50+ GB/month) self-hosting Loki on a VPS gets cheaper on dollars but costs ops time. Real tradeoff is ops capacity, not dollars.

What's the difference between Laravel log aggregation and APM?

Log aggregation collects text log lines from your app and lets you search them. APM collects structured events tied to requests — traces, spans, query timings, error fingerprints. Logs answer 'what was logged at 14:23?'; APM answers 'why was /checkout slow at 14:23?'. Most teams need both. NightOwl captures both — structured APM data plus Laravel log records — in one PostgreSQL.

How do I structure Laravel logs for aggregation?

Log JSON instead of free text. Use Monolog's JsonFormatter or the monolog-bridge package. Structured logs let the aggregator index specific fields (user_id, request_id, exception.class) rather than doing full-text search. Include a correlation ID on every log line so you can trace a single request's logs end-to-end.

How long should I retain Laravel logs?

Depends on compliance and debugging needs. 7-30 days covers most debugging. SOC 2 and PCI typically require 365 days for audit logs (which is a subset — not all app logs). Use tiered retention: hot (searchable, 7-30 days), warm (archived, 30-365 days), cold (object storage, 1+ year). Loki's retention config handles tiering natively.

Should I log PII in Laravel?

No, and your logging setup should prevent it at the source. Use Laravel's Log::withContext with pre-redacted fields, never dump request bodies containing credentials or PII, and filter password/token fields before logging. If PII ends up in logs anyway, you need redaction at ingest time — Loki's relabel_configs or a dedicated scrubbing agent.

PRICING

Flat pricing. No event caps. No per-seat fees.

14-day free trial, no credit card. Your PostgreSQL, your data.

HOBBY

$5 /month

1 app · 14 days lookback · all Laravel events

TEAM

$15 /month

Up to 3 connected apps · unlimited environments · all Laravel events

AGENCY

$69 /month

Unlimited apps · unlimited agent instances · same flat rate at any traffic

Related