From 1c86e26ee3597901bb81c06b2348c43981f866b5 Mon Sep 17 00:00:00 2001 From: Florian Lehner Date: Thu, 28 Jul 2022 15:15:16 +0200 Subject: [PATCH 1/2] Reduce memory footprint by reordering struct elements --- .../handlers/handler_action_unenroll.go | 4 +- .../pkg/agent/application/upgrade/upgrade.go | 10 ++-- .../agent/operation/operation_retryable.go | 2 +- internal/pkg/agent/stateresolver/resolve.go | 4 +- .../composable/providers/kubernetes/pod.go | 12 ++--- .../kubernetesleaderelection/config.go | 6 ++- internal/pkg/core/plugin/process/app.go | 51 +++++++++---------- internal/pkg/core/state/state.go | 4 +- internal/pkg/core/status/reporter.go | 28 +++++----- internal/pkg/crypto/io.go | 2 +- .../pkg/fleetapi/acker/retrier/retrier.go | 15 +++--- internal/pkg/reporter/fleet/reporter.go | 4 +- 12 files changed, 70 insertions(+), 72 deletions(-) diff --git a/internal/pkg/agent/application/pipeline/actions/handlers/handler_action_unenroll.go b/internal/pkg/agent/application/pipeline/actions/handlers/handler_action_unenroll.go index 71fe0f30644..66b1ce8612b 100644 --- a/internal/pkg/agent/application/pipeline/actions/handlers/handler_action_unenroll.go +++ b/internal/pkg/agent/application/pipeline/actions/handlers/handler_action_unenroll.go @@ -26,11 +26,11 @@ type stateStore interface { // Unenroll results in running agent entering idle state, non managed non standalone. // For it to be operational again it needs to be either enrolled or reconfigured. type Unenroll struct { + dispatcher pipeline.Router + stateStore stateStore log *logger.Logger emitter pipeline.EmitterFunc - dispatcher pipeline.Router closers []context.CancelFunc - stateStore stateStore } // NewUnenroll creates a new Unenroll handler. diff --git a/internal/pkg/agent/application/upgrade/upgrade.go b/internal/pkg/agent/application/upgrade/upgrade.go index ce811036176..1c6a85fa9d9 100644 --- a/internal/pkg/agent/application/upgrade/upgrade.go +++ b/internal/pkg/agent/application/upgrade/upgrade.go @@ -44,15 +44,15 @@ var ( // Upgrader performs an upgrade type Upgrader struct { - agentInfo *info.AgentInfo + reporter stateReporter + caps capabilities.Capability + reexec reexecManager + acker acker settings *artifact.Config + agentInfo *info.AgentInfo log *logger.Logger closers []context.CancelFunc - reexec reexecManager - acker acker - reporter stateReporter upgradeable bool - caps capabilities.Capability } // Action is the upgrade action state. diff --git a/internal/pkg/agent/operation/operation_retryable.go b/internal/pkg/agent/operation/operation_retryable.go index b30fd68563c..53544cec92b 100644 --- a/internal/pkg/agent/operation/operation_retryable.go +++ b/internal/pkg/agent/operation/operation_retryable.go @@ -18,8 +18,8 @@ import ( // if nth operation fails all preceding are retried as well type retryableOperations struct { logger *logger.Logger - operations []operation retryConfig *retry.Config + operations []operation } func newRetryableOperations( diff --git a/internal/pkg/agent/stateresolver/resolve.go b/internal/pkg/agent/stateresolver/resolve.go index 5afe2256cb6..526ad8befa3 100644 --- a/internal/pkg/agent/stateresolver/resolve.go +++ b/internal/pkg/agent/stateresolver/resolve.go @@ -60,10 +60,10 @@ func (s *state) String() string { } type active struct { - LastChange stateChange + Program program.Program LastModified time.Time Identifier string - Program program.Program + LastChange stateChange } func (s *active) String() string { diff --git a/internal/pkg/composable/providers/kubernetes/pod.go b/internal/pkg/composable/providers/kubernetes/pod.go index a8b11b06585..034df3c7a72 100644 --- a/internal/pkg/composable/providers/kubernetes/pod.go +++ b/internal/pkg/composable/providers/kubernetes/pod.go @@ -23,15 +23,15 @@ import ( ) type pod struct { - logger *logp.Logger - cleanupTimeout time.Duration - comm composable.DynamicProviderComm - scope string - config *Config - metagen metadata.MetaGen watcher kubernetes.Watcher nodeWatcher kubernetes.Watcher + comm composable.DynamicProviderComm + metagen metadata.MetaGen namespaceWatcher kubernetes.Watcher + config *Config + logger *logp.Logger + scope string + cleanupTimeout time.Duration // Mutex used by configuration updates not triggered by the main watcher, // to avoid race conditions between cross updates and deletions. diff --git a/internal/pkg/composable/providers/kubernetesleaderelection/config.go b/internal/pkg/composable/providers/kubernetesleaderelection/config.go index d92d35566a2..7ccc2f9a799 100644 --- a/internal/pkg/composable/providers/kubernetesleaderelection/config.go +++ b/internal/pkg/composable/providers/kubernetesleaderelection/config.go @@ -8,10 +8,12 @@ import "github.com/elastic/elastic-agent-autodiscover/kubernetes" // Config for kubernetes_leaderelection provider type Config struct { - KubeConfig string `config:"kube_config"` - KubeClientOptions kubernetes.KubeClientOptions `config:"kube_client_options"` + KubeConfig string `config:"kube_config"` + // Name of the leaderelection lease LeaderLease string `config:"leader_lease"` + + KubeClientOptions kubernetes.KubeClientOptions `config:"kube_client_options"` } // InitDefaults initializes the default values for the config. diff --git a/internal/pkg/core/plugin/process/app.go b/internal/pkg/core/plugin/process/app.go index acb38ee92df..1c5ad2067af 100644 --- a/internal/pkg/core/plugin/process/app.go +++ b/internal/pkg/core/plugin/process/app.go @@ -35,34 +35,32 @@ var ( // Application encapsulates a concrete application ran by elastic-agent e.g Beat. type Application struct { - bgContext context.Context - id string - name string - pipelineID string - logLevel string - desc *app.Descriptor - srv *server.Server - srvState *server.ApplicationState - limiter *tokenbucket.Bucket - startContext context.Context - tag app.Taggable - state state.State - reporter state.Reporter - watchClosers map[int]context.CancelFunc + state state.State + startContext context.Context + statusReporter status.Reporter + monitor monitoring.Monitor + reporter state.Reporter + tag app.Taggable + bgContext context.Context + srvState *server.ApplicationState + limiter *tokenbucket.Bucket + srv *server.Server + desc *app.Descriptor + restartCanceller context.CancelFunc + logger *logger.Logger + watchClosers map[int]context.CancelFunc + processConfig *process.Config + restartConfig map[string]interface{} + + name string + id string + pipelineID string + logLevel string uid int gid int - monitor monitoring.Monitor - statusReporter status.Reporter - - processConfig *process.Config - - logger *logger.Logger - - appLock sync.Mutex - restartCanceller context.CancelFunc - restartConfig map[string]interface{} + appLock sync.Mutex } // ArgsDecorator decorates arguments before calling an application @@ -79,8 +77,8 @@ func NewApplication( logger *logger.Logger, reporter state.Reporter, monitor monitoring.Monitor, - statusController status.Controller) (*Application, error) { - + statusController status.Controller, +) (*Application, error) { s := desc.ProcessSpec() uid, gid, err := s.UserGroup() if err != nil { @@ -157,7 +155,6 @@ func (a *Application) Stop() { a.logger.Error(err) } - } a.appLock.Lock() diff --git a/internal/pkg/core/state/state.go b/internal/pkg/core/state/state.go index 080efb42c88..a15a8ba4c3c 100644 --- a/internal/pkg/core/state/state.go +++ b/internal/pkg/core/state/state.go @@ -76,9 +76,9 @@ func FromProto(s proto.StateObserved_Status) Status { // State wraps the process state and application status. type State struct { ProcessInfo *process.Info - Status Status - Message string Payload map[string]interface{} + Message string + Status Status } // Reporter is interface that is called when a state is changed. diff --git a/internal/pkg/core/status/reporter.go b/internal/pkg/core/status/reporter.go index 92632af2ed5..9e0f47a9b56 100644 --- a/internal/pkg/core/status/reporter.go +++ b/internal/pkg/core/status/reporter.go @@ -39,19 +39,19 @@ func (s AgentStatusCode) String() string { // AgentApplicationStatus returns the status of specific application. type AgentApplicationStatus struct { + Payload map[string]interface{} ID string Name string - Status state.Status Message string - Payload map[string]interface{} + Status state.Status } // AgentStatus returns the overall status of the Elastic Agent. type AgentStatus struct { - Status AgentStatusCode + UpdateTime time.Time Message string Applications []AgentApplicationStatus - UpdateTime time.Time + Status AgentStatusCode } // Controller takes track of component statuses. @@ -68,15 +68,15 @@ type Controller interface { } type controller struct { - mx sync.Mutex - status AgentStatusCode - message string updateTime time.Time + log *logger.Logger reporters map[string]*reporter appReporters map[string]*reporter - log *logger.Logger stateID string + message string agentID string + status AgentStatusCode + mx sync.Mutex } // NewController creates a new reporter. @@ -272,15 +272,15 @@ type Reporter interface { } type reporter struct { - name string - mx sync.Mutex - isPersistent bool - isRegistered bool - status state.Status - message string payload map[string]interface{} unregisterFunc func() notifyChangeFunc func() + message string + name string + status state.Status + mx sync.Mutex + isRegistered bool + isPersistent bool } // Update updates the status of a component. diff --git a/internal/pkg/crypto/io.go b/internal/pkg/crypto/io.go index 738a216774a..1b25a9a1fa8 100644 --- a/internal/pkg/crypto/io.go +++ b/internal/pkg/crypto/io.go @@ -21,11 +21,11 @@ import ( // Option is the default options used to generate the encrypt and decrypt writer. // NOTE: the defined options need to be same for both the Reader and the writer. type Option struct { + Generator bytesGen IterationsCount int KeyLength int SaltLength int IVLength int - Generator bytesGen // BlockSize must be a factor of aes.BlockSize BlockSize int diff --git a/internal/pkg/fleetapi/acker/retrier/retrier.go b/internal/pkg/fleetapi/acker/retrier/retrier.go index 406d6570611..38961cc1803 100644 --- a/internal/pkg/fleetapi/acker/retrier/retrier.go +++ b/internal/pkg/fleetapi/acker/retrier/retrier.go @@ -32,19 +32,19 @@ type Option func(*Retrier) // Retrier implements retrier for actions acks type Retrier struct { - log *logger.Logger acker BatchAcker // AckBatch provider + log *logger.Logger - initialRetryInterval time.Duration // initial retry interval - maxRetryInterval time.Duration // max retry interval - maxRetries int // configurable maxNumber of retries per action + doneCh chan struct{} // signal channel to kickoff retry loop if not running + kickCh chan struct{} // signal channel when retry loop is done actions []fleetapi.Action // pending actions - mx sync.Mutex - kickCh chan struct{} // signal channel to kickoff retry loop if not running + maxRetryInterval time.Duration // max retry interval + maxRetries int // configurable maxNumber of retries per action + initialRetryInterval time.Duration // initial retry interval - doneCh chan struct{} // signal channel when retry loop is done + mx sync.Mutex } // New creates new instance of retrier @@ -173,7 +173,6 @@ func (r *Retrier) runRetries(ctx context.Context) { default: } r.log.Debug("ack retrier: exit retry loop") - } func (r *Retrier) updateRetriesMap(retries map[string]int, actions []fleetapi.Action, resp *fleetapi.AckResponse) (failed []fleetapi.Action) { diff --git a/internal/pkg/reporter/fleet/reporter.go b/internal/pkg/reporter/fleet/reporter.go index d334a9b45cd..d7694dfc761 100644 --- a/internal/pkg/reporter/fleet/reporter.go +++ b/internal/pkg/reporter/fleet/reporter.go @@ -38,12 +38,12 @@ func (e *event) Message() string { // Reporter is a reporter without any effects, serves just as a showcase for further implementations. type Reporter struct { + lastAck time.Time info agentInfo logger *logger.Logger queue []fleetapi.SerializableEvent - qlock sync.Mutex threshold int - lastAck time.Time + qlock sync.Mutex } type agentInfo interface { From 05c2015c759b015fed10695d6fce7b7a2a134445 Mon Sep 17 00:00:00 2001 From: Florian Lehner Date: Thu, 28 Jul 2022 16:02:37 +0200 Subject: [PATCH 2/2] rename struct element for linter Signed-off-by: Florian Lehner --- .../pipeline/actions/handlers/handler_action_unenroll.go | 1 + internal/pkg/core/plugin/process/app.go | 2 ++ internal/pkg/crypto/io.go | 6 +++--- internal/pkg/reporter/fleet/reporter.go | 6 +++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/internal/pkg/agent/application/pipeline/actions/handlers/handler_action_unenroll.go b/internal/pkg/agent/application/pipeline/actions/handlers/handler_action_unenroll.go index 66b1ce8612b..8abf094ee37 100644 --- a/internal/pkg/agent/application/pipeline/actions/handlers/handler_action_unenroll.go +++ b/internal/pkg/agent/application/pipeline/actions/handlers/handler_action_unenroll.go @@ -75,6 +75,7 @@ func (h *Unenroll) Handle(ctx context.Context, a fleetapi.Action, acker store.Fl } else if h.stateStore != nil { // backup action for future start to avoid starting fleet gateway loop h.stateStore.Add(a) + // nolint: errcheck // Ignore the error at this point. h.stateStore.Save() } diff --git a/internal/pkg/core/plugin/process/app.go b/internal/pkg/core/plugin/process/app.go index 1c5ad2067af..3e2778674e9 100644 --- a/internal/pkg/core/plugin/process/app.go +++ b/internal/pkg/core/plugin/process/app.go @@ -228,6 +228,7 @@ func (a *Application) watch(ctx context.Context, p app.Taggable, proc *process.I a.setState(state.Restarting, msg, nil) // it was a crash + // nolint: errcheck // Ignore the error at this point. a.start(ctx, p, cfg, true) }() } @@ -274,6 +275,7 @@ func (a *Application) setState(s state.Status, msg string, payload map[string]in } func (a *Application) cleanUp() { + // nolint: errcheck // Ignore the error at this point. a.monitor.Cleanup(a.desc.Spec(), a.pipelineID) } diff --git a/internal/pkg/crypto/io.go b/internal/pkg/crypto/io.go index 1b25a9a1fa8..2012bdf1b5c 100644 --- a/internal/pkg/crypto/io.go +++ b/internal/pkg/crypto/io.go @@ -180,7 +180,6 @@ func (w *Writer) Write(b []byte) (int, error) { } func (w *Writer) writeBlock(b []byte) error { - // randomly generate the salt and the initialization vector, this information will be saved // on disk in the file as part of the header iv, err := w.generator(w.option.IVLength) @@ -189,12 +188,14 @@ func (w *Writer) writeBlock(b []byte) error { return w.err } + // nolint: errcheck // Ignore the error at this point. w.writer.Write(iv) encodedBytes := w.gcm.Seal(nil, iv, b, nil) l := make([]byte, 4) binary.LittleEndian.PutUint32(l, uint32(len(encodedBytes))) + // nolint: errcheck // Ignore the error at this point. w.writer.Write(l) _, err = w.writer.Write(encodedBytes) @@ -325,7 +326,7 @@ func (r *Reader) consumeBlock() error { } encodedBytes := make([]byte, l) - _, err = io.ReadAtLeast(r.reader, encodedBytes, int(l)) + _, err = io.ReadAtLeast(r.reader, encodedBytes, l) if err != nil { r.err = errors.Wrapf(err, "fail read the block of %d bytes", l) } @@ -364,7 +365,6 @@ func (r *Reader) Close() error { func randomBytes(length int) ([]byte, error) { r := make([]byte, length) _, err := rand.Read(r) - if err != nil { return nil, err } diff --git a/internal/pkg/reporter/fleet/reporter.go b/internal/pkg/reporter/fleet/reporter.go index d7694dfc761..edf5008bc01 100644 --- a/internal/pkg/reporter/fleet/reporter.go +++ b/internal/pkg/reporter/fleet/reporter.go @@ -18,7 +18,7 @@ import ( type event struct { AgentID string `json:"agent_id"` EventType string `json:"type"` - Ts fleetapi.Time `json:"timestamp"` + TS fleetapi.Time `json:"timestamp"` SubType string `json:"subtype"` Msg string `json:"message"` Payload map[string]interface{} `json:"payload,omitempty"` @@ -29,7 +29,7 @@ func (e *event) Type() string { } func (e *event) Timestamp() time.Time { - return time.Time(e.Ts) + return time.Time(e.TS) } func (e *event) Message() string { @@ -70,7 +70,7 @@ func (r *Reporter) Report(ctx context.Context, e reporter.Event) error { r.queue = append(r.queue, &event{ AgentID: r.info.AgentID(), EventType: e.Type(), - Ts: fleetapi.Time(e.Time()), + TS: fleetapi.Time(e.Time()), SubType: e.SubType(), Msg: e.Message(), Payload: e.Payload(),