diff --git a/packages/core/src/awsService/cloudWatchLogs/commands/tailLogGroup.ts b/packages/core/src/awsService/cloudWatchLogs/commands/tailLogGroup.ts index 53903f9610d..129d22760ee 100644 --- a/packages/core/src/awsService/cloudWatchLogs/commands/tailLogGroup.ts +++ b/packages/core/src/awsService/cloudWatchLogs/commands/tailLogGroup.ts @@ -3,26 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import * as nls from 'vscode-nls' -import { DefaultCloudWatchLogsClient } from '../../../shared/clients/cloudWatchLogsClient' -import { createBackButton, createExitButton, createHelpButton } from '../../../shared/ui/buttons' -import { createInputBox } from '../../../shared/ui/inputPrompter' -import { DataQuickPickItem } from '../../../shared/ui/pickerPrompter' -import { Wizard } from '../../../shared/wizards/wizard' -import { CloudWatchLogsGroupInfo } from '../registry/logDataRegistry' -import { RegionSubmenu, RegionSubmenuResponse } from '../../../shared/ui/common/regionSubmenu' +import { TailLogGroupWizard } from '../wizard/tailLogGroupWizard' +import { getLogger } from '../../../shared' import { CancellationError } from '../../../shared/utilities/timeoutUtils' -import { LogStreamFilterResponse, LogStreamFilterSubmenu } from '../liveTailLogStreamSubmenu' -import { getLogger, ToolkitError } from '../../../shared' -import { cwlFilterPatternHelpUrl } from '../../../shared/constants' - -const localize = nls.loadMessageBundle() - -export interface TailLogGroupWizardResponse { - regionLogGroupSubmenuResponse: RegionSubmenuResponse - logStreamFilter: LogStreamFilterResponse - filterPattern: string -} export async function tailLogGroup(logData?: { regionName: string; groupName: string }): Promise { const wizard = new TailLogGroupWizard(logData) @@ -34,75 +17,3 @@ export async function tailLogGroup(logData?: { regionName: string; groupName: st //TODO: Remove Log. For testing while we aren't yet consuming the wizardResponse. getLogger().info(JSON.stringify(wizardResponse)) } - -export class TailLogGroupWizard extends Wizard { - public constructor(logGroupInfo?: CloudWatchLogsGroupInfo) { - super({ - initState: { - regionLogGroupSubmenuResponse: logGroupInfo - ? { - data: logGroupInfo.groupName, - region: logGroupInfo.regionName, - } - : undefined, - }, - }) - this.form.regionLogGroupSubmenuResponse.bindPrompter(createRegionLogGroupSubmenu) - this.form.logStreamFilter.bindPrompter((state) => { - if (!state.regionLogGroupSubmenuResponse?.data) { - throw new ToolkitError('LogGroupName is null') - } - return new LogStreamFilterSubmenu( - state.regionLogGroupSubmenuResponse.data, - state.regionLogGroupSubmenuResponse.region - ) - }) - this.form.filterPattern.bindPrompter((state) => createFilterPatternPrompter()) - } -} - -export function createRegionLogGroupSubmenu(): RegionSubmenu { - return new RegionSubmenu( - getLogGroupQuickPickOptions, - { - title: localize('AWS.cwl.tailLogGroup.logGroupPromptTitle', 'Select Log Group to tail'), - buttons: [createExitButton()], - }, - { title: localize('AWS.cwl.tailLogGroup.regionPromptTitle', 'Select Region for Log Group') }, - 'LogGroups' - ) -} - -async function getLogGroupQuickPickOptions(regionCode: string): Promise[]> { - const client = new DefaultCloudWatchLogsClient(regionCode) - const logGroups = client.describeLogGroups() - - const logGroupsOptions: DataQuickPickItem[] = [] - - for await (const logGroupObject of logGroups) { - if (!logGroupObject.arn || !logGroupObject.logGroupName) { - throw new ToolkitError('LogGroupObject name or arn undefined') - } - - logGroupsOptions.push({ - label: logGroupObject.logGroupName, - data: formatLogGroupArn(logGroupObject.arn), - }) - } - - return logGroupsOptions -} - -function formatLogGroupArn(logGroupArn: string): string { - return logGroupArn.endsWith(':*') ? logGroupArn.substring(0, logGroupArn.length - 2) : logGroupArn -} - -export function createFilterPatternPrompter() { - const helpUri = cwlFilterPatternHelpUrl - return createInputBox({ - title: 'Provide log event filter pattern', - placeholder: 'filter pattern (case sensitive; empty matches all)', - prompt: 'Optional pattern to use to filter the results to include only log events that match the pattern.', - buttons: [createHelpButton(helpUri), createBackButton(), createExitButton()], - }) -} diff --git a/packages/core/src/awsService/cloudWatchLogs/registry/liveTailSession.ts b/packages/core/src/awsService/cloudWatchLogs/registry/liveTailSession.ts index fe116e54621..ff2b044616d 100644 --- a/packages/core/src/awsService/cloudWatchLogs/registry/liveTailSession.ts +++ b/packages/core/src/awsService/cloudWatchLogs/registry/liveTailSession.ts @@ -4,10 +4,11 @@ */ import * as vscode from 'vscode' import { CloudWatchLogsClient, StartLiveTailCommand, StartLiveTailCommandOutput } from '@aws-sdk/client-cloudwatch-logs' -import { LogStreamFilterResponse } from '../liveTailLogStreamSubmenu' +import { LogStreamFilterResponse } from '../wizard/liveTailLogStreamSubmenu' import { CloudWatchLogsSettings } from '../cloudWatchLogsUtils' import { Settings, ToolkitError } from '../../../shared' import { createLiveTailURIFromArgs } from './liveTailSessionRegistry' +import { getUserAgent } from '../../../shared/telemetry/util' export type LiveTailSessionConfiguration = { logGroupName: string @@ -35,7 +36,10 @@ export class LiveTailSession { this._logGroupName = configuration.logGroupName this.logStreamFilter = configuration.logStreamFilter this.liveTailClient = { - cwlClient: new CloudWatchLogsClient({ region: configuration.region }), + cwlClient: new CloudWatchLogsClient({ + region: configuration.region, + customUserAgent: getUserAgent(), + }), abortController: new AbortController(), } this._maxLines = LiveTailSession.settings.get('liveTailMaxEvents', 10000) diff --git a/packages/core/src/awsService/cloudWatchLogs/liveTailLogStreamSubmenu.ts b/packages/core/src/awsService/cloudWatchLogs/wizard/liveTailLogStreamSubmenu.ts similarity index 90% rename from packages/core/src/awsService/cloudWatchLogs/liveTailLogStreamSubmenu.ts rename to packages/core/src/awsService/cloudWatchLogs/wizard/liveTailLogStreamSubmenu.ts index e39cd1b8282..a76ec8861e4 100644 --- a/packages/core/src/awsService/cloudWatchLogs/liveTailLogStreamSubmenu.ts +++ b/packages/core/src/awsService/cloudWatchLogs/wizard/liveTailLogStreamSubmenu.ts @@ -2,20 +2,20 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ -import { Prompter, PromptResult } from '../../shared/ui/prompter' -import { DefaultCloudWatchLogsClient } from '../../shared/clients/cloudWatchLogsClient' -import { createCommonButtons } from '../../shared/ui/buttons' -import { createInputBox, InputBoxPrompter } from '../../shared/ui/inputPrompter' -import { createQuickPick, DataQuickPickItem, QuickPickPrompter } from '../../shared/ui/pickerPrompter' -import { pageableToCollection } from '../../shared/utilities/collectionUtils' +import { Prompter, PromptResult } from '../../../shared/ui/prompter' +import { DefaultCloudWatchLogsClient } from '../../../shared/clients/cloudWatchLogsClient' +import { createCommonButtons } from '../../../shared/ui/buttons' +import { createInputBox, InputBoxPrompter } from '../../../shared/ui/inputPrompter' +import { createQuickPick, DataQuickPickItem, QuickPickPrompter } from '../../../shared/ui/pickerPrompter' +import { pageableToCollection } from '../../../shared/utilities/collectionUtils' import { CloudWatchLogs } from 'aws-sdk' -import { isValidResponse, StepEstimator } from '../../shared/wizards/wizard' -import { isNonNullable } from '../../shared/utilities/tsUtils' +import { isValidResponse, StepEstimator } from '../../../shared/wizards/wizard' +import { isNonNullable } from '../../../shared/utilities/tsUtils' import { startLiveTailHelpUrl, startLiveTailLogStreamNamesHelpUrl, startLiveTailLogStreamPrefixHelpUrl, -} from '../../shared/constants' +} from '../../../shared/constants' export type LogStreamFilterType = 'menu' | 'prefix' | 'specific' | 'all' diff --git a/packages/core/src/awsService/cloudWatchLogs/wizard/tailLogGroupWizard.ts b/packages/core/src/awsService/cloudWatchLogs/wizard/tailLogGroupWizard.ts new file mode 100644 index 00000000000..c0ba4bdc3af --- /dev/null +++ b/packages/core/src/awsService/cloudWatchLogs/wizard/tailLogGroupWizard.ts @@ -0,0 +1,96 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as nls from 'vscode-nls' +import { ToolkitError } from '../../../shared' +import { DefaultCloudWatchLogsClient } from '../../../shared/clients/cloudWatchLogsClient' +import { cwlFilterPatternHelpUrl } from '../../../shared/constants' +import { createBackButton, createExitButton, createHelpButton } from '../../../shared/ui/buttons' +import { RegionSubmenu, RegionSubmenuResponse } from '../../../shared/ui/common/regionSubmenu' +import { createInputBox } from '../../../shared/ui/inputPrompter' +import { DataQuickPickItem } from '../../../shared/ui/pickerPrompter' +import { Wizard } from '../../../shared/wizards/wizard' +import { CloudWatchLogsGroupInfo } from '../registry/logDataRegistry' +import { LogStreamFilterResponse, LogStreamFilterSubmenu } from './liveTailLogStreamSubmenu' + +const localize = nls.loadMessageBundle() + +export interface TailLogGroupWizardResponse { + regionLogGroupSubmenuResponse: RegionSubmenuResponse + logStreamFilter: LogStreamFilterResponse + filterPattern: string +} + +export class TailLogGroupWizard extends Wizard { + public constructor(logGroupInfo?: CloudWatchLogsGroupInfo) { + super({ + initState: { + regionLogGroupSubmenuResponse: logGroupInfo + ? { + data: logGroupInfo.groupName, + region: logGroupInfo.regionName, + } + : undefined, + }, + }) + this.form.regionLogGroupSubmenuResponse.bindPrompter(createRegionLogGroupSubmenu) + this.form.logStreamFilter.bindPrompter((state) => { + if (!state.regionLogGroupSubmenuResponse?.data) { + throw new ToolkitError('LogGroupName is null') + } + return new LogStreamFilterSubmenu( + state.regionLogGroupSubmenuResponse.data, + state.regionLogGroupSubmenuResponse.region + ) + }) + this.form.filterPattern.bindPrompter((state) => createFilterPatternPrompter()) + } +} + +export function createRegionLogGroupSubmenu(): RegionSubmenu { + return new RegionSubmenu( + getLogGroupQuickPickOptions, + { + title: localize('AWS.cwl.tailLogGroup.logGroupPromptTitle', 'Select Log Group to tail'), + buttons: [createExitButton()], + }, + { title: localize('AWS.cwl.tailLogGroup.regionPromptTitle', 'Select Region for Log Group') }, + 'LogGroups' + ) +} + +async function getLogGroupQuickPickOptions(regionCode: string): Promise[]> { + const client = new DefaultCloudWatchLogsClient(regionCode) + const logGroups = client.describeLogGroups() + + const logGroupsOptions: DataQuickPickItem[] = [] + + for await (const logGroupObject of logGroups) { + if (!logGroupObject.arn || !logGroupObject.logGroupName) { + throw new ToolkitError('LogGroupObject name or arn undefined') + } + + logGroupsOptions.push({ + label: logGroupObject.logGroupName, + data: formatLogGroupArn(logGroupObject.arn), + }) + } + + return logGroupsOptions +} + +function formatLogGroupArn(logGroupArn: string): string { + return logGroupArn.endsWith(':*') ? logGroupArn.substring(0, logGroupArn.length - 2) : logGroupArn +} + +export function createFilterPatternPrompter() { + const helpUri = cwlFilterPatternHelpUrl + return createInputBox({ + title: 'Provide log event filter pattern', + placeholder: 'filter pattern (case sensitive; empty matches all)', + prompt: 'Optional pattern to use to filter the results to include only log events that match the pattern.', + buttons: [createHelpButton(helpUri), createBackButton(), createExitButton()], + }) +} diff --git a/packages/core/src/test/awsService/cloudWatchLogs/liveTailLogStreamSubmenu.test.ts b/packages/core/src/test/awsService/cloudWatchLogs/wizard/liveTailLogStreamSubmenu.test.ts similarity index 93% rename from packages/core/src/test/awsService/cloudWatchLogs/liveTailLogStreamSubmenu.test.ts rename to packages/core/src/test/awsService/cloudWatchLogs/wizard/liveTailLogStreamSubmenu.test.ts index 0ac71141b7a..7918817dd91 100644 --- a/packages/core/src/test/awsService/cloudWatchLogs/liveTailLogStreamSubmenu.test.ts +++ b/packages/core/src/test/awsService/cloudWatchLogs/wizard/liveTailLogStreamSubmenu.test.ts @@ -4,9 +4,9 @@ */ import assert from 'assert' -import { LogStreamFilterSubmenu } from '../../../awsService/cloudWatchLogs/liveTailLogStreamSubmenu' -import { createQuickPickPrompterTester, QuickPickPrompterTester } from '../../shared/ui/testUtils' -import { getTestWindow } from '../../shared/vscode/window' +import { LogStreamFilterSubmenu } from '../../../../awsService/cloudWatchLogs/wizard/liveTailLogStreamSubmenu' +import { createQuickPickPrompterTester, QuickPickPrompterTester } from '../../../shared/ui/testUtils' +import { getTestWindow } from '../../../shared/vscode/window' describe('liveTailLogStreamSubmenu', async function () { let logStreamFilterSubmenu: LogStreamFilterSubmenu diff --git a/packages/core/src/test/awsService/cloudWatchLogs/commands/tailLogGroup.test.ts b/packages/core/src/test/awsService/cloudWatchLogs/wizard/tailLogGroupWizard.test.ts similarity index 96% rename from packages/core/src/test/awsService/cloudWatchLogs/commands/tailLogGroup.test.ts rename to packages/core/src/test/awsService/cloudWatchLogs/wizard/tailLogGroupWizard.test.ts index 4b2e382f38c..137b372438e 100644 --- a/packages/core/src/test/awsService/cloudWatchLogs/commands/tailLogGroup.test.ts +++ b/packages/core/src/test/awsService/cloudWatchLogs/wizard/tailLogGroupWizard.test.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { TailLogGroupWizard } from '../../../../awsService/cloudWatchLogs/commands/tailLogGroup' +import { TailLogGroupWizard } from '../../../../awsService/cloudWatchLogs/wizard/tailLogGroupWizard' import { createWizardTester } from '../../../shared/wizards/wizardTestUtils' describe('TailLogGroupWizard', async function () {