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

Default Custom Event Harvest Increase from 10,000 to 30,000 #553

Merged
merged 7 commits into from Nov 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions v3/internal/connect_reply.go
Expand Up @@ -255,6 +255,32 @@ func CreateFullTxnName(input string, reply *ConnectReply, isWeb bool) string {
return reply.SegmentTerms.apply(afterNameRules)
}

// RequestEventLimits sets limits for reservior testing
type RequestEventLimits struct {
CustomEvents int
}

const (
// CustomEventHarvestsPerMinute is the number of times per minute custom events are harvested
CustomEventHarvestsPerMinute = 5
)

// MockConnectReplyEventLimits sets up a mock connect reply to test event limits
func (r *ConnectReply) MockConnectReplyEventLimits(limits *RequestEventLimits) {
r.SetSampleEverything()

r.EventData.Limits.CustomEvents = uintPtr(uint(limits.CustomEvents) / (60 / CustomEventHarvestsPerMinute))

// The mock server will be limited to a maximum of 100,000 events per minute
if limits.CustomEvents > 100000 {
r.EventData.Limits.CustomEvents = uintPtr(uint(100000) / (60 / CustomEventHarvestsPerMinute))
}

if limits.CustomEvents <= 0 {
r.EventData.Limits.CustomEvents = uintPtr(uint(0) / (60 / CustomEventHarvestsPerMinute))
}
}

// SetSampleEverything is used for testing to ensure span events get saved.
func (r *ConnectReply) SetSampleEverything() {
// These constants are not large enough to sample everything forever,
Expand Down
2 changes: 1 addition & 1 deletion v3/internal/limits.go
Expand Up @@ -15,7 +15,7 @@ const (
MaxPayloadSizeInBytes = 1000 * 1000
// MaxCustomEvents is the maximum number of Transaction Events that can be captured
// per 60-second harvest cycle
MaxCustomEvents = 10 * 1000
MaxCustomEvents = 30 * 1000
// MaxLogEvents is the maximum number of Log Events that can be captured per
// 60-second harvest cycle
MaxLogEvents = 10 * 1000
Expand Down
5 changes: 5 additions & 0 deletions v3/newrelic/config_options.go
Expand Up @@ -47,6 +47,11 @@ func ConfigCustomInsightsEventsMaxSamplesStored(limit int) ConfigOption {
return func(cfg *Config) { cfg.CustomInsightsEvents.MaxSamplesStored = limit }
}

// ConfigCustomInsightsEventsEnabled enables or disables the collection of custom insight events.
func ConfigCustomInsightsEventsEnabled(enabled bool) ConfigOption {
return func(cfg *Config) { cfg.CustomInsightsEvents.Enabled = enabled }
}

// 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
118 changes: 118 additions & 0 deletions v3/newrelic/reservoir_limits_test.go
@@ -0,0 +1,118 @@
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package newrelic

import (
"testing"

"github.com/newrelic/go-agent/v3/internal"
)

// Check Default Value
func TestCustomLimitsBasic(t *testing.T) {
limit := internal.MaxCustomEvents
limits := &internal.RequestEventLimits{
CustomEvents: limit,
}
// This function will mock a connect reply from the server
mockReplyFunction := func(reply *internal.ConnectReply) {
reply.MockConnectReplyEventLimits(limits)
}
testApp := newTestApp(
mockReplyFunction,
ConfigCustomInsightsEventsMaxSamplesStored(limit),
)

customEventRate := limit / (60 / internal.CustomEventHarvestsPerMinute)

// Check if custom event queue capacity == rate
if customEventRate != testApp.app.testHarvest.CustomEvents.capacity() {
t.Errorf("Custom Events Rate is not equal to harvest: expected %d, actual %d", customEventRate, testApp.app.testHarvest.CustomEvents.capacity())
}
}
func TestCustomEventLimitUserSet(t *testing.T) {
limit := 7000
limits := &internal.RequestEventLimits{
CustomEvents: limit,
}
mockReplyFunction := func(reply *internal.ConnectReply) {
reply.MockConnectReplyEventLimits(limits)
}
testApp := newTestApp(
mockReplyFunction,
ConfigCustomInsightsEventsMaxSamplesStored(limit),
)

customEventRate := limit / (60 / internal.CustomEventHarvestsPerMinute)

if customEventRate != testApp.app.testHarvest.CustomEvents.capacity() {
t.Errorf("Custom Events Rate is not equal to harvest: expected %d, actual %d", customEventRate, testApp.app.testHarvest.CustomEvents.capacity())
}
}

func TestCustomLimitEnthusiast(t *testing.T) {
limit := 100000
limits := &internal.RequestEventLimits{
CustomEvents: limit,
}
// This function will mock a connect reply from the server
mockReplyFunction := func(reply *internal.ConnectReply) {
reply.MockConnectReplyEventLimits(limits)
}
testApp := newTestApp(
mockReplyFunction,
ConfigCustomInsightsEventsMaxSamplesStored(limit),
)

customEventRate := limit / (60 / internal.CustomEventHarvestsPerMinute)

// Check if custom event queue capacity == rate
if customEventRate != testApp.app.testHarvest.CustomEvents.capacity() {
t.Errorf("Custom Events Rate is not equal to harvest: expected %d, actual %d", customEventRate, testApp.app.testHarvest.CustomEvents.capacity())
}
}

func TestCustomLimitsTypo(t *testing.T) {
limit := 1000000
limits := &internal.RequestEventLimits{
CustomEvents: limit,
}
// This function will mock a connect reply from the server
mockReplyFunction := func(reply *internal.ConnectReply) {
reply.MockConnectReplyEventLimits(limits)
}
testApp := newTestApp(
mockReplyFunction,
ConfigCustomInsightsEventsMaxSamplesStored(limit),
)

customEventRate := 100000 / (60 / internal.CustomEventHarvestsPerMinute)

// Check if custom event queue capacity == rate
if customEventRate != testApp.app.testHarvest.CustomEvents.capacity() {
t.Errorf("Custom Events Rate is not equal to harvest: expected %d, actual %d", 8333, testApp.app.testHarvest.CustomEvents.capacity())
}
}

func TestCustomLimitZero(t *testing.T) {
limit := 0
limits := &internal.RequestEventLimits{
CustomEvents: limit,
}
// This function will mock a connect reply from the server
mockReplyFunction := func(reply *internal.ConnectReply) {
reply.MockConnectReplyEventLimits(limits)
}
testApp := newTestApp(
mockReplyFunction,
ConfigCustomInsightsEventsMaxSamplesStored(limit),
)

customEventRate := limit / (60 / internal.CustomEventHarvestsPerMinute)

// Check if custom event queue capacity == rate
if customEventRate != testApp.app.testHarvest.CustomEvents.capacity() {
t.Errorf("Custom Events Rate is not equal to harvest: expected %d, actual %d", customEventRate, testApp.app.testHarvest.CustomEvents.capacity())
}
}