Skip to content

Commit 16e2363

Browse files
feat: Enable server-side instrumentation via tracing.server.ts
This commit consolidates all changes to support server-side instrumentation: - Add support for tracing.server.ts configuration file - Implement adapter support for Netlify, Cloudflare, Vercel, and Node - Add better export generation and catalog functionality - Include necessary type definitions and configuration options - Fix various bugs and conflicts during development
1 parent b526831 commit 16e2363

File tree

9 files changed

+287
-42
lines changed

9 files changed

+287
-42
lines changed

packages/adapter-cloudflare/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ export default function (options = {}) {
113113
ASSETS: assets_binding
114114
}
115115
});
116+
builder.trace({
117+
entrypoint: worker_dest,
118+
tracing: `${builder.getServerDirectory()}/tracing.server.js`,
119+
tla: false
120+
});
116121

117122
// _headers
118123
if (existsSync('_headers')) {
@@ -184,7 +189,8 @@ export default function (options = {}) {
184189
}
185190

186191
return true;
187-
}
192+
},
193+
tracing: () => true
188194
}
189195
};
190196
}

packages/adapter-netlify/index.js

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** @import { BuildOptions } from 'esbuild' */
12
import { appendFileSync, existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
23
import { dirname, join, resolve, posix } from 'node:path';
34
import { fileURLToPath } from 'node:url';
@@ -106,7 +107,8 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) {
106107
}
107108

108109
return true;
109-
}
110+
},
111+
tracing: () => true
110112
}
111113
};
112114
}
@@ -174,9 +176,8 @@ async function generate_edge_functions({ builder }) {
174176
version: 1
175177
};
176178

177-
await esbuild.build({
178-
entryPoints: [`${tmp}/entry.js`],
179-
outfile: '.netlify/edge-functions/render.js',
179+
/** @type {BuildOptions} */
180+
const esbuild_config = {
180181
bundle: true,
181182
format: 'esm',
182183
platform: 'browser',
@@ -194,6 +195,21 @@ async function generate_edge_functions({ builder }) {
194195
// https://docs.netlify.com/edge-functions/api/#runtime-environment
195196
external: builtinModules.map((id) => `node:${id}`),
196197
alias: Object.fromEntries(builtinModules.map((id) => [id, `node:${id}`]))
198+
};
199+
await esbuild.build({
200+
entryPoints: [`${tmp}/entry.js`],
201+
outfile: '.netlify/edge-functions/render.js',
202+
...esbuild_config
203+
});
204+
await esbuild.build({
205+
entryPoints: [`${builder.getServerDirectory()}/tracing.server.js`],
206+
outfile: '.netlify/edge-functions/tracing.server.js',
207+
...esbuild_config
208+
});
209+
builder.trace({
210+
entrypoint: '.netlify/edge-functions/render.js',
211+
tracing: '.netlify/edge-functions/tracing.server.js',
212+
tla: false
197213
});
198214

199215
writeFileSync('.netlify/edge-functions/manifest.json', JSON.stringify(edge_manifest));
@@ -272,6 +288,12 @@ function generate_lambda_functions({ builder, publish, split }) {
272288

273289
writeFileSync(`.netlify/functions-internal/${name}.mjs`, fn);
274290
writeFileSync(`.netlify/functions-internal/${name}.json`, fn_config);
291+
builder.trace({
292+
entrypoint: `.netlify/functions-internal/${name}.mjs`,
293+
tracing: '.netlify/server/tracing.server.js',
294+
start: `${name}.start.mjs`,
295+
exports: ['handler']
296+
});
275297

276298
const redirect = `/.netlify/functions/${name} 200`;
277299
redirects.push(`${pattern} ${redirect}`);
@@ -286,6 +308,12 @@ function generate_lambda_functions({ builder, publish, split }) {
286308

287309
writeFileSync(`.netlify/functions-internal/${FUNCTION_PREFIX}render.json`, fn_config);
288310
writeFileSync(`.netlify/functions-internal/${FUNCTION_PREFIX}render.mjs`, fn);
311+
builder.trace({
312+
entrypoint: `.netlify/functions-internal/${FUNCTION_PREFIX}render.mjs`,
313+
tracing: '.netlify/server/tracing.server.js',
314+
exports: ['handler']
315+
});
316+
289317
redirects.push(`* /.netlify/functions/${FUNCTION_PREFIX}render 200`);
290318
}
291319

packages/adapter-node/index.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,18 @@ export default function (opts = {}) {
4848

4949
const pkg = JSON.parse(readFileSync('package.json', 'utf8'));
5050

51+
/** @type {Record<string, string>} */
52+
const input = {
53+
index: `${tmp}/index.js`,
54+
manifest: `${tmp}/manifest.js`,
55+
'tracing.server': `${tmp}/tracing.server.js`
56+
};
57+
5158
// we bundle the Vite output so that deployments only need
5259
// their production dependencies. Anything in devDependencies
5360
// will get included in the bundled code
5461
const bundle = await rollup({
55-
input: {
56-
index: `${tmp}/index.js`,
57-
manifest: `${tmp}/manifest.js`
58-
},
62+
input,
5963
external: [
6064
// dependencies could have deep exports, so we need a regex
6165
...Object.keys(pkg.dependencies || {}).map((d) => new RegExp(`^${d}(\\/.*)?$`))
@@ -89,10 +93,17 @@ export default function (opts = {}) {
8993
ENV_PREFIX: JSON.stringify(envPrefix)
9094
}
9195
});
96+
97+
builder.trace({
98+
entrypoint: `${out}/index.js`,
99+
tracing: `${out}/server/tracing.server.js`,
100+
exports: ['path', 'host', 'port', 'server']
101+
});
92102
},
93103

94104
supports: {
95-
read: () => true
105+
read: () => true,
106+
tracing: () => true
96107
}
97108
};
98109
}

packages/adapter-node/rollup.config.js

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,8 @@ export default [
4242
file: 'files/index.js',
4343
format: 'esm'
4444
},
45-
plugins: [
46-
clearOutput('files/index.js'),
47-
nodeResolve({ preferBuiltins: true }),
48-
commonjs(),
49-
json(),
50-
prefixBuiltinModules()
51-
],
52-
external: ['ENV', 'HANDLER']
45+
plugins: [nodeResolve({ preferBuiltins: true }), commonjs(), json(), prefixBuiltinModules()],
46+
external: ['./start.js']
5347
},
5448
{
5549
input: 'src/env.js',

packages/adapter-vercel/index.js

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** @import { BuildOptions } from 'esbuild' */
12
import fs from 'node:fs';
23
import path from 'node:path';
34
import process from 'node:process';
@@ -93,13 +94,16 @@ const plugin = function (defaults = {}) {
9394
const dir = `${dirs.functions}/${name}.func`;
9495

9596
const relativePath = path.posix.relative(tmp, builder.getServerDirectory());
96-
9797
builder.copy(`${files}/serverless.js`, `${tmp}/index.js`, {
9898
replace: {
9999
SERVER: `${relativePath}/index.js`,
100100
MANIFEST: './manifest.js'
101101
}
102102
});
103+
builder.trace({
104+
entrypoint: `${tmp}/index.js`,
105+
tracing: `${builder.getServerDirectory()}/tracing.server.js`
106+
});
103107

104108
write(
105109
`${tmp}/manifest.js`,
@@ -136,9 +140,9 @@ const plugin = function (defaults = {}) {
136140
);
137141

138142
try {
139-
const result = await esbuild.build({
140-
entryPoints: [`${tmp}/edge.js`],
141-
outfile: `${dirs.functions}/${name}.func/index.js`,
143+
const outdir = `${dirs.functions}/${name}.func`;
144+
/** @type {BuildOptions} */
145+
const esbuild_config = {
142146
// minimum Node.js version supported is v14.6.0 that is mapped to ES2019
143147
// https://edge-runtime.vercel.app/features/polyfills
144148
// TODO verify the latest ES version the edge runtime supports
@@ -168,13 +172,32 @@ const plugin = function (defaults = {}) {
168172
'.eot': 'copy',
169173
'.otf': 'copy'
170174
}
175+
};
176+
const result = await esbuild.build({
177+
entryPoints: [`${tmp}/edge.js`],
178+
outfile: `${outdir}/index.js`,
179+
...esbuild_config
180+
});
181+
const instrumentation_result = await esbuild.build({
182+
entryPoints: [`${builder.getServerDirectory()}/tracing.server.js`],
183+
outfile: `${outdir}/tracing.server.js`,
184+
...esbuild_config
171185
});
172186

173-
if (result.warnings.length > 0) {
174-
const formatted = await esbuild.formatMessages(result.warnings, {
175-
kind: 'warning',
176-
color: true
177-
});
187+
builder.trace({
188+
entrypoint: `${outdir}/index.js`,
189+
tracing: `${outdir}/tracing.server.js`,
190+
tla: false
191+
});
192+
193+
if (result.warnings.length > 0 || instrumentation_result.warnings.length > 0) {
194+
const formatted = await esbuild.formatMessages(
195+
[...result.warnings, ...instrumentation_result.warnings],
196+
{
197+
kind: 'warning',
198+
color: true
199+
}
200+
);
178201

179202
console.error(formatted.join('\n'));
180203
}
@@ -477,7 +500,8 @@ const plugin = function (defaults = {}) {
477500
}
478501

479502
return true;
480-
}
503+
},
504+
tracing: () => true
481505
}
482506
};
483507
};

0 commit comments

Comments
 (0)