Skip to content

Commit

Permalink
Add jaeger bindings to asset-worker
Browse files Browse the repository at this point in the history
  • Loading branch information
WillTaylorDev committed Jan 14, 2025
1 parent 4fe93de commit 1c563e3
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/tough-walls-poke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cloudflare/workers-shared": minor
---

Adds jaeger tracing for asset-worker.
13 changes: 12 additions & 1 deletion packages/workers-shared/asset-worker/src/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import {
import { getHeaders } from "./utils/headers";
import type { AssetConfig } from "../../utils/types";
import type EntrypointType from "./index";
import type { Env } from "./index";

export const handleRequest = async (
request: Request,
env: Env,
configuration: Required<AssetConfig>,
exists: typeof EntrypointType.prototype.unstable_exists,
getByETag: typeof EntrypointType.prototype.unstable_getByETag
Expand Down Expand Up @@ -52,7 +54,16 @@ export const handleRequest = async (
return new InternalServerErrorResponse(new Error("Unknown action"));
}

const asset = await getByETag(intent.asset.eTag);
const asset = await env.JAEGER.enterSpan("getByETag", async (span) => {
span.setTags({
pathname,
eTag: intent.asset.eTag,
status: intent.asset.status,
});

return await getByETag(intent.asset.eTag);
});

const headers = getHeaders(intent.asset.eTag, asset.contentType, request);

const strongETag = `"${intent.asset.eTag}"`;
Expand Down
35 changes: 25 additions & 10 deletions packages/workers-shared/asset-worker/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ import { applyConfigurationDefaults } from "./configuration";
import { decodePath, getIntent, handleRequest } from "./handler";
import { InternalServerErrorResponse } from "./responses";
import { getAssetWithMetadataFromKV } from "./utils/kv";
import type { AssetConfig, UnsafePerformanceTimer } from "../../utils/types";
import type {
AssetConfig,
JaegerTracing,
UnsafePerformanceTimer,
} from "../../utils/types";
import type { ColoMetadata, Environment, ReadyAnalytics } from "./types";

type Env = {
export type Env = {
/*
* ASSETS_MANIFEST is a pipeline binding to an ArrayBuffer containing the
* binary-encoded site manifest
Expand All @@ -26,10 +30,11 @@ type Env = {
CONFIG: AssetConfig;

SENTRY_DSN: string;

SENTRY_ACCESS_CLIENT_ID: string;
SENTRY_ACCESS_CLIENT_SECRET: string;

JAEGER: JaegerTracing;

ENVIRONMENT: Environment;
ANALYTICS: ReadyAnalytics;
COLO_METADATA: ColoMetadata;
Expand Down Expand Up @@ -74,8 +79,8 @@ export default class extends WorkerEntrypoint<Env> {
sentry.setUser({ userAgent: userAgent, colo: colo });
}

const url = new URL(request.url);
if (this.env.COLO_METADATA && this.env.VERSION_METADATA) {
const url = new URL(request.url);
analytics.setData({
coloId: this.env.COLO_METADATA.coloId,
metalId: this.env.COLO_METADATA.metalId,
Expand All @@ -89,12 +94,22 @@ export default class extends WorkerEntrypoint<Env> {
});
}

return handleRequest(
request,
config,
this.unstable_exists.bind(this),
this.unstable_getByETag.bind(this)
);
return await this.env.JAEGER.enterSpan("handleRequest", (span) => {
span.setTags({
hostname: url.hostname,
eyeballPath: url.pathname,
env: this.env.ENVIRONMENT,
coloId: this.env.COLO_METADATA.coloId,
});

return handleRequest(
request,
this.env,
config,
this.unstable_exists.bind(this),
this.unstable_getByETag.bind(this)
);
});
} catch (err) {
const response = new InternalServerErrorResponse(err as Error);

Expand Down
57 changes: 56 additions & 1 deletion packages/workers-shared/asset-worker/tests/handler.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,37 @@
import { vi } from "vitest";
import { handleRequest } from "../src/handler";
import type { AssetConfig } from "../../utils/types";
import type { AssetConfig, JaegerTracing, Span } from "../../utils/types";

function mockJaegerBindingSpan(): Span {
return {
addLogs: () => {},
setTags: () => {},
end: () => {},
isRecording: true,
};
}

function mockJaegerBinding(): JaegerTracing {
return {
enterSpan: (_, span, ...args) => {
return span(mockJaegerBindingSpan(), ...args);
},
getSpanContext: () => ({
traceId: "test-trace",
spanId: "test-span",
parentSpanId: "test-parent-span",
traceFlags: 0,
}),
runWithSpanContext: (_, callback, ...args) => {
return callback(...args);
},

traceId: "test-trace",
spanId: "test-span",
parentSpanId: "test-parent-span",
cfTraceIdHeader: "test-trace:test-span:0",
};
}

describe("[Asset Worker] `handleRequest`", () => {
it("attaches ETag headers to responses", async () => {
Expand All @@ -16,8 +47,14 @@ describe("[Asset Worker] `handleRequest`", () => {
contentType: "text/html",
});

const mockEnv = {
JAEGER: mockJaegerBinding(),
};

const response = await handleRequest(
new Request("https://example.com/"),
// @ts-expect-error Only jaeger
mockEnv,
configuration,
exists,
getByETag
Expand All @@ -39,10 +76,16 @@ describe("[Asset Worker] `handleRequest`", () => {
contentType: "text/html",
});

const mockEnv = {
JAEGER: mockJaegerBinding(),
};

const response = await handleRequest(
new Request("https://example.com/", {
headers: { "If-None-Match": `"${eTag}"` },
}),
// @ts-expect-error Only jaeger
mockEnv,
configuration,
exists,
getByETag
Expand All @@ -64,10 +107,16 @@ describe("[Asset Worker] `handleRequest`", () => {
contentType: "text/html",
});

const mockEnv = {
JAEGER: mockJaegerBinding(),
};

const response = await handleRequest(
new Request("https://example.com/", {
headers: { "If-None-Match": `W/"${eTag}"` },
}),
// @ts-expect-error Only jaeger
mockEnv,
configuration,
exists,
getByETag
Expand All @@ -89,10 +138,16 @@ describe("[Asset Worker] `handleRequest`", () => {
contentType: "text/html",
});

const mockEnv = {
JAEGER: mockJaegerBinding(),
};

const response = await handleRequest(
new Request("https://example.com/", {
headers: { "If-None-Match": "a fake etag!" },
}),
// @ts-expect-error Only jaeger
mockEnv,
configuration,
exists,
getByETag
Expand Down
37 changes: 37 additions & 0 deletions packages/workers-shared/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,40 @@ export interface UnsafePerformanceTimer {
readonly timeOrigin: number;
now: () => number;
}

export interface JaegerTracing {
enterSpan<T extends unknown[], R = void>(
name: string,
span: (s: Span, ...args: T) => R,
...args: T
): R;
getSpanContext(): SpanContext | null;
runWithSpanContext<T extends unknown[]>(
spanContext: SpanContext | null,
callback: (...args: T) => unknown,
...args: T
): unknown;

readonly traceId: string | null;
readonly spanId: string | null;
readonly parentSpanId: string | null;
readonly cfTraceIdHeader: string | null;
}

export interface Span {
addLogs(logs: JaegerRecord): void;
setTags(tags: JaegerRecord): void;
end(): void;

isRecording: boolean;
}

export interface SpanContext {
traceId: string;
spanId: string;
parentSpanId: string;
traceFlags: number;
}

export type JaegerValue = string | number | boolean;
export type JaegerRecord = Record<string, JaegerValue>;

0 comments on commit 1c563e3

Please sign in to comment.