diff --git a/.chloggen/sighup-configuration-reloading.yaml b/.chloggen/sighup-configuration-reloading.yaml new file mode 100644 index 00000000000..48f1a8ccb9c --- /dev/null +++ b/.chloggen/sighup-configuration-reloading.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) +component: service/collector + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Support SIGHUP configuration reloading" + +# One or more tracking issues or pull requests related to the change +issues: [5966] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/service/collector.go b/service/collector.go index 7201342f9d6..d768f15a1ec 100644 --- a/service/collector.go +++ b/service/collector.go @@ -158,6 +158,21 @@ func (col *Collector) setupConfigurationComponents(ctx context.Context) error { return nil } +func (col *Collector) reloadConfiguration(ctx context.Context) error { + col.service.telemetrySettings.Logger.Warn("Config updated, restart service") + col.setCollectorState(Closing) + + if err := col.service.Shutdown(ctx); err != nil { + return fmt.Errorf("failed to shutdown the retiring config: %w", err) + } + + if err := col.setupConfigurationComponents(ctx); err != nil { + return fmt.Errorf("failed to setup configuration components: %w", err) + } + + return nil +} + // Run starts the collector according to the given configuration, and waits for it to complete. // Consecutive calls to Run are not allowed, Run shouldn't be called once a collector is shut down. func (col *Collector) Run(ctx context.Context) error { @@ -166,6 +181,9 @@ func (col *Collector) Run(ctx context.Context) error { return err } + // Always notify with SIGHUP for configuration reloading. + signal.Notify(col.signalsChannel, syscall.SIGHUP) + // Only notify with SIGTERM and SIGINT if graceful shutdown is enabled. if !col.set.DisableGracefulShutdown { signal.Notify(col.signalsChannel, os.Interrupt, syscall.SIGTERM) @@ -180,21 +198,22 @@ LOOP: break LOOP } - col.service.telemetrySettings.Logger.Warn("Config updated, restart service") - col.setCollectorState(Closing) - - if err = col.service.Shutdown(ctx); err != nil { - return fmt.Errorf("failed to shutdown the retiring config: %w", err) - } - if err = col.setupConfigurationComponents(ctx); err != nil { - return fmt.Errorf("failed to setup configuration components: %w", err) + if err = col.reloadConfiguration(ctx); err != nil { + return err } case err := <-col.asyncErrorChannel: col.service.telemetrySettings.Logger.Error("Asynchronous error received, terminating process", zap.Error(err)) break LOOP case s := <-col.signalsChannel: col.service.telemetrySettings.Logger.Info("Received signal from OS", zap.String("signal", s.String())) - break LOOP + switch s { + case syscall.SIGHUP: + if err := col.reloadConfiguration(ctx); err != nil { + return err + } + default: + break LOOP + } case <-col.shutdownChan: col.service.telemetrySettings.Logger.Info("Received shutdown request") break LOOP diff --git a/service/collector_test.go b/service/collector_test.go index da661b9682a..3506880bcd2 100644 --- a/service/collector_test.go +++ b/service/collector_test.go @@ -197,6 +197,12 @@ func TestCollectorSendSignal(t *testing.T) { return Running == col.GetState() }, 2*time.Second, 200*time.Millisecond) + col.signalsChannel <- syscall.SIGHUP + + assert.Eventually(t, func() bool { + return Running == col.GetState() + }, 2*time.Second, 200*time.Millisecond) + col.signalsChannel <- syscall.SIGTERM wg.Wait()