Installation Require the package via Composer (note: this is for Guzzle 3.x, which is deprecated):
composer require guzzle/log
For Laravel projects, prioritize Guzzle 6/7.x and use alternatives like guzzlehttp/logger-middleware.
Basic Setup Integrate with Guzzle 3.x’s client by passing a PSR-3 logger (e.g., Monolog):
use Guzzle3\Log\LogAdapter;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$logger = new Logger('guzzle');
$logger->pushHandler(new StreamHandler('php://stdout', Logger::DEBUG));
$logAdapter = new LogAdapter($logger);
$client = new Guzzle3\Client(['logger' => $logAdapter]);
First Use Case Log HTTP requests/responses for debugging:
$response = $client->get('https://api.example.com/data');
// Logs appear in stdout with request/response details.
Laravel Integration Use Laravel’s Monolog instance with the adapter:
$client = new Guzzle3\Client([
'logger' => new LogAdapter(app('log')->getMonolog())
]);
Conditional Logging Disable logging in production by adjusting the logger level:
$logger->setLevel(env('APP_DEBUG') ? Logger::DEBUG : Logger::ERROR);
Custom Log Context
Extend LogAdapter to add metadata (e.g., request IDs):
class CustomLogAdapter extends LogAdapter {
public function log($level, $message, array $context = []) {
$context['request_id'] = request()->header('X-Request-ID');
parent::log($level, $message, $context);
}
}
Log to External Services Route logs to Sentry or ELK via Monolog handlers:
$logger->pushHandler(new \Sentry\Monolog\Handler(
Sentry::getClient(),
Sentry\State\ScopeCallback::LEVEL_ERROR
));
Service Provider Binding
Bind the Guzzle client with logging in AppServiceProvider:
public function register() {
$this->app->singleton('guzzle.client', function ($app) {
$logger = $app['log']->getMonolog();
return new Guzzle3\Client([
'logger' => new LogAdapter($logger)
]);
});
}
Queue Job Logging Log HTTP calls in queued jobs:
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
class ProcessPaymentJob implements Queueable, SerializesModels {
public function handle() {
$client = app('guzzle.client');
$response = $client->post('https://payment-gateway.com/charge', [...]);
}
}
Guzzle 3.x Deprecation
guzzlehttp/logger-middleware or Laravel’s HttpClient.Log Bloat
$logger->pushProcessor(function (array $record) {
$record['context']['body'] = substr($record['context']['body'], 0, 200) . '...';
return $record;
});
Sensitive Data Leaks
class SecureLogAdapter extends LogAdapter {
public function log($level, $message, array $context = []) {
unset($context['request']['headers']['authorization']);
parent::log($level, $message, $context);
}
}
Performance in High-Load Environments
$logger->pushHandler(new \Monolog\Handler\AsyncHandler(
new \Monolog\Handler\StreamHandler('php://stderr')
));
Verify Logger Integration Check if logs appear by testing a simple request:
$client->get('https://httpbin.org/get'); // Should log request/response.
Check Monolog Configuration
Ensure Laravel’s logging.php routes Guzzle logs correctly:
'channels' => [
'guzzle' => [
'driver' => 'single',
'path' => storage_path('logs/guzzle.log'),
'level' => 'debug',
],
],
Handle Binary Data Guzzle 3.x may log binary payloads as base64. Use a custom adapter to decode:
class BinaryLogAdapter extends LogAdapter {
public function log($level, $message, array $context = []) {
if (isset($context['request']['body'])) {
$context['request']['body'] = base64_decode($context['request']['body']);
}
parent::log($level, $message, $context);
}
}
Custom Log Formatters
Override LogAdapter to format logs as JSON:
class JsonLogAdapter extends LogAdapter {
public function log($level, $message, array $context = []) {
$log = [
'timestamp' => date('c'),
'level' => $level,
'message' => $message,
'context' => $context,
];
parent::log($level, json_encode($log), []);
}
}
Dynamic Logger Levels Adjust log levels based on environment:
$logAdapter = new LogAdapter($logger);
$logAdapter->setLevel(env('GUZZLE_LOG_LEVEL', Logger::WARNING));
Integration with Laravel Events Trigger events on log entries:
$logger->pushHandler(new class extends AbstractProcessingHandler {
protected function processRecord($record) {
if ($record['level'] === Logger::ERROR) {
event(new GuzzleLogError($record));
}
}
});
Queue Job Logging
Logs from queued jobs may appear out of order. Use request_id for correlation:
$logger->pushProcessor(function ($record) {
$record['extra']['request_id'] = Str::uuid()->toString();
return $record;
});
Horizon Queue Monitoring Combine with Laravel Horizon to track failed jobs with logged HTTP errors.
Telescope Integration Forward Guzzle logs to Laravel Telescope for real-time inspection:
$logger->pushHandler(new \Laravel\Telescope\Handlers\LogHandler());
How can I help you explore Laravel packages today?