diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 9d741130502..89070cbf96b 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -178,7 +178,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { restrictedHTTPClient := opts.RestrictedHTTPClient unrestrictedHTTPClient := opts.UnrestrictedHTTPClient - // LOOPs can be be created as options, in the case of LOOP relayers, or + // LOOPs can be created as options, in the case of LOOP relayers, or // as OCR2 job implementations, in the case of Median today. // We will have a non-nil registry here in LOOP relayers are being used, otherwise // we need to initialize in case we serve OCR2 LOOPs @@ -217,8 +217,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) { globalLogger.Info("Nurse service (automatic pprof profiling) is disabled") } - healthChecker := services.NewChecker() - telemetryIngressClient := synchronization.TelemetryIngressClient(&synchronization.NoopTelemetryIngressClient{}) telemetryIngressBatchClient := synchronization.TelemetryIngressBatchClient(&synchronization.NoopTelemetryIngressBatchClient{}) monitoringEndpointGen := telemetry.MonitoringEndpointGenerator(&telemetry.NoopAgent{}) @@ -443,7 +441,14 @@ func NewApplication(opts ApplicationOpts) (Application, error) { feedsService = &feeds.NullService{} } - app := &ChainlinkApplication{ + healthChecker := services.NewChecker() + for _, s := range srvcs { + if err := healthChecker.Register(s); err != nil { + return nil, err + } + } + + return &ChainlinkApplication{ relayers: opts.RelayerChainInteroperators, EventBroadcaster: eventBroadcaster, jobORM: jobORM, @@ -472,27 +477,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { // NOTE: Can keep things clean by putting more things in srvcs instead of manually start/closing srvcs: srvcs, - } - - for _, service := range app.srvcs { - checkable := service.(services.Checkable) - if err := app.HealthChecker.Register(service.Name(), checkable); err != nil { - return nil, err - } - } - - // To avoid subscribing chain services twice, we only subscribe them if OCR2 is not enabled. - // If it's enabled, they are going to be registered with relayers by default. - if !cfg.OCR2().Enabled() { - for _, service := range app.relayers.Services() { - checkable := service.(services.Checkable) - if err := app.HealthChecker.Register(service.Name(), checkable); err != nil { - return nil, err - } - } - } - - return app, nil + }, nil } func (app *ChainlinkApplication) SetLogLevel(lvl zapcore.Level) error { diff --git a/core/services/checkable.go b/core/services/checkable.go index 298e3dda471..a702f9f979d 100644 --- a/core/services/checkable.go +++ b/core/services/checkable.go @@ -10,4 +10,6 @@ type Checkable interface { // HealthReport returns a full health report of the callee including it's dependencies. // key is the dep name, value is nil if healthy, or error message otherwise. HealthReport() map[string]error + // Name returns the fully qualified name of the component. Usually the logger name. + Name() string } diff --git a/core/services/health.go b/core/services/health.go index da3a99b34d9..1912a49b75e 100644 --- a/core/services/health.go +++ b/core/services/health.go @@ -21,7 +21,7 @@ type ( // Checker provides a service which can be probed for system health. Checker interface { // Register a service for health checks. - Register(name string, service Checkable) error + Register(service Checkable) error // Unregister a service. Unregister(name string) error // IsReady returns the current readiness of the system. @@ -176,8 +176,9 @@ func (c *checker) update() { uptimeSeconds.Add(interval.Seconds()) } -func (c *checker) Register(name string, service Checkable) error { - if service == nil || name == "" { +func (c *checker) Register(service Checkable) error { + name := service.Name() + if name == "" { return errors.Errorf("misconfigured check %#v for %v", name, service) } diff --git a/core/services/health_test.go b/core/services/health_test.go index 295eb86119c..f8e139af157 100644 --- a/core/services/health_test.go +++ b/core/services/health_test.go @@ -1,7 +1,6 @@ package services_test import ( - "fmt" "net/http" "testing" "time" @@ -22,6 +21,8 @@ type boolCheck struct { healthy bool } +func (b boolCheck) Name() string { return b.name } + func (b boolCheck) Ready() error { if b.healthy { return nil @@ -57,8 +58,8 @@ func TestCheck(t *testing.T) { }}, } { c := services.NewChecker() - for i, check := range test.checks { - require.NoError(t, c.Register(fmt.Sprint(i), check)) + for _, check := range test.checks { + require.NoError(t, c.Register(check)) } require.NoError(t, c.Start()) diff --git a/core/services/mocks/checker.go b/core/services/mocks/checker.go index cfccc2537f8..8a6541bba36 100644 --- a/core/services/mocks/checker.go +++ b/core/services/mocks/checker.go @@ -78,13 +78,13 @@ func (_m *Checker) IsReady() (bool, map[string]error) { return r0, r1 } -// Register provides a mock function with given fields: name, service -func (_m *Checker) Register(name string, service services.Checkable) error { - ret := _m.Called(name, service) +// Register provides a mock function with given fields: service +func (_m *Checker) Register(service services.Checkable) error { + ret := _m.Called(service) var r0 error - if rf, ok := ret.Get(0).(func(string, services.Checkable) error); ok { - r0 = rf(name, service) + if rf, ok := ret.Get(0).(func(services.Checkable) error); ok { + r0 = rf(service) } else { r0 = ret.Error(0) } diff --git a/core/services/service.go b/core/services/service.go index b3c1bf36779..5bf61e062d2 100644 --- a/core/services/service.go +++ b/core/services/service.go @@ -81,8 +81,5 @@ type ServiceCtx interface { // again, you need to build a new Service to do so. Close() error - // Name returns the fully qualified name of the service - Name() string - Checkable } diff --git a/plugins/cmd/chainlink-median/main.go b/plugins/cmd/chainlink-median/main.go index aac68eb5005..4d966548525 100644 --- a/plugins/cmd/chainlink-median/main.go +++ b/plugins/cmd/chainlink-median/main.go @@ -20,7 +20,7 @@ func main() { p := median.NewPlugin(s.Logger) defer s.Logger.ErrorIfFn(p.Close, "Failed to close") - s.MustRegister(p.Name(), p) + s.MustRegister(p) stop := make(chan struct{}) defer close(stop) diff --git a/plugins/cmd/chainlink-solana/main.go b/plugins/cmd/chainlink-solana/main.go index df2824fb338..132d7244fdf 100644 --- a/plugins/cmd/chainlink-solana/main.go +++ b/plugins/cmd/chainlink-solana/main.go @@ -27,7 +27,7 @@ func main() { p := &pluginRelayer{Base: plugins.Base{Logger: s.Logger}} defer s.Logger.ErrorIfFn(p.Close, "Failed to close") - s.MustRegister(p.Name(), p) + s.MustRegister(p) stopCh := make(chan struct{}) defer close(stopCh) diff --git a/plugins/cmd/chainlink-starknet/main.go b/plugins/cmd/chainlink-starknet/main.go index 5015f70be2e..aa69c85fe42 100644 --- a/plugins/cmd/chainlink-starknet/main.go +++ b/plugins/cmd/chainlink-starknet/main.go @@ -27,7 +27,7 @@ func main() { p := &pluginRelayer{Base: plugins.Base{Logger: s.Logger}} defer s.Logger.ErrorIfFn(p.Close, "Failed to close") - s.MustRegister(p.Name(), p) + s.MustRegister(p) stopCh := make(chan struct{}) defer close(stopCh) diff --git a/plugins/server.go b/plugins/server.go index 2c1bffb85b8..0d0e0dc62c4 100644 --- a/plugins/server.go +++ b/plugins/server.go @@ -53,10 +53,9 @@ type Server struct { } // MustRegister registers the Checkable with services.Checker, or exits upon failure. -func (s *Server) MustRegister(name string, c services.Checkable) { - err := s.Register(name, c) - if err != nil { - s.Logger.Fatalf("Failed to register %s with health checker: %v", name, err) +func (s *Server) MustRegister(c services.Checkable) { + if err := s.Register(c); err != nil { + s.Logger.Fatalf("Failed to register %s with health checker: %v", c.Name(), err) } }