Skip to content

Commit

Permalink
👌use single option + limit log with custom status
Browse files Browse the repository at this point in the history
  • Loading branch information
amortemousque committed Jan 6, 2022
1 parent 3a47229 commit 331753d
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 36 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/domain/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export interface Configuration extends TransportConfiguration {
silentMultipleInit: boolean

// Event limits
maxErrorsPerMinute: number
eventRateLimiterThreshold: number // Limit the maximum number of actions, errors and logs per minutes
maxInternalMonitoringMessagesPerPage: number
requestErrorResponseLengthLimit: number

Expand Down Expand Up @@ -103,7 +103,7 @@ export function validateAndBuildConfiguration(
*/
batchBytesLimit: 16 * ONE_KILO_BYTE,

maxErrorsPerMinute: 3000,
eventRateLimiterThreshold: 3000,
maxInternalMonitoringMessagesPerPage: 15,

/**
Expand Down
17 changes: 9 additions & 8 deletions packages/logs/src/boot/startLogs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,14 +340,15 @@ describe('logs', () => {
})
})
;[
{ status: StatusType.error, configuration: { maxErrorsPerMinute: 1 } },
{ status: StatusType.warn, configuration: { maxWarningsPerMinute: 1 } },
{ status: StatusType.info, configuration: { maxInfosPerMinute: 1 } },
{ status: StatusType.debug, configuration: { maxDebugsPerMinute: 1 } },
].forEach(({ status, configuration }) => {
{ status: StatusType.error, message: 'Reached max number of errors by minute: 1' },
{ status: StatusType.warn, message: 'Reached max number of warns by minute: 1' },
{ status: StatusType.info, message: 'Reached max number of infos by minute: 1' },
{ status: StatusType.debug, message: 'Reached max number of debugs by minute: 1' },
{ status: 'unknown' as StatusType, message: 'Reached max number of customs by minute: 1' },
].forEach(({ status, message }) => {
describe(`${status} logs limitation`, () => {
let clock: Clock

const configuration = { eventRateLimiterThreshold: 1 }
beforeEach(() => {
clock = mockClock()
})
Expand All @@ -365,7 +366,7 @@ describe('logs', () => {
expect(server.requests.length).toEqual(1)
expect(getLoggedMessage(server, 0).message).toBe('foo')
expect(sendLogSpy).toHaveBeenCalledOnceWith({
message: `Reached max number of ${status}s by minute: 1`,
message,
status: StatusType.error,
error: {
origin: ErrorSource.AGENT,
Expand All @@ -376,7 +377,7 @@ describe('logs', () => {
})
})

it(`does not take discarded ${status}s into account`, () => {
it(`does not take discarded ${status} los into account`, () => {
const sendLogSpy = jasmine.createSpy<(message: LogsMessage & { foo?: string }) => void>()
const sendLog = startLogs({
errorLogger: new Logger(sendLogSpy),
Expand Down
11 changes: 6 additions & 5 deletions packages/logs/src/boot/startLogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,11 @@ export function buildAssemble(
reportError: (error: RawError) => void
) {
const logRateLimiters = {
[StatusType.error]: createEventRateLimiter(StatusType.error, configuration.maxErrorsPerMinute, reportError),
[StatusType.warn]: createEventRateLimiter(StatusType.warn, configuration.maxWarningsPerMinute, reportError),
[StatusType.info]: createEventRateLimiter(StatusType.info, configuration.maxInfosPerMinute, reportError),
[StatusType.debug]: createEventRateLimiter(StatusType.debug, configuration.maxDebugsPerMinute, reportError),
[StatusType.error]: createEventRateLimiter(StatusType.error, configuration.eventRateLimiterThreshold, reportError),
[StatusType.warn]: createEventRateLimiter(StatusType.warn, configuration.eventRateLimiterThreshold, reportError),
[StatusType.info]: createEventRateLimiter(StatusType.info, configuration.eventRateLimiterThreshold, reportError),
[StatusType.debug]: createEventRateLimiter(StatusType.debug, configuration.eventRateLimiterThreshold, reportError),
['custom']: createEventRateLimiter('custom', configuration.eventRateLimiterThreshold, reportError),
}

return (message: LogsMessage, currentContext: Context) => {
Expand All @@ -126,7 +127,7 @@ export function buildAssemble(

if (
configuration.beforeSend?.(contextualizedMessage) === false ||
logRateLimiters[contextualizedMessage.status]?.isLimitReached()
(logRateLimiters[contextualizedMessage.status] ?? logRateLimiters['custom']).isLimitReached()
) {
return undefined
}
Expand Down
8 changes: 0 additions & 8 deletions packages/logs/src/domain/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ export type HybridInitConfiguration = Omit<LogsInitConfiguration, 'clientToken'>

export interface LogsConfiguration extends Configuration {
forwardErrorsToLogs: boolean

// Event limits
maxWarningsPerMinute: number
maxInfosPerMinute: number
maxDebugsPerMinute: number
}

export function validateAndBuildLogsConfiguration(
Expand All @@ -30,8 +25,5 @@ export function validateAndBuildLogsConfiguration(
...baseConfiguration,

forwardErrorsToLogs: !!initConfiguration.forwardErrorsToLogs,
maxWarningsPerMinute: 3000,
maxInfosPerMinute: 3000,
maxDebugsPerMinute: 3000,
}
}
18 changes: 12 additions & 6 deletions packages/rum-core/src/domain/assembly.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ describe('rum assembly', () => {
})

it('stops sending error events when reaching the limit', () => {
const { lifeCycle } = setupBuilder.withConfiguration({ maxErrorsPerMinute: 1 }).build()
const { lifeCycle } = setupBuilder.withConfiguration({ eventRateLimiterThreshold: 1 }).build()
notifyRawRumErrorEvent(lifeCycle, 'foo')
notifyRawRumErrorEvent(lifeCycle, 'bar')

Expand All @@ -631,7 +631,7 @@ describe('rum assembly', () => {
it('does not take discarded errors into account', () => {
const { lifeCycle } = setupBuilder
.withConfiguration({
maxErrorsPerMinute: 1,
eventRateLimiterThreshold: 1,
beforeSend: (event) => {
if (event.type === RumEventType.ERROR && (event as RumErrorEvent).error.message === 'discard me') {
return false
Expand All @@ -649,7 +649,10 @@ describe('rum assembly', () => {
})

it('allows to send new errors after a minute', () => {
const { lifeCycle, clock } = setupBuilder.withFakeClock().withConfiguration({ maxErrorsPerMinute: 1 }).build()
const { lifeCycle, clock } = setupBuilder
.withFakeClock()
.withConfiguration({ eventRateLimiterThreshold: 1 })
.build()
notifyRawRumErrorEvent(lifeCycle, 'foo')
notifyRawRumErrorEvent(lifeCycle, 'bar')
clock.tick(ONE_MINUTE)
Expand Down Expand Up @@ -680,7 +683,7 @@ describe('rum assembly', () => {
})

it('stops sending action events when reaching the limit', () => {
const { lifeCycle } = setupBuilder.withConfiguration({ maxActionsPerMinute: 1 }).build()
const { lifeCycle } = setupBuilder.withConfiguration({ eventRateLimiterThreshold: 1 }).build()

notifyRumActionEvent(lifeCycle, 'foo')
notifyRumActionEvent(lifeCycle, 'bar')
Expand All @@ -699,7 +702,7 @@ describe('rum assembly', () => {
it('does not take discarded actions into account', () => {
const { lifeCycle } = setupBuilder
.withConfiguration({
maxErrorsPerMinute: 1,
eventRateLimiterThreshold: 1,
beforeSend: (event) => {
if (event.type === RumEventType.ACTION && (event as RumActionEvent).action.target?.name === 'discard me') {
return false
Expand All @@ -717,7 +720,10 @@ describe('rum assembly', () => {
})

it('allows to send new actions after a minute', () => {
const { lifeCycle, clock } = setupBuilder.withFakeClock().withConfiguration({ maxActionsPerMinute: 1 }).build()
const { lifeCycle, clock } = setupBuilder
.withFakeClock()
.withConfiguration({ eventRateLimiterThreshold: 1 })
.build()
notifyRumActionEvent(lifeCycle, 'foo')
notifyRumActionEvent(lifeCycle, 'bar')
clock.tick(ONE_MINUTE)
Expand Down
12 changes: 10 additions & 2 deletions packages/rum-core/src/domain/assembly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,16 @@ export function startRumAssembly(
}

const eventRateLimiters = {
[RumEventType.ERROR]: createEventRateLimiter(RumEventType.ERROR, configuration.maxErrorsPerMinute, reportError),
[RumEventType.ACTION]: createEventRateLimiter(RumEventType.ACTION, configuration.maxActionsPerMinute, reportError),
[RumEventType.ERROR]: createEventRateLimiter(
RumEventType.ERROR,
configuration.eventRateLimiterThreshold,
reportError
),
[RumEventType.ACTION]: createEventRateLimiter(
RumEventType.ACTION,
configuration.eventRateLimiterThreshold,
reportError
),
}

const syntheticsContext = getSyntheticsContext()
Expand Down
5 changes: 0 additions & 5 deletions packages/rum-core/src/domain/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ export interface RumConfiguration extends Configuration {
replaySampleRate: number
trackInteractions: boolean
trackViewsManually: boolean

// Event limits
maxActionsPerMinute: number
}

export function validateAndBuildRumConfiguration(
Expand Down Expand Up @@ -88,7 +85,5 @@ export function validateAndBuildRumConfiguration(
defaultPrivacyLevel: objectHasValue(DefaultPrivacyLevel, initConfiguration.defaultPrivacyLevel)
? initConfiguration.defaultPrivacyLevel
: DefaultPrivacyLevel.MASK_USER_INPUT,

maxActionsPerMinute: 3000,
}
}

0 comments on commit 331753d

Please sign in to comment.