Skip to content

Commit 04dd410

Browse files
sshaderConvex, Inc.
authored andcommitted
Make the CLI handle structured log lines (#24129)
Unstructured log lines (`string`) can still be sent. The visible change here is being able to see timestamps for each log line as opposed to just using the start timestamp of the function. GitOrigin-RevId: 1e2853cfdfd6645e810877598dc2031cb5a20a0d
1 parent 83924d0 commit 04dd410

File tree

1 file changed

+40
-17
lines changed
  • npm-packages/convex/src/cli/lib

1 file changed

+40
-17
lines changed

npm-packages/convex/src/cli/lib/logs.ts

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,18 @@ function createAuthHeader(adminKey: string): string {
8181

8282
type UdfType = "Query" | "Mutation" | "Action" | "HttpAction";
8383

84+
type StructuredLogLine = {
85+
messages: string[];
86+
level: "LOG" | "DEBUG" | "INFO" | "WARN" | "ERROR";
87+
timestamp: number;
88+
isTruncated: boolean;
89+
};
90+
type LogLine = string | StructuredLogLine;
91+
8492
type UdfExecutionResponse = {
8593
identifier: string;
8694
udfType: UdfType;
87-
logLines: string[];
95+
logLines: LogLine[];
8896
// Unix timestamp (in seconds)
8997
timestamp: number;
9098
// UDF execution duration (in seconds)
@@ -187,34 +195,49 @@ function logToTerminal(
187195
timestamp: number,
188196
udfType: UdfType,
189197
udfPath: string,
190-
message: string,
198+
message: LogLine,
191199
dest: LogDestination,
192200
) {
193201
const prefix = prefixForSource(udfType);
194-
if (type === "info") {
195-
const match = message.match(/^\[.*?\] /);
196-
if (match === null) {
202+
if (typeof message === "string") {
203+
if (type === "info") {
204+
const match = message.match(/^\[.*?\] /);
205+
if (match === null) {
206+
logToDestination(
207+
ctx,
208+
dest,
209+
chalk.red(
210+
`[CONVEX ${prefix}(${udfPath})] Could not parse console.log`,
211+
),
212+
);
213+
return;
214+
}
215+
const level = message.slice(1, match[0].length - 2);
216+
const args = message.slice(match[0].length);
217+
197218
logToDestination(
198219
ctx,
199220
dest,
200-
chalk.red(`[CONVEX ${prefix}(${udfPath})] Could not parse console.log`),
221+
chalk.cyan(`${prefixLog(timestamp, udfType, udfPath)} [${level}]`),
222+
args,
223+
);
224+
} else {
225+
logToDestination(
226+
ctx,
227+
dest,
228+
chalk.red(`${prefixLog(timestamp, udfType, udfPath)} ${message}`),
201229
);
202-
return;
203230
}
204-
const level = message.slice(1, match[0].length - 2);
205-
const args = message.slice(match[0].length);
206-
207-
logToDestination(
208-
ctx,
209-
dest,
210-
chalk.cyan(`${prefixLog(timestamp, udfType, udfPath)} [${level}]`),
211-
args,
212-
);
213231
} else {
232+
const level = message.level;
233+
const formattedMessage = `${message.messages.join(" ")}${message.isTruncated ? " (truncated due to length)" : ""}`;
214234
logToDestination(
215235
ctx,
216236
dest,
217-
chalk.red(`$${prefixLog(timestamp, udfType, udfPath)} ${message}`),
237+
chalk.cyan(
238+
`${prefixLog(message.timestamp, udfType, udfPath)} [${level}]`,
239+
),
240+
formattedMessage,
218241
);
219242
}
220243
}

0 commit comments

Comments
 (0)