edwinekr/otel-elk-laravel

OpenTelemetry activity logging integration with ELK Stack for Laravel applications

Installs: 4

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/edwinekr/otel-elk-laravel

v1.0.4 2026-02-05 04:10 UTC

This package is auto-updated.

Last update: 2026-02-05 04:11:50 UTC


README

Latest Version on Packagist Total Downloads

OpenTelemetry activity logging integration with ELK Stack (Elasticsearch, Logstash, Kibana) for Laravel applications.

Architecture

Laravel App → OpenTelemetry SDK → Logstash HTTP (5044) → Elasticsearch → Kibana (Map View)

Features

  • 🚀 Automatic HTTP Request Logging - All requests are logged with response time, status codes, and user info
  • 🔐 Authentication Event Logging - Login, logout, failed attempts, lockouts, and password resets
  • 📊 Model Activity Logging - Track create, update, and delete operations on Eloquent models
  • 🎯 Custom Activity Logging - Log any custom activity with metadata
  • Async Logging - Non-blocking log submission for better performance
  • 🔒 Sensitive Data Masking - Automatically redact passwords, tokens, and other sensitive fields
  • 🌍 GeoIP Ready - Works with Logstash GeoIP filter for location visualization in Kibana

Requirements

  • PHP 8.1+
  • Laravel 10.x, 11.x, or 12.x
  • Guzzle HTTP Client

Installation

Install the package via Composer:

composer require edwinekr/otel-elk-laravel

The package will auto-register its service provider.

Publish Configuration

php artisan vendor:publish --tag=otel-elk-config

This will create config/activity_log.php in your application.

Configuration

Add the following to your .env file:

# ===========================================
# Activity Log / OpenTelemetry Configuration
# ===========================================

# Enable/disable activity logging (default: true)
ACTIVITY_LOG_ENABLED=true

# Logstash HTTP endpoint for receiving logs
ACTIVITY_LOG_ENDPOINT=http://localhost:5044

# Application name for log identification
ACTIVITY_LOG_APP_NAME=my-laravel-app

# Environment identifier (development, staging, production)
ACTIVITY_LOG_ENVIRONMENT=production

# Request timeout in seconds for sending logs
ACTIVITY_LOG_TIMEOUT=2

# Send logs asynchronously (recommended for performance)
ACTIVITY_LOG_ASYNC=true

# Log request body (⚠️ be careful with sensitive data)
ACTIVITY_LOG_REQUEST_BODY=false

# Auto-register middleware globally (default: true)
ACTIVITY_LOG_AUTO_MIDDLEWARE=true

# Log authentication events (default: true)
ACTIVITY_LOG_AUTH_EVENTS=true

# Exclude AJAX/XHR requests (default: true) - reduces DataTable noise
ACTIVITY_LOG_EXCLUDE_AJAX=true

# Exclude requests expecting JSON response (default: false)
ACTIVITY_LOG_EXCLUDE_JSON=false

# Exclude static assets - CSS, JS, images, fonts (default: true)
ACTIVITY_LOG_EXCLUDE_ASSETS=true

# Exclude redirect responses - 3xx status codes (default: true)
ACTIVITY_LOG_EXCLUDE_REDIRECTS=true

# Only log controller actions, exclude Closures (default: true)
ACTIVITY_LOG_ONLY_CONTROLLERS=true

# Only log HTML requests, exclude CSS/JS preloads (default: true)
ACTIVITY_LOG_ONLY_HTML=true

# Only log routes that have a name (default: true)
ACTIVITY_LOG_ONLY_NAMED_ROUTES=true

# Fallback IP for local development (default: Banten, Indonesia)
ACTIVITY_LOG_LOCAL_IP=103.28.12.1

# Use fallback IP when running locally (default: true)
ACTIVITY_LOG_USE_LOCAL_IP=true

# User resolver: 'default', 'session', or 'custom'
ACTIVITY_LOG_USER_RESOLVER=default

# Session key for user data (when using session resolver)
ACTIVITY_LOG_SESSION_USER_KEY=user

Usage

Automatic HTTP Request Logging

All HTTP requests are automatically logged when the middleware is enabled. No additional code required!

Manual Activity Logging

Use the ActivityLog facade or inject ActivityLogService:

use Edwinekr\OtelElkLaravel\Facades\ActivityLog;

// Log a custom activity
ActivityLog::log(
    action: 'order.checkout',
    entity: 'Order',
    entityId: $order->id,
    metadata: [
        'total' => $order->total,
        'items_count' => $order->items->count(),
        'payment_method' => $order->payment_method,
    ]
);

Using Dependency Injection

use Edwinekr\OtelElkLaravel\Services\ActivityLogService;

class OrderController extends Controller
{
    public function __construct(private ActivityLogService $activityLog)
    {
    }

    public function checkout(Request $request)
    {
        $order = Order::create([...]);

        $this->activityLog->log(
            action: 'order.checkout',
            entity: 'Order',
            entityId: $order->id,
            metadata: [
                'total' => $order->total,
                'items_count' => $order->items->count(),
            ]
        );

        return response()->json(['order' => $order]);
    }
}

Model Activity Logging

Use the LogsActivity trait on your Eloquent models:

use Edwinekr\OtelElkLaravel\Traits\LogsActivity;

class Product extends Model
{
    use LogsActivity;

    // Model will automatically log created, updated, deleted events
}

You can also log custom activities on a model:

$product->logActivity('viewed', ['viewer_ip' => request()->ip()]);

Authentication Events

Authentication events are automatically logged when enabled. These events are tracked:

  • auth.login - User logged in
  • auth.logout - User logged out
  • auth.failed - Login attempt failed
  • auth.lockout - User was locked out
  • auth.registered - New user registered
  • auth.password_reset - Password was reset

Using Session-Based User Resolver

If your application uses session-based authentication instead of Laravel's built-in auth:

ACTIVITY_LOG_USER_RESOLVER=session
ACTIVITY_LOG_SESSION_USER_KEY=user

Make sure your session contains user data:

// Store user in session
Session::put('user', [
    'id' => $user->id,
    'name' => $user->name,
    'email' => $user->email,
]);

Manual Middleware Registration

If you prefer to register the middleware manually, disable auto-registration:

ACTIVITY_LOG_AUTO_MIDDLEWARE=false

Then register it in your routes or kernel:

// In routes/api.php
Route::middleware(['activity-log'])->group(function () {
    // Your routes
});

Or for Laravel 11+ in bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->append(\Edwinekr\OtelElkLaravel\Middleware\ActivityLogMiddleware::class);
})

Excluding Paths and Methods

Configure excluded paths in config/activity_log.php:

'excluded_paths' => [
    'health',
    'ready',
    'livez',
    'metrics',
    '_debugbar/*',
    'telescope/*',
    'horizon/*',
    'sanctum/csrf-cookie',
    'api/internal/*',
],

'excluded_methods' => [
    'OPTIONS',
],

Sensitive Fields

Sensitive fields are automatically masked in request body logs:

'sensitive_fields' => [
    'password',
    'password_confirmation',
    'token',
    'secret',
    'api_key',
    'credit_card',
    'cvv',
],

Logstash Configuration

Example Logstash configuration for receiving logs:

input {
    http {
        port => 5044
        codec => json
    }
}

filter {
    # Add GeoIP data based on client IP
    if [ip] {
        geoip {
            source => "ip"
            target => "geoip"
        }
    }

    # Parse timestamp
    date {
        match => ["timestamp", "ISO8601"]
        target => "@timestamp"
    }
}

output {
    elasticsearch {
        hosts => ["elasticsearch:9200"]
        index => "activity-logs-%{+YYYY.MM.dd}"
    }
}

Kibana Visualization

After logs are ingested, you can create visualizations in Kibana:

  1. Go to Kibana → Maps
  2. Click Add layer → Documents
  3. Select your index pattern activity-logs-*
  4. Choose geoip.location as the geospatial field
  5. Configure tooltips to show: ip, user_email, action, path

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security-related issues, please email security@example.com instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.