From 8bb2bf55c1f82388b330ed3e956eaa749ea054e8 Mon Sep 17 00:00:00 2001 From: Dan Jaglowski Date: Thu, 26 Sep 2024 16:43:03 -0400 Subject: [PATCH] Separate concerns --- .chloggen/wel-supress-rendering-info2.yaml | 2 +- .../operator/input/windows/config_all.go | 18 +-- .../operator/input/windows/config_windows.go | 25 ++-- pkg/stanza/operator/input/windows/input.go | 109 ++++++++++-------- 4 files changed, 89 insertions(+), 65 deletions(-) diff --git a/.chloggen/wel-supress-rendering-info2.yaml b/.chloggen/wel-supress-rendering-info2.yaml index 978cce3a1405..466f181d809e 100644 --- a/.chloggen/wel-supress-rendering-info2.yaml +++ b/.chloggen/wel-supress-rendering-info2.yaml @@ -7,7 +7,7 @@ change_type: 'breaking' component: windowseventlogreceiver # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: The 'raw' flag no longer supresses rendering info. +note: The 'raw' flag no longer suppresses rendering info. # Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. issues: [34720] diff --git a/pkg/stanza/operator/input/windows/config_all.go b/pkg/stanza/operator/input/windows/config_all.go index 396ebc90122c..1952edf5c27f 100644 --- a/pkg/stanza/operator/input/windows/config_all.go +++ b/pkg/stanza/operator/input/windows/config_all.go @@ -28,15 +28,15 @@ func NewConfigWithID(operatorID string) *Config { // Config is the configuration of a windows event log operator. type Config struct { - helper.InputConfig `mapstructure:",squash"` - Channel string `mapstructure:"channel"` - MaxReads int `mapstructure:"max_reads,omitempty"` - StartAt string `mapstructure:"start_at,omitempty"` - PollInterval time.Duration `mapstructure:"poll_interval,omitempty"` - Raw bool `mapstructure:"raw,omitempty"` - SupressRenderingInfo bool `mapstructure:"suppress_rendering_info,omitempty"` - ExcludeProviders []string `mapstructure:"exclude_providers,omitempty"` - Remote RemoteConfig `mapstructure:"remote,omitempty"` + helper.InputConfig `mapstructure:",squash"` + Channel string `mapstructure:"channel"` + MaxReads int `mapstructure:"max_reads,omitempty"` + StartAt string `mapstructure:"start_at,omitempty"` + PollInterval time.Duration `mapstructure:"poll_interval,omitempty"` + Raw bool `mapstructure:"raw,omitempty"` + SuppressRenderingInfo bool `mapstructure:"suppress_rendering_info,omitempty"` + ExcludeProviders []string `mapstructure:"exclude_providers,omitempty"` + Remote RemoteConfig `mapstructure:"remote,omitempty"` } // RemoteConfig is the configuration for a remote server. diff --git a/pkg/stanza/operator/input/windows/config_windows.go b/pkg/stanza/operator/input/windows/config_windows.go index 86ff18ddc68c..72c5ec48f820 100644 --- a/pkg/stanza/operator/input/windows/config_windows.go +++ b/pkg/stanza/operator/input/windows/config_windows.go @@ -42,19 +42,24 @@ func (c *Config) Build(set component.TelemetrySettings) (operator.Operator, erro } input := &Input{ - InputOperator: inputOperator, - buffer: NewBuffer(), - channel: c.Channel, - maxReads: c.MaxReads, - startAt: c.StartAt, - pollInterval: c.PollInterval, - raw: c.Raw, - supressRenderingInfo: c.SupressRenderingInfo, - excludeProviders: excludeProvidersSet(c.ExcludeProviders), - remote: c.Remote, + InputOperator: inputOperator, + buffer: NewBuffer(), + channel: c.Channel, + maxReads: c.MaxReads, + startAt: c.StartAt, + pollInterval: c.PollInterval, + raw: c.Raw, + excludeProviders: excludeProvidersSet(c.ExcludeProviders), + remote: c.Remote, } input.startRemoteSession = input.defaultStartRemoteSession + if c.SuppressRenderingInfo { + input.processEvent = input.processEventWithoutRenderingInfo + } else { + input.processEvent = input.processEventWithRenderingInfo + } + return input, nil } diff --git a/pkg/stanza/operator/input/windows/input.go b/pkg/stanza/operator/input/windows/input.go index 6228a51de77b..bbd69cab0cdf 100644 --- a/pkg/stanza/operator/input/windows/input.go +++ b/pkg/stanza/operator/input/windows/input.go @@ -23,23 +23,23 @@ import ( // Input is an operator that creates entries using the windows event log api. type Input struct { helper.InputOperator - bookmark Bookmark - buffer Buffer - channel string - maxReads int - startAt string - raw bool - supressRenderingInfo bool - excludeProviders map[string]struct{} - pollInterval time.Duration - persister operator.Persister - publisherCache publisherCache - cancel context.CancelFunc - wg sync.WaitGroup - subscription Subscription - remote RemoteConfig - remoteSessionHandle windows.Handle - startRemoteSession func() error + bookmark Bookmark + buffer Buffer + channel string + maxReads int + startAt string + raw bool + excludeProviders map[string]struct{} + pollInterval time.Duration + persister operator.Persister + publisherCache publisherCache + cancel context.CancelFunc + wg sync.WaitGroup + subscription Subscription + remote RemoteConfig + remoteSessionHandle windows.Handle + startRemoteSession func() error + processEvent func(context.Context, Event) } // newInput creates a new Input operator. @@ -231,51 +231,70 @@ func (i *Input) read(ctx context.Context) int { return len(events) } -// processEvent will process and send an event retrieved from windows event log. -func (i *Input) processEvent(ctx context.Context, event Event) { +func (i *Input) getPublisherName(event Event) (name string, excluded bool) { providerName, err := event.GetPublisherName(i.buffer) if err != nil { i.Logger().Error("Failed to get provider name", zap.Error(err)) - return + return "", true } if _, exclude := i.excludeProviders[providerName]; exclude { + return "", true + } + + return providerName, false +} + +func (i *Input) renderSimpleAndSend(ctx context.Context, event Event) { + simpleEvent, err := event.RenderSimple(i.buffer) + if err != nil { + i.Logger().Error("Failed to render simple event", zap.Error(err)) return } + i.sendEvent(ctx, simpleEvent) +} - if i.supressRenderingInfo { - simpleEvent, simpleErr := event.RenderSimple(i.buffer) - if simpleErr != nil { - i.Logger().Error("Failed to render simple event", zap.Error(simpleErr)) - return - } - i.sendEvent(ctx, simpleEvent) +func (i *Input) renderDeepAndSend(ctx context.Context, event Event, publisher Publisher) { + deepEvent, err := event.RenderDeep(i.buffer, publisher) + if err == nil { + i.sendEvent(ctx, deepEvent) return } + i.Logger().Error("Failed to render formatted event", zap.Error(err)) + i.renderSimpleAndSend(ctx, event) +} - publisher, openPublisherErr := i.publisherCache.get(providerName) - if openPublisherErr != nil { - // Do not return. Log error here and try to send as simple event later. +// processEvent will process and send an event retrieved from windows event log. +func (i *Input) processEventWithoutRenderingInfo(ctx context.Context, event Event) { + if len(i.excludeProviders) == 0 { + i.renderSimpleAndSend(ctx, event) + return + } + if _, exclude := i.getPublisherName(event); exclude { + return + } + i.renderSimpleAndSend(ctx, event) +} + +func (i *Input) processEventWithRenderingInfo(ctx context.Context, event Event) { + providerName, exclude := i.getPublisherName(event) + if exclude { + return + } + + publisher, err := i.publisherCache.get(providerName) + if err != nil { i.Logger().Warn( "Failed to open event source, respective log entries cannot be formatted", - zap.String("provider", providerName), zap.Error(openPublisherErr)) - } else if publisher.Valid() { - deepEvent, deepErr := event.RenderDeep(i.buffer, publisher) - if deepErr != nil { - // Do not return. Log error here and try to send as simple event later. - i.Logger().Error("Failed to render formatted event", zap.Error(deepErr)) - } else { - i.sendEvent(ctx, deepEvent) - return - } + zap.String("provider", providerName), zap.Error(err)) + i.renderSimpleAndSend(ctx, event) + return } - // Since we coudn't render the event deeply, send it as a simple event. - simpleEvent, err := event.RenderSimple(i.buffer) - if err != nil { - i.Logger().Error("Failed to render simple event as fallback", zap.Error(err)) + if publisher.Valid() { + i.renderDeepAndSend(ctx, event, publisher) return } - i.sendEvent(ctx, simpleEvent) + i.renderSimpleAndSend(ctx, event) } // sendEvent will send EventXML as an entry to the operator's output.