mirror of
https://github.com/unpoller/unpoller.git
synced 2026-04-05 08:54:09 -04:00
Add Docker health check support
Implements #406 by adding a --health CLI flag and HEALTHCHECK instruction to the Dockerfile. This allows Docker and container orchestration platforms to monitor container health automatically. Changes: - Added --health flag that validates configuration and plugin connectivity - Implemented HealthCheck() method in pkg/poller/commands.go - Updated Dockerfile with HEALTHCHECK instruction (30s interval, 10s timeout) - Updated MANUAL.md with --health flag documentation - Added health check documentation to Docker README - Added comments to docker-compose examples about built-in health check The health check: - Validates configuration file is found and parseable - Ensures at least one input and one enabled output are configured - Performs basic validation on enabled outputs - Returns exit code 0 (healthy) or 1 (unhealthy) - Runs silently for Docker compatibility 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -122,3 +122,66 @@ func (u *UnifiPoller) DebugIO() error {
|
||||
|
||||
return allErr
|
||||
}
|
||||
|
||||
// HealthCheck performs a basic health check suitable for Docker HEALTHCHECK.
|
||||
// It validates configuration and checks if inputs/outputs are properly configured.
|
||||
// Returns nil (exit 0) if healthy, error (exit 1) if unhealthy.
|
||||
func (u *UnifiPoller) HealthCheck() error {
|
||||
// Silence output for health checks (Docker doesn't need verbose logs).
|
||||
u.Quiet = true
|
||||
|
||||
// Load configuration.
|
||||
cfile, err := getFirstFile(strings.Split(u.Flags.ConfigFile, ","))
|
||||
if err != nil {
|
||||
return fmt.Errorf("health check failed: config file not found: %w", err)
|
||||
}
|
||||
|
||||
u.Flags.ConfigFile = cfile
|
||||
|
||||
if err := u.ParseConfigs(); err != nil {
|
||||
return fmt.Errorf("health check failed: config parse error: %w", err)
|
||||
}
|
||||
|
||||
inputSync.RLock()
|
||||
defer inputSync.RUnlock()
|
||||
|
||||
outputSync.RLock()
|
||||
defer outputSync.RUnlock()
|
||||
|
||||
// Check that we have at least one input and one output configured.
|
||||
if len(inputs) == 0 {
|
||||
return fmt.Errorf("health check failed: no input plugins configured")
|
||||
}
|
||||
|
||||
if len(outputs) == 0 {
|
||||
return fmt.Errorf("health check failed: no output plugins configured")
|
||||
}
|
||||
|
||||
// Check if at least one output is enabled.
|
||||
hasEnabledOutput := false
|
||||
for _, output := range outputs {
|
||||
if output.Enabled() {
|
||||
hasEnabledOutput = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !hasEnabledOutput {
|
||||
return fmt.Errorf("health check failed: no enabled output plugins")
|
||||
}
|
||||
|
||||
// Perform basic validation checks on enabled outputs.
|
||||
for _, output := range outputs {
|
||||
if !output.Enabled() {
|
||||
continue
|
||||
}
|
||||
|
||||
ok, err := output.DebugOutput()
|
||||
if !ok || err != nil {
|
||||
return fmt.Errorf("health check failed: output %s validation failed: %w", output.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// All checks passed, application is healthy.
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user