Skip to content
advanced Phase 88 · Integration Advanced

Integration Monitoring

Integration monitoring - health checks, integration status, failure alerting

45m
0 problems
Topic Progress 0%

Health Check System

Integration Health Check

namespace Vendor\Integration\Monitor\HealthCheck;

interface HealthCheckInterface
{
    public function check(): HealthStatus;
    public function getName(): string;
}

class ErpHealthCheck implements HealthCheckInterface
{
    private ErpAdapterInterface $erpAdapter;

    public function check(): HealthStatus
    {
        try {
            $start = microtime(true);
            $this->erpAdapter->ping();
            $latency = (microtime(true) - $start) * 1000;

            return new HealthStatus([
                'name' => 'ERP Connection',
                'status' => 'healthy',
                'latency_ms' => $latency,
                'timestamp' => (new \DateTime())->format('c'),
            ]);
        } catch (\Exception $e) {
            return new HealthStatus([
                'name' => 'ERP Connection',
                'status' => 'unhealthy',
                'error' => $e->getMessage(),
                'timestamp' => (new \DateTime())->format('c'),
            ]);
        }
    }
}

Health Check Aggregator

namespace Vendor\Integration\Monitor\HealthCheck;

class HealthCheckAggregator
{
    private array $checks;
    private AlertInterface $alert;

    public function runAll(): array
    {
        $results = [];

        foreach ($this->checks as $check) {
            $result = $check->check();
            $results[] = $result;

            if ($result->isUnhealthy()) {
                $this->alert->send(
                    'Integration health check failed',
                    sprintf(
                        '%s is unhealthy: %s',
                        $result->getName(),
                        $result->getError()
                    )
                );
            }
        }

        return $results;
    }
}

Integration Status Dashboard

Status Tracker

namespace Vendor\Integration\Monitor\Status;

class IntegrationStatusTracker
{
    private StatusRepositoryInterface $statusRepo;

    public function recordSuccess(string $integration, string $operation): void
    {
        $status = $this->statusRepo->getByIntegration($integration);
        $status->incrementSuccess();
        $status->setLastSuccess(new \DateTime());
        $status->setCircuitState('closed');
        $this->statusRepo->save($status);
    }

    public function recordFailure(string $integration, string $operation, string $error): void
    {
        $status = $this->statusRepo->getByIntegration($integration);
        $status->incrementFailure();
        $status->setLastFailure(new \DateTime());
        $status->setLastError($error);

        // Open circuit after 5 consecutive failures
        if ($status->getConsecutiveFailures() >= 5) {
            $status->setCircuitState('open');
        }

        $this->statusRepo->save($status);
    }
}

Status Response

namespace Vendor\Integration\Monitor\Status;

class StatusResponse
{
    public function toArray(): array
    {
        return [
            'integrations' => [
                'erp' => [
                    'status' => 'healthy',
                    'circuit' => 'closed',
                    'success_rate' => '99.5%',
                    'avg_latency_ms' => 150,
                    'last_check' => '2024-01-15T10:30:00Z',
                ],
                'crm' => [
                    'status' => 'degraded',
                    'circuit' => 'half-open',
                    'success_rate' => '85.0%',
                    'avg_latency_ms' => 500,
                    'last_check' => '2024-01-15T10:29:00Z',
                ],
                'payment' => [
                    'status' => 'healthy',
                    'circuit' => 'closed',
                    'success_rate' => '99.9%',
                    'avg_latency_ms' => 200,
                    'last_check' => '2024-01-15T10:30:00Z',
                ],
            ],
        ];
    }
}

Failure Alerting

Alert Manager

namespace Vendor\Integration\Monitor\Alert;

class AlertManager
{
    private array $channels;
    private AlertRuleRepositoryInterface $rulesRepo;

    public function evaluate(array $statusData): void
    {
        $rules = $this->rulesRepo->getActive();

        foreach ($rules as $rule) {
            if ($rule->matches($statusData)) {
                $alert = new Alert([
                    'severity' => $rule->getSeverity(),
                    'message' => $rule->getMessage($statusData),
                    'integration' => $rule->getIntegration(),
                    'timestamp' => new \DateTime(),
                ]);

                $this->sendAlert($alert);
            }
        }
    }

    private function sendAlert(Alert $alert): void
    {
        foreach ($this->channels as $channel) {
            if ($channel->supports($alert->getSeverity())) {
                $channel->send($alert);
            }
        }
    }
}

Alert Channels

namespace Vendor\Integration\Monitor\Alert\Channel;

interface AlertChannelInterface
{
    public function send(Alert $alert): void;
    public function supports(string $severity): bool;
}

class SlackChannel implements AlertChannelInterface
{
    private SlackClient $client;

    public function send(Alert $alert): void
    {
        $this->client->postMessage([
            'channel' => '#integration-alerts',
            'text' => sprintf(
                '*[%s]* %s',
                strtoupper($alert->getSeverity()),
                $alert->getMessage()
            ),
        ]);
    }
}

class EmailChannel implements AlertChannelInterface
{
    private MailerInterface $mailer;

    public function send(Alert $alert): void
    {
        $this->mailer->send([
            'to' => 'ops@example.com',
            'subject' => sprintf('[%s] Integration Alert', $alert->getSeverity()),
            'body' => $alert->getMessage(),
        ]);
    }
}

Metrics Collection

Integration Metrics

namespace Vendor\Integration\Monitor\Metrics;

class IntegrationMetrics
{
    private MetricsCollectorInterface $collector;

    public function recordRequest(
        string $integration,
        string $operation,
        float $duration,
        bool $success
    ): void {
        $this->collector->increment('integration_requests_total', [
            'integration' => $integration,
            'operation' => $operation,
            'status' => $success ? 'success' : 'failure',
        ]);

        $this->collector->histogram('integration_request_duration_seconds', $duration, [
            'integration' => $integration,
            'operation' => $operation,
        ]);
    }

    public function getStats(string $integration): array
    {
        return [
            'total_requests' => $this->collector->getCounter('integration_requests_total', [
                'integration' => $integration,
            ]),
            'avg_duration' => $this->collector->getHistogramMean('integration_request_duration_seconds', [
                'integration' => $integration,
            ]),
            'error_rate' => $this->collector->getCounter('integration_requests_total', [
                'integration' => $integration,
                'status' => 'failure',
            ]) / max(1, $this->collector->getCounter('integration_requests_total', [
                'integration' => $integration,
            ])),
        ];
    }
}

Cron for Monitoring

namespace Vendor\Integration\Cron;

class IntegrationMonitor
{
    private HealthCheckAggregator $healthCheck;
    private IntegrationStatusTracker $statusTracker;
    private AlertManager $alertManager;

    public function execute(): void
    {
        $results = $this->healthCheck->runAll();

        foreach ($results as $result) {
            if ($result->isUnhealthy()) {
                $this->statusTracker->recordFailure(
                    $result->getName(),
                    'health_check',
                    $result->getError()
                );
            } else {
                $this->statusTracker->recordSuccess(
                    $result->getName(),
                    'health_check'
                );
            }
        }

        $this->alertManager->evaluate($results);
    }
}

Quiz

1. What does a health check verify?

Question 1 options

2. What is a circuit breaker state?

Question 2 options

3. Why send alerts via multiple channels?

Question 3 options

Flashcards

Question

What is a health check?

Answer

A periodic test verifying integration connectivity

Question

What are integration metrics?

Answer

Request counts, latency, error rates per integration

Question

What is circuit breaker state?

Answer

Closed (normal), Open (failing), Half-open (testing)

Question

What does alerting provide?

Answer

Notifications when integrations fail or degrade

Revision Notes

Key Takeaways

  • 1. Health checks verify integration connectivity and latency
  • 2. Status tracking monitors success rates and circuit state
  • 3. Alert channels ensure notifications reach the right people
  • 4. Metrics provide quantitative integration performance data
  • 5. Cron jobs run periodic health checks and alert evaluations

Interview Tips

  • Explain the circuit breaker pattern states
  • Discuss how to design meaningful health checks
  • Describe alert escalation strategies
  • Talk about integration performance monitoring

Cheat Sheet

Monitoring:
  Health Check → connectivity test
  Status Tracker → success/failure rates
  Metrics → request count, latency, error rate
  Alerts → Slack, Email, SMS

Circuit States:
  Closed → normal operation
  Open → failing, block requests
  Half-open → testing recovery

Metrics:
  integration_requests_total
  integration_request_duration_seconds
  integration_errors_total