🏝 If you like the content of this blog, I would really appreciate your vote in Tuple's Send an Open Source Developer on Vacation contest. Just search for "Freek Van der Herten" in the nominees list and cast your vote. 🙌

😀 This holiday won't only be a nice reward for me, but also for my girlfriend who always gives me a lot of time working on open source packages and blog posts.

Displaying sites that are down on a dashboard using Oh Dear! webhooks

Original – by Freek Van der Herten – 4 minute read

At Spatie we have a dashboard against the wall that displays a lot of information useful for our company. One of the things it shows are the urls of client sites that are down. Behind the scenes it leverages the webhooks from Oh Dear!, a website monitoring service that Mattias Geniar and I launched a few weeks ago.

In this blogpost I'd like to show how all of this works.

The dashboard

Spatie's dashboard is a Laravel / Vue application. It's open sourced. You'll find the actual code that's deployed to our server in this repo on GitHub.

Here's how our dashboard looks like.

dashboard

And this is what it looks like when one of our sites is down.

dashboard downtime

Before continuing you should read this blogpost or watch the video of my Laracon EU 2017 talk to know how the dashboard works.

Integrating Oh Dear! webhooks

Logged into Oh Dear! notifications screen a webhook can be setup. If entered the url of our dashboard (that webhook secret in the screenshot isn't the real secret).

webhooks

To easily handle Oh Dear! webhook calls in a Laravel app the ohdearapp/laravel-ohdear-webhooks package can be used. Once installed and the initial setup is out of the way you can listen for Oh Dear! events.

In the routes file there's a route where the Oh Dear! events will be received.

Route::ohDearWebhooks('/oh-dear-webhooks');

When Oh Dear! hits that route certain events will get fired off in the app. You can define an event handler to handle those events. Here is the code of the actual event handler in our dashboard.

namespace App\Services\OhDearWebhooks;

use Illuminate\Events\Dispatcher;
use App\Events\Uptime\UptimeCheckFailed;
use App\Events\Uptime\UptimeCheckRecovered;
use OhDear\LaravelWebhooks\OhDearWebhookCall;

class EventSubscriber
{
    public function subscribe(Dispatcher $events)
    {
        $events->listen(
            'ohdear-webhooks::uptimeCheckFailed',
            'App\Services\OhDearWebhooks\EventSubscriber@onUptimeCheckFailed'
        );

        $events->listen(
            'ohdear-webhooks::uptimeCheckRecovered',
            'App\Services\OhDearWebhooks\EventSubscriber@onUptimeCheckRecovered'
        );
    }

    public function onUptimeCheckFailed(OhDearWebhookCall $ohDearWebhookCall)
    {
        $site = $ohDearWebhookCall->site();

        event(new UptimeCheckFailed($site['id'], $site['url']));
    }

    public function onUptimeCheckRecovered(OhDearWebhookCall $ohDearWebhookCall)
    {
        $site = $ohDearWebhookCall->site();

        event(new UptimeCheckRecovered($site['id'], $site['url']));
    }
}

You can see that when even an Oh Dear! event comes in (such as ohdear-webhooks::uptimeCheckFailed) were are going to fire off an new event of our own (for instance UptimeCheckFailed). Our own events extend DashboardEvent which means they will be broadcasted via Pusher to the browser.

This is the code of the Uptime Vue component that receives the events at the client side.

<template>
    <tile v-if="hasFailingUrls" :position="position" modifiers="overflow yellow above">
        <section class="uptime">
            <h1 class="uptime__title">Downtime</h1>
            <ul class="uptime__notifications">
                <li v-for="failing in failingUrls" class="uptime__notification">
                    <h2 class="uptime__notification__title h-ellipsis">{{ failing.url }}</h2>
                </li>
            </ul>
        </section>
    </tile>
</template>
<script>
    import echo from '../mixins/echo';
    import Tile from './atoms/Tile';
    import { addClassModifiers, formatDuration } from '../helpers';

    export default {

        components: {
            Tile,
        },

        filters: {
            formatDuration,
        },

        mixins: [echo],

        props: ['position'],

        data() {
            return {
                failingUrls: [],
            };
        },

        computed: {
            hasFailingUrls() {
                return this.failingUrls.length > 0;
            },
        },

        methods: {
            addClassModifiers,

            getEventHandlers() {
                return {
                    'Uptime.UptimeCheckFailed': response => {
                        this.add(response.url);
                    },
                    'Uptime.UptimeCheckRecovered': response => {
                        this.remove(response.url);
                    },
                };
            },

            add(url) {
                this.failingUrls = this.failingUrls.filter(failingUrl => url !== failingUrl.url);

                this.failingUrls.push({ url });
            },

            remove(url) {
                this.failingUrls = this.failingUrls.filter(failingUrl => url !== failingUrl.url);
            },
        },
    };
</script>

This component will listen for incoming events (some setup work is done inside the echo Mixin). As soon as there is one failingUrl that the Uptime tile is being displayed. The above css class makes sure that the component is displayed over the Twitter component that is normally visible in the first column.

In closing

Integrating Oh Dear! webhooks in your applications isn't difficult at all. You'll find more info on the webhooks package in the Oh Dear! documention. Instead of using the webhooks, you could also opt to use the regular API or PHP SDK. The dashboard is entirely free, you'll find the source code in this repo on GitHub.

Stay up to date with all things Laravel, PHP, and JavaScript.

Follow me on Twitter. I regularly tweet out programming tips, and what I myself have learned in ongoing projects.

Every month I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments

What are your thoughts on "Displaying sites that are down on a dashboard using Oh Dear! webhooks"?

Want to join the conversation? Log in or create an account to post a comment.

Webmentions

TALLtuts liked on 16th July 2020
Diar liked on 16th July 2020
Martin Medina liked on 16th July 2020
Coderatio liked on 16th July 2020
Maaz Ali liked on 16th July 2020
ali ali liked on 16th July 2020
Stefan Tanevski liked on 16th July 2020
Pavlo Bezdverniy liked on 16th July 2020
Stephen Shead liked on 16th July 2020
Brandon Surowiec retweeted on 15th July 2020
AndreBoyle liked on 15th July 2020
Jamie Shiers liked on 15th July 2020
Angel Rushkov liked on 15th July 2020
Сута Фунду retweeted on 15th July 2020
Shawn Hooper retweeted on 15th July 2020
🤔🤔🤔 rick retweeted on 15th July 2020
Maxime liked on 15th July 2020
🤔🤔🤔 rick liked on 15th July 2020
Mudassir Ahmad Adili liked on 15th July 2020
Niels liked on 15th July 2020
DeanLJ liked on 15th July 2020
Owen Voke liked on 15th July 2020
Rich Klein liked on 15th July 2020
Joan Morell liked on 15th July 2020
Сута Фунду liked on 15th July 2020
Bart Joris liked on 15th July 2020
Noe liked on 15th July 2020
François liked on 15th July 2020
Flamur Mavraj liked on 15th July 2020
Oh Dear retweeted on 15th July 2020
Mattias Geniar retweeted on 15th July 2020
Hardik Shah liked on 15th July 2020
flowdee ツ liked on 15th July 2020
Jerrell Niu liked on 15th July 2020
Kennedy Tedesco liked on 15th July 2020
Silvan Hagen 🍀 liked on 15th July 2020
Bill Richards liked on 15th July 2020
Wyatt liked on 15th July 2020
Richard liked on 15th July 2020