Skip to content

Commit

Permalink
Fix RPC method invocations showing up as unknown events (#7811)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshthoward authored Jan 23, 2025
1 parent 3886065 commit 7d138d9
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 41 deletions.
5 changes: 5 additions & 0 deletions .changeset/fifty-pots-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler": patch
---

Fix RPC method invocations showing up as unknown events
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ import type {
QueueEvent,
RequestEvent,
ScheduledEvent,
TailEvent,
TailEventMessage,
TailInfo,
TailEventMessageType,
} from "../../tail/createTail";
import type { RequestInit } from "undici";
import type WebSocket from "ws";
Expand Down Expand Up @@ -807,18 +806,7 @@ function serialize(message: TailEventMessage): WebSocket.RawData {
* @param event A TailEvent
* @returns true if `event` is a RequestEvent
*/
function isRequest(
event:
| ScheduledEvent
| RequestEvent
| AlarmEvent
| EmailEvent
| TailEvent
| TailInfo
| QueueEvent
| undefined
| null
): event is RequestEvent {
function isRequest(event: TailEventMessageType): event is RequestEvent {
return Boolean(event && "request" in event);
}

Expand Down
51 changes: 39 additions & 12 deletions packages/wrangler/src/__tests__/tail.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import type {
EmailEvent,
QueueEvent,
RequestEvent,
RpcEvent,
ScheduledEvent,
TailEvent,
TailEventMessage,
TailEventMessageType,
TailInfo,
} from "../tail/createTail";
import type { RequestInit } from "undici";
Expand Down Expand Up @@ -91,6 +93,7 @@ describe("tail", () => {
await api.closeHelper();
expect(api.requests.deletion.count).toStrictEqual(1);
});

it("should connect to the worker assigned to a given route", async () => {
api = mockWebsocketAPIs();
expect(api.requests.creation.length).toStrictEqual(0);
Expand Down Expand Up @@ -532,6 +535,33 @@ describe("tail", () => {
await api.closeHelper();
});

it("logs rpc messages in pretty format", async () => {
api = mockWebsocketAPIs();
await runWrangler("tail test-worker --format pretty");

const event = generateMockRpcEvent();
const message = generateMockEventMessage({
entrypoint: "MyDurableObject",
event,
});
const serializedMessage = serialize(message);

api.ws.send(serializedMessage);
expect(
std.out
.replace(
new Date(mockEventTimestamp).toLocaleString(),
"[mock event timestamp]"
)
.replace(mockTailExpiration.toISOString(), "[mock expiration date]")
).toMatchInlineSnapshot(`
"Successfully created tail, expires at [mock expiration date]
Connected to test-worker, waiting for logs...
MyDurableObject.foo - Ok @ [mock event timestamp]"
`);
await api.closeHelper();
});

it("logs scheduled messages in pretty format", async () => {
api = mockWebsocketAPIs();
await runWrangler("tail test-worker --format pretty");
Expand Down Expand Up @@ -908,18 +938,7 @@ function serialize(message: TailEventMessage): WebSocket.RawData {
* @param event A TailEvent
* @returns true if `event` is a RequestEvent
*/
function isRequest(
event:
| ScheduledEvent
| RequestEvent
| AlarmEvent
| EmailEvent
| TailEvent
| TailInfo
| QueueEvent
| undefined
| null
): event is RequestEvent {
function isRequest(event: TailEventMessageType): event is RequestEvent {
return Boolean(event && "request" in event);
}

Expand Down Expand Up @@ -1133,13 +1152,15 @@ function mockWebsocketAPIs(
*/
function generateMockEventMessage({
outcome = "ok",
entrypoint = undefined,
exceptions = [],
logs = [],
eventTimestamp = mockEventTimestamp,
event = generateMockRequestEvent(),
}: Partial<TailEventMessage>): TailEventMessage {
return {
outcome,
entrypoint,
exceptions,
logs,
eventTimestamp,
Expand Down Expand Up @@ -1229,3 +1250,9 @@ function generateMockQueueEvent(opts?: Partial<QueueEvent>): QueueEvent {
batchSize: opts?.batchSize || 7,
};
}

function generateMockRpcEvent(opts?: Partial<RpcEvent>): RpcEvent {
return {
rpcMethod: opts?.rpcMethod || "foo",
};
}
47 changes: 32 additions & 15 deletions packages/wrangler/src/tail/createTail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,18 @@ export async function createTail(
return { tail, expiration, deleteTail };
}

export type TailEventMessageType =
| RequestEvent
| ScheduledEvent
| AlarmEvent
| EmailEvent
| TailEvent
| TailInfo
| QueueEvent
| RpcEvent
| undefined
| null;

/**
* Everything captured by the trace worker and sent to us via
* `wrangler tail` is structured JSON that deserializes to this type.
Expand All @@ -213,6 +225,11 @@ export type TailEventMessage = {
*/
scriptName?: string;

/**
* The name of the entrypoint invoked by the Worker
*/
entrypoint?: string;

/**
* Any exceptions raised by the worker
*/
Expand Down Expand Up @@ -250,29 +267,19 @@ export type TailEventMessage = {
/**
* The event that triggered the worker. In the case of an HTTP request,
* this will be a RequestEvent. If it's a cron trigger, it'll be a
* ScheduledEvent. If it's a durable object alarm, it's an AlarmEvent.
* ScheduledEvent. If it's a Durable Object alarm, it's an AlarmEvent.
* If it's a email, it'a an EmailEvent. If it's a Queue consumer event,
* it's a QueueEvent.
*
* Until workers-types exposes individual types for export, we'll have
* to just re-define these types ourselves.
*/
event:
| RequestEvent
| ScheduledEvent
| AlarmEvent
| EmailEvent
| TailEvent
| TailInfo
| QueueEvent
| undefined
| null;
event: TailEventMessageType;
};

/**
* A request that triggered worker execution
*/

export type RequestEvent = {
request: Pick<Request, "url" | "method" | "headers"> & {
/**
Expand Down Expand Up @@ -386,7 +393,7 @@ export type ScheduledEvent = {
};

/**
* A event that was triggered from a durable object alarm
* An event that was triggered from a Durable Object alarm
*/
export type AlarmEvent = {
/**
Expand Down Expand Up @@ -442,8 +449,8 @@ export type TailInfo = {
type: string;
};

/*
* A event that was triggered by receiving a batch of messages from a Queue for consumption.
/**
* An event that was triggered by receiving a batch of messages from a Queue for consumption.
*/
export type QueueEvent = {
/**
Expand All @@ -456,3 +463,13 @@ export type QueueEvent = {
*/
batchSize: number;
};

/**
* An RPC method that was invoked
*/
export type RpcEvent = {
/**
* The name of the RPC method that was invoked
*/
rpcMethod: string;
};
12 changes: 12 additions & 0 deletions packages/wrangler/src/tail/printing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
EmailEvent,
QueueEvent,
RequestEvent,
RpcEvent,
ScheduledEvent,
TailEvent,
TailEventMessage,
Expand Down Expand Up @@ -82,6 +83,13 @@ export function prettyPrintLogs(data: WebSocket.RawData): void {
logger.log(
`Queue ${queueName} (${batchSizeMsg}) - ${outcome} @ ${datetime}`
);
} else if (isRpcEvent(eventMessage.event)) {
const outcome = prettifyOutcome(eventMessage.outcome);
const datetime = new Date(eventMessage.eventTimestamp).toLocaleString();

logger.log(
`${eventMessage.entrypoint}.${eventMessage.event.rpcMethod} - ${outcome} @ ${datetime}`
);
} else {
// Unknown event type
const outcome = prettifyOutcome(eventMessage.outcome);
Expand Down Expand Up @@ -127,6 +135,10 @@ function isQueueEvent(event: TailEventMessage["event"]): event is QueueEvent {
return Boolean(event && "queue" in event);
}

function isRpcEvent(event: TailEventMessage["event"]): event is RpcEvent {
return Boolean(event && "rpcMethod" in event);
}

/**
* Check to see if an event sent from a worker is an AlarmEvent.
*
Expand Down

0 comments on commit 7d138d9

Please sign in to comment.