diff --git a/packages/plugins/build-report/src/esbuild.ts b/packages/plugins/build-report/src/esbuild.ts index 041038ad4..441617c54 100644 --- a/packages/plugins/build-report/src/esbuild.ts +++ b/packages/plugins/build-report/src/esbuild.ts @@ -31,6 +31,7 @@ export const getEsbuildPlugin = (context: GlobalContext, log: Logger): PluginOpt const resolvedEntries: ResolvedEntry[] = []; build.onStart(async () => { + const timeEnd = log.time('process entries'); // Store entry names based on the configuration. resolvedEntries.push(...(await getEsbuildEntries(build, context, log))); for (const entry of resolvedEntries) { @@ -41,9 +42,11 @@ export const getEsbuildPlugin = (context: GlobalContext, log: Logger): PluginOpt entryNames.set(cleanedName, cleanedName); } } + timeEnd(); }); build.onEnd((result) => { + const collectTimeEnd = log.time('collecting errors and warnings'); const cwd = context.cwd; for (const error of result.errors) { context.build.errors.push(error.text); @@ -51,6 +54,7 @@ export const getEsbuildPlugin = (context: GlobalContext, log: Logger): PluginOpt for (const warning of result.warnings) { context.build.warnings.push(warning.text); } + collectTimeEnd(); if (!result.metafile) { const warning = 'Missing metafile from build report.'; @@ -68,8 +72,10 @@ export const getEsbuildPlugin = (context: GlobalContext, log: Logger): PluginOpt const reportInputsIndexed: Record = {}; const reportOutputsIndexed: Record = {}; + const indexTimeEnd = log.time('indexing metafile data'); const metaInputsIndexed = reIndexMeta(result.metafile.inputs, cwd); const metaOutputsIndexed = reIndexMeta(result.metafile.outputs, cwd); + indexTimeEnd(); // From a proxy entry point, created by our injection plugin, get the real path. const getRealPathFromInjectionProxy = (entryPoint: string): string => { @@ -94,6 +100,7 @@ export const getEsbuildPlugin = (context: GlobalContext, log: Logger): PluginOpt }; // Loop through inputs. + const inputsTimeEnd = log.time('looping through inputs'); for (const [filename, input] of Object.entries(result.metafile.inputs)) { if (isInjectionFile(filename)) { continue; @@ -113,8 +120,10 @@ export const getEsbuildPlugin = (context: GlobalContext, log: Logger): PluginOpt reportInputsIndexed[filepath] = file; inputs.push(file); } + inputsTimeEnd(); // Loop through outputs. + const outputTimeEnd = log.time('looping through outputs'); for (const [filename, output] of Object.entries(result.metafile.outputs)) { const fullPath = getAbsolutePath(cwd, filename); const cleanedName = cleanName(context, fullPath); @@ -193,8 +202,10 @@ export const getEsbuildPlugin = (context: GlobalContext, log: Logger): PluginOpt tempEntryFiles.push(entry); } } + outputTimeEnd(); // Loop through sourcemaps. + const sourcemapsTimeEnd = log.time('looping through sourcemaps'); for (const sourcemap of tempSourcemaps) { const outputFilepath = sourcemap.filepath.replace(/\.map$/, ''); const foundOutput = reportOutputsIndexed[outputFilepath]; @@ -206,6 +217,7 @@ export const getEsbuildPlugin = (context: GlobalContext, log: Logger): PluginOpt sourcemap.inputs.push(foundOutput); } + sourcemapsTimeEnd(); // Build our references for the entries. const references = { @@ -272,6 +284,7 @@ export const getEsbuildPlugin = (context: GlobalContext, log: Logger): PluginOpt }; // Loop through entries. + const entriesTimeEnd = log.time('looping through entries'); // TODO This is slightly underperformant due to getAllImports' recursivity. for (const entryFile of tempEntryFiles) { const entryInputs: Record = {}; @@ -300,8 +313,10 @@ export const getEsbuildPlugin = (context: GlobalContext, log: Logger): PluginOpt entries.push(entryFile); } + entriesTimeEnd(); // Loop through all inputs to aggregate dependencies and dependents. + const depsTimeEnd = log.time('aggregate dependencies and dependents'); for (const input of inputs) { const metaFile = references.inputs.meta[input.filepath]; if (!metaFile) { @@ -326,6 +341,7 @@ export const getEsbuildPlugin = (context: GlobalContext, log: Logger): PluginOpt dependencyFile.dependents.add(input); } } + depsTimeEnd(); context.build.outputs = outputs; context.build.inputs = inputs; diff --git a/packages/plugins/telemetry/src/esbuild-plugin/index.ts b/packages/plugins/telemetry/src/esbuild-plugin/index.ts index b617b80ba..1d873a0a2 100644 --- a/packages/plugins/telemetry/src/esbuild-plugin/index.ts +++ b/packages/plugins/telemetry/src/esbuild-plugin/index.ts @@ -19,14 +19,18 @@ export const getEsbuildPlugin = ( // We force esbuild to produce its metafile. build.initialOptions.metafile = true; + const wrapTimeEnd = logger.time('wrapping plugins'); wrapPlugins(build, globalContext.cwd); + wrapTimeEnd(); build.onEnd(async (result: BuildResult) => { if (!result.metafile) { logger.warn("Missing metafile, can't proceed with modules data."); return; } + const resultTimeEnd = logger.time('getting plugins results'); const { plugins, modules } = getPluginsResults(); + resultTimeEnd(); bundlerContext.report = { timings: { diff --git a/packages/plugins/telemetry/src/index.ts b/packages/plugins/telemetry/src/index.ts index 7df11edde..56578c81c 100644 --- a/packages/plugins/telemetry/src/index.ts +++ b/packages/plugins/telemetry/src/index.ts @@ -2,7 +2,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2019-Present Datadog, Inc. -import type { GlobalContext, GetPlugins, PluginOptions } from '@dd/core/types'; +import type { GlobalContext, GetPlugins, PluginOptions, Logger } from '@dd/core/types'; import { addMetrics } from './common/aggregator'; import { defaultFilters } from './common/filters'; @@ -56,14 +56,17 @@ export const getPlugins: GetPlugins = ( webpack: getWebpackPlugin(bundlerContext, context), rspack: getWebpackPlugin(bundlerContext, context), }; + let buildTimeEnd: ReturnType; // Universal plugin. const universalPlugin: PluginOptions = { name: 'datadog-universal-telemetry-plugin', enforce: 'post', buildStart() { + buildTimeEnd = log.time('build'); context.build.start = context.build.start || Date.now(); }, buildEnd() { + buildTimeEnd(); realBuildEnd = Date.now(); }, @@ -76,22 +79,30 @@ export const getPlugins: GetPlugins = ( const metrics: Set = new Set(); const optionsDD = getOptionsDD(telemetryOptions); + const metricsTimeEnd = log.time(`adding metrics`); addMetrics(context, optionsDD, metrics, bundlerContext.report); + metricsTimeEnd(); // TODO Extract the files output in an internal plugin. + const writeTimeEnd = log.time(`writing to files`); await outputFiles( { report: bundlerContext.report, metrics }, telemetryOptions.output, log, context.bundler.outDir, ); + writeTimeEnd(); + const reportTimeEnd = log.time('outputing report'); outputTexts(context, log, bundlerContext.report); + reportTimeEnd(); + const sendTimeEnd = log.time('sending metrics to Datadog.'); await sendMetrics( metrics, { apiKey: context.auth?.apiKey, endPoint: telemetryOptions.endPoint }, log, ); + sendTimeEnd(); }, };