Skip to content

Commit 5e28b1f

Browse files
refactor(telemetry): @withTelemetryContext can emit with source
Now the @withTelemetryContext decorator can have a method emit when called and will also add the `source` field automatically. By default it does not emit. Signed-off-by: nkomonen-amazon <[email protected]>
1 parent bf79660 commit 5e28b1f

File tree

3 files changed

+43
-9
lines changed

3 files changed

+43
-9
lines changed

packages/core/src/shared/telemetry/util.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { isValidationExemptMetric } from './exemptMetrics'
2626
import { isAmazonQ, isCloud9, isSageMaker } from '../../shared/extensionUtilities'
2727
import { randomUUID } from '../crypto'
2828
import { ClassToInterfaceType } from '../utilities/tsUtils'
29-
import { FunctionEntry } from './spans'
29+
import { asStringifiedStack, FunctionEntry } from './spans'
3030
import { telemetry } from './telemetry'
3131
import { v5 as uuidV5 } from 'uuid'
3232
import { ToolkitError } from '../errors'
@@ -369,30 +369,37 @@ export function getOperatingSystem(): OperatingSystem {
369369
* }
370370
* ```
371371
*/
372-
export function withTelemetryContext(functionId: FunctionEntry) {
372+
export function withTelemetryContext(opts: FunctionEntry & { emit?: boolean }) {
373373
function decorator<This, Args extends any[], Return>(
374374
originalMethod: (this: This, ...args: Args) => Return,
375375
_context: ClassMethodDecoratorContext // we dont need this currently but it keeps the compiler happy
376376
) {
377377
function decoratedMethod(this: This, ...args: Args): Return {
378378
return telemetry.function_call.run(
379-
() => {
379+
(span) => {
380380
try {
381-
// DEVELOPERS: Set a breakpoint here and step in to it to debug the original function
381+
span.record({
382+
functionName: opts.name,
383+
className: opts.class,
384+
source: asStringifiedStack(telemetry.getFunctionStack()),
385+
})
386+
387+
// DEVELOPERS: Set a breakpoint here and step in and debug the original function
382388
const result = originalMethod.call(this, ...args)
389+
383390
if (result instanceof Promise) {
384391
return result.catch((e) => {
385-
throw addContextToError(e, functionId)
392+
throw addContextToError(e, opts)
386393
}) as Return
387394
}
388395
return result
389396
} catch (e) {
390-
throw addContextToError(e, functionId)
397+
throw addContextToError(e, opts)
391398
}
392399
},
393400
{
394-
emit: false,
395-
functionId: functionId,
401+
emit: opts.emit !== undefined ? opts.emit : false,
402+
functionId: opts,
396403
}
397404
)
398405
}
@@ -401,7 +408,7 @@ export function withTelemetryContext(functionId: FunctionEntry) {
401408
return decorator
402409

403410
function addContextToError(e: unknown, functionId: FunctionEntry) {
404-
return ToolkitError.chain(e, `ctx: ${functionId.class ? functionId.class + '#' : ''}${functionId.name}`, {
411+
return ToolkitError.chain(e, `ctx: ${functionId.name}`, {
405412
code: functionId.class,
406413
})
407414
}

packages/core/src/shared/telemetry/vscodeTelemetry.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,10 @@
11161116
{
11171117
"type": "className",
11181118
"required": false
1119+
},
1120+
{
1121+
"type": "source",
1122+
"required": false
11191123
}
11201124
],
11211125
"passive": true

packages/core/src/test/shared/telemetry/spans.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,29 @@ describe('TelemetryTracer', function () {
576576
)
577577
})
578578

579+
class DecoratorEmits {
580+
@withTelemetryContext({ name: 'outerFunc', class: 'DecoratorEmits' })
581+
outerFunc() {
582+
this.decoratorEmits()
583+
}
584+
@withTelemetryContext({ name: 'decoratorEmits', class: 'DecoratorEmits', emit: true })
585+
decoratorEmits() {
586+
return true
587+
}
588+
}
589+
590+
it(`will emit the method call when emit is true`, function () {
591+
const inst = new DecoratorEmits()
592+
inst.outerFunc()
593+
assertTelemetry('function_call', [
594+
{
595+
functionName: 'decoratorEmits',
596+
className: 'DecoratorEmits',
597+
source: 'DecoratorEmits#outerFunc,decoratorEmits',
598+
},
599+
])
600+
})
601+
579602
class TestEmit {
580603
@withTelemetryContext({ name: 'doesNotEmit', class: 'TestEmit' })
581604
doesNotEmit() {

0 commit comments

Comments
 (0)