laravel-logpilot maintained by maksudur-dev
Laravel LogPilot
A lightweight Laravel activity logging package that improves debugging, tracing, and business-event visibility while using Laravel's EXISTING logging system or a database.
Key Features
- Request Tracing: Group multiple logs under a single
log_idautomatically. - Dual Drivers: Support for Laravel Logs, Database, or both.
- Auto-Context: Automatically captures User ID, IP, URL, and Method.
- Model Support: Easily associate activities with Eloquent models.
- API Support: Optional API endpoints to view activity logs.
- Artisan Commands: Install, prune, and test your setup easily.
- Laravel 8-13 & PHP 8.1+: Compatible with Laravel 8, 9, 10, 11, 12, and 13.
- Lightweight: Zero-config by default, minimal overhead.
Installation
You can install the package via composer:
composer require maksudur-dev/laravel-logpilot
Run the installation command:
php artisan activity:install
If you are using the database driver, run the migrations:
php artisan migrate
Updating Package
To update the package to the latest version (v1.0.3):
composer update maksudur-dev/laravel-logpilot
Or target the version explicitly:
composer require maksudur-dev/laravel-logpilot:^1.0.3
If you are developing locally with a path repository in composer.json, simply run:
composer update maksudur-dev/laravel-logpilot
Configuration
The configuration file is located at config/logpilot.php.
return [
'enabled' => env('LOGPILOT_ENABLED', true),
'driver' => env('LOGPILOT_DRIVER', 'log'), // log, database, both
'channel' => env('LOGPILOT_CHANNEL', null), // default log channel
'auto_group_id' => true,
'store_request_context' => true,
'api_enabled' => env('LOGPILOT_API_ENABLED', false),
'queue' => env('LOGPILOT_QUEUE', false),
'retention_days' => 30,
];
Usage
1. Global Helper (Quickest)
activity('user_login');
// With details
activity('profile_updated', $user, 'User updated their profile photo');
// With array message (automatically cast to JSON)
activity('api_response', null, [
'status' => 'success',
'data' => ['id' => 1]
]);
// Full control
activity(
action: 'withdraw_request',
model: $user,
message: 'Gateway timeout',
level: 'error',
meta: ['amount' => 500]
);
2. Eloquent Trait (Recommended for Models)
Add the LogsActivity trait to your models:
use LaravelLogPilot\Traits\LogsActivity;
class Order extends Model
{
use LogsActivity;
}
// Now you can do:
$order->logActivity('shipped', 'Order has been shipped to customer');
// Retrieve logs for this model:
$logs = $order->activities;
3. Service Usage
Inject the ActivityLogger service into your classes:
use LaravelLogPilot\Services\ActivityLogger;
class PaymentService
{
public function __construct(protected ActivityLogger $logger) {}
public function process()
{
$this->logger->log('payment_started');
}
}
4. Grouping Related Logs (Tracing)
Perfect for complex flows like checkouts or background jobs:
activity_group('checkout_flow_001');
activity('cart_validated');
activity('payment_processing');
activity('order_created'); // All will share log_id: checkout_flow_001
5. Clean Architecture (DTOs, Enums & Services)
LogPilot uses Clean Architecture patterns out-of-the-box. You can leverage Enums, DTOs, and Services in your application:
Enums
use LaravelLogPilot\Enums\LogLevel;
use LaravelLogPilot\Enums\ActivityAction;
activity(
action: ActivityAction::UPDATED->value,
message: 'User profile updated',
level: LogLevel::WARNING
);
ActivityService & DTOs
use LaravelLogPilot\Services\ActivityService;
use LaravelLogPilot\DataTransferObjects\ActivityQueryDTO;
class ActivityReportController
{
public function __construct(protected ActivityService $activityService) {}
public function index(Request $request)
{
$dto = ActivityQueryDTO::fromRequest($request);
$paginatedLogs = $this->activityService->getPaginatedLogs($dto);
return response()->json($paginatedLogs);
}
}
Encapsulated Model Query Methods
use LaravelLogPilot\Models\ActivityLog;
// Filtered logs via DTO
$logs = ActivityLog::fetchFiltered($queryDTO);
// Grouped trace logs by log_id
$traceLogs = ActivityLog::fetchByGroup('checkout_flow_001');
// Logs for a specific Eloquent model
$modelLogs = ActivityLog::fetchForModel(User::class, 1, perPage: 15);
Frontend Integration (Vue/React Example)
Since LogPilot provides an API, you can easily build a "Recent Activity" component.
Example Vue Component
<template>
<div class="activity-feed">
<div v-for="log in logs" :key="log.id" class="log-item">
<span class="badge" :class="log.level">{{ log.action }}</span>
<p v-if="typeof log.message === 'string'">{{ log.message }}</p>
<pre v-else>{{ JSON.stringify(log.message, null, 2) }}</pre>
<small>{{ formatDate(log.created_at) }}</small>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
const props = defineProps(['modelType', 'modelId']);
const logs = ref([]);
onMounted(async () => {
const response = await fetch(`/api/activity-logs/model/${props.modelType}/${props.modelId}`);
const data = await response.json();
logs.value = data.data;
});
</script>
Example React Component
import React, { useState, useEffect } from 'react';
const ActivityFeed = ({ modelType, modelId }) => {
const [logs, setLogs] = useState([]);
useEffect(() => {
fetch(`/api/activity-logs/model/${modelType}/${modelId}`)
.then(res => res.json())
.then(data => setLogs(data.data));
}, [modelType, modelId]);
return (
<div className="activity-feed">
{logs.map(log => (
<div key={log.id} className={`log-item ${log.level}`}>
<span className="badge">{log.action}</span>
{typeof log.message === 'object' ? (
<pre>{JSON.stringify(log.message, null, 2)}</pre>
) : (
<p>{log.message}</p>
)}
<small>{new Date(log.created_at).toLocaleString()}</small>
</div>
))}
</div>
);
};
export default ActivityFeed;
Example Blade Component
If you prefer server-side rendering, you can pass logs to a Blade component:
{{-- In your controller --}}
$logs = $order->activities()->paginate(10);
return view('orders.show', compact('order', 'logs'));
{{-- In orders/show.blade.php --}}
<div class="activity-feed">
@foreach($logs as $log)
<div class="log-item {{ $log->level }}">
<strong>{{ $log->action }}</strong>
<div>
@if(is_array($log->message))
<pre>{{ json_encode($log->message, JSON_PRETTY_PRINT) }}</pre>
@else
{{ $log->message }}
@endif
</div>
<small>{{ $log->created_at->diffForHumans() }}</small>
</div>
@endforeach
{{ $logs->links() }}
</div>
API Support
LogPilot exposes clean, JSON-ready endpoints with comprehensive search, filtering, and pagination support:
GET /api/activity-logs: List and filter activity logs.GET /api/activity-logs/levels: Get all log levels formatted for frontend select/dropdown inputs.GET /api/activity-logs/trace/{log_id}: Trace a full request lifecycle bylog_id.GET /api/activity-logs/model/{type}/{id}: Activity for a specific resource.
Query Parameters & Filtering (GET /api/activity-logs)
You can pass query parameters to filter, search, and paginate logs:
| Parameter | Type | Description | Example |
|---|---|---|---|
search / q / query |
string |
Search across action, message, url, log_id, ip, and model_type fields. |
?search=Failed |
level |
string |
Filter by log level (case-insensitive: error, warning, info, debug, critical, alert, emergency, notice). Pass all or empty to include all levels. |
?level=Error |
action |
string |
Filter by exact action name. | ?action=USER_LOGIN |
user_id |
mixed |
Filter logs for a specific User ID. | ?user_id=42 |
log_id |
string |
Filter logs by trace ID (log_id). |
?log_id=c2753c6f-6f06-... |
model_type |
string |
Filter logs for a specific model class. | ?model_type=App\Models\User |
model_id |
mixed |
Filter logs for a specific model ID. | ?model_id=5 |
start_date / date_from / from |
date |
Filter logs created on or after date/time. | ?start_date=2026-08-01 |
end_date / date_to / to |
date |
Filter logs created on or before date/time. | ?end_date=2026-08-14 |
per_page |
integer |
Results per page (default: 20, max: 500). |
?per_page=50 |
page |
integer |
Page number for pagination (default: 1). |
?page=2 |
Filtering Example
GET /api/activity-logs?search=Reward&level=Error&per_page=20&page=1
Artisan Commands
php artisan activity:install: Setup everything.php artisan activity:prune: Cleanup old logs.php artisan activity:test: Verify installation.
License
The MIT License (MIT). Please see License File for more information.