Comprehensive Logging for Laravel: Track Every Action That Matters

In modern web applications, knowing what happened, when it happened, and who did it isn’t optional -it’s essential. Whether you’re debugging production issues, conducting security audits, or ensuring regulatory compliance, comprehensive logging is the foundation of application observability.

The mattyeend/logging package brings enterprise-grade action logging to Laravel applications with a simple, structured approach that tracks user and system actions in a searchable database format.

What Is the Logging Package?

This Laravel package provides a complete logging solution that records application events into a dedicated database table. Unlike traditional file-based logging, this approach stores logs as structured data, making them queryable, filterable, and analyzable through your application’s interface.

The package offers:

  • Predefined action constants for 31 common operations
  • User relationship tracking for both the actor and subject of actions
  • Flexible metadata storage through JSON fields
  • Zero-configuration setup with sensible defaults
  • Extensible architecture for custom action types

Why Database Logging?

Traditional log files have limitations. They’re difficult to search, hard to aggregate, and nearly impossible to present to non-technical stakeholders. Database logging transforms logs from debug artifacts into actionable business intelligence.

With database logging, you can:

  • Answer compliance questions instantly: “Who accessed this user’s data in the last 30 days?”
  • Track user behavior patterns: “How often do users change their passwords?”
  • Audit security events: “Show me all failed login attempts today”
  • Debug production issues: “What actions did this user take before the error?”
  • Generate activity reports: “How many users enabled MFA this month?”

Installation and Setup

Getting started takes just three steps:

bash

# 1. Install the package
composer require mattyeend/logging

# 2. Publish the Log model to your application
php artisan vendor:publish --tag=logging-model

# 3. Run the migration to create the logs table
php artisan migrate

The package automatically registers itself through Laravel’s auto-discovery. The published model lives in app/Models/Log.php, giving you full control to customize it for your application.

Basic Usage

The package’s API is intentionally simple. The Log::log() method accepts four parameters:

php

use App\Models\Log;

// Log a user login
Log::log(
    Log::ACTION_LOGIN,                    // Action constant
    ['ip' => request()->ip()],            // Additional metadata
    auth()->id()                          // ID of user performing action
);

// Log updating another user
Log::log(
    Log::ACTION_UPDATE_USER,
    ['fields_changed' => ['email', 'name']],
    auth()->id(),                         // Current user
    $targetUser->id                       // User being updated
);

The metadata parameter accepts any array, which gets stored as JSON. This flexibility lets you capture context-specific information without modifying the database schema.

Predefined Action Constants

The package includes 31 predefined action constants covering authentication, user management, authorization, and error tracking:

Authentication Actions:

  • ACTION_LOGIN – User logged in
  • ACTION_LOGOUT – User logged out
  • ACTION_LOGIN_FAILED – Login attempt failed
  • ACTION_LOGIN_SUCCESS – Successful login
  • ACTION_REGISTER_USER – New user registration
  • ACTION_VERIFY_USER – Email verification completed

User Management:

  • ACTION_CREATE_USER – Created a new user
  • ACTION_UPDATE_USER – Updated user details
  • ACTION_DELETE_USER – Deleted a user
  • ACTION_SHOW_USER – Viewed user profile
  • ACTION_PROFILE_UPDATED – User updated their profile

Security & Authentication:

  • ACTION_CONFIRM_PASSWORD – Password confirmation
  • ACTION_FORGOT_PASSWORD – Password reset initiated
  • ACTION_RESET_PASSWORD – Password reset completed
  • ACTION_PASSWORD_CHANGED – Password changed
  • ACTION_MFA_ENABLED – Enabled multi-factor authentication
  • ACTION_MFA_DISABLED – Disabled multi-factor authentication

Authorization:

  • ACTION_ROLE_ASSIGNED – Assigned role to user
  • ACTION_PERMISSION_GRANTED – Granted permissions
  • ACTION_PERMISSION_REVOKED – Revoked permissions

System Actions:

  • ACTION_CLEAR_CACHE – Cache cleared
  • ACTION_GENERAL_ERROR – General application error
  • ACTION_FOUR_HUNDRED_ERROR – Client error (4xx)
  • ACTION_FIVE_HUNDRED_ERROR – Server error (5xx)

These constants ensure consistency across your application and make queries more reliable.

Model Relationships

The Log model includes two Eloquent relationships:

php

$log = Log::find(1);

// Get the user who performed the action
$actor = $log->loggedInUser;

// Get the user affected by the action
$subject = $log->relatedToUser;

These relationships make it trivial to build audit trails, user activity feeds, or administrator dashboards showing who did what to whom.

Custom Actions

While the predefined actions cover common scenarios, you can log custom actions by using any integer value:

php

// Define your own constants in a config file or class
const ACTION_EXPORT_DATA = 100;
const ACTION_IMPORT_BATCH = 101;

// Use them like predefined actions
Log::log(
    ACTION_EXPORT_DATA,
    ['format' => 'csv', 'records' => 1500],
    auth()->id()
);

This extensibility ensures the package grows with your application’s needs.

Real-World Scenarios

Security Audit Trail

Track all authentication attempts to identify brute force attacks or compromised accounts:

php

// In your LoginController
public function login(Request $request)
{
    $credentials = $request->only('email', 'password');
    
    if (Auth::attempt($credentials)) {
        Log::log(
            Log::ACTION_LOGIN_SUCCESS,
            ['ip' => $request->ip(), 'user_agent' => $request->userAgent()],
            auth()->id()
        );
        return redirect()->intended('dashboard');
    }
    
    Log::log(
        Log::ACTION_LOGIN_FAILED,
        ['email' => $request->email, 'ip' => $request->ip()],
        null // No authenticated user
    );
    return back()->withErrors(['email' => 'Invalid credentials']);
}

Compliance Reporting

Generate GDPR-compliant access logs showing who viewed a user’s data:

php

// When viewing a user profile
public function show(User $user)
{
    Log::log(
        Log::ACTION_SHOW_USER,
        ['viewed_at' => now()],
        auth()->id(),
        $user->id
    );
    
    return view('users.show', compact('user'));
}

// Generate report of all access to a specific user's data
$accessLog = Log::where('related_to_user_id', $userId)
    ->where('action', Log::ACTION_SHOW_USER)
    ->with('loggedInUser')
    ->get();

System Monitoring

Track cache clears to correlate with performance issues:

php

// In your cache management command
Artisan::command('cache:clear', function () {
    Cache::flush();
    Log::log(
        Log::ACTION_CLEAR_CACHE,
        ['cleared_by' => 'artisan'],
        auth()->id() ?? null
    );
})->describe('Clear the application cache');

Package Stats and Adoption

The logging package has been installed 94 times, with 1 GitHub star. The package is actively maintained, with version v1.2.3 released on March 13, 2026. It supports Laravel 10, 11, 12, and 13, ensuring compatibility with both current and future Laravel versions.

With zero open issues, the package demonstrates stability and reliability in production environments.

Development Quality

The package includes comprehensive development dependencies:

  • PHPUnit for testing
  • PHP CS Fixer for code style consistency
  • Faker for generating test data
  • Orchestra Testbench for Laravel-specific testing

You can run the test suite with:

bash

composer install
composer test

This commitment to testing and code quality gives you confidence when deploying to production.

Customization and Extension

Since the Log model is published to your application, you can extend it freely:

php

// In app/Models/Log.php

public function scopeFailedLogins($query)
{
    return $query->where('action', self::ACTION_LOGIN_FAILED);
}

public function scopeToday($query)
{
    return $query->whereDate('created_at', today());
}

// Usage
$todaysFailedLogins = Log::failedLogins()->today()->count();

Add custom attributes, relationships, or scopes to match your application’s specific needs.

Performance Considerations

Database logging is more resource-intensive than file logging. For high-traffic applications, consider:

  • Adding database indexes on frequently queried columns
  • Implementing log rotation to archive old entries
  • Using asynchronous job queues for non-critical logging
  • Monitoring table growth and planning retention policies

The flexibility of database logging lets you implement these optimizations as your application scales.

The Bottom Line

The mattyeend/logging package transforms logging from a debugging tool into a business asset. By storing logs as structured data, you gain query ability, reporting capabilities, and audit trails that file-based logging simply cannot provide.

For applications requiring compliance, security audits, or detailed user activity tracking, this package provides the foundation you need. The combination of predefined actions, flexible metadata storage, and relationship tracking covers the vast majority of logging scenarios while remaining extensible for custom needs.

At 94 installs and counting, this package represents a proven solution for Laravel applications that take logging seriously.


Package Stats:

  • Installs: 94
  • Stars: 1
  • Open Issues: 0
  • License: MIT
  • Latest Version: v1.2.3

Links: