Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .changeset/observability-nested-sampling-rate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@cloudflare/workers-utils": patch
---

Validate `observability.logs.head_sampling_rate` and `observability.traces.head_sampling_rate` are between 0 and 1

The 0–1 range check was only applied to the top level `observability.head_sampling_rate`. The two nested fields were type-checked as numbers but never bounds-checked, so a value such as `10` (a common mix-up with a percentage) was accepted locally and sent to the API.

```jsonc
{
"observability": {
"logs": { "enabled": true, "head_sampling_rate": 10 },
},
}
```

All three fields now report `must be a value between 0 and 1.` consistently.
34 changes: 29 additions & 5 deletions packages/workers-utils/src/config/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6516,16 +6516,40 @@ const validateObservability: ValidatorFn = (diagnostics, field, value) => {
) && isValid;
}

const samplingRate = val?.head_sampling_rate;
validateHeadSamplingRate(
diagnostics,
field,
"head_sampling_rate",
val?.head_sampling_rate
);
validateHeadSamplingRate(
diagnostics,
field,
"logs.head_sampling_rate",
val?.logs?.head_sampling_rate
);
validateHeadSamplingRate(
diagnostics,
field,
"traces.head_sampling_rate",
val?.traces?.head_sampling_rate
);

return isValid;
};

function validateHeadSamplingRate(
diagnostics: Diagnostics,
container: string,
key: string,
samplingRate: number | undefined
) {
if (samplingRate && (samplingRate < 0 || samplingRate > 1)) {
diagnostics.errors.push(
`"${field}.head_sampling_rate" must be a value between 0 and 1.`
`"${container}.${key}" must be a value between 0 and 1.`
);
}

return isValid;
};
}

const validateCache: ValidatorFn = (diagnostics, field, value) => {
if (value === undefined) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10283,6 +10283,73 @@ describe("normalizeAndValidateConfig()", () => {
`);
});

it("should error on a nested logs sampling rate out of range", ({
expect,
}) => {
const { diagnostics } = normalizeAndValidateConfig(
{
observability: {
logs: {
enabled: true,
head_sampling_rate: 10,
},
},
} satisfies RawConfig,
undefined,
undefined,
{ env: undefined }
);

expect(diagnostics.hasWarnings()).toBe(false);
expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
"Processing wrangler configuration:
- "observability.logs.head_sampling_rate" must be a value between 0 and 1."
`);
});

it("should error on a nested traces sampling rate out of range", ({
expect,
}) => {
const { diagnostics } = normalizeAndValidateConfig(
{
observability: {
traces: {
enabled: true,
head_sampling_rate: -1,
},
},
} satisfies RawConfig,
undefined,
undefined,
{ env: undefined }
);

expect(diagnostics.hasWarnings()).toBe(false);
expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
"Processing wrangler configuration:
- "observability.traces.head_sampling_rate" must be a value between 0 and 1."
`);
});

it("should not error on nested sampling rates within range", ({
expect,
}) => {
const { diagnostics } = normalizeAndValidateConfig(
{
observability: {
logs: { enabled: true, head_sampling_rate: 0.5 },
traces: { enabled: true, head_sampling_rate: 1 },
},
} satisfies RawConfig,
undefined,
undefined,
{ env: undefined }
);

expect(diagnostics.hasWarnings()).toBe(false);
expect(diagnostics.hasErrors()).toBe(false);
});

it("should error on invalid additional fields", ({ expect }) => {
const { diagnostics } = normalizeAndValidateConfig(
{
Expand Down
Loading