Install the Bundle
composer require arty/probe-bundle
Register the bundle in config/bundles.php if not using Symfony Flex:
Arty\ProbeBundle\ArtyProbeBundle::class => ['all' => true],
Configure the Bundle
Create config/packages/arty_probe.yaml:
arty_probe:
probe_status_history_class: App\Entity\ProbeStatusHistory
alerting:
enabled: true
channel: email # or 'chat'
to: "admin@example.com"
Set Up Alerting
MAILER_DSN in .env.symfony/slack-notifier) and configure the DSN in .env:
SLACK_DSN=slack://TOKEN@default?channel=CHANNEL
Create the Database Entity
Extend BaseProbeStatusHistory in App\Entity\ProbeStatusHistory:
use Arty\ProbeBundle\Entity\ProbeStatusHistory as BaseProbeStatusHistory;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ProbeStatusHistoryRepository::class)]
class ProbeStatusHistory extends BaseProbeStatusHistory {}
Run migrations:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
Write Your First Probe
Implement ProbeInterface and annotate with #[Probe]:
use Arty\ProbeBundle\Attribute\Probe;
use Arty\ProbeBundle\Model\ProbeInterface;
#[Probe(name: 'database_connectivity', description: 'Checks DB reachability')]
class DatabaseProbe implements ProbeInterface {
public function check(): int {
return $this->isDatabaseReachable() ? Probe::SUCCESS : Probe::FAILURE;
}
}
Run Probes Execute all probes via CLI:
php bin/console arty:probe:run
Probe Development
Probe::SUCCESS, Probe::WARNING, or Probe::FAILURE constants for simple pass/fail logic.
public function check(): int {
return $this->apiResponseValid() ? Probe::SUCCESS : Probe::FAILURE;
}
#[Probe]:
#[Probe(
name: 'cache_hit_rate',
successThreshold: 0.8,
warningThreshold: 0.6,
failureThreshold: 0.4,
description: 'Monitors cache efficiency'
)]
class CacheProbe implements ProbeInterface {
public function check(): float {
return $this->getCacheHitRate();
}
}
Alerting Integration
MAILER_DSN and set channel: email in arty_probe.yaml..env:
arty_probe:
alerting:
channel: chat
notify: false in #[Probe] or alerting.enabled: false in config.Probe Scheduling
CronBundle or EasyAdmin to schedule arty:probe:run:
# config/packages/easy_admin.yaml
easy_admin:
cronjobs:
- command: 'arty:probe:run'
schedule: '0 * * * *' # Run hourly
Probe Results in Templates
Inject ProbeManagerInterface into controllers to fetch statuses:
public function dashboard(ProbeManagerInterface $probeManager): Response {
$statuses = $probeManager->findAllLastStatuses();
return $this->render('dashboard.html.twig', ['statuses' => $statuses]);
}
Display in Twig:
{% for probe, status in statuses %}
<div class="probe {{ status.status }}">
{{ probe.name }}: {{ status.status|humanize }}
</div>
{% endfor %}
Testing Probes Use PHPUnit to mock dependencies and test probe logic:
public function testDatabaseProbeFails() {
$probe = new DatabaseProbe($this->createMock(DbConnection::class));
$this->assertEquals(Probe::FAILURE, $probe->check());
}
Threshold Mismatches
int, float) aligns with the thresholds. For example, comparing a float (e.g., 0.8) with int thresholds (e.g., 80) will fail silently.return (int)($this->getCacheHitRate() * 100); // Convert to percentage
Alerting Delays
message_bus: false in notifier.yaml to force synchronous delivery:
framework:
notifier:
message_bus: false
Entity Mapping Issues
ProbeStatusHistory isn’t properly mapped, migrations may fail. Ensure:
BaseProbeStatusHistory.probe_status_history).#[ORM\Entity]).Probe Registration
# config/services.yaml
services:
App\Probe\DatabaseProbe:
tags: ['arty.probe']
Performance Overhead
arty:probe:run. Optimize by:
Symfony\Component\Process\Process).Check Probe Execution Enable debug mode to see probe output:
php bin/console arty:probe:run --env=dev
Or log results manually:
public function check(): int {
$result = $this->isHealthy() ? Probe::SUCCESS : Probe::FAILURE;
$this->logger->info("Probe result: {$result}");
return $result;
}
Verify Alerts
php bin/console debug:notifier
Inspect Database
Query the probe_status_history table to verify records are saved:
SELECT * FROM probe_status_history ORDER BY created_at DESC;
Custom Probe Statuses
Extend the ProbeStatus enum to add custom states (e.g., DEGRADED):
namespace App\Enum;
use Arty\ProbeBundle\Model\ProbeStatus;
enum CustomProbeStatus: string {
case DEGRADED = 'degraded';
public function isValid(): bool {
return in_array($this->value, [ProbeStatus::SUCCESS->value, ProbeStatus::WARNING->value, ...]);
}
}
Dynamic Probe Configuration Load probe thresholds from a config file or database:
# config/probes.yaml
probes:
database:
success_threshold: 0
warning_threshold: 1
Inject the config into the probe:
#[Probe(name: 'database')]
class DatabaseProbe implements ProbeInterface {
public function __construct(private array $config) {}
public function check(): int {
return $this->getErrorCount();
}
}
Probe Metadata
Add metadata (e.g., severity, owner) to probes via the #[Probe] attribute:
#[Probe(
name: 'payment_gateway',
description: 'Checks payment processing',
severity: 'high',
How can I help you explore Laravel packages today?