Skip to content

Commit 5cb806f

Browse files
authored
feat: support tracing configuration for Worker observability (#10491)
1 parent 4e49d3e commit 5cb806f

File tree

5 files changed

+171
-2
lines changed

5 files changed

+171
-2
lines changed

.changeset/seven-bars-end.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"wrangler": minor
3+
---
4+
5+
Add traces, OTEL destinations, and configurable persistence to observability settings
6+
7+
Adds a new `traces` field to the `observability` settings in your Worker configuration that configures the behavior of automatic tracing. Both `traces` and `logs` support providing a list of OpenTelemetry compliant `destinations` where your logs/traces will be exported to as well as an implicitly-enabled `persist` option that controls whether or not logs/traces are persisted to the Cloudflare observability platform and viewable in the Cloudflare dashboard.

packages/wrangler/src/__tests__/config/configuration.test.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,7 @@ describe("normalizeAndValidateConfig()", () => {
11831183
- Expected \\"upload_source_maps\\" to be of type boolean but got \\"INVALID\\".
11841184
- Expected \\"observability.enabled\\" to be of type boolean but got \\"INVALID\\".
11851185
- Expected \\"observability.logs.enabled\\" to be of type boolean but got undefined.
1186+
- Expected \\"observability.traces.enabled\\" to be of type boolean but got undefined.
11861187
- Expected \\"observability.head_sampling_rate\\" to be of type number but got \\"INVALID\\"."
11871188
`);
11881189
});
@@ -6299,7 +6300,7 @@ describe("normalizeAndValidateConfig()", () => {
62996300
expect(diagnostics.hasErrors()).toBe(true);
63006301
expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
63016302
"Processing wrangler configuration:
6302-
- \\"observability.enabled\\" or \\"observability.logs.enabled\\" is required.
6303+
- \\"observability.enabled\\" or \\"observability.logs.enabled\\" or \\"observability.traces.enabled\\" is required.
63036304
- Expected \\"observability.head_sampling_rate\\" to be of type number but got true."
63046305
`);
63056306
});
@@ -6353,6 +6354,29 @@ describe("normalizeAndValidateConfig()", () => {
63536354
expect(diagnostics.hasErrors()).toBe(false);
63546355
});
63556356

6357+
it("should not error on nested [observability.traces] config only", () => {
6358+
const { diagnostics } = normalizeAndValidateConfig(
6359+
{
6360+
observability: {
6361+
traces: {
6362+
enabled: true,
6363+
},
6364+
},
6365+
} as unknown as RawConfig,
6366+
undefined,
6367+
undefined,
6368+
{ env: undefined }
6369+
);
6370+
6371+
expect(diagnostics.hasWarnings()).toBe(false);
6372+
expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
6373+
"Processing wrangler configuration:
6374+
"
6375+
`);
6376+
6377+
expect(diagnostics.hasErrors()).toBe(false);
6378+
});
6379+
63566380
it("should not error on mixed observability config", () => {
63576381
const { diagnostics } = normalizeAndValidateConfig(
63586382
{
@@ -6361,6 +6385,9 @@ describe("normalizeAndValidateConfig()", () => {
63616385
logs: {
63626386
invocation_logs: false,
63636387
},
6388+
traces: {
6389+
destinations: [],
6390+
},
63646391
},
63656392
} as unknown as RawConfig,
63666393
undefined,

packages/wrangler/src/__tests__/deploy.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12984,6 +12984,8 @@ export default{
1298412984
logs: {
1298512985
enabled: true,
1298612986
head_sampling_rate: 0.3,
12987+
destinations: ["cloudflare", "foo"],
12988+
persist: false,
1298712989
invocation_logs: false,
1298812990
},
1298912991
},
@@ -12997,6 +12999,8 @@ export default{
1299712999
logs: {
1299813000
enabled: true,
1299913001
head_sampling_rate: 0.3,
13002+
destinations: ["cloudflare", "foo"],
13003+
persist: false,
1300013004
invocation_logs: false,
1300113005
},
1300213006
},
@@ -13013,6 +13017,45 @@ export default{
1301313017
`);
1301413018
});
1301513019

13020+
it("should allow uploading workers with nested observability logs setting", async () => {
13021+
writeWranglerConfig({
13022+
observability: {
13023+
enabled: true,
13024+
head_sampling_rate: 0.5,
13025+
traces: {
13026+
enabled: true,
13027+
head_sampling_rate: 0.3,
13028+
destinations: ["cloudflare", "foo"],
13029+
persist: false,
13030+
},
13031+
},
13032+
});
13033+
await fs.promises.writeFile("index.js", `export default {};`);
13034+
mockSubDomainRequest();
13035+
mockUploadWorkerRequest({
13036+
expectedObservability: {
13037+
enabled: true,
13038+
head_sampling_rate: 0.5,
13039+
traces: {
13040+
enabled: true,
13041+
head_sampling_rate: 0.3,
13042+
destinations: ["cloudflare", "foo"],
13043+
persist: false,
13044+
},
13045+
},
13046+
});
13047+
13048+
await runWrangler("deploy index.js");
13049+
expect(std.out).toMatchInlineSnapshot(`
13050+
"Total Upload: xx KiB / gzip: xx KiB
13051+
Worker Startup Time: 100 ms
13052+
Uploaded test-name (TIMINGS)
13053+
Deployed test-name triggers (TIMINGS)
13054+
https://test-name.test-sub-domain.workers.dev
13055+
Current Version ID: Galaxy-Class"
13056+
`);
13057+
});
13058+
1301613059
it("should disable observability if not explicitly defined", async () => {
1301713060
writeWranglerConfig({});
1301813061
await fs.promises.writeFile("index.js", `export default {};`);

packages/wrangler/src/config/environment.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,35 @@ export interface Observability {
12051205
head_sampling_rate?: number;
12061206
/** Set to false to disable invocation logs */
12071207
invocation_logs?: boolean;
1208+
/**
1209+
* If logs should be persisted to the Cloudflare observability platform where they can be queried in the dashboard.
1210+
*
1211+
* @default true
1212+
*/
1213+
persist?: boolean;
1214+
/**
1215+
* What destinations logs emitted from the Worker should be sent to.
1216+
*
1217+
* @default []
1218+
*/
1219+
destinations?: string[];
1220+
};
1221+
traces?: {
1222+
enabled?: boolean;
1223+
/** The sampling rate */
1224+
head_sampling_rate?: number;
1225+
/**
1226+
* If traces should be persisted to the Cloudflare observability platform where they can be queried in the dashboard.
1227+
*
1228+
* @default true
1229+
*/
1230+
persist?: boolean;
1231+
/**
1232+
* What destinations traces emitted from the Worker should be sent to.
1233+
*
1234+
* @default []
1235+
*/
1236+
destinations?: string[];
12081237
};
12091238
}
12101239

packages/wrangler/src/config/validation.ts

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3988,7 +3988,7 @@ const validateObservability: ValidatorFn = (diagnostics, field, value) => {
39883988
let isValid = true;
39893989

39903990
/**
3991-
* One of observability.enabled or observability.logs.enabled must be defined
3991+
* One of observability.enabled, observability.logs.enabled, observability.traces.enabled must be defined
39923992
*/
39933993
isValid =
39943994
validateAtLeastOnePropertyRequired(diagnostics, field, [
@@ -4002,6 +4002,11 @@ const validateObservability: ValidatorFn = (diagnostics, field, value) => {
40024002
value: val.logs?.enabled,
40034003
type: "boolean",
40044004
},
4005+
{
4006+
key: "traces.enabled",
4007+
value: val.traces?.enabled,
4008+
type: "boolean",
4009+
},
40054010
]) && isValid;
40064011

40074012
isValid =
@@ -4017,11 +4022,21 @@ const validateObservability: ValidatorFn = (diagnostics, field, value) => {
40174022
validateOptionalProperty(diagnostics, field, "logs", val.logs, "object") &&
40184023
isValid;
40194024

4025+
isValid =
4026+
validateOptionalProperty(
4027+
diagnostics,
4028+
field,
4029+
"traces",
4030+
val.traces,
4031+
"object"
4032+
) && isValid;
4033+
40204034
isValid =
40214035
validateAdditionalProperties(diagnostics, field, Object.keys(val), [
40224036
"enabled",
40234037
"head_sampling_rate",
40244038
"logs",
4039+
"traces",
40254040
]) && isValid;
40264041

40274042
/**
@@ -4055,14 +4070,62 @@ const validateObservability: ValidatorFn = (diagnostics, field, value) => {
40554070
"boolean"
40564071
) && isValid;
40574072

4073+
isValid =
4074+
validateOptionalTypedArray(
4075+
diagnostics,
4076+
"logs.destinations",
4077+
val.logs?.destinations,
4078+
"string"
4079+
) && isValid;
4080+
40584081
isValid =
40594082
validateAdditionalProperties(diagnostics, field, Object.keys(val.logs), [
40604083
"enabled",
40614084
"head_sampling_rate",
40624085
"invocation_logs",
4086+
"destinations",
40634087
]) && isValid;
40644088
}
40654089

4090+
/**
4091+
* Validate the optional nested traces configuration
4092+
*/
4093+
if (typeof val.traces === "object") {
4094+
isValid =
4095+
validateOptionalProperty(
4096+
diagnostics,
4097+
field,
4098+
"traces.enabled",
4099+
val.traces.enabled,
4100+
"boolean"
4101+
) && isValid;
4102+
4103+
isValid =
4104+
validateOptionalProperty(
4105+
diagnostics,
4106+
field,
4107+
"traces.head_sampling_rate",
4108+
val.traces.head_sampling_rate,
4109+
"number"
4110+
) && isValid;
4111+
4112+
isValid =
4113+
validateOptionalTypedArray(
4114+
diagnostics,
4115+
"traces.destinations",
4116+
val.traces?.destinations,
4117+
"string"
4118+
) && isValid;
4119+
4120+
isValid =
4121+
validateAdditionalProperties(
4122+
diagnostics,
4123+
field,
4124+
Object.keys(val.traces),
4125+
["enabled", "head_sampling_rate", "destinations"]
4126+
) && isValid;
4127+
}
4128+
40664129
const samplingRate = val?.head_sampling_rate;
40674130

40684131
if (samplingRate && (samplingRate < 0 || samplingRate > 1)) {

0 commit comments

Comments
 (0)