Example: Use a ZendHQ monitoring webhook to send an email
One use case for ZendHQ monitoring webhooks is to send pro-active notifications to DevOps staff. A common integration is to send these to an email address monitored by IT or DevOps personnel.
This example demonstrates a webhook that will react to ZendHQ warning and critical events, and send an email. The webhook handler is written using PHP 8.1, and uses the following libraries:
- symfony/mailer, a library for sending emails from PHP. The example DOES NOT detail how to configure the mail transport (represented by Symfony\Component\Mailer\MailerInterface); refer to the library documentation for details on configuring a mail transport.
- a PSR-15 request handler responding to the webhook; it makes the assumption that previous middleware has parsed the JSON response into the "parsed body" of the request.
- a PSR-17 HTTP response factory to send a 204 response on receipt.
<?php
declare(strict_types=1);
namespace App\Handler;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Throwable;
class EmailWebhookHandler implements RequestHandlerInterface
{
private const SEVERITIES = [
'warning',
'critical',
];
public function __construct(
private MailerInterface $mailer,
private ResponseFactoryInterface $responseFactory,
) {
}
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$response = $this->responseFactory->createResponse(204);
$event = $request->getParsedBody();
if (! isset($event['severity']) || ! in_array($event['severity'], self::SEVERITIES, true)) {
return $response;
}
$mail = (new Email())
->from('it-noreply@example.com')
->to('it-triage@example.com')
->subject("[{$event['severity']}] {$event['name']}")
->text(<<<END
A monitoring event with severity {$event['severity']} occurred.
- Event type: {$event['name']}
- Server: {$event['request']['node_name']}
- Request ID: {$event['request_id']}
- URL: {$event['request']['url']}
- Location: {$event['source']['function_name']} in {$event['source']['file_name']}, line {$event['source']['line_no']}
Please investigate and resolve.
END);
try {
$this->mailer->send($mail);
} catch (Throwable) {
} finally {
return $response;
}
}
}
The webhook workflow is as follows:
- It checks to see if the severity of the event is of interest; if not, it immediately returns a response without further processing.
- It then creates an email from the event (the event type, the filename and ZendPHP node triggering the event, the request ID, and more).
- It sends the email
- It returns a response indicating it has completed.
The data available in the webhook is detailed in the mon.get_issues method documentation of the Websocket API.