@netlify/build 29.13.0 → 29.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/core/build.js +4 -2
- package/lib/core/flags.js +34 -0
- package/lib/core/main.js +88 -61
- package/lib/core/normalize_flags.js +3 -0
- package/lib/core/types.js +1 -1
- package/lib/error/report.js +2 -0
- package/lib/steps/error.js +2 -0
- package/lib/steps/run_step.js +106 -86
- package/lib/tracing/main.js +52 -0
- package/package.json +5 -2
package/lib/core/build.js
CHANGED
|
@@ -12,6 +12,7 @@ import { reportStatuses } from '../status/report.js';
|
|
|
12
12
|
import { getDevSteps, getSteps } from '../steps/get.js';
|
|
13
13
|
import { runSteps } from '../steps/run_steps.js';
|
|
14
14
|
import { initTimers, measureDuration } from '../time/main.js';
|
|
15
|
+
import { startTracing } from '../tracing/main.js';
|
|
15
16
|
import { getConfigOpts, loadConfig } from './config.js';
|
|
16
17
|
import { getConstants } from './constants.js';
|
|
17
18
|
import { doDryRun } from './dry.js';
|
|
@@ -27,8 +28,9 @@ export const startBuild = function (flags) {
|
|
|
27
28
|
if (!flags.quiet) {
|
|
28
29
|
logBuildStart(logs);
|
|
29
30
|
}
|
|
30
|
-
const { bugsnagKey, ...flagsA } = normalizeFlags(flags, logs);
|
|
31
|
-
const errorMonitor = startErrorMonitor({ flags: flagsA, logs, bugsnagKey });
|
|
31
|
+
const { bugsnagKey, tracing, ...flagsA } = normalizeFlags(flags, logs);
|
|
32
|
+
const errorMonitor = startErrorMonitor({ flags: { tracing, ...flagsA }, logs, bugsnagKey });
|
|
33
|
+
startTracing(tracing);
|
|
32
34
|
return { ...flagsA, errorMonitor, logs, timers };
|
|
33
35
|
};
|
|
34
36
|
const tExecBuild = async function ({ config, defaultConfig, cachedConfig, cachedConfigPath, outputConfigPath, cwd, repositoryRoot, apiHost, token, siteId, context, branch, baseRelDir, env: envOpt, debug, systemLogFile, verbose, nodePath, functionsDistDir, edgeFunctionsDistDir, cacheDir, dry, mode, offline, deployId, buildId, testOpts, errorMonitor, errorParams, logs, timers, buildbotServerSocket, sendStatus, saveConfig, featureFlags, timeline, devCommand, quiet, framework, explicitSecretKeys, }) {
|
package/lib/core/flags.js
CHANGED
|
@@ -189,6 +189,40 @@ Default: false`,
|
|
|
189
189
|
describe: 'Statsd port',
|
|
190
190
|
hidden: true,
|
|
191
191
|
},
|
|
192
|
+
tracing: {
|
|
193
|
+
describe: 'Tracing related options',
|
|
194
|
+
hidden: true,
|
|
195
|
+
},
|
|
196
|
+
'tracing.enabled': {
|
|
197
|
+
boolean: true,
|
|
198
|
+
describe: 'Enable distributed tracing for build',
|
|
199
|
+
hidden: true,
|
|
200
|
+
},
|
|
201
|
+
'tracing.host': {
|
|
202
|
+
string: true,
|
|
203
|
+
describe: 'Traces backend host',
|
|
204
|
+
hidden: true,
|
|
205
|
+
},
|
|
206
|
+
'tracing.port': {
|
|
207
|
+
number: true,
|
|
208
|
+
describe: 'Traces backend port',
|
|
209
|
+
hidden: true,
|
|
210
|
+
},
|
|
211
|
+
'tracing.traceId': {
|
|
212
|
+
string: true,
|
|
213
|
+
describe: 'Trace ID used to stitch the emited traces to',
|
|
214
|
+
hidden: true,
|
|
215
|
+
},
|
|
216
|
+
'tracing.parentSpanId': {
|
|
217
|
+
string: true,
|
|
218
|
+
describe: 'Parent Span ID used to stitch the root parent span to',
|
|
219
|
+
hidden: true,
|
|
220
|
+
},
|
|
221
|
+
'tracing.traceFlags': {
|
|
222
|
+
number: true,
|
|
223
|
+
describe: 'Trace flags containing the trace settings for the given trace ID',
|
|
224
|
+
hidden: true,
|
|
225
|
+
},
|
|
192
226
|
offline: {
|
|
193
227
|
boolean: true,
|
|
194
228
|
describe: `Do not send requests to the Netlify API to retrieve site settings.
|
package/lib/core/main.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
import { trace } from '@opentelemetry/api';
|
|
1
2
|
import { handleBuildError } from '../error/handle.js';
|
|
2
3
|
import { reportError } from '../error/report.js';
|
|
3
4
|
import { getSystemLogger } from '../log/logger.js';
|
|
4
5
|
import { logTimer, logBuildSuccess } from '../log/messages/core.js';
|
|
5
6
|
import { trackBuildComplete } from '../telemetry/main.js';
|
|
6
7
|
import { reportTimers } from '../time/report.js';
|
|
8
|
+
import { stopTracing, setMultiSpanAttributes } from '../tracing/main.js';
|
|
7
9
|
import { execBuild, startBuild } from './build.js';
|
|
8
10
|
import { reportMetrics } from './report_metrics.js';
|
|
9
11
|
import { getSeverity } from './severity.js';
|
|
10
12
|
export { startDev } from './dev.js';
|
|
11
13
|
export { runCoreSteps } from '../steps/run_core_steps.js';
|
|
14
|
+
const tracer = trace.getTracer('core');
|
|
12
15
|
/**
|
|
13
16
|
* Main entry point of Netlify Build.
|
|
14
17
|
* Runs a builds and returns whether it succeeded or not.
|
|
@@ -19,67 +22,91 @@ export default async function buildSite(flags = {}) {
|
|
|
19
22
|
const { errorMonitor, framework, mode, logs, debug, systemLogFile, testOpts, statsdOpts, dry, telemetry, buildId, deployId, ...flagsA } = startBuild(flags);
|
|
20
23
|
const errorParams = { errorMonitor, mode, logs, debug, testOpts };
|
|
21
24
|
const systemLog = getSystemLogger(logs, debug, systemLogFile);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
errorParams
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
25
|
+
const attributes = {
|
|
26
|
+
'deploy.id': deployId,
|
|
27
|
+
'build.id': buildId,
|
|
28
|
+
'deploy.context': flagsA.context,
|
|
29
|
+
'site.id': flagsA.siteId,
|
|
30
|
+
};
|
|
31
|
+
const rootCtx = setMultiSpanAttributes(attributes);
|
|
32
|
+
return await tracer.startActiveSpan('exec-build', {}, rootCtx, async (span) => {
|
|
33
|
+
try {
|
|
34
|
+
const { pluginsOptions, netlifyConfig: netlifyConfigA, siteInfo, userNodeVersion, stepsCount, timers, durationNs, configMutations, metrics, } = await execBuild({
|
|
35
|
+
...flagsA,
|
|
36
|
+
buildId,
|
|
37
|
+
systemLogFile,
|
|
38
|
+
deployId,
|
|
39
|
+
dry,
|
|
40
|
+
errorMonitor,
|
|
41
|
+
mode,
|
|
42
|
+
logs,
|
|
43
|
+
debug,
|
|
44
|
+
testOpts,
|
|
45
|
+
errorParams,
|
|
46
|
+
framework,
|
|
47
|
+
});
|
|
48
|
+
await handleBuildSuccess({
|
|
49
|
+
framework,
|
|
50
|
+
dry,
|
|
51
|
+
logs,
|
|
52
|
+
timers,
|
|
53
|
+
durationNs,
|
|
54
|
+
statsdOpts,
|
|
55
|
+
systemLog,
|
|
56
|
+
metrics,
|
|
57
|
+
});
|
|
58
|
+
const { success, severityCode, status } = getSeverity('success');
|
|
59
|
+
span.setAttributes({
|
|
60
|
+
'build.execution.success': success,
|
|
61
|
+
'build.execution.code': severityCode,
|
|
62
|
+
'build.execution.status': status,
|
|
63
|
+
});
|
|
64
|
+
await telemetryReport({
|
|
65
|
+
buildId,
|
|
66
|
+
deployId,
|
|
67
|
+
status,
|
|
68
|
+
stepsCount,
|
|
69
|
+
pluginsOptions,
|
|
70
|
+
durationNs,
|
|
71
|
+
siteInfo,
|
|
72
|
+
telemetry,
|
|
73
|
+
userNodeVersion,
|
|
74
|
+
framework,
|
|
75
|
+
testOpts,
|
|
76
|
+
errorParams,
|
|
77
|
+
});
|
|
78
|
+
return { success, severityCode, netlifyConfig: netlifyConfigA, logs, configMutations };
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
const { severity } = await handleBuildError(error, errorParams);
|
|
82
|
+
const { pluginsOptions, siteInfo, userNodeVersion } = errorParams;
|
|
83
|
+
const { success, severityCode, status } = getSeverity(severity);
|
|
84
|
+
span.setAttributes({
|
|
85
|
+
'build.execution.success': success,
|
|
86
|
+
'build.execution.code': severityCode,
|
|
87
|
+
'build.execution.status': status,
|
|
88
|
+
});
|
|
89
|
+
await telemetryReport({
|
|
90
|
+
buildId,
|
|
91
|
+
deployId,
|
|
92
|
+
status,
|
|
93
|
+
pluginsOptions,
|
|
94
|
+
siteInfo,
|
|
95
|
+
telemetry,
|
|
96
|
+
userNodeVersion,
|
|
97
|
+
framework,
|
|
98
|
+
testOpts,
|
|
99
|
+
errorParams,
|
|
100
|
+
});
|
|
101
|
+
await reportError(error, statsdOpts, framework);
|
|
102
|
+
return { success, severityCode, logs };
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
span.end();
|
|
106
|
+
// Ensure we flush the resulting spans
|
|
107
|
+
await stopTracing();
|
|
108
|
+
}
|
|
109
|
+
});
|
|
83
110
|
}
|
|
84
111
|
// Logs and reports that a build successfully ended
|
|
85
112
|
const handleBuildSuccess = async function ({ framework, dry, logs, timers, durationNs, statsdOpts, systemLog, metrics, }) {
|
|
@@ -7,6 +7,7 @@ const DEFAULT_EDGE_FUNCTIONS_DIST = '.netlify/edge-functions-dist/';
|
|
|
7
7
|
const DEFAULT_FUNCTIONS_DIST = '.netlify/functions/';
|
|
8
8
|
const DEFAULT_CACHE_DIR = '.netlify/cache/';
|
|
9
9
|
const DEFAULT_STATSD_PORT = 8125;
|
|
10
|
+
const DEFAULT_OTEL_TRACING_PORT = 4317;
|
|
10
11
|
/** Normalize CLI flags */
|
|
11
12
|
export const normalizeFlags = function (flags, logs) {
|
|
12
13
|
const rawFlags = removeFalsy(flags);
|
|
@@ -20,6 +21,7 @@ export const normalizeFlags = function (flags, logs) {
|
|
|
20
21
|
...rawFlags,
|
|
21
22
|
...telemetryFlag,
|
|
22
23
|
statsdOpts: { ...defaultFlags.statsd, ...rawFlags.statsd },
|
|
24
|
+
tracingOpts: { ...defaultFlags.tracing, ...rawFlags.tracing },
|
|
23
25
|
featureFlags: { ...defaultFlags.featureFlags, ...rawFlags.featureFlags },
|
|
24
26
|
};
|
|
25
27
|
const normalizedFlags = removeFalsy(mergedFlags);
|
|
@@ -51,6 +53,7 @@ const getDefaultFlags = function ({ env: envOpt = {} }, combinedEnv) {
|
|
|
51
53
|
testOpts: {},
|
|
52
54
|
featureFlags: DEFAULT_FEATURE_FLAGS,
|
|
53
55
|
statsd: { port: DEFAULT_STATSD_PORT },
|
|
56
|
+
tracing: { enabled: false, port: DEFAULT_OTEL_TRACING_PORT },
|
|
54
57
|
timeline: 'build',
|
|
55
58
|
quiet: false,
|
|
56
59
|
};
|
package/lib/core/types.js
CHANGED
|
@@ -5,4 +5,4 @@ export var SeverityCode;
|
|
|
5
5
|
SeverityCode[SeverityCode["userError"] = 3] = "userError";
|
|
6
6
|
SeverityCode[SeverityCode["pluginError"] = 4] = "pluginError";
|
|
7
7
|
SeverityCode[SeverityCode["systemError"] = 5] = "systemError";
|
|
8
|
-
})(SeverityCode
|
|
8
|
+
})(SeverityCode || (SeverityCode = {}));
|
package/lib/error/report.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isNetlifyMaintainedPlugin } from '../plugins/internal.js';
|
|
2
2
|
import { closeClient, formatTags, normalizeTagName, startClient, validateStatsDOptions, } from '../report/statsd.js';
|
|
3
|
+
import { addErrorToActiveSpan } from '../tracing/main.js';
|
|
3
4
|
import { getErrorInfo } from './info.js';
|
|
4
5
|
const TOP_PARENT_TAG = 'run_netlify_build';
|
|
5
6
|
/**
|
|
@@ -7,6 +8,7 @@ const TOP_PARENT_TAG = 'run_netlify_build';
|
|
|
7
8
|
* Sends to statsd daemon.
|
|
8
9
|
*/
|
|
9
10
|
export const reportError = async function (error, statsdOpts, framework) {
|
|
11
|
+
addErrorToActiveSpan(error);
|
|
10
12
|
if (!validateStatsDOptions(statsdOpts)) {
|
|
11
13
|
return;
|
|
12
14
|
}
|
package/lib/steps/error.js
CHANGED
|
@@ -3,6 +3,7 @@ import { handleBuildError } from '../error/handle.js';
|
|
|
3
3
|
import { getFullErrorInfo, parseErrorInfo } from '../error/parse/parse.js';
|
|
4
4
|
import { serializeErrorStatus } from '../error/parse/serialize_status.js';
|
|
5
5
|
import { isSoftFailEvent } from '../plugins/events.js';
|
|
6
|
+
import { addErrorToActiveSpan } from '../tracing/main.js';
|
|
6
7
|
// Handle build command errors and plugin errors:
|
|
7
8
|
// - usually, propagate the error to make the build stop.
|
|
8
9
|
// - `utils.build.cancelBuild()` also cancels the build by calling the API
|
|
@@ -11,6 +12,7 @@ import { isSoftFailEvent } from '../plugins/events.js';
|
|
|
11
12
|
// plugin.
|
|
12
13
|
// This also computes error statuses that are sent to the API.
|
|
13
14
|
export const handleStepError = function ({ event, newError, childEnv, mode, api, errorMonitor, deployId, coreStep, netlifyConfig, logs, debug, testOpts, }) {
|
|
15
|
+
addErrorToActiveSpan(newError);
|
|
14
16
|
// Core steps do not report error statuses
|
|
15
17
|
if (coreStep !== undefined) {
|
|
16
18
|
return { newError };
|
package/lib/steps/run_step.js
CHANGED
|
@@ -1,100 +1,120 @@
|
|
|
1
|
+
import { trace } from '@opentelemetry/api';
|
|
1
2
|
import { addMutableConstants } from '../core/constants.js';
|
|
2
3
|
import { logStepStart } from '../log/messages/steps.js';
|
|
3
4
|
import { runsAlsoOnBuildFailure, runsOnlyOnBuildFailure } from '../plugins/events.js';
|
|
4
5
|
import { normalizeTagName } from '../report/statsd.js';
|
|
5
6
|
import { measureDuration } from '../time/main.js';
|
|
7
|
+
import { setMultiSpanAttributes } from '../tracing/main.js';
|
|
6
8
|
import { fireCoreStep } from './core_step.js';
|
|
7
9
|
import { firePluginStep } from './plugin.js';
|
|
8
10
|
import { getStepReturn } from './return.js';
|
|
11
|
+
const tracer = trace.getTracer('steps');
|
|
9
12
|
// Run a step (core, build command or plugin)
|
|
10
13
|
export const runStep = async function ({ event, childProcess, packageName, coreStep, coreStepId, coreStepName, coreStepDescription, pluginPackageJson, loadedFrom, origin, condition, configPath, outputConfigPath, buildDir, repositoryRoot, nodePath, index, childEnv, context, branch, envChanges, constants, steps, buildbotServerSocket, events, mode, api, errorMonitor, deployId, errorParams, error, failedPlugins, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, logs, debug, systemLog, verbose, saveConfig, timers, testOpts, featureFlags, quiet, userNodeVersion, explicitSecretKeys, }) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
14
|
+
// Add relevant attributes to the upcoming span context
|
|
15
|
+
const attributes = {
|
|
16
|
+
'build.execution.step.name': coreStepName,
|
|
17
|
+
'build.execution.step.description': coreStepDescription,
|
|
18
|
+
'build.execution.step.package_name': packageName,
|
|
19
|
+
'build.execution.step.id': coreStepId,
|
|
20
|
+
'build.execution.step.loaded_from': loadedFrom,
|
|
21
|
+
'build.execution.step.origin': origin,
|
|
22
|
+
'build.execution.step.event': event,
|
|
23
|
+
};
|
|
24
|
+
const spanCtx = setMultiSpanAttributes(attributes);
|
|
25
|
+
return tracer.startActiveSpan(`run-step-${coreStepId}`, {}, spanCtx, async (span) => {
|
|
26
|
+
const constantsA = await addMutableConstants({ constants, buildDir, netlifyConfig });
|
|
27
|
+
const shouldRun = await shouldRunStep({
|
|
28
|
+
event,
|
|
29
|
+
packageName,
|
|
30
|
+
error,
|
|
31
|
+
failedPlugins,
|
|
32
|
+
netlifyConfig,
|
|
33
|
+
condition,
|
|
34
|
+
constants: constantsA,
|
|
35
|
+
buildbotServerSocket,
|
|
36
|
+
buildDir,
|
|
37
|
+
saveConfig,
|
|
38
|
+
explicitSecretKeys,
|
|
39
|
+
});
|
|
40
|
+
span.setAttribute('build.execution.step.should_run', shouldRun);
|
|
41
|
+
if (!shouldRun) {
|
|
42
|
+
span.end();
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
if (!quiet) {
|
|
46
|
+
logStepStart({ logs, event, packageName, coreStepDescription, error, netlifyConfig });
|
|
47
|
+
}
|
|
48
|
+
const fireStep = getFireStep(packageName, coreStepId, event);
|
|
49
|
+
const { newEnvChanges, netlifyConfig: netlifyConfigA = netlifyConfig, configMutations: configMutationsA = configMutations, headersPath: headersPathA = headersPath, redirectsPath: redirectsPathA = redirectsPath, newError, newStatus, timers: timersA, durationNs, metrics, } = await fireStep({
|
|
50
|
+
event,
|
|
51
|
+
childProcess,
|
|
52
|
+
packageName,
|
|
53
|
+
pluginPackageJson,
|
|
54
|
+
loadedFrom,
|
|
55
|
+
origin,
|
|
56
|
+
coreStep,
|
|
57
|
+
coreStepId,
|
|
58
|
+
coreStepName,
|
|
59
|
+
configPath,
|
|
60
|
+
outputConfigPath,
|
|
61
|
+
buildDir,
|
|
62
|
+
repositoryRoot,
|
|
63
|
+
nodePath,
|
|
64
|
+
childEnv,
|
|
65
|
+
context,
|
|
66
|
+
branch,
|
|
67
|
+
envChanges,
|
|
68
|
+
constants: constantsA,
|
|
69
|
+
steps,
|
|
70
|
+
buildbotServerSocket,
|
|
71
|
+
events,
|
|
72
|
+
error,
|
|
73
|
+
logs,
|
|
74
|
+
debug,
|
|
75
|
+
systemLog,
|
|
76
|
+
verbose,
|
|
77
|
+
saveConfig,
|
|
78
|
+
timers,
|
|
79
|
+
errorParams,
|
|
80
|
+
configOpts,
|
|
81
|
+
netlifyConfig,
|
|
82
|
+
configMutations,
|
|
83
|
+
headersPath,
|
|
84
|
+
redirectsPath,
|
|
85
|
+
featureFlags,
|
|
86
|
+
userNodeVersion,
|
|
87
|
+
explicitSecretKeys,
|
|
88
|
+
});
|
|
89
|
+
const newValues = await getStepReturn({
|
|
90
|
+
event,
|
|
91
|
+
packageName,
|
|
92
|
+
newError,
|
|
93
|
+
newEnvChanges,
|
|
94
|
+
newStatus,
|
|
95
|
+
coreStep,
|
|
96
|
+
coreStepName,
|
|
97
|
+
childEnv,
|
|
98
|
+
mode,
|
|
99
|
+
api,
|
|
100
|
+
errorMonitor,
|
|
101
|
+
deployId,
|
|
102
|
+
netlifyConfig: netlifyConfigA,
|
|
103
|
+
configMutations: configMutationsA,
|
|
104
|
+
headersPath: headersPathA,
|
|
105
|
+
redirectsPath: redirectsPathA,
|
|
106
|
+
logs,
|
|
107
|
+
debug,
|
|
108
|
+
timers: timersA,
|
|
109
|
+
durationNs,
|
|
110
|
+
testOpts,
|
|
111
|
+
systemLog,
|
|
112
|
+
quiet,
|
|
113
|
+
metrics,
|
|
114
|
+
});
|
|
115
|
+
span.end();
|
|
116
|
+
return { ...newValues, newIndex: index + 1 };
|
|
96
117
|
});
|
|
97
|
-
return { ...newValues, newIndex: index + 1 };
|
|
98
118
|
};
|
|
99
119
|
// A plugin fails _without making the build fail_ when either:
|
|
100
120
|
// - using `utils.build.failPlugin()`
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { HoneycombSDK } from '@honeycombio/opentelemetry-node';
|
|
2
|
+
import { context, trace, propagation, SpanStatusCode } from '@opentelemetry/api';
|
|
3
|
+
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
|
|
4
|
+
import { ROOT_PACKAGE_JSON } from '../utils/json.js';
|
|
5
|
+
let sdk;
|
|
6
|
+
/** Starts the tracing SDK, if there's already a tracing service this will be a no-op */
|
|
7
|
+
export const startTracing = function (options) {
|
|
8
|
+
if (!options.enabled)
|
|
9
|
+
return;
|
|
10
|
+
if (sdk)
|
|
11
|
+
return;
|
|
12
|
+
sdk = new HoneycombSDK({
|
|
13
|
+
serviceName: ROOT_PACKAGE_JSON.name,
|
|
14
|
+
endpoint: `http://${options.host}:${options.port}`,
|
|
15
|
+
instrumentations: [new HttpInstrumentation()],
|
|
16
|
+
});
|
|
17
|
+
sdk.start();
|
|
18
|
+
// Sets the current trace ID and span ID based on the options received
|
|
19
|
+
// this is used as a way to propagate trace context from Buildbot
|
|
20
|
+
trace.setSpanContext(context.active(), {
|
|
21
|
+
traceId: options.traceId,
|
|
22
|
+
spanId: options.parentSpanId,
|
|
23
|
+
traceFlags: options.traceFlags,
|
|
24
|
+
isRemote: true,
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
/** Stops the tracing service if there's one running. This will flush any ongoing events */
|
|
28
|
+
export const stopTracing = async function () {
|
|
29
|
+
if (!sdk)
|
|
30
|
+
return;
|
|
31
|
+
return sdk.shutdown();
|
|
32
|
+
};
|
|
33
|
+
/** Sets attributes to be propagated across child spans under the current context */
|
|
34
|
+
export const setMultiSpanAttributes = function (attributes) {
|
|
35
|
+
const currentBaggage = propagation.getBaggage(context.active());
|
|
36
|
+
let baggage = currentBaggage === undefined ? propagation.createBaggage() : currentBaggage;
|
|
37
|
+
Object.entries(attributes).forEach((entry) => {
|
|
38
|
+
baggage = baggage.setEntry(entry[0], { value: entry[1] });
|
|
39
|
+
});
|
|
40
|
+
return propagation.setBaggage(context.active(), baggage);
|
|
41
|
+
};
|
|
42
|
+
/** Add error information to the current active span (if any) */
|
|
43
|
+
export const addErrorToActiveSpan = function (error) {
|
|
44
|
+
const span = trace.getActiveSpan();
|
|
45
|
+
if (!span)
|
|
46
|
+
return;
|
|
47
|
+
span.recordException(error);
|
|
48
|
+
span.setStatus({
|
|
49
|
+
code: SpanStatusCode.ERROR,
|
|
50
|
+
message: error.message,
|
|
51
|
+
});
|
|
52
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/build",
|
|
3
|
-
"version": "29.
|
|
3
|
+
"version": "29.14.0",
|
|
4
4
|
"description": "Netlify build module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": "./lib/core/main.js",
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
"license": "MIT",
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"@bugsnag/js": "^7.0.0",
|
|
67
|
+
"@honeycombio/opentelemetry-node": "^0.4.0",
|
|
67
68
|
"@netlify/cache-utils": "^5.1.5",
|
|
68
69
|
"@netlify/config": "^20.5.1",
|
|
69
70
|
"@netlify/edge-bundler": "8.16.2",
|
|
@@ -73,6 +74,8 @@
|
|
|
73
74
|
"@netlify/plugins-list": "^6.68.0",
|
|
74
75
|
"@netlify/run-utils": "^5.1.1",
|
|
75
76
|
"@netlify/zip-it-and-ship-it": "9.10.0",
|
|
77
|
+
"@opentelemetry/api": "^1.4.1",
|
|
78
|
+
"@opentelemetry/instrumentation-http": "^0.40.0",
|
|
76
79
|
"@sindresorhus/slugify": "^2.0.0",
|
|
77
80
|
"ansi-escapes": "^6.0.0",
|
|
78
81
|
"chalk": "^5.0.0",
|
|
@@ -146,5 +149,5 @@
|
|
|
146
149
|
"module": "commonjs"
|
|
147
150
|
}
|
|
148
151
|
},
|
|
149
|
-
"gitHead": "
|
|
152
|
+
"gitHead": "3ec21c7c8e5c221d96b32e739331dc44b18fe05c"
|
|
150
153
|
}
|