Installation:
composer require aminin/airbrake-bundle
Ensure your composer.json meets the PHP (7.2+) and Symfony (3.4+) requirements.
Enable the Bundle:
Add to config/bundles.php (Symfony 4+):
return [
// ...
Ami\AirbrakeBundle\AmiAirbrakeBundle::class => ['all' => true],
];
Configure:
Add to config/packages/ami_airbrake.yaml:
ami_airbrake:
project_id: YOUR_PROJECT_ID
project_key: "%env(AIRBRAKE_API_KEY)%" # Use env vars for security
First Use Case: The bundle auto-captures exceptions. Test by throwing an exception in a controller:
throw new \RuntimeException("Test error for Airbrake");
Verify the error appears in your Airbrake dashboard.
Exception Handling:
kernel.exception event. No manual intervention is needed for most use cases.config/packages/ami_airbrake.yaml:
ami_airbrake:
ignored_exceptions: ["Symfony\Component\HttpKernel\Exception\NotFoundHttpException"]
Manual Notifications:
Use the ami_airbrake.notifier service to send custom errors:
$notifier = $this->get('ami_airbrake.notifier');
$notifier->notify(new \RuntimeException("Custom error"), [
'context' => ['user_id' => 123],
]);
Filtering Notices: Modify notices before they’re sent via a filter:
# config/services.yaml
services:
Ami\AirbrakeBundle\EventListener\ExceptionListener:
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
calls:
- [addFilter, ['@my_airbrake_filter']]
// src/Service/MyAirbrakeFilter.php
class MyAirbrakeFilter {
public function __invoke($notice) {
$notice['context']['custom_data'] = 'value';
return $notice;
}
}
Environment-Specific Config:
Use Symfony’s environment variables or %kernel.environment% to toggle Airbrake:
# config/packages/dev/ami_airbrake.yaml
ami_airbrake:
project_key: null # Disable in dev
Shutdown Listener:
Capture fatal errors (e.g., PHP notices) via the ShutdownListener (enabled by default). Disable if needed:
ami_airbrake:
shutdown_listener: false
Ignored Exceptions:
HttpException. Override cautiously—logging 404s/500s may flood Airbrake.AccessDeniedException:
ami_airbrake:
ignored_exceptions: []
Performance Impact:
# config/packages/test/ami_airbrake.yaml
ami_airbrake:
project_key: null
Sensitive Data:
$notifier->addFilter(function ($notice) {
unset($notice['context']['password']);
return $notice;
});
Errbit Host Configuration:
host is correctly set (e.g., http://errbit.example.com).curl -v http://errbit.example.com/api/v3/projects/YOUR_ID/notices.Symfony 5+ Deprecations:
Verify Configuration: Dump the notifier service to confirm settings:
$notifier = $this->get('ami_airbrake.notifier');
dump($notifier->getOptions());
Check Network Requests:
Use a proxy (e.g., Charles) or stderr logging to inspect Airbrake API calls:
ami_airbrake:
host: "http://localhost:8000" # Errbit dev server
Test Locally:
docker-compose up errbit
http://localhost:3000.Log Levels:
# config/packages/dev/monolog.yaml
monolog:
handlers:
main:
level: debug
include_stacktraces: true
Custom Notifier:
Extend the default Airbrake\Notifier to add logic:
class CustomNotifier extends \Airbrake\Notifier {
public function notify($exception, array $context = []) {
$context['custom_metric'] = 'value';
return parent::notify($exception, $context);
}
}
Register as a service:
services:
ami_airbrake.notifier:
class: App\Service\CustomNotifier
arguments:
- "%ami_airbrake.project_id%"
- "%ami_airbrake.project_key%"
- "%ami_airbrake.host%"
Event Subscribers:
Listen to kernel.exception or kernel.request to enrich notices:
class AirbrakeSubscriber implements EventSubscriberInterface {
public static function getSubscribedEvents() {
return [
KernelEvents::EXCEPTION => 'onKernelException',
];
}
public function onKernelException(GetResponseForExceptionEvent $event) {
$notifier = $this->container->get('ami_airbrake.notifier');
$notifier->notify($event->getThrowable(), [
'context' => ['request_id' => $event->getRequest()->get('request_id')],
]);
}
}
Batch Processing: For high-volume apps, batch notices to reduce API calls:
$notifier->addFilter(function ($notice) use (&$batch) {
$batch[] = $notice;
if (count($batch) >= 10) {
$this->sendBatch($batch);
$batch = [];
}
return null; // Prevent default sending
});
How can I help you explore Laravel packages today?