Notice Before Your Client Does — Exposing health state of custom components in your TYPO3 instance
Some TYPO3 installations have no reliable way to tell whether they're actually working. A scheduler task can stop running. A queue can back up. A third-party API a custom extension depends on can go down. None of that shows up in a standard uptime check, because the page still renders fine — it just quietly stops doing its job.
EXT:monitoring tries to close that gap. It aggregates checks on the
components you care about into a single status, exposed through a backend
dashboard, an HTTP endpoint, and a CLI command.
The project started from a scheduler that had silently stopped running for several days before anyone noticed. What began as one check for that case grew into a small architecture — authorization, caching, push notifications — as more cases came up that needed the same kind of visibility.
Earlier versions secretly matured into what I was finally ready to release as stable today. So here's a look at what it does and what it gives you.
One status, three ways to read it
The extension collects results from monitoring providers — small classes that
each check one thing — and aggregates them into a single status: healthy,
degraded, or unhealthy. That status is available through:
- An HTTP endpoint (
/monitor/healthby default), returning structured JSON for polling by Nagios, Icinga, Uptime Kuma, or similar tools. - A CLI command, for cron jobs, deploy scripts, or manual checks.
- A backend dashboard, showing the same status with a wee more verbosity inside TYPO3, and
- optional push notifications, for setups where nothing polls the endpoint.
All three read from the same source, so the dashboard, the endpoint, and any notification stay consistent.
Response format
curl -H "X-TYPO3-MONITORING-AUTH: <token>" https://example.com/monitor/health{
"status": "healthy",
"services": {
"Scheduler": {
"status": "healthy",
"subResults": {
"Scheduler Execution": { "status": "healthy" },
"Overdue Tasks": { "status": "healthy" },
"Failed Tasks": { "status": "healthy" }
}
}
}
}
The overall status is the worst status of anything underneath it. unhealthy
returns HTTP 503; healthy and degraded both return 200 — degraded means
"operational, but worth a look," not "down." This distinction lets you page on
outages without paging on minor issues.
Providers
A provider is a small, focused class:
final readonly class MyServiceProvider implements MonitoringProvider
{
public function getName(): string { return 'MyService'; }
public function getDescription(): string { return 'Monitors my custom service'; }
public function isEnabled(): bool { return true; }
public function isActive(): bool { return $this->isEnabled(); }
public function execute(): Result
{
try {
// do the check
return new MonitoringResult($this->getName(), Status::Healthy);
} catch (\Exception $e) {
return new MonitoringResult($this->getName(), Status::Unhealthy, $e->getMessage());
}
}
}
Providers are auto-discovered via a PHP attribute on the interface — no
manual registration. A provider can report multiple sub-results under one
name, and expensive checks can implement CacheableMonitoringProvider to
avoid hitting a downstream system on every request.
The extension ships one built-in provider: a Scheduler Provider that checks the Scheduler as a whole — heartbeat, overdue tasks, and failed tasks together — rather than trusting individual task status, since a cron job that stops firing doesn't make any single task "fail."
Authorization
Two authorizers ship by default:
- Token authorization — an HMAC of the endpoint path, generated with
TYPO3's
HashService, sent as a header. The Monitoring → Authorizers backend module shows the ready-to-use token. - Admin session authorization — anyone logged into the TYPO3 backend as an administrator can open the endpoint directly.
Both are evaluated in priority order. Custom authorizers use the same attribute-based discovery as providers.
Push notifications
For setups without external polling, the extension can push status through
reporters — a built-in EmailReporter, with the same extension point for
Slack, Teams, or other channels. Reporters run on demand, typically from a
scheduler task, via a monitoring:report CLI command.
A small state machine tracks whether an outage is new, a reminder is due, or the system has recovered, and dispatches to reporters based on their configured threshold. This produces one notification when something breaks, periodic reminders while it stays broken, and one "all clear" when it's fixed, rather than an alert on every cron run.
Command line
./vendor/bin/typo3 monitoring:run
Checking Monitoring status
✅ Scheduler
✅ Solr Cores (cached)
✅ Redis Cache
🚨 FancyExternalApiService
✅ LDAP Import
✅ SSO Roundtrip
Monitoring status: FAILED
Standard exit codes (0/1/2) make it straightforward to wire into deploy
pipelines or health-gate scripts.
Getting started
composer require mteu/typo3-monitoring# config/system/settings.php
return [
'EXTENSIONS' => [
'monitoring' => [
'api' => [
'endpoint' => '/monitor/health',
'enforceHttps' => true,
],
'authorizer' => [
'mteu\Monitoring\Authorization\TokenAuthorizer' => [
'enabled' => true,
'secret' => 'your-secure-secret',
'authHeaderName' => 'X-TYPO3-MONITORING-AUTH',
],
],
],
],
];
That's enough for a working endpoint. From there, the extension point is open: write a provider for whatever a project depends on — a search index, an external api fetch,a payment gateway, a queue, a filesystem mount — and it slots into the same status, dashboard, and alerting path as everything else.
MonitoringProvider, Authorizer, and Reporter are the whole surface area
of the package. They've been in use in production for about a year, and the
interfaces are now considered stable.
The first stable version of EXT:monitoring was release today. It supports TYPO3 v13 and v14 LTS. Full documentation with advanced examples is available on GitHub: mteu/typo3-monitoring.