Skip to content
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

feat: Add usage data metrics for sandbox #642

Merged
merged 28 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b3c410c
feat: Add usage data metrics for sandbox
Amplifiyer Nov 14, 2023
35afe23
Merge branch 'telemetry_2' into telemetry_new
Amplifiyer Nov 14, 2023
09a90da
update api
Amplifiyer Nov 14, 2023
8f086ec
add more tests
Amplifiyer Nov 14, 2023
19be2bc
Merge branch 'main' into telemetry_new
Amplifiyer Nov 14, 2023
47a8c4e
add changeset
Amplifiyer Nov 14, 2023
b86d42d
fix automated tests
Amplifiyer Nov 14, 2023
023297d
Refactor packageJsonReader
Amplifiyer Nov 15, 2023
ffc1b1b
update tsconfig
Amplifiyer Nov 15, 2023
8437715
add comments
Amplifiyer Nov 15, 2023
3f5b1cf
Add usage data emitter factory
Amplifiyer Nov 15, 2023
89b09ad
Update interface of usage metrics to take metrics and dimensions
Amplifiyer Nov 15, 2023
96414ec
is it better?
Amplifiyer Nov 15, 2023
9ce7681
remove extra variable
Amplifiyer Nov 15, 2023
ae1a81f
changing to 'on' data listener
Amplifiyer Nov 15, 2023
905027e
Merge branch 'main' into telemetry_new
Amplifiyer Nov 15, 2023
fd0f1f7
update snapshots
Amplifiyer Nov 15, 2023
3d870ce
minor changes
Amplifiyer Nov 15, 2023
66a7ca8
change to use readline
Amplifiyer Nov 15, 2023
4149515
PR updates
Amplifiyer Nov 15, 2023
c60d63f
Move the uuid types dep
Amplifiyer Nov 15, 2023
8614266
PR updates
Amplifiyer Nov 15, 2023
5ff37f2
Merge branch 'main' into telemetry_new
Amplifiyer Nov 15, 2023
5780a85
update to use __dirname
Amplifiyer Nov 16, 2023
d894d12
update snapshots
Amplifiyer Nov 16, 2023
4288f53
Replace package json reeader in create-amplify
Amplifiyer Nov 16, 2023
95e11a0
small rename
Amplifiyer Nov 16, 2023
442ffc5
remove packageJson.name from installationId
Amplifiyer Nov 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions packages/backend-deployer/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
```ts

import { BackendIdentifier } from '@aws-amplify/plugin-types';
import { DeploymentTimes } from '@aws-amplify/platform-core';
import { DeploymentType } from '@aws-amplify/plugin-types';

// @public
Expand All @@ -19,6 +18,12 @@ export class BackendDeployerFactory {
static getInstance: () => BackendDeployer;
}

// @public (undocumented)
export type DeploymentTimes = {
synthesisTime?: number;
totalTime?: number;
};

// @public (undocumented)
export type DeployProps = {
deploymentType?: DeploymentType;
Expand All @@ -28,7 +33,6 @@ export type DeployProps = {

// @public (undocumented)
export type DeployResult = {
hotswapped?: boolean;
deploymentTimes: DeploymentTimes;
};

Expand Down
2 changes: 1 addition & 1 deletion packages/backend-deployer/src/cdk_deployer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void describe('invokeCDKCommand', () => {

const invoker = new CDKDeployer(new CdkErrorMapper(), backendLocator);
const execaMock = mock.method(invoker, 'executeChildProcess', () =>
Promise.resolve('some cdk output')
Promise.resolve()
);

beforeEach(() => {
Expand Down
73 changes: 31 additions & 42 deletions packages/backend-deployer/src/cdk_deployer.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { execa } from 'execa';
import stream from 'stream';
import readline from 'readline';
import {
BackendDeployer,
DeployProps,
DeployResult,
DestroyProps,
DestroyResult,
} from './cdk_deployer_singleton_factory.js';
import { CdkErrorMapper } from './cdk_error_mapper.js';
import { BackendIdentifier, DeploymentType } from '@aws-amplify/plugin-types';
import {
BackendLocator,
CDKContextKey,
DeploymentTimes,
} from '@aws-amplify/platform-core';
import { BackendLocator, CDKContextKey } from '@aws-amplify/platform-core';
import { BackendDeployerEnvironmentVariables } from './environment_variables.js';

/**
Expand Down Expand Up @@ -51,17 +50,12 @@ export class CDKDeployer implements BackendDeployer {
}
}

const cdkOutput = await this.invokeCdk(
return this.invokeCdk(
InvokableCommand.DEPLOY,
backendId,
deployProps?.deploymentType,
cdkCommandArgs
);

return {
deploymentTimes: this.getDeploymentTimes(cdkOutput),
hotswapped: this.deploymentHotswapped(cdkOutput),
};
};

/**
Expand All @@ -71,15 +65,12 @@ export class CDKDeployer implements BackendDeployer {
backendId?: BackendIdentifier,
destroyProps?: DestroyProps
) => {
const cdkOutput = await this.invokeCdk(
return this.invokeCdk(
InvokableCommand.DESTROY,
backendId,
destroyProps?.deploymentType,
['--force']
);
return {
deploymentTimes: this.getDeploymentTimes(cdkOutput),
};
};

private invokeTsc = async (deployProps?: DeployProps) => {
Expand Down Expand Up @@ -116,7 +107,7 @@ export class CDKDeployer implements BackendDeployer {
backendId?: BackendIdentifier,
deploymentType?: DeploymentType,
additionalArguments?: string[]
): Promise<string> => {
): Promise<DeployResult | DestroyResult> => {
// Basic args
const cdkCommandArgs = [
'cdk',
Expand Down Expand Up @@ -173,54 +164,52 @@ export class CDKDeployer implements BackendDeployer {
// actionable errors being hidden among the stdout. Moreover execa errors are
// useless when calling CLIs unless you made execa calling error.
let aggregatedStderr = '';
let aggregatedStdout = '';
const aggregatorStderrStream = new stream.Writable();
const aggregatorStdoutStream = new stream.Writable();
aggregatorStderrStream._write = function (chunk, encoding, done) {
aggregatedStderr += chunk;
done();
};
aggregatorStdoutStream._write = function (chunk, encoding, done) {
aggregatedStdout += chunk;
done();
};
const childProcess = execa(command, cdkCommandArgs, {
stdin: 'inherit',
stdout: 'pipe',
stderr: 'pipe',
});
childProcess.stderr?.pipe(aggregatorStderrStream);
childProcess.stdout?.pipe(aggregatorStdoutStream);
childProcess.stdout?.pipe(process.stdout);

const cdkOutput = { deploymentTimes: {} };
if (childProcess.stdout) {
await this.populateCDKOutputFromStdout(cdkOutput, childProcess.stdout);
}

try {
await childProcess;
return aggregatedStdout;
return cdkOutput;
} catch (error) {
// swallow execa error which is not really helpful, rather throw stderr
throw new Error(aggregatedStderr);
}
};

private getDeploymentTimes = (cdkOutput: string) => {
const deploymentTimes: DeploymentTimes = {};
// the time can be in fractional or whole seconds. 24.3, 24, 24.22 etc.
private populateCDKOutputFromStdout = async (
output: DeployResult | DestroyResult,
stdout: stream.Readable
) => {
const regexTotalTime = /✨ {2}Total time: (\d*\.*\d*)s.*/;
const totalTime = cdkOutput.match(regexTotalTime);
if (totalTime && totalTime.length > 1 && !isNaN(+totalTime[1])) {
deploymentTimes.totalTime = +totalTime[1];
}

const regexSynthTime = /✨ {2}Synthesis time: (\d*\.*\d*)s/;
const synthTime = cdkOutput.match(regexSynthTime);
if (synthTime && synthTime.length > 1 && !isNaN(+synthTime[1])) {
deploymentTimes.synthesisTime = +synthTime[1];
const reader = readline.createInterface(stdout);
for await (const line of reader) {
Amplifiyer marked this conversation as resolved.
Show resolved Hide resolved
if (line.includes('✨')) {
// Good chance that it contains timing information
const totalTime = line.match(regexTotalTime);
if (totalTime && totalTime.length > 1 && !isNaN(+totalTime[1])) {
output.deploymentTimes.totalTime = +totalTime[1];
}
const synthTime = line.match(regexSynthTime);
if (synthTime && synthTime.length > 1 && !isNaN(+synthTime[1])) {
output.deploymentTimes.synthesisTime = +synthTime[1];
}
}
}

return deploymentTimes;
};

private deploymentHotswapped = (cdkOutput: string) => {
const regexTotalTime = /✨.*hotswapped!/;
return regexTotalTime.test(cdkOutput);
};
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BackendIdentifier, DeploymentType } from '@aws-amplify/plugin-types';
import { CDKDeployer } from './cdk_deployer.js';
import { CdkErrorMapper } from './cdk_error_mapper.js';
import { BackendLocator, DeploymentTimes } from '@aws-amplify/platform-core';
import { BackendLocator } from '@aws-amplify/platform-core';

export type DeployProps = {
deploymentType?: DeploymentType;
Expand All @@ -10,7 +10,6 @@ export type DeployProps = {
};

export type DeployResult = {
hotswapped?: boolean;
deploymentTimes: DeploymentTimes;
};

Expand All @@ -22,6 +21,11 @@ export type DestroyResult = {
deploymentTimes: DeploymentTimes;
};

export type DeploymentTimes = {
synthesisTime?: number;
totalTime?: number;
};

/**
* Invokes an invokable command
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/backend-output-storage/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

import { BackendOutputEntry } from '@aws-amplify/plugin-types';
import { BackendOutputStorageStrategy } from '@aws-amplify/plugin-types';
import { LibraryVersionFetcher } from '@aws-amplify/platform-core';
import * as _os from 'os';
import { PackageJsonReader } from '@aws-amplify/platform-core';
import { Stack } from 'aws-cdk-lib';

// @public (undocumented)
Expand All @@ -23,7 +23,7 @@ export type AttributionMetadata = {

// @public
export class AttributionMetadataStorage {
constructor(os?: typeof _os, libraryVersionFetcher?: LibraryVersionFetcher);
constructor(os?: typeof _os, packageJsonReader?: PackageJsonReader);
storeAttributionMetadata: (stack: Stack, stackType: string, libraryPackageJsonAbsolutePath: string, additionalMetadata?: Record<string, string>) => void;
}

Expand Down
Loading
Loading