rtheunissen/guzzle-log-middleware
Lightweight Guzzle middleware for logging HTTP requests and responses. Capture method, URL, headers, body, status and timing, and route logs through PSR-3/Monolog with configurable formats, levels, and filtering—ideal for debugging and auditing API traffic.
Installation Add the package via Composer:
composer require rtheunissen/guzzle-log-middleware
Basic Usage Import the middleware and attach it to your Guzzle client:
use RTheunissen\GuzzleLogMiddleware\GuzzleLogMiddleware;
$client = new \GuzzleHttp\Client([
'middleware' => [
new GuzzleLogMiddleware(),
],
]);
First Use Case Log a simple GET request to debug API responses:
$response = $client->get('https://api.example.com/users');
// Check Laravel logs for request/response details
Logging All Requests
Attach the middleware globally in Laravel’s AppServiceProvider:
public function boot()
{
$this->app->extend('http-client', function ($client) {
$client->getEmitter()->attach(
new GuzzleLogMiddleware()
);
return $client;
});
}
Conditional Logging Use middleware options to filter logs (e.g., by HTTP method or URL):
$middleware = new GuzzleLogMiddleware([
'log_request' => true,
'log_response' => true,
'log_body' => true,
'exclude' => ['/health', '/ping'],
]);
Custom Logging Channels Override the default logger (e.g., Monolog) by binding a custom handler:
$client->getEmitter()->attach(
new GuzzleLogMiddleware(['logger' => app('custom-logger')])
);
Logging in API Services Wrap Guzzle calls in a service class:
class ApiService {
protected $client;
public function __construct(\GuzzleHttp\Client $client)
{
$this->client = $client->withMiddleware(
new GuzzleLogMiddleware()
);
}
public function fetchUsers()
{
return $this->client->get('/users')->getBody();
}
}
Performance Overhead
exclude patterns for non-critical endpoints.$middleware = new GuzzleLogMiddleware(['enabled' => env('APP_DEBUG')]);
Sensitive Data Leaks
$middleware = new GuzzleLogMiddleware(['log_body' => false]);
Str::mask()).Log Format Inconsistencies
log config or override the logger:
$middleware = new GuzzleLogMiddleware([
'logger' => \Monolog\Logger::create('guzzle', [
new \Monolog\Formatter\LineFormatter(
"[%datetime%] %level_name%: %message%\n%context%\n"
)
])
]);
Middleware Order Matters
GuzzleLogMiddleware after error-handling middleware to avoid masking exceptions:
$stack = \GuzzleHttp\HandlerStack::create();
$stack->push(\GuzzleHttp\Middleware::retry(), 'retry');
$stack->push(new GuzzleLogMiddleware(), 'log'); // Log after retries
Verify Middleware Attachment
Check if the middleware is active by inspecting the HandlerStack:
dd($client->getConfig('handler')->getMiddleware());
Log Levels
Adjust Monolog’s log level (e.g., debug for Guzzle logs):
'channels' => [
'guzzle' => [
'driver' => 'single',
'level' => 'debug',
],
],
Exclude Specific Requests
Use regex in exclude to skip internal calls:
$middleware = new GuzzleLogMiddleware([
'exclude' => ['/internal/.*', 'localhost']
]);
Custom Context Data Add request IDs or user context:
$request = $client->get('...', [
'on_stats' => function ($result) {
$result['request_id'] = Str::uuid()->toString();
}
]);
Pre/Post-Processing Extend the middleware by subclassing:
class CustomGuzzleLogMiddleware extends GuzzleLogMiddleware {
public function __construct(array $options = [])
{
parent::__construct($options);
}
protected function logRequest($request, $options)
{
// Add custom logic (e.g., enrich context)
$options['context']['custom_field'] = 'value';
parent::logRequest($request, $options);
}
}
Integrate with Laravel Debugbar
Use barryvdh/laravel-debugbar to display Guzzle logs in the debug panel:
$middleware = new GuzzleLogMiddleware([
'logger' => \Debugbar::getMessageCollector('guzzle')
]);
How can I help you explore Laravel packages today?