Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Events Limiter #524

Merged
merged 10 commits into from Jun 29, 2022
8 changes: 4 additions & 4 deletions v3/internal/connect_reply.go
Expand Up @@ -137,20 +137,20 @@ func (r *ConnectReply) ConfigurablePeriod() time.Duration {
func uintPtr(x uint) *uint { return &x }

// DefaultEventHarvestConfig provides faster event harvest defaults.
func DefaultEventHarvestConfig(maxTxnEvents, maxLogEvents int) EventHarvestConfig {
func DefaultEventHarvestConfig(maxTxnEvents, maxLogEvents, maxCustomEvents int) EventHarvestConfig {
cfg := EventHarvestConfig{}
cfg.ReportPeriodMs = DefaultConfigurableEventHarvestMs
cfg.Limits.TxnEvents = uintPtr(uint(maxTxnEvents))
cfg.Limits.CustomEvents = uintPtr(uint(MaxCustomEvents))
cfg.Limits.CustomEvents = uintPtr(uint(maxCustomEvents))
cfg.Limits.LogEvents = uintPtr(uint(maxLogEvents))
cfg.Limits.ErrorEvents = uintPtr(uint(MaxErrorEvents))
return cfg
}

// DefaultEventHarvestConfigWithDT is an extended version of DefaultEventHarvestConfig,
// with the addition that it takes into account distributed tracer span event harvest limits.
func DefaultEventHarvestConfigWithDT(maxTxnEvents, maxLogEvents, spanEventLimit int, dtEnabled bool) EventHarvestConfig {
cfg := DefaultEventHarvestConfig(maxTxnEvents, maxLogEvents)
func DefaultEventHarvestConfigWithDT(maxTxnEvents, maxLogEvents, maxCustomEvents, spanEventLimit int, dtEnabled bool) EventHarvestConfig {
cfg := DefaultEventHarvestConfig(maxTxnEvents, maxLogEvents, maxCustomEvents)
if dtEnabled {
cfg.Limits.SpanEvents = uintPtr(uint(spanEventLimit))
}
Expand Down
2 changes: 1 addition & 1 deletion v3/internal/connect_reply_test.go
Expand Up @@ -173,7 +173,7 @@ func TestNegativeHarvestLimits(t *testing.T) {
}

func TestDefaultEventHarvestConfigJSON(t *testing.T) {
js, err := json.Marshal(DefaultEventHarvestConfig(MaxTxnEvents, MaxLogEvents))
js, err := json.Marshal(DefaultEventHarvestConfig(MaxTxnEvents, MaxLogEvents, MaxCustomEvents))
if err != nil {
t.Error(err)
}
Expand Down
21 changes: 17 additions & 4 deletions v3/newrelic/config.go
Expand Up @@ -71,6 +71,8 @@ type Config struct {
// custom analytics events. High security mode overrides this
// setting.
Enabled bool
// MaxSamplesStored sets the desired maximum custom event samples stored
MaxSamplesStored int
}

// TransactionEvents controls the behavior of transaction analytics
Expand Down Expand Up @@ -408,6 +410,7 @@ func defaultConfig() Config {
c.Enabled = true
c.Labels = make(map[string]string)
c.CustomInsightsEvents.Enabled = true
c.CustomInsightsEvents.MaxSamplesStored = internal.MaxCustomEvents
c.TransactionEvents.Enabled = true
c.TransactionEvents.Attributes.Enabled = true
c.TransactionEvents.MaxSamplesStored = internal.MaxTxnEvents
Expand Down Expand Up @@ -545,12 +548,22 @@ func (c Config) maxTxnEvents() int {
return configured
}

// maxTxnEvents returns the configured maximum number of Transaction Events if it has been configured
// maxCustomEvents returns the configured maximum number of Custom Events if it has been configured
// and is less than the default maximum; otherwise it returns the default max.
func (c Config) maxCustomEvents() int {
configured := c.CustomInsightsEvents.MaxSamplesStored
if configured < 0 || configured > internal.MaxCustomEvents {
return internal.MaxCustomEvents
}
return configured
}

// maxLogEvents returns the configured maximum number of Log Events if it has been configured
// and is less than the default maximum; otherwise it returns the default max.
func (c Config) maxLogEvents() int {
configured := c.ApplicationLogging.Forwarding.MaxSamplesStored
if configured < 0 || configured > internal.MaxTxnEvents {
return internal.MaxTxnEvents
if configured < 0 || configured > internal.MaxLogEvents {
return internal.MaxLogEvents
}
return configured
}
Expand Down Expand Up @@ -709,7 +722,7 @@ func configConnectJSONInternal(c Config, pid int, util *utilization.Data, e envi
Util: util,
SecurityPolicies: securityPolicies,
Metadata: metadata,
EventData: internal.DefaultEventHarvestConfigWithDT(c.maxTxnEvents(), c.maxLogEvents(), c.DistributedTracer.ReservoirLimit, c.DistributedTracer.Enabled),
EventData: internal.DefaultEventHarvestConfigWithDT(c.maxTxnEvents(), c.maxLogEvents(), c.maxCustomEvents(), c.DistributedTracer.ReservoirLimit, c.DistributedTracer.Enabled),
}})
}

Expand Down
7 changes: 7 additions & 0 deletions v3/newrelic/config_options.go
Expand Up @@ -36,6 +36,13 @@ func ConfigDistributedTracerEnabled(enabled bool) ConfigOption {
return func(cfg *Config) { cfg.DistributedTracer.Enabled = enabled }
}

// ConfigCustomInsightsEventsMaxSamplesStored alters the sample size allowing control
// of how many custom events are stored in an agent for a given harvest cycle.
// Alters the CustomInsightsEvents.MaxSamplesStored setting.
func ConfigCustomInsightsEventsMaxSamplesStored(limit int) ConfigOption {
return func(cfg *Config) { cfg.CustomInsightsEvents.MaxSamplesStored = limit }
}

// ConfigDistributedTracerReservoirLimit alters the sample reservoir size (maximum
// number of span events to be collected) for distributed tracing instead of
// using the built-in default.
Expand Down
20 changes: 18 additions & 2 deletions v3/newrelic/config_test.go
Expand Up @@ -145,7 +145,10 @@ func TestCopyConfigReferenceFieldsPresent(t *testing.T) {
"Enabled":true
},
"CrossApplicationTracer":{"Enabled":false},
"CustomInsightsEvents":{"Enabled":true},
"CustomInsightsEvents":{
"Enabled":true,
"MaxSamplesStored":10000
},
"DatastoreTracer":{
"DatabaseNameReporting":{"Enabled":true},
"InstanceReporting":{"Enabled":true},
Expand Down Expand Up @@ -333,7 +336,10 @@ func TestCopyConfigReferenceFieldsAbsent(t *testing.T) {
"Enabled":true
},
"CrossApplicationTracer":{"Enabled":false},
"CustomInsightsEvents":{"Enabled":true},
"CustomInsightsEvents":{
"Enabled":true,
"MaxSamplesStored":10000
},
"DatastoreTracer":{
"DatabaseNameReporting":{"Enabled":true},
"InstanceReporting":{"Enabled":true},
Expand Down Expand Up @@ -797,3 +803,13 @@ func TestNewInternalConfig(t *testing.T) {
t.Error(c.metadata)
}
}

func TestConfigurableMaxCustomEvents(t *testing.T) {
expected := 1000
cfg := config{Config: defaultConfig()}
cfg.CustomInsightsEvents.MaxSamplesStored = expected
result := cfg.maxCustomEvents()
if result != expected {
t.Errorf("Unexpected max number of custom events, expected %d but got %d", expected, result)
}
}