.
This commit is contained in:
+185
@@ -0,0 +1,185 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
const _findup = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/find-up"));
|
||||
const _promises = /*#__PURE__*/ _interop_require_default(require("fs/promises"));
|
||||
const _child_process = /*#__PURE__*/ _interop_require_default(require("child_process"));
|
||||
const _assert = /*#__PURE__*/ _interop_require_default(require("assert"));
|
||||
const _os = /*#__PURE__*/ _interop_require_default(require("os"));
|
||||
const _readline = require("readline");
|
||||
const _fs = require("fs");
|
||||
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
|
||||
function _interop_require_default(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
default: obj
|
||||
};
|
||||
}
|
||||
const COMMON_ALLOWED_EVENTS = [
|
||||
'memory-usage'
|
||||
];
|
||||
// Predefined set of the event names to be included in the trace.
|
||||
// If the trace span's name matches to one of the event names in the set,
|
||||
// it'll up uploaded to the trace server.
|
||||
const DEV_ALLOWED_EVENTS = new Set([
|
||||
...COMMON_ALLOWED_EVENTS,
|
||||
'client-hmr-latency',
|
||||
'render-path',
|
||||
'hot-reloader',
|
||||
'webpack-invalid-client',
|
||||
'webpack-invalidated-server',
|
||||
'navigation-to-hydration',
|
||||
'start-dev-server',
|
||||
'compile-path',
|
||||
'memory-usage',
|
||||
'server-restart-close-to-memory-threshold'
|
||||
]);
|
||||
const BUILD_ALLOWED_EVENTS = new Set([
|
||||
...COMMON_ALLOWED_EVENTS,
|
||||
'next-build',
|
||||
'run-turbopack',
|
||||
'webpack-compilation',
|
||||
'run-webpack-compiler',
|
||||
'create-entrypoints',
|
||||
'worker-main-edge-server',
|
||||
'worker-main-client',
|
||||
'worker-main-server',
|
||||
'server',
|
||||
'make',
|
||||
'seal',
|
||||
'chunk-graph',
|
||||
'optimize-modules',
|
||||
'optimize-chunks',
|
||||
'optimize',
|
||||
'optimize-tree',
|
||||
'optimize-chunk-modules',
|
||||
'module-hash',
|
||||
'client',
|
||||
'static-check',
|
||||
'node-file-trace-build',
|
||||
'static-generation',
|
||||
'next-export',
|
||||
'run-typescript',
|
||||
'run-eslint'
|
||||
]);
|
||||
const { NEXT_TRACE_UPLOAD_DEBUG, // An external env to allow to upload full trace without picking up the relavant spans.
|
||||
// This is mainly for the debugging purpose, to allow manual audit for full trace for the given build.
|
||||
// [NOTE] This may fail if build is large and generated trace is excessively large.
|
||||
NEXT_TRACE_UPLOAD_FULL } = process.env;
|
||||
const isDebugEnabled = !!NEXT_TRACE_UPLOAD_DEBUG || !!NEXT_TRACE_UPLOAD_FULL;
|
||||
const shouldUploadFullTrace = !!NEXT_TRACE_UPLOAD_FULL;
|
||||
const [, , traceUploadUrl, mode, projectDir, distDir, _isTurboSession, traceId, anonymousId, sessionId] = process.argv;
|
||||
const isTurboSession = _isTurboSession === 'true';
|
||||
(async function upload() {
|
||||
const nextVersion = JSON.parse(await _promises.default.readFile(_path.default.resolve(__dirname, '../../package.json'), 'utf8')).version;
|
||||
const projectPkgJsonPath = await (0, _findup.default)('package.json');
|
||||
(0, _assert.default)(projectPkgJsonPath);
|
||||
const projectPkgJson = JSON.parse(await _promises.default.readFile(projectPkgJsonPath, 'utf-8'));
|
||||
const pkgName = projectPkgJson.name;
|
||||
const git = _os.default.platform() === 'win32' ? 'git.exe' : 'git';
|
||||
const isVercelEnvironment = !!process.env.VERCEL;
|
||||
const commit = process.env.VERCEL_GIT_COMMIT_SHA || _child_process.default.spawnSync(git, [
|
||||
'rev-parse',
|
||||
'HEAD'
|
||||
]).stdout.toString().trimEnd();
|
||||
const branch = process.env.VERCEL_GIT_COMMIT_REF || _child_process.default.spawnSync(git, [
|
||||
'rev-parse',
|
||||
'--abbrev-ref',
|
||||
'HEAD'
|
||||
]).stdout.toString().trimEnd();
|
||||
const readLineInterface = (0, _readline.createInterface)({
|
||||
input: (0, _fs.createReadStream)(_path.default.join(projectDir, distDir, 'trace')),
|
||||
crlfDelay: Infinity
|
||||
});
|
||||
const sessionTrace = [];
|
||||
let sessionEnabledFeatures = {};
|
||||
const spanEnabledFeatures = new Map();
|
||||
for await (const line of readLineInterface){
|
||||
const lineEvents = JSON.parse(line);
|
||||
for (const event of lineEvents){
|
||||
if (event.traceId !== traceId) {
|
||||
continue;
|
||||
}
|
||||
// Extract enabled features from the root span (next-dev or next-build)
|
||||
if (event.parentId === undefined && event.tags && (event.name === 'next-dev' || event.name === 'next-build')) {
|
||||
for (const [key, value] of Object.entries(event.tags)){
|
||||
if (key.startsWith('feature.')) {
|
||||
sessionEnabledFeatures[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Collect feature tags from all events for inheritance
|
||||
if (event.tags) {
|
||||
const enabledFeatures = {};
|
||||
for (const [key, value] of Object.entries(event.tags)){
|
||||
if (key.startsWith('feature.')) {
|
||||
enabledFeatures[key] = value;
|
||||
}
|
||||
}
|
||||
if (Object.keys(enabledFeatures).length > 0) {
|
||||
spanEnabledFeatures.set(event.id, enabledFeatures);
|
||||
}
|
||||
}
|
||||
if (// Always include root spans
|
||||
event.parentId === undefined || shouldUploadFullTrace || (mode === 'dev' ? DEV_ALLOWED_EVENTS.has(event.name) : BUILD_ALLOWED_EVENTS.has(event.name))) {
|
||||
sessionTrace.push(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Apply feature tag inheritance to session trace
|
||||
const sessionTraceWithInheritance = sessionTrace.map((event)=>{
|
||||
if (event.parentId !== undefined) {
|
||||
const parentFlags = spanEnabledFeatures.get(event.parentId);
|
||||
if (parentFlags && Object.keys(parentFlags).length > 0) {
|
||||
// Inherit parent flags, but child's own tags take precedence
|
||||
return {
|
||||
...event,
|
||||
tags: {
|
||||
...parentFlags,
|
||||
...event.tags
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return event;
|
||||
});
|
||||
const body = {
|
||||
metadata: {
|
||||
anonymousId,
|
||||
arch: _os.default.arch(),
|
||||
branch,
|
||||
commit,
|
||||
cpus: _os.default.cpus().length,
|
||||
isVercelEnvironment,
|
||||
isTurboSession,
|
||||
mode,
|
||||
nextVersion,
|
||||
pkgName,
|
||||
platform: _os.default.platform(),
|
||||
sessionId,
|
||||
enabledFeatures: sessionEnabledFeatures
|
||||
},
|
||||
// The trace file can contain events spanning multiple sessions.
|
||||
// Only submit traces for the current session, as the metadata we send is
|
||||
// intended for this session only.
|
||||
traces: [
|
||||
sessionTraceWithInheritance
|
||||
]
|
||||
};
|
||||
if (isDebugEnabled) {
|
||||
console.log('Sending request with body', JSON.stringify(body, null, 2));
|
||||
}
|
||||
let res = await fetch(traceUploadUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-trace-transfer-mode': shouldUploadFullTrace ? 'full' : 'default'
|
||||
},
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
if (isDebugEnabled) {
|
||||
console.log('Received response', res.status, await res.json());
|
||||
}
|
||||
})();
|
||||
|
||||
//# sourceMappingURL=trace-uploader.js.map
|
||||
Reference in New Issue
Block a user