aping/laravel-alarm
Laravel package for sending alarms/notifications from exceptions, logs, or custom events. Includes DingTalk robot handler with signature support, configurable event-to-alarm mapping, localization, and queued delivery via laravel-alarm queue. Mail, rate limit, and tests are planned.
Installation
composer require aping/laravel-alarm
Publish the config file:
php artisan vendor:publish --provider="Aping\LaravelAlarm\AlarmServiceProvider"
Publish migrations:
php artisan vendor:publish --provider="Aping\LaravelAlarm\AlarmServiceProvider" --tag="migrations"
Run migrations:
php artisan migrate
Basic Setup
config/alarm.php (e.g., alarms array, default alarm).app/Providers/AlarmServiceProvider.php (or a custom provider):
public function boot()
{
Alarm::create('order_processing_failed', 'Order Processing Failed')
->description('An order failed to process.')
->severity('high')
->notifyVia('email', 'slack');
}
First Use Case: Triggering an Alarm
use Aping\LaravelAlarm\Facades\Alarm;
// Trigger an alarm with context
Alarm::trigger('order_processing_failed', [
'order_id' => 123,
'user_email' => 'customer@example.com',
]);
Dynamic Alarm Creation Useful for plugins or modular apps where alarms are defined at runtime:
$alarm = Alarm::create('dynamic_alarm', 'Dynamic Event')
->description('Triggered dynamically.')
->severity('medium')
->notifyVia('email');
Conditional Alarm Triggering
Integrate with Laravel’s if statements or services:
if ($order->isFailed()) {
Alarm::trigger('order_processing_failed', ['order_id' => $order->id]);
}
Custom Notifications
Extend the AlarmNotification class to add logic (e.g., enriching payloads):
use Aping\LaravelAlarm\Notifications\AlarmNotification;
class CustomAlarmNotification extends AlarmNotification
{
public function toMail($notifiable)
{
return (new MailMessage)
->subject("ALERT: {$this->alarm->name}")
->line($this->alarm->description)
->line("Order ID: {$this->context['order_id']}");
}
}
Register it in config/alarm.php under notifications.
Scheduled Alarm Checks Use Laravel’s scheduler to periodically check for unresolved alarms:
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
$schedule->command('alarm:check')->daily();
}
Grouping Alarms Tag alarms for filtering (e.g., by team or system):
Alarm::create('payment_failed', 'Payment Failed')
->tags(['finance', 'high-risk'])
->notifyVia('email', 'pagerduty');
Log facade to log alarm triggers for auditing.Alarm::fake() in PHPUnit to assert alarms were triggered:
public function test_alarm_triggered()
{
Alarm::fake();
$this->triggerAlarm();
Alarm::assertTriggered('order_processing_failed');
}
Missing Migrations
Forgetting to run php artisan migrate after publishing will break alarm storage.
Fix: Always run migrations post-installation.
Notification Failures
If notifyVia() channels fail silently, check:
php artisan queue:work).Alarm::trigger()->withContext(['debug' => true]) to log raw payloads.Severity Overrides
The severity field is stored but not enforced by the package. Implement custom logic (e.g., route high-severity alarms to a dedicated channel) in a service class.
Context Data Limits
The context array is stored as JSON in the database. Avoid nesting deeply or storing large payloads (e.g., entire objects). Use IDs or hashes instead.
Race Conditions
Concurrent triggers for the same alarm may cause duplicate notifications. Use Laravel’s queue option to dedupe:
Alarm::trigger('alarm_name')->queue();
DB::enableQueryLog();
Alarm::trigger('test');
dd(DB::getQueryLog());
dd(\Aping\LaravelAlarm\Models\Alarm::all()->toArray());
// In a custom notification class
\Log::debug('Alarm payload', $this->context);
Custom Storage
Override the Alarm model to use a different database or cache layer (e.g., Redis):
// app/Providers/AppServiceProvider.php
public function boot()
{
$this->app->singleton(\Aping\LaravelAlarm\Models\Alarm::class, function () {
return new CustomAlarmModel();
});
}
Webhook Endpoints Create a route to fetch unresolved alarms for external systems:
Route::get('/api/alarms', function () {
return response()->json(Alarm::unresolved()->get());
});
Acknowledgment Workflow
Extend the Alarm model to add acknowledge() and resolve() methods:
// app/Models/Alarm.php
public function acknowledge(User $user)
{
$this->update(['acknowledged_at' => now(), 'acknowledged_by' => $user->id]);
}
Slack/Teams Integrations
Use Laravel’s via() method to add rich formatting:
Alarm::create('deployment_failed', 'Deployment Failed')
->notifyVia('slack', function ($notifiable, $context) {
return (new SlackMessage)
->content("*:rotating_light: {$context['message']} *:rotating_light:")
->attachment([
'title' => 'Deployment Failed',
'fields' => [
['value' => 'Repo: ' . $context['repo'], 'short' => true],
['value' => 'Branch: ' . $context['branch'], 'short' => true],
],
]);
});
How can I help you explore Laravel packages today?