A Laravel package for capturing and tracking HTTP requests with configurable storage drivers and filtering options.
HookShot provides middleware-based HTTP request tracking for Laravel applications. It captures request/response data and stores it using database, cache, or file storage drivers with configurable filtering and performance controls.
How it works: The middleware captures request data during the request lifecycle and stores the complete
request/response information during Laravel's terminate
phase, ensuring your application's response time is not
affected by the logging process.
- 🔍 Debug Issues - Reproduce bugs by seeing exactly what requests caused them
- 📊 Analytics - Track API usage patterns, popular endpoints, and user behavior
- 🛡️ Security - Monitor suspicious requests and track authentication attempts
- đź“‹ Compliance - Meet audit requirements with comprehensive request logging
- ⚡ Performance - Identify slow endpoints and optimize request handling
- 🔌 API Monitoring - Track external API integrations and webhook deliveries
- PHP 8.2+
- Laravel 11.x, 12.x
Install via Composer:
composer require vildanbina/hookshot
Publish configuration:
php artisan vendor:publish --tag=hookshot-config
Run migrations for database storage:
php artisan migrate
Manual Registration (Recommended)
Apply to specific routes:
Route::middleware('track-requests')->group(function () {
Route::get('/api/users', [UserController::class, 'index']);
Route::post('/api/users', [UserController::class, 'store']);
});
Global Registration (Laravel 11+)
Add to bootstrap/app.php
:
->withMiddleware(function (Middleware $middleware) {
$middleware->append(\VildanBina\HookShot\Middleware\TrackRequestsMiddleware::class);
})
use VildanBina\HookShot\Facades\RequestTracker;
// Get all recent requests
$requests = RequestTracker::get(50);
// Find specific request by ID
$request = RequestTracker::find('uuid-here');
// Get requests with database driver (supports advanced queries)
$slowRequests = RequestTracker::query()
->where('execution_time', '>', 2.0)
->where('response_status', '>=', 400)
->get();
// Filter by date range
$todayRequests = RequestTracker::query()
->whereDate('timestamp', today())
->get();
Listen to request capture events:
use VildanBina\HookShot\Events\RequestCaptured;
use Illuminate\Support\Facades\Event;
Event::listen(RequestCaptured::class, function (RequestCaptured $event) {
$request = $event->request;
$requestData = $event->requestData;
// Do something with the request and request data
});
Storage Drivers:
- Database: Full query support with Eloquent models
- Cache: In-memory storage with configurable TTL
- File: JSON or raw format file logging
- Custom: Implement your own storage driver
Filtering & Sampling:
- Path exclusion patterns
- User agent filtering
- Configurable sampling rates
- Content-type based exclusions
Performance Controls:
- Request/response payload size limits
- Queue-based processing support
- Automatic data retention cleanup
Security:
- Sensitive header filtering
- Authentication data redaction
- Configurable data sanitization
All configuration options with their purposes:
<?php
declare(strict_types=1);
return [
/*
|--------------------------------------------------------------------------
| HookShot Request Tracking
|--------------------------------------------------------------------------
|
| This file contains the configuration options for HookShot request tracking.
| You can enable/disable tracking, choose storage drivers, and configure
| filtering options to control what gets tracked.
|
*/
// Enable or disable request tracking globally
'enabled' => env('HOOKSHOT_ENABLED', true),
// Default storage driver: 'database', 'cache', or 'file'
'default' => env('HOOKSHOT_DRIVER', 'database'),
/*
|--------------------------------------------------------------------------
| Storage Drivers
|--------------------------------------------------------------------------
|
| Configure how and where request data is stored. Each driver has its own
| settings for connection, retention, and other storage-specific options.
|
*/
'drivers' => [
'database' => [
'connection' => env('HOOKSHOT_DB_CONNECTION'),
'table' => env('HOOKSHOT_TABLE', 'hookshot_logs'),
'retention_days' => 30,
],
'cache' => [
'store' => env('HOOKSHOT_CACHE_STORE'),
'prefix' => 'hookshot',
'retention_days' => 7,
'max_index_size' => 10000,
],
'file' => [
'path' => storage_path('app/hookshot'),
'format' => 'json', // json or raw
'retention_days' => 30,
],
],
/*
|--------------------------------------------------------------------------
| Exclusion Filters
|--------------------------------------------------------------------------
|
| Define which requests should be excluded from tracking to reduce noise
| and focus on meaningful application requests.
|
*/
// Paths to exclude from tracking (health checks, admin panels, etc.)
'excluded_paths' => [
'health-check',
'up',
'_debugbar/*',
'telescope/*',
'horizon/*',
'pulse/*',
],
// User agents to exclude (monitoring tools, bots, crawlers)
'excluded_user_agents' => [
'pingdom',
'uptimerobot',
'googlebot',
'bingbot',
],
/*
|--------------------------------------------------------------------------
| Performance Controls
|--------------------------------------------------------------------------
|
| Configure performance-related settings to manage resource usage and
| ensure tracking doesn't impact application performance.
|
*/
// Percentage of requests to track (1.0 = 100%, 0.5 = 50%, etc.)
'sampling_rate' => env('HOOKSHOT_SAMPLING_RATE', 1.0),
// Maximum size of request payload to store (in bytes)
'max_payload_size' => 65536, // 64KB
// Maximum size of response body to store (in bytes)
'max_response_size' => 10240, // 10KB
// Queue request tracking for better performance
'use_queue' => env('HOOKSHOT_USE_QUEUE', false),
/*
|--------------------------------------------------------------------------
| Security Settings
|--------------------------------------------------------------------------
|
| Configure security-related settings for request tracking to ensure
| sensitive data is properly filtered and protected.
|
*/
// Headers to filter/redact in request and response tracking
'sensitive_headers' => [
'authorization',
'cookie',
'set-cookie',
'x-api-key',
'x-auth-token',
'x-csrf-token',
'x-xsrf-token',
],
/*
|--------------------------------------------------------------------------
| Response Capture Settings
|--------------------------------------------------------------------------
|
| Configure which responses should be captured and stored for analysis.
| These settings help control what response data is worth storing.
|
*/
// Enable or disable response header capture (saves database space)
'capture_response_headers' => env('HOOKSHOT_CAPTURE_RESPONSE_HEADERS', true),
// Enable or disable response body capture (saves significant database space)
'capture_response_body' => env('HOOKSHOT_CAPTURE_RESPONSE_BODY', true),
// Content types to exclude from response body capture (prefix matching)
'excluded_content_types' => [
'image/',
'video/',
'audio/',
'application/pdf',
'application/zip',
'application/octet-stream',
],
// HTTP status codes that are considered important to capture
'important_status_codes' => [
200, // OK
201, // Created
400, // Bad Request
401, // Unauthorized
403, // Forbidden
404, // Not Found
422, // Unprocessable Entity
500, // Internal Server Error
],
];
Remove old tracking data based on retention settings:
# Clean using default settings
php artisan hookshot:cleanup
# Clean specific driver
php artisan hookshot:cleanup --driver=database
# Dry run to see what would be deleted
php artisan hookshot:cleanup --dry-run
- Best for queryable, persistent data
- Supports complex filtering and relationships
- Automatic cleanup via retention settings
- Fastest performance for temporary data
- Good for high-traffic applications
- Limited querying capabilities
- Good for development and debugging
- Human-readable storage format
- No database dependencies
You can create custom storage drivers to integrate with your own storage systems or services. Custom drivers must implement the StorageDriverContract
.
<?php
namespace App\HookShot\Drivers;
use Illuminate\Support\Collection;
use VildanBina\HookShot\Contracts\StorageDriverContract;
use VildanBina\HookShot\Data\RequestData;
class CustomApiDriver implements StorageDriverContract
{
public function __construct(array $config = [])
{
// Initialize your driver with config (API keys, endpoints, etc.)
}
public function store(RequestData $requestData): bool
{
// Store the request data to your storage system
// Return true on success, false on failure
}
public function find(string $id): ?RequestData
{
// Find and return a specific request by ID
// Return null if not found
}
public function get(int $limit = 100): Collection
{
// Get multiple requests with the given limit
// Return Collection of RequestData objects
}
public function delete(string $id): bool
{
// Delete a specific request by ID
// Return true if deleted, false otherwise
}
public function cleanup(): int
{
// Clean up old requests based on retention policy
// Return number of deleted requests
}
public function isAvailable(): bool
{
// Check if your storage system is available
// Return true if operational, false otherwise
}
}
Add your custom driver to the configuration file:
// config/hookshot.php
'default' => 'custom',
'drivers' => [
// other drivers
'custom' => [
'via' => \App\HookShot\Drivers\CustomApiDriver::class,
'endpoint' => env('CUSTOM_ENDPOINT', 'https://api.example.com'),
'api_key' => env('CUSTOM_KEY'),
],
],
The via
key tells HookShot which class to use for this driver. The entire config array (including the via
key) is passed to your driver's constructor.
Each tracked request includes:
[
'id' => 'uuid',
'method' => 'POST',
'url' => 'https://app.com/api/users',
'path' => 'api/users',
'headers' => ['accept' => ['application/json']],
'payload' => ['name' => 'John', 'email' => '[email protected]'],
'ip' => '192.168.1.1',
'user_agent' => 'Mozilla/5.0...',
'user_id' => 123,
'timestamp' => '2024-01-15T10:30:00Z',
'execution_time' => 0.250,
'response_status' => 201,
'response_body' => ['id' => 456, 'name' => 'John'],
]
- High Traffic: Set
sampling_rate
to 0.1 (10%) or lower for production - Heavy Workloads: Enable
use_queue
to process tracking asynchronously - Memory Management: Limit
max_payload_size
andmax_response_size
based on your needs - Reduce Noise: Use
excluded_paths
for health checks, admin routes, and static assets - Storage Optimization: Configure
retention_days
for automatic cleanup of old data - Database Space: Disable response capture to save significant storage space:
- Set
capture_response_headers
to false in order to disable response header capture - Set
capture_response_body
to false in order to disable response body capture - Both can be individually controlled based on your storage and debugging needs
- Set
See CONTRIBUTING for details.
Please e-mail [email protected] to report any security vulnerabilities instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.