Skip to content

Commit 5684962

Browse files
atrakhConvex, Inc.
authored andcommitted
Add more data to the UDF log stream (#38877)
I want to the logs page to have more data, let's add the following: - Usage stats (to help customers debug usage in real time without axiom/datadog integrations set up) - `execution_timestamp` - if the result is not cached, this may be useful in the future for rendering a request tree instead of a sequential list of logs - `occ_info` - for showing insights in real time - execution environment - useful to show for actions - identity type (e.g. user, system, instance_admin, team_acting_user -- useful for showing who ran the function) In the future, I'd also like to add a `caller_execution_id` so we can render the logs in a tree view GitOrigin-RevId: 41cab817e6b7548e8e0247b0efc46495bdcc73b2
1 parent 25bb34f commit 5684962

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

crates/local_backend/src/logs.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ pub enum FunctionExecutionJson {
5656
error: Option<String>,
5757
request_id: String,
5858
execution_id: String,
59+
usage_stats: JsonValue,
60+
occ_info: Option<JsonValue>,
61+
execution_timestamp: f64,
62+
identity_type: String,
63+
environment: String,
5964
},
6065
#[serde(rename_all = "camelCase")]
6166
Progress {
@@ -230,10 +235,44 @@ pub async fn stream_function_logs(
230235
}
231236
}
232237

238+
fn usage_stats_to_json(
239+
stats: &usage_tracking::AggregatedFunctionUsageStats,
240+
action_memory_used_mb: Option<u64>,
241+
) -> JsonValue {
242+
serde_json::json!({
243+
"databaseReadBytes": stats.database_read_bytes,
244+
"databaseWriteBytes": stats.database_write_bytes,
245+
"databaseReadDocuments": stats.database_read_documents,
246+
"storageReadBytes": stats.storage_read_bytes,
247+
"storageWriteBytes": stats.storage_write_bytes,
248+
"vectorIndexReadBytes": stats.vector_index_read_bytes,
249+
"vectorIndexWriteBytes": stats.vector_index_write_bytes,
250+
"actionMemoryUsedMb": action_memory_used_mb,
251+
})
252+
}
253+
233254
fn execution_to_json(
234255
execution: FunctionExecution,
235256
supports_structured_log_lines: bool,
236257
) -> anyhow::Result<FunctionExecutionJson> {
258+
let usage_stats_json =
259+
usage_stats_to_json(&execution.usage_stats, execution.action_memory_used_mb);
260+
let occ_info_json = execution
261+
.occ_info
262+
.as_ref()
263+
.map(|occ| {
264+
let log_occ_info = common::log_streaming::OccInfo {
265+
table_name: occ.table_name.clone(),
266+
document_id: occ.document_id.clone(),
267+
write_source: occ.write_source.clone(),
268+
retry_count: occ.retry_count,
269+
};
270+
serde_json::to_value(log_occ_info)
271+
})
272+
.transpose()?;
273+
let identity_type = execution.identity.tag().value.to_string();
274+
let environment = execution.environment.to_string();
275+
let execution_timestamp = execution.execution_timestamp.as_secs_f64();
237276
let json = match execution.params {
238277
UdfParams::Function { error, identifier } => {
239278
let component_path = identifier.component.serialize();
@@ -252,6 +291,11 @@ fn execution_to_json(
252291
error: error.map(|e| e.to_string()),
253292
request_id: execution.context.request_id.to_string(),
254293
execution_id: execution.context.execution_id.to_string(),
294+
usage_stats: usage_stats_json,
295+
occ_info: occ_info_json,
296+
execution_timestamp,
297+
identity_type,
298+
environment,
255299
}
256300
},
257301
UdfParams::Http { result, identifier } => {
@@ -274,6 +318,11 @@ fn execution_to_json(
274318
error: error.map(|e| e.to_string()),
275319
request_id: execution.context.request_id.to_string(),
276320
execution_id: execution.context.execution_id.to_string(),
321+
usage_stats: usage_stats_json,
322+
occ_info: occ_info_json,
323+
execution_timestamp,
324+
identity_type,
325+
environment,
277326
}
278327
},
279328
};

0 commit comments

Comments
 (0)