Skip to content

Commit 124be1c

Browse files
committed
refactor: add build and rebuild related statistics and analytics
The new build and rebuild statistics are used by the CLI to submit build related information to GA.
1 parent c969152 commit 124be1c

File tree

14 files changed

+499
-195
lines changed

14 files changed

+499
-195
lines changed

docs/design/analytics.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ PROJECT NAME TO BUILD OR A MODULE NAME.**
4545
| User-scoped custom dimensions | 25 |
4646
| All custom metrics | 50 |
4747

48-
### List Of User Custom Dimensions
48+
### List of User Custom Dimensions
4949

5050
<!--USER_DIMENSIONS_TABLE_BEGIN-->
5151
| Name | Parameter | Type |
@@ -63,7 +63,7 @@ PROJECT NAME TO BUILD OR A MODULE NAME.**
6363
| Optimization | `ep.ng_optimization` | `string` |
6464
<!--USER_DIMENSIONS_TABLE_END-->
6565

66-
### List Of Event Custom Dimensions
66+
### List of Event Custom Dimensions
6767

6868
<!--DIMENSIONS_TABLE_BEGIN-->
6969
| Name | Parameter | Type |
@@ -81,7 +81,7 @@ PROJECT NAME TO BUILD OR A MODULE NAME.**
8181
| Optimization | `ep.ng_optimization` | `string` |
8282
<!--DIMENSIONS_TABLE_END-->
8383

84-
### List Of Event Custom Metrics
84+
### List of Event Custom Metrics
8585

8686
<!--METRICS_TABLE_BEGIN-->
8787
| Name | Parameter | Type |
@@ -91,6 +91,9 @@ PROJECT NAME TO BUILD OR A MODULE NAME.**
9191
| InitialChunksCount | `epn.ng_initial_chunks_count` | `number` |
9292
| ChangedChunksCount | `epn.ng_changed_chunks_count` | `number` |
9393
| DurationInMs | `epn.ng_duration_ms` | `number` |
94+
| CssSizeInBytes | `epn.ng_css_size_bytes` | `number` |
95+
| JsSizeInBytes | `epn.ng_js_size_bytes` | `number` |
96+
| NgComponentCount | `epn.ng_component_count` | `number` |
9497
<!--METRICS_TABLE_END-->
9598

9699
## Debugging

goldens/public-api/angular_devkit/build_angular/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export interface BrowserBuilderOptions {
7373

7474
// @public
7575
export type BrowserBuilderOutput = BuilderOutput & {
76+
stats: BuildEventStats;
7677
baseOutputPath: string;
7778
outputPaths: string[];
7879
outputPath: string;
@@ -112,6 +113,7 @@ export type DevServerBuilderOptions = Schema;
112113
// @public
113114
export type DevServerBuilderOutput = DevServerBuildOutput & {
114115
baseUrl: string;
116+
stats: BuildEventStats;
115117
};
116118

117119
// @public

goldens/public-api/angular_devkit/build_webpack/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export function runWebpack(config: webpack.Configuration, context: BuilderContex
4949

5050
// @public (undocumented)
5151
export function runWebpackDevServer(config: webpack.Configuration, context: BuilderContext, options?: {
52+
shouldProvideStats?: boolean;
5253
devServerConfig?: WebpackDevServer.Configuration;
5354
logging?: WebpackLoggingCallback;
5455
webpackFactory?: WebpackFactory;

packages/angular/cli/src/analytics/analytics-collector.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export class AnalyticsCollector {
3434
const requestParameters: Partial<Record<RequestParameter, PrimitiveTypes>> = {
3535
[RequestParameter.ProtocolVersion]: 2,
3636
[RequestParameter.ClientId]: userId,
37+
[RequestParameter.UserId]: userId,
3738
[RequestParameter.TrackingId]:
3839
/^\d+\.\d+\.\d+$/.test(VERSION.full) && VERSION.full !== '0.0.0'
3940
? TRACKING_ID_PROD

packages/angular/cli/src/analytics/analytics-parameters.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,7 @@ export enum EventCustomMetric {
9494
InitialChunksCount = 'epn.ng_initial_chunks_count',
9595
ChangedChunksCount = 'epn.ng_changed_chunks_count',
9696
DurationInMs = 'epn.ng_duration_ms',
97+
CssSizeInBytes = 'epn.ng_css_size_bytes',
98+
JsSizeInBytes = 'epn.ng_js_size_bytes',
99+
NgComponentCount = 'epn.ng_component_count',
97100
}

packages/angular/cli/src/command-builder/architect-base-command-module.ts

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { spawnSync } from 'child_process';
1616
import { existsSync } from 'fs';
1717
import { resolve } from 'path';
1818
import { isPackageNameSafeForAnalytics } from '../analytics/analytics';
19-
import { EventCustomDimension } from '../analytics/analytics-collector';
19+
import { EventCustomDimension, EventCustomMetric } from '../analytics/analytics-parameters';
2020
import { assertIsError } from '../utilities/error';
2121
import { askConfirmation, askQuestion } from '../utilities/prompt';
2222
import { isTTY } from '../utilities/tty';
@@ -62,18 +62,79 @@ export abstract class ArchitectBaseCommandModule<T extends object>
6262
? await this.getAnalytics()
6363
: undefined;
6464

65-
analytics?.reportArchitectRunEvent({
66-
[EventCustomDimension.BuilderTarget]: builderName,
67-
});
65+
let outputSubscription;
66+
if (analytics) {
67+
analytics.reportArchitectRunEvent({
68+
[EventCustomDimension.BuilderTarget]: builderName,
69+
});
70+
71+
let firstRun = true;
72+
outputSubscription = run.output.subscribe(({ stats }) => {
73+
const parameters = this.builderStatsToAnalyticsParameters(stats, builderName);
74+
if (!parameters) {
75+
return;
76+
}
6877

69-
const { error, success } = await run.output.toPromise();
70-
await run.stop();
78+
if (firstRun) {
79+
firstRun = false;
80+
analytics.reportBuildRunEvent(parameters);
81+
} else {
82+
analytics.reportRebuildRunEvent(parameters);
83+
}
84+
});
85+
}
86+
87+
try {
88+
const { error, success } = await run.output.toPromise();
7189

72-
if (error) {
73-
logger.error(error);
90+
if (error) {
91+
logger.error(error);
92+
}
93+
94+
return success ? 0 : 1;
95+
} finally {
96+
await run.stop();
97+
outputSubscription?.unsubscribe();
98+
}
99+
}
100+
101+
private builderStatsToAnalyticsParameters(
102+
stats: json.JsonValue,
103+
builderName: string,
104+
): Partial<
105+
| Record<EventCustomDimension & EventCustomMetric, string | number | undefined | boolean>
106+
| undefined
107+
> {
108+
if (!stats || typeof stats !== 'object' || !('durationInMs' in stats)) {
109+
return undefined;
74110
}
75111

76-
return success ? 0 : 1;
112+
const {
113+
optimization,
114+
allChunksCount,
115+
aot,
116+
lazyChunksCount,
117+
initialChunksCount,
118+
durationInMs,
119+
changedChunksCount,
120+
cssSizeInBytes,
121+
jsSizeInBytes,
122+
ngComponentCount,
123+
} = stats;
124+
125+
return {
126+
[EventCustomDimension.BuilderTarget]: builderName,
127+
[EventCustomDimension.Aot]: aot,
128+
[EventCustomDimension.Optimization]: optimization,
129+
[EventCustomMetric.AllChunksCount]: allChunksCount,
130+
[EventCustomMetric.LazyChunksCount]: lazyChunksCount,
131+
[EventCustomMetric.InitialChunksCount]: initialChunksCount,
132+
[EventCustomMetric.ChangedChunksCount]: changedChunksCount,
133+
[EventCustomMetric.DurationInMs]: durationInMs,
134+
[EventCustomMetric.JsSizeInBytes]: jsSizeInBytes,
135+
[EventCustomMetric.CssSizeInBytes]: cssSizeInBytes,
136+
[EventCustomMetric.NgComponentCount]: ngComponentCount,
137+
};
77138
}
78139

79140
private _architectHost: WorkspaceNodeModulesArchitectHost | undefined;

packages/angular_devkit/build_angular/src/builders/browser-esbuild/schema.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
"optimization": {
143143
"description": "Enables optimization of the build output. Including minification of scripts and styles, tree-shaking, dead-code elimination, inlining of critical CSS and fonts inlining. For more information, see https://angular.io/guide/workspace-config#optimization-configuration.",
144144
"default": true,
145+
"x-user-analytics": "ep.ng_optimization",
145146
"oneOf": [
146147
{
147148
"type": "object",

0 commit comments

Comments
 (0)