-
Notifications
You must be signed in to change notification settings - Fork 35
feat(cli): send telemetry events to local file #631
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 20 commits
0c1c0b3
2fe74df
c6bf5f4
e91e7e3
0d33ac5
7d5a19a
41a461b
c380240
e51d30d
9d980d5
d8dd12f
9126147
ab560fd
4e361ae
69e63cd
da20533
ca3f172
3b0082e
8824e28
f7cb38a
8760b44
ece2874
4dea47d
3dbbe62
feaf376
83ebd08
4b8397b
cf285bb
2c8191b
6c977b6
56f23e5
079bbc5
8e43ba7
9dd1580
55a4a73
1041bf8
635d6b7
18d9349
1811c9a
ea4720c
b9c0d6d
46cc2c8
76a19ff
2433e3e
b30d188
fe47576
4bf3be9
359a442
c20ad8b
54109d6
334b9dd
39152d3
fbd6dd6
70fa3e3
e02a283
25dec4a
5628ed9
cc8c6dd
9433b36
72c862e
d3c745c
da64d2b
b007f0e
9caf42e
ad0e6cd
c7d365a
fb85dfa
e139111
27ea7e6
f74bb90
d79756f
80fad80
e087b50
66bb8c1
64b5fa2
b5d0f32
b2b56d3
1adc88e
541eeb4
59aecf1
af1bbbb
6a86ee3
6427847
effed08
27fa7de
75b6490
9dc5a68
8341898
e783eb2
4fad6c6
31f5a92
670a289
8ea3e65
0a15701
d193044
c694d99
2b51b13
d17faf7
1c94d1b
1e138ac
3b0917d
956aa9f
cfc070d
3f850e0
2edd715
e317acd
17d4d19
c53f310
b37c6dd
30e054b
f36edc8
c933608
136546b
7fb93b9
fb49fa4
aa21c27
4d8620f
25afd6f
a90bf24
b6911c9
cd2d2d0
5b461b0
58254f8
3b75fd9
3a99e78
e66d364
84f6cc5
a737980
41389ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ import { GLOBAL_PLUGIN_HOST } from './singleton-plugin-host'; | |
import type { Command } from './user-configuration'; | ||
import { Configuration } from './user-configuration'; | ||
import * as version from './version'; | ||
import { asIoHelper } from '../../lib/api-private'; | ||
import { asIoHelper, IO } from '../../lib/api-private'; | ||
import type { IReadLock } from '../api'; | ||
import { ToolkitInfo, Notices } from '../api'; | ||
import { SdkProvider, IoHostSdkLogger, setSdkTracing, sdkRequestHandler } from '../api/aws-auth'; | ||
|
@@ -88,6 +88,13 @@ export async function exec(args: string[], synthesizer?: Synthesizer): Promise<n | |
}); | ||
await configuration.load(); | ||
|
||
if (process.env.TELEMETRY_TEST_ENV) { | ||
kaizencc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ioHost.bindTelemetryClient( | ||
argv, | ||
configuration.context.all, | ||
); | ||
} | ||
|
||
const ioHelper = asIoHelper(ioHost, ioHost.currentAction as any); | ||
|
||
// Always create and use ProxyAgent to support configuration via env vars | ||
|
@@ -613,17 +620,58 @@ function determineHotswapMode(hotswap?: boolean, hotswapFallback?: boolean, watc | |
|
||
/* c8 ignore start */ // we never call this in unit tests | ||
export function cli(args: string[] = process.argv.slice(2)) { | ||
const startTime = new Date().getTime(); | ||
kaizencc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
exec(args) | ||
.then(async (value) => { | ||
if (typeof value === 'number') { | ||
process.exitCode = value; | ||
} | ||
if (process.env.TELEMETRY_TEST_ENV) { | ||
if (value === 1) { | ||
await failedTelemetryExitEvent(args, startTime); | ||
} else { | ||
await successfulTelemetryExitEvent(args, startTime); | ||
} | ||
} | ||
}) | ||
.catch((err) => { | ||
.catch(async (err) => { | ||
// Log the stack trace if we're on a developer workstation. Otherwise this will be into a minified | ||
// file and the printed code line and stack trace are huge and useless. | ||
prettyPrintError(err, version.isDeveloperBuild()); | ||
if (process.env.TELEMETRY_TEST_ENV) { | ||
await failedTelemetryExitEvent(args, startTime, err); | ||
} | ||
process.exitCode = 1; | ||
}); | ||
} | ||
/* c8 ignore stop */ | ||
|
||
async function successfulTelemetryExitEvent(args: string[], startTime: number) { | ||
await CliIoHost.instance().asIoHelper().notify(IO.CDK_TOOLKIT_I0050.msg( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. method retrieves instance but not create a new one There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I will do the |
||
`Exiting ${args[1]}`, | ||
{ | ||
telemetry: { | ||
duration: new Date().getTime() - startTime, | ||
eventType: 'Exit', | ||
kaizencc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
state: 'SUCCEEDED', | ||
}, | ||
}, | ||
)); | ||
} | ||
|
||
async function failedTelemetryExitEvent(args: string[], startTime: number, err?: any) { | ||
await CliIoHost.instance().asIoHelper().notify(IO.CDK_TOOLKIT_I0050.msg( | ||
`Exiting ${args[1]}`, | ||
{ | ||
telemetry: { | ||
duration: new Date().getTime() - startTime, | ||
eventType: 'Exit', | ||
state: 'FAILED', | ||
error: { | ||
name: err?.name ?? 'ExitCode1Error', // TODO: sanitize | ||
// message: err.message, // TODO: sanitize | ||
}, | ||
}, | ||
}, | ||
)); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { | ||
GetCallerIdentityCommand, | ||
GetCallerIdentityCommandOutput, | ||
STSClient, | ||
} from '@aws-sdk/client-sts'; | ||
import { v5 as uuidV5 } from 'uuid'; | ||
|
||
// eslint-disable-next-line spellcheck/spell-checker | ||
const CDK_CLI_UUID_NAMESPACE = 'f47ac10b-58cc-4372-a567-0e02b2c3d479'; // A random v4 UUID | ||
|
||
/** | ||
* Retrieves the account ID of the user | ||
*/ | ||
export class AccountIdFetcher { | ||
private accountIdPromise?: Promise<GetCallerIdentityCommandOutput>; | ||
/** | ||
* constructor for AccountIdFetcher | ||
*/ | ||
constructor(private readonly stsClient = new STSClient()) {} | ||
fetch = async () => { | ||
if (this.accountIdPromise) { | ||
try { | ||
const stsResponse = await this.accountIdPromise; | ||
return this.getAccountIdFromStsResponse(stsResponse); | ||
} catch { | ||
// We failed to get the account Id. Most likely the user doesn't have credentials | ||
return; | ||
} | ||
} | ||
try { | ||
this.accountIdPromise = this.stsClient.send( | ||
new GetCallerIdentityCommand({}), | ||
); | ||
const stsResponse = await this.accountIdPromise; | ||
return this.getAccountIdFromStsResponse(stsResponse); | ||
} catch { | ||
// We failed to get the account Id. Most likely the user doesn't have credentials | ||
return; | ||
} | ||
}; | ||
|
||
private getAccountIdFromStsResponse = ( | ||
stsResponse: GetCallerIdentityCommandOutput, | ||
) => { | ||
if (stsResponse && stsResponse.Account) { | ||
return uuidV5( | ||
stsResponse.Account, | ||
CDK_CLI_UUID_NAMESPACE, | ||
); | ||
} | ||
// We failed to get the account Id. Most likely the user doesn't have credentials | ||
return; | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import type { TelemetrySchema } from './schema'; | ||
|
||
/** | ||
* Interface for all Telemetry Clients. | ||
* | ||
* A telemtry client receives event data and determines | ||
* when and where to send it. | ||
*/ | ||
export interface ITelemetryClient { | ||
/** | ||
* Send data to the client | ||
*/ | ||
emit(event: TelemetrySchema): Promise<boolean>; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trace
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
plus run by momo about the toolkit messages