From d3fdfe5264e64cb333795b32edbad36cfaab3dc7 Mon Sep 17 00:00:00 2001 From: Cory Hall <43035978+corymhall@users.noreply.github.com> Date: Fri, 4 Mar 2022 15:10:40 -0500 Subject: [PATCH] fix(cli): `watch` logs always end with the 'truncated' message (#19241) CloudWatchLogs.filterLogEvents will always return a `nextToken` as long as there are _any_ additional logs. This is regardless of any filter used (i.e. `startTime`). This PR updates the logic to only display the truncated message if `CloudWatchLogs.filterLogEvents` returns 100 events (the `limit`) _and_ the `nextToken`. If the limit is hit and there is a `nextToken` then we can assume that the _current_ request for log events was truncated. fixes #18805 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/lib/api/logs/logs-monitor.ts | 9 ++-- .../test/api/logs/logs-monitor.test.ts | 45 +++++++++++++++++-- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/packages/aws-cdk/lib/api/logs/logs-monitor.ts b/packages/aws-cdk/lib/api/logs/logs-monitor.ts index f6f2086bc20bf..9ad1ed393f5ce 100644 --- a/packages/aws-cdk/lib/api/logs/logs-monitor.ts +++ b/packages/aws-cdk/lib/api/logs/logs-monitor.ts @@ -198,10 +198,11 @@ export class CloudWatchLogEventMonitor { } } - // if we have > 100 events let the user know some - // messages have been supressed. We are essentially - // showing them a sampling (10000 events printed out is not very useful) - if (filteredEvents.length > 0 && response.nextToken) { + // As long as there are _any_ events in the log group `filterLogEvents` will return a nextToken. + // This is true even if these events are before `startTime`. So if we have 100 events and a nextToken + // then assume that we have hit the limit and let the user know some messages have been supressed. + // We are essentially showing them a sampling (10000 events printed out is not very useful) + if (filteredEvents.length === 100 && response.nextToken) { events.push({ message: '>>> `watch` shows only the first 100 log messages - the rest have been truncated...', logGroupName, diff --git a/packages/aws-cdk/test/api/logs/logs-monitor.test.ts b/packages/aws-cdk/test/api/logs/logs-monitor.test.ts index 930e6427dbab7..eed3cf2683540 100644 --- a/packages/aws-cdk/test/api/logs/logs-monitor.test.ts +++ b/packages/aws-cdk/test/api/logs/logs-monitor.test.ts @@ -12,18 +12,55 @@ beforeEach(() => { sdk = new MockSdk(); }); -afterAll(() => { +afterEach(() => { stderrMock.mockRestore(); monitor.deactivate(); }); -test('continue to the next page if it exists', async () => { +test('process events', async () => { // GIVEN const eventDate = new Date(T0 + 102 * 1000); sdk.stubCloudWatchLogs({ filterLogEvents() { return { events: [event(102, 'message', eventDate)], + }; + }, + }); + monitor.addLogGroups( + { + name: 'name', + account: '11111111111', + region: 'us-east-1', + }, + sdk, + ['loggroup'], + ); + // WHEN + monitor.activate(); + // need time for the log processing to occur + await sleep(1000); + + // THEN + const expectedLocaleTimeString = eventDate.toLocaleTimeString(); + expect(stderrMock).toHaveBeenCalledTimes(1); + expect(stderrMock.mock.calls[0][0]).toContain( + `[${blue('loggroup')}] ${yellow(expectedLocaleTimeString)} message`, + ); +}); + +test('process truncated events', async () => { + // GIVEN + const eventDate = new Date(T0 + 102 * 1000); + const events: AWS.CloudWatchLogs.FilteredLogEvents = []; + for (let i = 0; i < 100; i++) { + events.push(event(102+i, 'message' + i, eventDate)); + } + + sdk.stubCloudWatchLogs({ + filterLogEvents() { + return { + events, nextToken: 'some-token', }; }, @@ -44,11 +81,11 @@ test('continue to the next page if it exists', async () => { // THEN const expectedLocaleTimeString = eventDate.toLocaleTimeString(); - expect(stderrMock).toHaveBeenCalledTimes(2); + expect(stderrMock).toHaveBeenCalledTimes(101); expect(stderrMock.mock.calls[0][0]).toContain( `[${blue('loggroup')}] ${yellow(expectedLocaleTimeString)} message`, ); - expect(stderrMock.mock.calls[1][0]).toContain( + expect(stderrMock.mock.calls[100][0]).toContain( `[${blue('loggroup')}] ${yellow(expectedLocaleTimeString)} >>> \`watch\` shows only the first 100 log messages - the rest have been truncated...`, ); });