mirror of
https://github.com/unpoller/unpoller.git
synced 2026-03-31 06:24:21 -04:00
Fix health check port binding conflict (issue #892)
The Docker health check was attempting to bind to ports already in use by the running application, causing "address already in use" errors. This fix adds a health check mode that skips network binding operations while still validating output configuration (listen addresses, paths, etc.). Changes: - Add health check mode flag in pkg/poller/outputs.go - Update prometheus and webserver DebugOutput() to skip port binding in health check mode - Maintain full configuration validation without network conflicts Fixes #892 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -127,6 +127,10 @@ func (u *UnifiPoller) DebugIO() error {
|
||||
// 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 {
|
||||
// Enable health check mode to skip network binding in output validation.
|
||||
SetHealthCheckMode(true)
|
||||
defer SetHealthCheckMode(false)
|
||||
|
||||
// Silence output for health checks (Docker doesn't need verbose logs).
|
||||
u.Quiet = true
|
||||
|
||||
@@ -170,7 +174,8 @@ func (u *UnifiPoller) HealthCheck() error {
|
||||
return fmt.Errorf("health check failed: no enabled output plugins")
|
||||
}
|
||||
|
||||
// Perform basic validation checks on enabled outputs.
|
||||
// Perform configuration validation on enabled outputs.
|
||||
// Network binding checks will be skipped automatically due to health check mode.
|
||||
for _, output := range outputs {
|
||||
if !output.Enabled() {
|
||||
continue
|
||||
|
||||
@@ -11,6 +11,8 @@ var (
|
||||
outputSync sync.RWMutex // nolint: gochecknoglobals
|
||||
errNoOutputPlugins = fmt.Errorf("no output plugins imported")
|
||||
errAllOutputStopped = fmt.Errorf("all output plugins have stopped, or none enabled")
|
||||
// healthCheckMode indicates when we're running in health check mode to skip network operations
|
||||
healthCheckMode bool // nolint: gochecknoglobals
|
||||
)
|
||||
|
||||
// Collect is passed into output packages so they may collect metrics to output.
|
||||
@@ -50,6 +52,17 @@ func NewOutput(o *Output) {
|
||||
outputs = append(outputs, o)
|
||||
}
|
||||
|
||||
// SetHealthCheckMode enables or disables health check mode.
|
||||
// When enabled, output plugins should skip network operations in DebugOutput().
|
||||
func SetHealthCheckMode(enabled bool) {
|
||||
healthCheckMode = enabled
|
||||
}
|
||||
|
||||
// IsHealthCheckMode returns true if we're running in health check mode.
|
||||
func IsHealthCheckMode() bool {
|
||||
return healthCheckMode
|
||||
}
|
||||
|
||||
// Poller returns the poller config.
|
||||
func (u *UnifiPoller) Poller() Poller {
|
||||
return *u.Config.Poller
|
||||
|
||||
@@ -139,6 +139,12 @@ func (u *promUnifi) DebugOutput() (bool, error) {
|
||||
return false, fmt.Errorf("invalid listen address: %s (must be of the form \"IP:Port\"", u.HTTPListen)
|
||||
}
|
||||
|
||||
// Skip network binding check during health checks to avoid "address already in use"
|
||||
// errors when the main application is already running and bound to the port.
|
||||
if poller.IsHealthCheckMode() {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
ln, err := net.Listen("tcp", u.HTTPListen)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
||||
@@ -117,6 +117,12 @@ func (s *Server) DebugOutput() (bool, error) {
|
||||
return false, fmt.Errorf("problem with HTML path: %w", err)
|
||||
}
|
||||
|
||||
// Skip network binding check during health checks to avoid "address already in use"
|
||||
// errors when the main application is already running and bound to the port.
|
||||
if poller.IsHealthCheckMode() {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// check the port
|
||||
ln, err := net.Listen("tcp", fmt.Sprintf(":%d", s.Port))
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user