Files
michaelschiemer/src/Framework/ExceptionHandling/Health/ExceptionHealthChecker.php
Michael Schiemer 36ef2a1e2c
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
fix: Gitea Traefik routing and connection pool optimization
- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
2025-11-09 14:46:15 +01:00

109 lines
3.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\ExceptionHandling\Health;
use App\Framework\ExceptionHandling\Metrics\ExceptionMetrics;
use App\Framework\ExceptionHandling\Metrics\ExceptionMetricsCollector;
use App\Framework\Health\HealthCheckInterface;
use App\Framework\Health\HealthCheckResult;
/**
* Exception Health Checker
*
* Provides health checks based on exception rate.
*/
final readonly class ExceptionHealthChecker implements HealthCheckInterface
{
public readonly string $name;
public readonly int $timeout;
/**
* @param ExceptionMetricsCollector $metricsCollector Metrics collector
* @param string $name Health check name
* @param int $timeout Timeout in milliseconds
* @param float $errorRateThreshold Error rate threshold (0.0 to 1.0, e.g., 0.1 = 10%)
* @param int $timeWindowSeconds Time window in seconds for error rate calculation
*/
public function __construct(
private ExceptionMetricsCollector $metricsCollector,
string $name = 'Exception Rate',
int $timeout = 2000,
private float $errorRateThreshold = 0.1, // 10% default
private int $timeWindowSeconds = 60
) {
$this->name = $name;
$this->timeout = $timeout;
if ($errorRateThreshold < 0.0 || $errorRateThreshold > 1.0) {
throw new \InvalidArgumentException('errorRateThreshold must be between 0.0 and 1.0');
}
}
/**
* Perform health check
*/
public function check(): HealthCheckResult
{
$metrics = $this->metricsCollector->getMetrics();
$errorRate = $this->calculateErrorRate($metrics);
if ($errorRate >= $this->errorRateThreshold) {
return HealthCheckResult::unhealthy(
"Exception error rate too high: " . number_format($errorRate * 100, 2) . "%",
[
'error_rate' => $errorRate,
'threshold' => $this->errorRateThreshold,
'total_exceptions' => $metrics->totalCount,
]
);
}
if ($errorRate >= $this->errorRateThreshold * 0.5) {
return HealthCheckResult::warning(
"Exception error rate elevated: " . number_format($errorRate * 100, 2) . "%",
[
'error_rate' => $errorRate,
'threshold' => $this->errorRateThreshold,
'total_exceptions' => $metrics->totalCount,
]
);
}
return HealthCheckResult::healthy(
"Exception error rate normal: " . number_format($errorRate * 100, 2) . "%",
[
'error_rate' => $errorRate,
'total_exceptions' => $metrics->totalCount,
]
);
}
/**
* Calculate error rate
*
* Simplified implementation - in production, would calculate based on request count.
*/
private function calculateErrorRate(ExceptionMetrics $metrics): float
{
// Simplified: use total count as proxy for error rate
// In production, would compare against total request count
if ($metrics->totalCount === 0) {
return 0.0;
}
// Normalize to 0-1 range (simplified)
return min(1.0, $metrics->totalCount / 1000.0);
}
/**
* Get health check category
*/
public function getCategory(): \App\Framework\Health\HealthCheckCategory
{
return \App\Framework\Health\HealthCheckCategory::APPLICATION;
}
}