Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

Subscribe to the newsletter

Get new articles and course lessons delivered to your inbox. No spam, unsubscribe anytime.

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 47 of the Advanced Laravel: Architecture, Scaling & Performance course
LaravelJune 28, 20263 min read

Advanced Logging Patterns: Centralizing Laravel Logs for ELK Observability

Stop grepping through flat files. Learn to structure Laravel logs for searchability and integrate them with the ELK stack for production-grade observability.

LaravelLoggingObservabilityELKDevOpsphpbackend

Previously in this course, we discussed handling webhooks securely. While that lesson focused on maintaining integrity during external communication, today we shift our focus to how we actually see that activity inside our infrastructure. In distributed systems, relying on local log files is a recipe for disaster; this lesson teaches you to centralize and structure your logs for professional-grade observability.

Why Structured Logging Matters

In a monolithic application, you might get away with Log::info('User login'). In a distributed SaaS architecture, that string is useless. When a request traverses multiple services, you need context: trace_id, user_id, tenant_id, and execution_time.

Structured logging transforms these "human-readable" strings into machine-readable JSON objects. This allows the ELK stack (Elasticsearch, Logstash, Kibana) to index specific fields, enabling you to run queries like: "Show me all failed billing attempts for Tenant X in the last 10 minutes."

Designing Your Logging Architecture

To achieve observability, we need a pipeline:

  1. Emitter: Laravel sends JSON logs via a custom Monolog formatter.
  2. Transport: A local Logstash agent or Filebeat reads these logs.
  3. Indexer: Logstash parses the JSON and pushes it to Elasticsearch.
  4. Visualizer: Kibana provides the dashboarding interface.

The Worked Example: Customizing Monolog

Laravel uses Monolog under the hood. We’ll inject a custom formatter to ensure every log entry carries our required metadata.

First, create a ContextualLogFormatter that forces JSON output with a consistent schema:

PHP
namespace App\Logging;

use Monolog\Formatter\JsonFormatter;
use Monolog\LogRecord;

class ContextualLogFormatter extends JsonFormatter
{
    public function format(LogRecord $record): string
    {
        $record->extra = [
            'tenant_id' => tenant()?->id,
            'request_id' => request()->header('X-Request-ID'),
            'environment' => config('app.env'),
        ];

        return parent::format($record);
    }
}

Next, configure your logging.php to use this formatter for your stack or a custom channel:

PHP
'channels' => [
    'elk' => [
        'driver' => 'single',
        'path' => storage_path('logs/laravel-elk.log'),
        'level' => 'debug',
        'formatter' => \App\Logging\ContextualLogFormatter::class,
    ],
],

Integrating with Logstash

Once your logs are writing JSON to a file, Logstash needs to pick them up. Create a configuration file (logstash.conf) on your application server:

CONF
input {
  file {
    path => "/var/www/html/storage/logs/laravel-elk.log"
    codec => "json"
  }
}

filter {
  # Add logic to parse specific fields or drop noisy logs
}

output {
  elasticsearch {
    hosts => ["https://your-elasticsearch-cluster:9200"]
    index => "laravel-logs-%{+YYYY.MM.dd}"
  }
}

Hands-on Exercise

  1. Implement the Formatter: Create the ContextualLogFormatter shown above and register it in your logging.php file.
  2. Test the Output: Run a sample log command: Log::channel('elk')->info('Payment processed', ['amount' => 500]);.
  3. Verify: Check storage/logs/laravel-elk.log to confirm the JSON output includes the tenant_id and request_id you injected.
  4. Logstash Setup: If you have a local Docker instance of ELK, point a Logstash input at this file and verify the logs appear in your Kibana index pattern.

Common Pitfalls

  • Log Bloat: Structured logs are more verbose than plain text. Ensure you have log rotation configured (daily driver) or use a tool like Filebeat that handles rotation gracefully without losing data.
  • Sensitive Data Leakage: Never log PII (Personally Identifiable Information) in your structured logs. Use a tap to redact sensitive keys like password or credit_card_number before the logs hit the disk.
  • Performance Overhead: Formatting complex objects into JSON on every log call adds latency. In high-traffic systems, consider offloading the log writing to a non-blocking queue or a sidecar process.

Recap

We’ve moved from basic file logging to a structured approach that makes production debugging possible. By standardizing your JSON schema and routing logs through Logstash, you gain the ability to aggregate, filter, and alert on system events with surgical precision. For more on the broader landscape of telemetry, you may find our previous discussions on observability and logging or advanced error handling useful for contrast.

Up next: We will dive into Database Indexing for Joins, where we'll analyze execution plans to ensure our queries—and our logs—stay performant as the data grows.

Previous lessonHandling Webhooks SecurelyNext lesson Database Indexing for Joins
Back to Blog

Similar Posts

LaravelJune 26, 20263 min read

Logging and Monitoring: Mastering Laravel Production Debugging

Master production-grade logging and monitoring in Laravel. Learn to configure custom log channels, track application errors, and integrate external services.

Read more
LaravelJune 28, 20264 min read

Advanced Database Migration Strategies for Laravel

Master non-breaking migrations and safe rollback procedures. Learn the expand-and-contract pattern to evolve your database schema without production downtime.

Part of the course

Advanced Laravel: Architecture, Scaling & Performance

advanced · Lesson 47 of 57

  1. 1

    Transitioning from MVC to DDD

    3 min
  2. 2

    Defining Bounded Contexts

    3 min
  3. 3

    Implementing Action Classes

    3 min
Read more
LaravelJune 28, 20264 min read

Optimizing Asset Pipelines: Versioning and CDN Caching with Vite

Master production-grade asset management in Laravel. Learn to implement file hashing for versioning and configure Vite to scale your frontend performance via CDN.

Read more
4

Utilizing Data Transfer Objects (DTOs)

3 min
  • 5

    Service Layer Pattern

    4 min
  • 6

    Modular Monolith Structure

    3 min
  • 7

    Querying with Strict Eloquent

    4 min
  • 8

    Advanced Subqueries and Joins

    4 min
  • 9

    Raw Expressions for Performance

    4 min
  • 10

    Advanced Indexing Strategies

    4 min
  • 11

    Database Partitioning Techniques

    4 min
  • 12

    Read/Write Database Splitting

    4 min
  • 13

    Handling Multi-Database Connections

    3 min
  • 14

    Eloquent Caching Strategies

    3 min
  • 15

    Queue Worker Prioritization

    4 min
  • 16

    Unique Job Patterns

    4 min
  • 17

    Rate Limiting Background Jobs

    3 min
  • 18

    Event-Driven Architecture

    4 min
  • 19

    Integrating External Message Brokers

    4 min
  • 20

    Distributed Transactions and Sagas

    3 min
  • 21

    Eventual Consistency Patterns

    4 min
  • 22

    Multi-Layered Caching Strategy

    4 min
  • 23

    Cache Tagging and Invalidation

    4 min
  • 24

    Session Persistence in Clusters

    4 min
  • 25

    High-Availability Infrastructure

    4 min
  • 26

    Zero-Downtime Deployment Pipelines

    4 min
  • 27

    Advanced OAuth2 Implementation

    3 min
  • 28

    JWT and Stateless Security

    4 min
  • 29

    Multi-Tenant Security Isolation

    3 min
  • 30

    Defense Against SSRF

    3 min
  • 31

    Mass Assignment Hardening

    4 min
  • 32

    Automated Security Testing

    3 min
  • 33

    Custom Telemetry Design

    3 min
  • 34

    Distributed Tracing

    4 min
  • 35

    Profiling PHP Execution

    3 min
  • 36

    Memory Management in Long-Running Processes

    4 min
  • 37

    Testing DDD Components

    3 min
  • 38

    Contract Testing

    3 min
  • 39

    Handling Large File Uploads

    3 min
  • 40

    Optimizing Asset Pipelines

    4 min
  • 41

    Database Query Caching Layers

    3 min
  • 42

    Advanced Eloquent Scopes

    4 min
  • 43

    Distributed Locks

    3 min
  • 44

    API Versioning Strategies

    4 min
  • 45

    Database Migration Strategies

    4 min
  • 46

    Handling Webhooks Securely

    3 min
  • 47

    Advanced Logging Patterns

    3 min
  • 48

    Database Indexing for Joins

    4 min
  • 49

    Graceful Degradation

    3 min
  • 50

    Custom Middleware Development

    4 min
  • 51

    Database Connection Pooling

    4 min
  • 52

    Handling Large Data Exports

    Coming soon
  • 53

    Security Header Configuration

    Coming soon
  • 54

    Database Sharding Concepts

    Coming soon
  • 55

    Real-time Data Synchronization

    Coming soon
  • 56

    Database Deadlock Prevention

    Coming soon
  • 57

    Managing Third-Party API Integrations

    Coming soon
  • View full course