Skip to content

Commit e1c7e95

Browse files
authored
feat: add tarball bundling timing metric for Edge Functions and expose it via manifest/schema (#6786)
1 parent a107de7 commit e1c7e95

File tree

6 files changed

+58
-13
lines changed

6 files changed

+58
-13
lines changed

packages/build/src/core/report_metrics.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { closeClient, formatTags, InputStatsDOptions, startClient, validateStatsDOptions } from '../report/statsd.js'
22

33
export type Metric = {
4-
type: 'increment'
4+
type: 'increment' | 'timing'
55
name: string
66
value: number
77
tags: Record<string, string | string[]>

packages/build/src/plugins_core/edge_functions/index.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,23 @@ const getMetrics = (manifest): Metric[] => {
165165

166166
const numUserEfs = totalEfs.length - numGenEfs
167167

168-
return [
168+
const metrics: Metric[] = [
169169
{ type: 'increment', name: 'buildbot.build.functions', value: numGenEfs, tags: { type: 'edge:generated' } },
170170
{ type: 'increment', name: 'buildbot.build.functions', value: numUserEfs, tags: { type: 'edge:user' } },
171171
]
172+
173+
const tarballDurationMs = manifest.bundling_timing?.tarball_ms
174+
175+
if (typeof tarballDurationMs === 'number') {
176+
metrics.push({
177+
type: 'timing',
178+
name: 'buildbot.build.edge_functions.bundling_ms',
179+
value: tarballDurationMs,
180+
tags: { format: 'tarball' },
181+
})
182+
}
183+
184+
return metrics
172185
}
173186
// We run this core step if at least one of the functions directories (the
174187
// one configured by the user or the internal one) exists. We use a dynamic

packages/edge-bundler/node/bundler.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,8 @@ describe.skipIf(lt(denoVersion, '2.4.3'))(
787787
const manifestFile = await readFile(resolve(distPath, 'manifest.json'), 'utf8')
788788
const manifest = JSON.parse(manifestFile)
789789

790+
expect(manifest.bundling_timing).toEqual({ tarball_ms: expect.any(Number) })
791+
790792
const tarballPath = join(distPath, manifest.bundles[0].asset)
791793
const tarballResult = await runTarball(tarballPath)
792794
expect(tarballResult).toStrictEqual(expectedOutput)
@@ -879,6 +881,7 @@ describe.skipIf(lt(denoVersion, '2.4.3'))(
879881
const manifestFile = await readFile(resolve(distPath, 'manifest.json'), 'utf8')
880882
const manifest = JSON.parse(manifestFile)
881883

884+
expect(manifest.bundling_timing).toEqual({ tarball_ms: expect.any(Number) })
882885
expect(manifest.bundles.length).toBe(1)
883886
expect(manifest.bundles[0].format).toBe('eszip2')
884887

packages/edge-bundler/node/bundler.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,19 +128,28 @@ export const bundle = async (
128128
}
129129

130130
const bundles: Bundle[] = []
131+
let tarballBundleDurationMs: number | undefined
131132

132133
if (featureFlags.edge_bundler_generate_tarball || featureFlags.edge_bundler_dry_run_generate_tarball) {
133-
const tarballPromise = bundleTarball({
134-
basePath,
135-
buildID,
136-
debug,
137-
deno,
138-
distDirectory,
139-
functions,
140-
featureFlags,
141-
importMap: importMap.clone(),
142-
vendorDirectory: vendor?.directory,
143-
})
134+
const tarballPromise = (async () => {
135+
const start = Date.now()
136+
137+
try {
138+
return await bundleTarball({
139+
basePath,
140+
buildID,
141+
debug,
142+
deno,
143+
distDirectory,
144+
functions,
145+
featureFlags,
146+
importMap: importMap.clone(),
147+
vendorDirectory: vendor?.directory,
148+
})
149+
} finally {
150+
tarballBundleDurationMs = Date.now() - start
151+
}
152+
})()
144153

145154
if (featureFlags.edge_bundler_dry_run_generate_tarball) {
146155
try {
@@ -214,6 +223,7 @@ export const bundle = async (
214223
internalFunctionConfig,
215224
importMap: importMapSpecifier,
216225
layers: deployConfig.layers,
226+
bundlingTiming: tarballBundleDurationMs === undefined ? undefined : { tarball_ms: tarballBundleDurationMs },
217227
})
218228

219229
await vendor?.cleanup()

packages/edge-bundler/node/manifest.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,14 @@ export interface EdgeFunctionConfig {
4949
traffic_rules?: TrafficRules
5050
}
5151

52+
interface BundlingTiming {
53+
tarball_ms?: number
54+
}
55+
5256
interface Manifest {
5357
bundler_version: string
5458
bundles: { asset: string; format: string }[]
59+
bundling_timing?: BundlingTiming
5560
import_map?: string
5661
layers: { name: string; flag: string }[]
5762
routes: Route[]
@@ -68,6 +73,7 @@ interface GenerateManifestOptions {
6873
internalFunctionConfig?: Record<string, FunctionConfig>
6974
layers?: Layer[]
7075
userFunctionConfig?: Record<string, FunctionConfig>
76+
bundlingTiming?: BundlingTiming
7177
}
7278

7379
const removeEmptyConfigValues = (functionConfig: EdgeFunctionConfig) =>
@@ -149,6 +155,7 @@ const generateManifest = ({
149155
internalFunctionConfig = {},
150156
importMap,
151157
layers = [],
158+
bundlingTiming,
152159
}: GenerateManifestOptions) => {
153160
const preCacheRoutes: Route[] = []
154161
const postCacheRoutes: Route[] = []
@@ -259,6 +266,9 @@ const generateManifest = ({
259266
layers,
260267
import_map: importMap,
261268
function_config: sanitizeEdgeFunctionConfig(manifestFunctionConfig),
269+
...(bundlingTiming && Object.values(bundlingTiming).some((value) => value !== undefined)
270+
? { bundling_timing: bundlingTiming }
271+
: {}),
262272
}
263273
const unroutedFunctions = functions.filter(({ name }) => !routedFunctions.has(name)).map(({ name }) => name)
264274

packages/edge-bundler/node/validation/manifest/schema.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ const excludedPatternsSchema = {
1818
},
1919
}
2020

21+
const bundlingTimingSchema = {
22+
type: 'object',
23+
properties: {
24+
tarball_ms: { type: 'number', minimum: 0 },
25+
},
26+
additionalProperties: false,
27+
}
28+
2129
const headersSchema = {
2230
type: 'object',
2331
patternProperties: {
@@ -112,6 +120,7 @@ const edgeManifestSchema = {
112120
},
113121
import_map: { type: 'string' },
114122
bundler_version: { type: 'string' },
123+
bundling_timing: bundlingTimingSchema,
115124
function_config: { type: 'object', additionalProperties: functionConfigSchema },
116125
},
117126
additionalProperties: false,

0 commit comments

Comments
 (0)