2021-01-18 17:38:00 +01:00
|
|
|
import { webpack, isWebpack5 } from 'next/dist/compiled/webpack/webpack'
|
Telemetry-compatible tracing (#22713)
A number of changes here. I recommend viewing the diff with the <a href="?w=1">whitespace flag enabled</a>.
- OpenTelemetry is replaced with a custom and lightweight tracing solution.
- Three trace targets are currently supported: console, Zipkin, and NextJS.
- Tracing is now governed by environment variables rather than `--require instrument.js`.
+ `TRACE_TARGET`: one of `CONSOLE`, `ZIPKIN`, or `TELEMETRY`; defaults to `TELEMETRY` if unset or invalid.
+ `TRACE_ID`: an 8-byte hex-encoded value used as the Zipkin trace ID; if not provided, this value will be randomly generated and passed down to subprocesses.
Other sundry:
- I'm missing something, probably a setup step, with the Zipkin target. Traces are captured successfully, but you have to manually enter the Trace ID in order to view the trace - it doesn't show up in queries.
- I'm generally unhappy with [this commit](https://github.com/vercel/next.js/pull/22713/commits/235cedcb3ead76b630b4c8aa695f904489da2831). It is... untidy to provide a telemetry object via `setGlobal`, but I don't have a ready alternative. Is `distDir` strictly required when creating a new Telemetry object? I didn't dig too deep here.
As noted, there are a lot of changes, so it'd be great if a reviewer could:
- [ ] pull down the branch and try to break it
- [ ] check the Zipkin traces and identify possible regressions in the functionality
Closes #22570
Fixes #22574
2021-03-10 22:00:20 +01:00
|
|
|
import { trace, stackPush, stackPop, Span } from '../../../telemetry/trace'
|
2019-08-18 21:45:39 +02:00
|
|
|
|
|
|
|
const pluginName = 'ProfilingPlugin'
|
Telemetry-compatible tracing (#22713)
A number of changes here. I recommend viewing the diff with the <a href="?w=1">whitespace flag enabled</a>.
- OpenTelemetry is replaced with a custom and lightweight tracing solution.
- Three trace targets are currently supported: console, Zipkin, and NextJS.
- Tracing is now governed by environment variables rather than `--require instrument.js`.
+ `TRACE_TARGET`: one of `CONSOLE`, `ZIPKIN`, or `TELEMETRY`; defaults to `TELEMETRY` if unset or invalid.
+ `TRACE_ID`: an 8-byte hex-encoded value used as the Zipkin trace ID; if not provided, this value will be randomly generated and passed down to subprocesses.
Other sundry:
- I'm missing something, probably a setup step, with the Zipkin target. Traces are captured successfully, but you have to manually enter the Trace ID in order to view the trace - it doesn't show up in queries.
- I'm generally unhappy with [this commit](https://github.com/vercel/next.js/pull/22713/commits/235cedcb3ead76b630b4c8aa695f904489da2831). It is... untidy to provide a telemetry object via `setGlobal`, but I don't have a ready alternative. Is `distDir` strictly required when creating a new Telemetry object? I didn't dig too deep here.
As noted, there are a lot of changes, so it'd be great if a reviewer could:
- [ ] pull down the branch and try to break it
- [ ] check the Zipkin traces and identify possible regressions in the functionality
Closes #22570
Fixes #22574
2021-03-10 22:00:20 +01:00
|
|
|
export const spans = new WeakMap<any, Span>()
|
2019-08-18 21:45:39 +02:00
|
|
|
|
2021-01-18 17:38:00 +01:00
|
|
|
function getNormalModuleLoaderHook(compilation: any) {
|
|
|
|
if (isWebpack5) {
|
|
|
|
// @ts-ignore TODO: Remove ignore when webpack 5 is stable
|
|
|
|
return webpack.NormalModule.getCompilationHooks(compilation).loader
|
|
|
|
}
|
|
|
|
|
|
|
|
return compilation.hooks.normalModuleLoader
|
|
|
|
}
|
|
|
|
|
2021-01-10 02:12:13 +01:00
|
|
|
export class ProfilingPlugin {
|
2021-01-29 11:32:26 +01:00
|
|
|
compiler: any
|
|
|
|
|
2019-08-18 21:45:39 +02:00
|
|
|
apply(compiler: any) {
|
2021-01-29 11:32:26 +01:00
|
|
|
this.traceTopLevelHooks(compiler)
|
|
|
|
this.traceCompilationHooks(compiler)
|
|
|
|
this.compiler = compiler
|
|
|
|
}
|
2019-08-18 21:45:39 +02:00
|
|
|
|
2021-01-29 11:32:26 +01:00
|
|
|
traceHookPair(
|
|
|
|
spanName: string,
|
|
|
|
startHook: any,
|
|
|
|
stopHook: any,
|
|
|
|
attrs?: any,
|
Telemetry-compatible tracing (#22713)
A number of changes here. I recommend viewing the diff with the <a href="?w=1">whitespace flag enabled</a>.
- OpenTelemetry is replaced with a custom and lightweight tracing solution.
- Three trace targets are currently supported: console, Zipkin, and NextJS.
- Tracing is now governed by environment variables rather than `--require instrument.js`.
+ `TRACE_TARGET`: one of `CONSOLE`, `ZIPKIN`, or `TELEMETRY`; defaults to `TELEMETRY` if unset or invalid.
+ `TRACE_ID`: an 8-byte hex-encoded value used as the Zipkin trace ID; if not provided, this value will be randomly generated and passed down to subprocesses.
Other sundry:
- I'm missing something, probably a setup step, with the Zipkin target. Traces are captured successfully, but you have to manually enter the Trace ID in order to view the trace - it doesn't show up in queries.
- I'm generally unhappy with [this commit](https://github.com/vercel/next.js/pull/22713/commits/235cedcb3ead76b630b4c8aa695f904489da2831). It is... untidy to provide a telemetry object via `setGlobal`, but I don't have a ready alternative. Is `distDir` strictly required when creating a new Telemetry object? I didn't dig too deep here.
As noted, there are a lot of changes, so it'd be great if a reviewer could:
- [ ] pull down the branch and try to break it
- [ ] check the Zipkin traces and identify possible regressions in the functionality
Closes #22570
Fixes #22574
2021-03-10 22:00:20 +01:00
|
|
|
onSetSpan?: (span: Span) => void
|
2021-01-29 11:32:26 +01:00
|
|
|
) {
|
|
|
|
let span: Span | undefined
|
|
|
|
startHook.tap(pluginName, () => {
|
|
|
|
span = stackPush(this.compiler, spanName, attrs)
|
|
|
|
onSetSpan?.(span)
|
|
|
|
})
|
|
|
|
stopHook.tap(pluginName, () => {
|
2021-02-12 11:17:38 +01:00
|
|
|
// `stopHook` may be triggered when `startHook` has not in cases
|
|
|
|
// where `stopHook` is used as the terminating event for more
|
|
|
|
// than one pair of hooks.
|
|
|
|
if (!span) {
|
|
|
|
return
|
|
|
|
}
|
Telemetry-compatible tracing (#22713)
A number of changes here. I recommend viewing the diff with the <a href="?w=1">whitespace flag enabled</a>.
- OpenTelemetry is replaced with a custom and lightweight tracing solution.
- Three trace targets are currently supported: console, Zipkin, and NextJS.
- Tracing is now governed by environment variables rather than `--require instrument.js`.
+ `TRACE_TARGET`: one of `CONSOLE`, `ZIPKIN`, or `TELEMETRY`; defaults to `TELEMETRY` if unset or invalid.
+ `TRACE_ID`: an 8-byte hex-encoded value used as the Zipkin trace ID; if not provided, this value will be randomly generated and passed down to subprocesses.
Other sundry:
- I'm missing something, probably a setup step, with the Zipkin target. Traces are captured successfully, but you have to manually enter the Trace ID in order to view the trace - it doesn't show up in queries.
- I'm generally unhappy with [this commit](https://github.com/vercel/next.js/pull/22713/commits/235cedcb3ead76b630b4c8aa695f904489da2831). It is... untidy to provide a telemetry object via `setGlobal`, but I don't have a ready alternative. Is `distDir` strictly required when creating a new Telemetry object? I didn't dig too deep here.
As noted, there are a lot of changes, so it'd be great if a reviewer could:
- [ ] pull down the branch and try to break it
- [ ] check the Zipkin traces and identify possible regressions in the functionality
Closes #22570
Fixes #22574
2021-03-10 22:00:20 +01:00
|
|
|
stackPop(this.compiler, span)
|
2021-01-29 11:32:26 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
traceLoopedHook(spanName: string, startHook: any, stopHook: any) {
|
|
|
|
let span: Span | undefined
|
|
|
|
startHook.tap(pluginName, () => {
|
|
|
|
if (!span) {
|
|
|
|
span = stackPush(this.compiler, spanName)
|
|
|
|
}
|
2019-08-18 21:45:39 +02:00
|
|
|
})
|
2021-01-29 11:32:26 +01:00
|
|
|
stopHook.tap(pluginName, () => {
|
Telemetry-compatible tracing (#22713)
A number of changes here. I recommend viewing the diff with the <a href="?w=1">whitespace flag enabled</a>.
- OpenTelemetry is replaced with a custom and lightweight tracing solution.
- Three trace targets are currently supported: console, Zipkin, and NextJS.
- Tracing is now governed by environment variables rather than `--require instrument.js`.
+ `TRACE_TARGET`: one of `CONSOLE`, `ZIPKIN`, or `TELEMETRY`; defaults to `TELEMETRY` if unset or invalid.
+ `TRACE_ID`: an 8-byte hex-encoded value used as the Zipkin trace ID; if not provided, this value will be randomly generated and passed down to subprocesses.
Other sundry:
- I'm missing something, probably a setup step, with the Zipkin target. Traces are captured successfully, but you have to manually enter the Trace ID in order to view the trace - it doesn't show up in queries.
- I'm generally unhappy with [this commit](https://github.com/vercel/next.js/pull/22713/commits/235cedcb3ead76b630b4c8aa695f904489da2831). It is... untidy to provide a telemetry object via `setGlobal`, but I don't have a ready alternative. Is `distDir` strictly required when creating a new Telemetry object? I didn't dig too deep here.
As noted, there are a lot of changes, so it'd be great if a reviewer could:
- [ ] pull down the branch and try to break it
- [ ] check the Zipkin traces and identify possible regressions in the functionality
Closes #22570
Fixes #22574
2021-03-10 22:00:20 +01:00
|
|
|
stackPop(this.compiler, span)
|
2019-08-18 21:45:39 +02:00
|
|
|
})
|
2021-01-29 11:32:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
traceTopLevelHooks(compiler: any) {
|
|
|
|
this.traceHookPair(
|
|
|
|
'webpack-compile',
|
|
|
|
compiler.hooks.compile,
|
|
|
|
compiler.hooks.done,
|
|
|
|
() => {
|
Telemetry-compatible tracing (#22713)
A number of changes here. I recommend viewing the diff with the <a href="?w=1">whitespace flag enabled</a>.
- OpenTelemetry is replaced with a custom and lightweight tracing solution.
- Three trace targets are currently supported: console, Zipkin, and NextJS.
- Tracing is now governed by environment variables rather than `--require instrument.js`.
+ `TRACE_TARGET`: one of `CONSOLE`, `ZIPKIN`, or `TELEMETRY`; defaults to `TELEMETRY` if unset or invalid.
+ `TRACE_ID`: an 8-byte hex-encoded value used as the Zipkin trace ID; if not provided, this value will be randomly generated and passed down to subprocesses.
Other sundry:
- I'm missing something, probably a setup step, with the Zipkin target. Traces are captured successfully, but you have to manually enter the Trace ID in order to view the trace - it doesn't show up in queries.
- I'm generally unhappy with [this commit](https://github.com/vercel/next.js/pull/22713/commits/235cedcb3ead76b630b4c8aa695f904489da2831). It is... untidy to provide a telemetry object via `setGlobal`, but I don't have a ready alternative. Is `distDir` strictly required when creating a new Telemetry object? I didn't dig too deep here.
As noted, there are a lot of changes, so it'd be great if a reviewer could:
- [ ] pull down the branch and try to break it
- [ ] check the Zipkin traces and identify possible regressions in the functionality
Closes #22570
Fixes #22574
2021-03-10 22:00:20 +01:00
|
|
|
return { name: compiler.name }
|
2021-01-29 11:32:26 +01:00
|
|
|
},
|
|
|
|
(span) => spans.set(compiler, span)
|
|
|
|
)
|
|
|
|
this.traceHookPair(
|
|
|
|
'webpack-prepare-env',
|
|
|
|
compiler.hooks.environment,
|
|
|
|
compiler.hooks.afterEnvironment
|
|
|
|
)
|
2021-02-10 00:21:38 +01:00
|
|
|
if (compiler.options.mode === 'development') {
|
|
|
|
this.traceHookPair(
|
|
|
|
'webpack-invalidated',
|
|
|
|
compiler.hooks.invalid,
|
2021-06-25 13:55:46 +02:00
|
|
|
compiler.hooks.done,
|
|
|
|
() => ({ name: compiler.name })
|
2021-02-10 00:21:38 +01:00
|
|
|
)
|
|
|
|
}
|
2021-01-29 11:32:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
traceCompilationHooks(compiler: any) {
|
2021-02-10 00:21:38 +01:00
|
|
|
if (isWebpack5) {
|
|
|
|
this.traceHookPair(
|
|
|
|
'webpack-compilation',
|
|
|
|
compiler.hooks.beforeCompile,
|
2021-06-25 13:55:46 +02:00
|
|
|
compiler.hooks.afterCompile,
|
|
|
|
() => ({ name: compiler.name })
|
2021-02-10 00:21:38 +01:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-01-10 02:12:13 +01:00
|
|
|
compiler.hooks.compilation.tap(pluginName, (compilation: any) => {
|
|
|
|
compilation.hooks.buildModule.tap(pluginName, (module: any) => {
|
2021-01-29 11:32:26 +01:00
|
|
|
const compilerSpan = spans.get(compiler)
|
|
|
|
if (!compilerSpan) {
|
|
|
|
return
|
|
|
|
}
|
Telemetry-compatible tracing (#22713)
A number of changes here. I recommend viewing the diff with the <a href="?w=1">whitespace flag enabled</a>.
- OpenTelemetry is replaced with a custom and lightweight tracing solution.
- Three trace targets are currently supported: console, Zipkin, and NextJS.
- Tracing is now governed by environment variables rather than `--require instrument.js`.
+ `TRACE_TARGET`: one of `CONSOLE`, `ZIPKIN`, or `TELEMETRY`; defaults to `TELEMETRY` if unset or invalid.
+ `TRACE_ID`: an 8-byte hex-encoded value used as the Zipkin trace ID; if not provided, this value will be randomly generated and passed down to subprocesses.
Other sundry:
- I'm missing something, probably a setup step, with the Zipkin target. Traces are captured successfully, but you have to manually enter the Trace ID in order to view the trace - it doesn't show up in queries.
- I'm generally unhappy with [this commit](https://github.com/vercel/next.js/pull/22713/commits/235cedcb3ead76b630b4c8aa695f904489da2831). It is... untidy to provide a telemetry object via `setGlobal`, but I don't have a ready alternative. Is `distDir` strictly required when creating a new Telemetry object? I didn't dig too deep here.
As noted, there are a lot of changes, so it'd be great if a reviewer could:
- [ ] pull down the branch and try to break it
- [ ] check the Zipkin traces and identify possible regressions in the functionality
Closes #22570
Fixes #22574
2021-03-10 22:00:20 +01:00
|
|
|
|
2021-08-16 22:05:57 +02:00
|
|
|
const moduleType = (() => {
|
|
|
|
if (!module.userRequest) {
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
|
|
|
|
return module.userRequest.split('.').pop()
|
|
|
|
})()
|
|
|
|
|
|
|
|
const span = trace(
|
|
|
|
`build-module${moduleType ? `-${moduleType}` : ''}`,
|
|
|
|
compilerSpan.id
|
|
|
|
)
|
Telemetry-compatible tracing (#22713)
A number of changes here. I recommend viewing the diff with the <a href="?w=1">whitespace flag enabled</a>.
- OpenTelemetry is replaced with a custom and lightweight tracing solution.
- Three trace targets are currently supported: console, Zipkin, and NextJS.
- Tracing is now governed by environment variables rather than `--require instrument.js`.
+ `TRACE_TARGET`: one of `CONSOLE`, `ZIPKIN`, or `TELEMETRY`; defaults to `TELEMETRY` if unset or invalid.
+ `TRACE_ID`: an 8-byte hex-encoded value used as the Zipkin trace ID; if not provided, this value will be randomly generated and passed down to subprocesses.
Other sundry:
- I'm missing something, probably a setup step, with the Zipkin target. Traces are captured successfully, but you have to manually enter the Trace ID in order to view the trace - it doesn't show up in queries.
- I'm generally unhappy with [this commit](https://github.com/vercel/next.js/pull/22713/commits/235cedcb3ead76b630b4c8aa695f904489da2831). It is... untidy to provide a telemetry object via `setGlobal`, but I don't have a ready alternative. Is `distDir` strictly required when creating a new Telemetry object? I didn't dig too deep here.
As noted, there are a lot of changes, so it'd be great if a reviewer could:
- [ ] pull down the branch and try to break it
- [ ] check the Zipkin traces and identify possible regressions in the functionality
Closes #22570
Fixes #22574
2021-03-10 22:00:20 +01:00
|
|
|
span.setAttribute('name', module.userRequest)
|
|
|
|
spans.set(module, span)
|
2021-01-10 02:12:13 +01:00
|
|
|
})
|
2019-08-18 21:45:39 +02:00
|
|
|
|
2021-01-18 17:38:00 +01:00
|
|
|
getNormalModuleLoaderHook(compilation).tap(
|
2021-01-10 02:12:13 +01:00
|
|
|
pluginName,
|
|
|
|
(loaderContext: any, module: any) => {
|
|
|
|
const parentSpan = spans.get(module)
|
|
|
|
loaderContext.currentTraceSpan = parentSpan
|
|
|
|
}
|
2019-08-18 21:45:39 +02:00
|
|
|
)
|
|
|
|
|
2021-01-10 02:12:13 +01:00
|
|
|
compilation.hooks.succeedModule.tap(pluginName, (module: any) => {
|
Telemetry-compatible tracing (#22713)
A number of changes here. I recommend viewing the diff with the <a href="?w=1">whitespace flag enabled</a>.
- OpenTelemetry is replaced with a custom and lightweight tracing solution.
- Three trace targets are currently supported: console, Zipkin, and NextJS.
- Tracing is now governed by environment variables rather than `--require instrument.js`.
+ `TRACE_TARGET`: one of `CONSOLE`, `ZIPKIN`, or `TELEMETRY`; defaults to `TELEMETRY` if unset or invalid.
+ `TRACE_ID`: an 8-byte hex-encoded value used as the Zipkin trace ID; if not provided, this value will be randomly generated and passed down to subprocesses.
Other sundry:
- I'm missing something, probably a setup step, with the Zipkin target. Traces are captured successfully, but you have to manually enter the Trace ID in order to view the trace - it doesn't show up in queries.
- I'm generally unhappy with [this commit](https://github.com/vercel/next.js/pull/22713/commits/235cedcb3ead76b630b4c8aa695f904489da2831). It is... untidy to provide a telemetry object via `setGlobal`, but I don't have a ready alternative. Is `distDir` strictly required when creating a new Telemetry object? I didn't dig too deep here.
As noted, there are a lot of changes, so it'd be great if a reviewer could:
- [ ] pull down the branch and try to break it
- [ ] check the Zipkin traces and identify possible regressions in the functionality
Closes #22570
Fixes #22574
2021-03-10 22:00:20 +01:00
|
|
|
spans.get(module)?.stop()
|
2019-08-18 21:45:39 +02:00
|
|
|
})
|
2021-01-29 11:32:26 +01:00
|
|
|
|
|
|
|
this.traceHookPair(
|
|
|
|
'webpack-compilation-chunk-graph',
|
|
|
|
compilation.hooks.beforeChunks,
|
|
|
|
compilation.hooks.afterChunks
|
|
|
|
)
|
|
|
|
this.traceHookPair(
|
|
|
|
'webpack-compilation-optimize',
|
|
|
|
compilation.hooks.optimize,
|
|
|
|
compilation.hooks.reviveModules
|
|
|
|
)
|
|
|
|
this.traceLoopedHook(
|
|
|
|
'webpack-compilation-optimize-modules',
|
|
|
|
compilation.hooks.optimizeModules,
|
|
|
|
compilation.hooks.afterOptimizeModules
|
|
|
|
)
|
|
|
|
this.traceLoopedHook(
|
|
|
|
'webpack-compilation-optimize-chunks',
|
|
|
|
compilation.hooks.optimizeChunks,
|
|
|
|
compilation.hooks.afterOptimizeChunks
|
|
|
|
)
|
|
|
|
this.traceHookPair(
|
|
|
|
'webpack-compilation-optimize-tree',
|
|
|
|
compilation.hooks.optimizeTree,
|
|
|
|
compilation.hooks.afterOptimizeTree
|
|
|
|
)
|
|
|
|
this.traceHookPair(
|
|
|
|
'webpack-compilation-hash',
|
|
|
|
compilation.hooks.beforeHash,
|
|
|
|
compilation.hooks.afterHash
|
|
|
|
)
|
2019-08-18 21:45:39 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|