As part of our Oh Dear! monitoring service, we run workers. A lot of workers. Every site uptime check is a new worker, every broken links job is a new worker, every certificate check is a- you get the idea.
We use Laravel Horizon extensively for this. We dispatch jobs on the queue, Horizon picks them of and processes them.
By default, if we were to look at one of our servers, the htop
view would be this.
We see lots of php artisan horizon:work
with some queue parameters attached to them. This is a sane default and will allow you to quickly see what kind of processes are eating your CPU or memory.
By looking at the name, you can see on what queue they were dispatched and you can make some educated guesses from there on.
Normally, I would return to my trusty strace
utility to see what a particular process would be doing. But PHP offers us a better way in the form of cli_set_process_title()
.
It does exactly what’s in the function name: it allows you to set a custom process title if your PHP process was started via CLI (this won’t work in mod_php
or php-fpm
, luckily).
To make my life easier to debug, I applied this to our workers and this is what they look like now.
Notice anything different?
Each job is still a Laravel Horizon worker, but the process name includes the URL of the site that’s being monitored as well as the team name that it belongs to.
The implementation is super easy and I encourage you to see if you can implement it yourself, if only to thank yourself later if you’re troubleshooting high CPU usages.
In our helpers-file, I added a new global function.
<?php
function setHorizonProcessName(string $url, string $team, string $type)
{
@cli_set_process_title('php artisan horizon:work '. $type .' '. $url .' (team: '. $team .')');
}
Now in every job we dispatch, I call that function.
<?php
class PerformRunJob implements ShouldQueue
{
// Code removed for readability [...]
public function handle()
{
setHorizonProcessName(
$this->url,
$this->teamName,
$type
);
// ...
}
}
I had to add some error suppression to the cli_set_process_title
because Mac apparently no longer supports this and that’s where our primary development is.
This just makes it be quiet on Mac and functional on Linux, just the way we like it. 😉