Skip to content

Commit 12caeb3

Browse files
authored
Merge branch 'aws:master' into fix
2 parents 89b5930 + 5bfb867 commit 12caeb3

File tree

24 files changed

+2528
-223
lines changed

24 files changed

+2528
-223
lines changed

package-lock.json

Lines changed: 916 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"generateNonCodeFiles": "npm run generateNonCodeFiles -w packages/ --if-present"
4040
},
4141
"devDependencies": {
42-
"@aws-toolkits/telemetry": "^1.0.284",
42+
"@aws-toolkits/telemetry": "^1.0.287",
4343
"@playwright/browser-chromium": "^1.43.1",
4444
"@stylistic/eslint-plugin": "^2.11.0",
4545
"@types/he": "^1.2.3",

packages/core/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@
495495
"dependencies": {
496496
"@amzn/amazon-q-developer-streaming-client": "file:../../src.gen/@amzn/amazon-q-developer-streaming-client",
497497
"@amzn/codewhisperer-streaming": "file:../../src.gen/@amzn/codewhisperer-streaming",
498+
"@aws-sdk/client-cloudwatch-logs": "^3.666.0",
498499
"@aws-sdk/client-cloudformation": "^3.667.0",
499500
"@aws-sdk/client-cognito-identity": "^3.637.0",
500501
"@aws-sdk/client-lambda": "^3.637.0",

packages/core/package.nls.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@
177177
"AWS.command.downloadSchemaItemCode": "Download Code Bindings",
178178
"AWS.command.viewLogs": "View Logs",
179179
"AWS.command.cloudWatchLogs.searchLogGroup": "Search Log Group",
180+
"AWS.command.cloudWatchLogs.tailLogGroup": "Tail Log Group",
180181
"AWS.command.sam.newTemplate": "Create new SAM Template",
181182
"AWS.command.cloudFormation.newTemplate": "Create new CloudFormation Template",
182183
"AWS.command.quickStart": "View Quick Start",
@@ -253,7 +254,7 @@
253254
"AWS.appcomposer.explorerTitle": "Infrastructure Composer",
254255
"AWS.cdk.explorerTitle": "CDK",
255256
"AWS.codecatalyst.explorerTitle": "CodeCatalyst",
256-
"AWS.cwl.limit.desc": "Maximum amount of log entries pulled per request from CloudWatch Logs (max 10000)",
257+
"AWS.cwl.limit.desc": "Maximum amount of log entries pulled per request from CloudWatch Logs. For LiveTail, when the limit is reached, the oldest events will be removed to accomodate new events. (max 10000)",
257258
"AWS.samcli.deploy.bucket.recentlyUsed": "Buckets recently used for SAM deployments",
258259
"AWS.submenu.amazonqEditorContextSubmenu.title": "Amazon Q",
259260
"AWS.submenu.auth.title": "Authentication",

packages/core/src/amazonqTest/chat/controller/controller.ts

Lines changed: 52 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -242,22 +242,20 @@ export class TestController {
242242
this.messenger.sendUpdatePromptProgress(data.tabID, null)
243243
const session = this.sessionStorage.getSession()
244244
const isCancel = data.error.message === unitTestGenerationCancelMessage
245-
telemetry.amazonq_utgGenerateTests.emit({
246-
cwsprChatProgrammingLanguage: session.fileLanguage ?? 'plaintext',
247-
jobId: session.listOfTestGenerationJobId[0], // For RIV, UTG does only one StartTestGeneration API call
248-
jobGroup: session.testGenerationJobGroupName,
249-
requestId: session.startTestGenerationRequestId,
250-
hasUserPromptSupplied: session.hasUserPromptSupplied,
251-
isCodeBlockSelected: session.isCodeBlockSelected,
252-
buildPayloadBytes: session.srcPayloadSize,
253-
buildZipFileBytes: session.srcZipFileSize,
254-
artifactsUploadDuration: session.artifactsUploadDuration,
255-
perfClientLatency: performance.now() - session.testGenerationStartTime,
256-
result: isCancel ? 'Cancelled' : 'Failed',
257-
reasonDesc: getTelemetryReasonDesc(data.error),
258-
isSupportedLanguage: true,
259-
credentialStartUrl: AuthUtil.instance.startUrl,
260-
})
245+
246+
TelemetryHelper.instance.sendTestGenerationToolkitEvent(
247+
session,
248+
true,
249+
isCancel ? 'Cancelled' : 'Failed',
250+
session.startTestGenerationRequestId,
251+
performance.now() - session.testGenerationStartTime,
252+
getTelemetryReasonDesc(data.error),
253+
session.isCodeBlockSelected,
254+
session.artifactsUploadDuration,
255+
session.srcPayloadSize,
256+
session.srcZipFileSize
257+
)
258+
261259
if (session.stopIteration) {
262260
// Error from Science
263261
this.messenger.sendMessage(data.error.message.replaceAll('```', ''), data.tabID, 'answer')
@@ -715,27 +713,25 @@ export class TestController {
715713
// TODO: send the message once again once build is enabled
716714
// this.messenger.sendMessage('Accepted', message.tabID, 'prompt')
717715
telemetry.ui_click.emit({ elementId: 'unitTestGeneration_acceptDiff' })
718-
telemetry.amazonq_utgGenerateTests.emit({
719-
generatedCount: session.numberOfTestsGenerated,
720-
acceptedCount: session.numberOfTestsGenerated,
721-
generatedCharactersCount: session.charsOfCodeGenerated,
722-
acceptedCharactersCount: session.charsOfCodeAccepted,
723-
generatedLinesCount: session.linesOfCodeGenerated,
724-
acceptedLinesCount: session.linesOfCodeAccepted,
725-
cwsprChatProgrammingLanguage: session.fileLanguage ?? 'plaintext',
726-
jobId: session.listOfTestGenerationJobId[0], // For RIV, UTG does only one StartTestGeneration API call so jobId = session.listOfTestGenerationJobId[0]
727-
jobGroup: session.testGenerationJobGroupName,
728-
requestId: session.startTestGenerationRequestId,
729-
buildPayloadBytes: session.srcPayloadSize,
730-
buildZipFileBytes: session.srcZipFileSize,
731-
artifactsUploadDuration: session.artifactsUploadDuration,
732-
hasUserPromptSupplied: session.hasUserPromptSupplied,
733-
isCodeBlockSelected: session.isCodeBlockSelected,
734-
perfClientLatency: session.latencyOfTestGeneration,
735-
isSupportedLanguage: true,
736-
credentialStartUrl: AuthUtil.instance.startUrl,
737-
result: 'Succeeded',
738-
})
716+
717+
TelemetryHelper.instance.sendTestGenerationToolkitEvent(
718+
session,
719+
true,
720+
'Succeeded',
721+
session.startTestGenerationRequestId,
722+
session.latencyOfTestGeneration,
723+
undefined,
724+
session.isCodeBlockSelected,
725+
session.artifactsUploadDuration,
726+
session.srcPayloadSize,
727+
session.srcZipFileSize,
728+
session.charsOfCodeAccepted,
729+
session.numberOfTestsGenerated,
730+
session.linesOfCodeAccepted,
731+
session.charsOfCodeGenerated,
732+
session.numberOfTestsGenerated,
733+
session.linesOfCodeGenerated
734+
)
739735

740736
await this.endSession(message, FollowUpTypes.SkipBuildAndFinish)
741737
await this.sessionCleanUp()
@@ -839,27 +835,25 @@ export class TestController {
839835
private async endSession(data: any, step: FollowUpTypes) {
840836
const session = this.sessionStorage.getSession()
841837
if (step === FollowUpTypes.RejectCode) {
842-
telemetry.amazonq_utgGenerateTests.emit({
843-
generatedCount: session.numberOfTestsGenerated,
844-
acceptedCount: 0,
845-
generatedCharactersCount: session.charsOfCodeGenerated,
846-
acceptedCharactersCount: 0,
847-
generatedLinesCount: session.linesOfCodeGenerated,
848-
acceptedLinesCount: 0,
849-
cwsprChatProgrammingLanguage: session.fileLanguage ?? 'plaintext',
850-
jobId: session.listOfTestGenerationJobId[0], // For RIV, UTG does only one StartTestGeneration API call so jobId = session.listOfTestGenerationJobId[0]
851-
jobGroup: session.testGenerationJobGroupName,
852-
requestId: session.startTestGenerationRequestId,
853-
buildPayloadBytes: session.srcPayloadSize,
854-
buildZipFileBytes: session.srcZipFileSize,
855-
artifactsUploadDuration: session.artifactsUploadDuration,
856-
hasUserPromptSupplied: session.hasUserPromptSupplied,
857-
isCodeBlockSelected: session.isCodeBlockSelected,
858-
perfClientLatency: session.latencyOfTestGeneration,
859-
isSupportedLanguage: true,
860-
credentialStartUrl: AuthUtil.instance.startUrl,
861-
result: 'Succeeded',
862-
})
838+
TelemetryHelper.instance.sendTestGenerationToolkitEvent(
839+
session,
840+
true,
841+
'Succeeded',
842+
session.startTestGenerationRequestId,
843+
session.latencyOfTestGeneration,
844+
undefined,
845+
session.isCodeBlockSelected,
846+
session.artifactsUploadDuration,
847+
session.srcPayloadSize,
848+
session.srcZipFileSize,
849+
0,
850+
0,
851+
0,
852+
session.charsOfCodeGenerated,
853+
session.numberOfTestsGenerated,
854+
session.linesOfCodeGenerated
855+
)
856+
863857
telemetry.ui_click.emit({ elementId: 'unitTestGeneration_rejectDiff' })
864858
}
865859

packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ import { CodeReference } from '../../../../amazonq/webview/ui/apps/amazonqCommon
3636
import { getHttpStatusCode, getRequestId, getTelemetryReasonDesc, ToolkitError } from '../../../../shared/errors'
3737
import { sleep, waitUntil } from '../../../../shared/utilities/timeoutUtils'
3838
import { keys } from '../../../../shared/utilities/tsUtils'
39-
import { AuthUtil, testGenState } from '../../../../codewhisperer'
39+
import { TelemetryHelper, testGenState } from '../../../../codewhisperer'
4040
import { cancellingProgressField, testGenCompletedField } from '../../../models/constants'
41-
import { telemetry } from '../../../../shared/telemetry/telemetry'
4241

4342
export type UnrecoverableErrorType = 'no-project-found' | 'no-open-file-found' | 'invalid-file-type'
4443

@@ -275,31 +274,28 @@ export class Messenger {
275274
.finally(async () => {
276275
if (testGenState.isCancelling()) {
277276
this.sendMessage(CodeWhispererConstants.unitTestGenerationCancelMessage, tabID, 'answer')
278-
telemetry.amazonq_utgGenerateTests.emit({
279-
cwsprChatProgrammingLanguage: session.fileLanguage ?? 'plaintext',
280-
hasUserPromptSupplied: session.hasUserPromptSupplied,
281-
perfClientLatency: performance.now() - session.testGenerationStartTime,
282-
result: 'Cancelled',
283-
reasonDesc: getTelemetryReasonDesc(CodeWhispererConstants.unitTestGenerationCancelMessage),
284-
isSupportedLanguage: false,
285-
credentialStartUrl: AuthUtil.instance.startUrl,
286-
requestId: messageId,
287-
})
277+
TelemetryHelper.instance.sendTestGenerationToolkitEvent(
278+
session,
279+
false,
280+
'Cancelled',
281+
messageId,
282+
performance.now() - session.testGenerationStartTime,
283+
getTelemetryReasonDesc(CodeWhispererConstants.unitTestGenerationCancelMessage)
284+
)
288285

289286
this.dispatcher.sendUpdatePromptProgress(
290287
new UpdatePromptProgressMessage(tabID, cancellingProgressField)
291288
)
292289
await sleep(500)
293290
} else {
294-
telemetry.amazonq_utgGenerateTests.emit({
295-
cwsprChatProgrammingLanguage: session.fileLanguage ?? 'plaintext',
296-
hasUserPromptSupplied: session.hasUserPromptSupplied,
297-
perfClientLatency: performance.now() - session.testGenerationStartTime,
298-
result: 'Succeeded',
299-
isSupportedLanguage: false,
300-
credentialStartUrl: AuthUtil.instance.startUrl,
301-
requestId: messageId,
302-
})
291+
TelemetryHelper.instance.sendTestGenerationToolkitEvent(
292+
session,
293+
false,
294+
'Succeeded',
295+
messageId,
296+
performance.now() - session.testGenerationStartTime
297+
)
298+
303299
this.dispatcher.sendUpdatePromptProgress(
304300
new UpdatePromptProgressMessage(tabID, testGenCompletedField)
305301
)

packages/core/src/awsService/cloudWatchLogs/activation.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import * as vscode from 'vscode'
7-
import { CLOUDWATCH_LOGS_SCHEME } from '../../shared/constants'
7+
import { cloudwatchLogsLiveTailScheme, CLOUDWATCH_LOGS_SCHEME } from '../../shared/constants'
88
import { Settings } from '../../shared/settings'
99
import { addLogEvents } from './commands/addLogEvents'
1010
import { copyLogResource } from './commands/copyLogResource'
@@ -19,16 +19,22 @@ import { searchLogGroup } from './commands/searchLogGroup'
1919
import { changeLogSearchParams } from './changeLogSearch'
2020
import { CloudWatchLogsNode } from './explorer/cloudWatchLogsNode'
2121
import { loadAndOpenInitialLogStreamFile, LogStreamCodeLensProvider } from './document/logStreamsCodeLensProvider'
22+
import { clearDocument, closeSession, tailLogGroup } from './commands/tailLogGroup'
23+
import { LiveTailDocumentProvider } from './document/liveTailDocumentProvider'
24+
import { LiveTailSessionRegistry } from './registry/liveTailSessionRegistry'
2225
import { DeployedResourceNode } from '../appBuilder/explorer/nodes/deployedNode'
2326
import { isTreeNode } from '../../shared/treeview/resourceTreeDataProvider'
2427
import { getLogger } from '../../shared/logger/logger'
2528
import { ToolkitError } from '../../shared'
29+
import { LiveTailCodeLensProvider } from './document/liveTailCodeLensProvider'
2630

2731
export async function activate(context: vscode.ExtensionContext, configuration: Settings): Promise<void> {
2832
const registry = LogDataRegistry.instance
33+
const liveTailRegistry = LiveTailSessionRegistry.instance
2934

3035
const documentProvider = new LogDataDocumentProvider(registry)
31-
36+
const liveTailDocumentProvider = new LiveTailDocumentProvider()
37+
const liveTailCodeLensProvider = new LiveTailCodeLensProvider(liveTailRegistry)
3238
context.subscriptions.push(
3339
vscode.languages.registerCodeLensProvider(
3440
{
@@ -43,6 +49,20 @@ export async function activate(context: vscode.ExtensionContext, configuration:
4349
vscode.workspace.registerTextDocumentContentProvider(CLOUDWATCH_LOGS_SCHEME, documentProvider)
4450
)
4551

52+
context.subscriptions.push(
53+
vscode.languages.registerCodeLensProvider(
54+
{
55+
language: 'log',
56+
scheme: cloudwatchLogsLiveTailScheme,
57+
},
58+
liveTailCodeLensProvider
59+
)
60+
)
61+
62+
context.subscriptions.push(
63+
vscode.workspace.registerTextDocumentContentProvider(cloudwatchLogsLiveTailScheme, liveTailDocumentProvider)
64+
)
65+
4666
context.subscriptions.push(
4767
vscode.workspace.onDidCloseTextDocument((doc) => {
4868
if (doc.isClosed && doc.uri.scheme === CLOUDWATCH_LOGS_SCHEME) {
@@ -95,6 +115,23 @@ export async function activate(context: vscode.ExtensionContext, configuration:
95115

96116
Commands.register('aws.cwl.changeTimeFilter', async () => changeLogSearchParams(registry, 'timeFilter')),
97117

118+
Commands.register('aws.cwl.tailLogGroup', async (node: LogGroupNode | CloudWatchLogsNode) => {
119+
const logGroupInfo =
120+
node instanceof LogGroupNode
121+
? { regionName: node.regionCode, groupName: node.logGroup.logGroupName! }
122+
: undefined
123+
const source = node ? (logGroupInfo ? 'ExplorerLogGroupNode' : 'ExplorerServiceNode') : 'Command'
124+
await tailLogGroup(liveTailRegistry, source, liveTailCodeLensProvider, logGroupInfo)
125+
}),
126+
127+
Commands.register('aws.cwl.stopTailingLogGroup', async (document: vscode.TextDocument, source: string) => {
128+
closeSession(document.uri, liveTailRegistry, source, liveTailCodeLensProvider)
129+
}),
130+
131+
Commands.register('aws.cwl.clearDocument', async (document: vscode.TextDocument) => {
132+
await clearDocument(document)
133+
}),
134+
98135
Commands.register('aws.appBuilder.searchLogs', async (node: DeployedResourceNode) => {
99136
try {
100137
const logGroupInfo = isTreeNode(node)
@@ -112,6 +149,7 @@ export async function activate(context: vscode.ExtensionContext, configuration:
112149
})
113150
)
114151
}
152+
115153
function getFunctionLogGroupName(configuration: any) {
116154
const logGroupPrefix = '/aws/lambda/'
117155
return configuration.logGroupName || logGroupPrefix + configuration.FunctionName

0 commit comments

Comments
 (0)