Skip to content

Commit

Permalink
Custom Events Limiter (#524)
Browse files Browse the repository at this point in the history
Allows custom events to be configured by users and adds tests to verify changes.
  • Loading branch information
mirackara committed Jun 29, 2022
1 parent 69c4599 commit ea1dcf9
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 11 deletions.
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)
}
}

0 comments on commit ea1dcf9

Please sign in to comment.