@ogcio/o11y-sdk-node
Version:
Opentelemetry standard instrumentation SDK for NodeJS based project
216 lines (186 loc) • 4.93 kB
text/typescript
import { Context } from "@opentelemetry/api";
import {
SamplingDecision,
SamplingResult,
} from "@opentelemetry/sdk-trace-base";
import { describe, expect, test, vi } from "vitest";
import { UrlSampler } from "../lib/url-sampler";
describe("url sampler", () => {
// mock sampler to be sure every trace after UrlSamper has RECORD status
const mockSampler = {
shouldSample: vi
.fn()
.mockImplementation(
(_context, _traceId, _spanName, _spanKind, attributes, _links) => {
return {
decision: SamplingDecision.RECORD,
attributes: attributes,
} as SamplingResult;
},
),
};
test("should add custom span attributes to trace", async () => {
const sampler: UrlSampler = new UrlSampler(
[
{
type: "endsWith",
url: "/health",
},
],
mockSampler,
{
"signal.namespace": "unittest",
"signal.callback.result": () => "test",
},
);
expect(sampler).not.toBeNull();
const result = sampler.shouldSample(
{} as Context,
"traceId",
"span",
0,
{ "http.target": "/track" },
[],
);
expect(sampler.toString()).toBe("UrlSampler");
expect(result.decision).toBe(SamplingDecision.RECORD);
expect(result.attributes).not.toBeNull();
});
test("should not record trace about /health api", async () => {
const sampler: UrlSampler = new UrlSampler(
[
{
type: "endsWith",
url: "/health",
},
],
mockSampler,
);
const result = sampler.shouldSample(
{} as Context,
"traceId",
"span",
0,
{ "http.target": "/health" },
[],
);
expect(sampler.toString()).toBe("UrlSampler");
expect(result.decision).toBe(SamplingDecision.NOT_RECORD);
});
test("should record every other trace which is not /health api", async () => {
const sampler: UrlSampler = new UrlSampler(
[
{
type: "endsWith",
url: "/health",
},
],
mockSampler,
);
let result = sampler.shouldSample(
{} as Context,
"traceId",
"span",
0,
{ "http.target": "/test" },
[],
);
expect(result.decision).toBe(SamplingDecision.RECORD);
result = sampler.shouldSample(
{} as Context,
"traceId",
"span",
0,
{ "http.target": "/another/url" },
[],
);
expect(result.decision).toBe(SamplingDecision.RECORD);
});
test("operator 'includes', should not record every trace which include /block in url", async () => {
const sampler: UrlSampler = new UrlSampler(
[
{
type: "includes",
url: "/block",
},
],
mockSampler,
);
expect(sampler).not.toBeNull();
const result = sampler.shouldSample(
{} as Context,
"traceId",
"span",
0,
{ "http.target": "/namespace/block/example/12" },
[],
);
expect(sampler.toString()).toBe("UrlSampler");
expect(result.decision).toBe(SamplingDecision.NOT_RECORD);
});
test("operator 'endsWith', should not record only trace which ends with /block in url", async () => {
const sampler: UrlSampler = new UrlSampler(
[
{
type: "endsWith",
url: "/block",
},
],
mockSampler,
);
expect(sampler).not.toBeNull();
// expect traced with block in the URL middle
let result = sampler.shouldSample(
{} as Context,
"traceId",
"span",
0,
{ "http.target": "/namespace/block/example/12" },
[],
);
expect(sampler.toString()).toBe("UrlSampler");
expect(result.decision).toBe(SamplingDecision.RECORD);
// should stop trace with block at the end
result = sampler.shouldSample(
{} as Context,
"traceId",
"span",
0,
{ "http.target": "/namespace/example/block" },
[],
);
expect(sampler.toString()).toBe("UrlSampler");
expect(result.decision).toBe(SamplingDecision.NOT_RECORD);
});
test("operator 'equals', should not record trace which is equal to /block in url", async () => {
const sampler: UrlSampler = new UrlSampler(
[
{
type: "equals",
url: "/block",
},
],
mockSampler,
);
expect(sampler).not.toBeNull();
let result = sampler.shouldSample(
{} as Context,
"traceId",
"span",
0,
{ "http.target": "/namespace/block/example/12" },
[],
);
expect(sampler.toString()).toBe("UrlSampler");
expect(result.decision).toBe(SamplingDecision.RECORD);
result = sampler.shouldSample(
{} as Context,
"traceId",
"span",
0,
{ "http.target": "/block" },
[],
);
expect(result.decision).toBe(SamplingDecision.NOT_RECORD);
});
});