pd.log()
Log the result of an LLM call back to VersionR. This is how results appear in the dashboard — latency trends, token usage, and output history all come from pd.log().
Logging is fire-and-forget — it never throws or delays your application.
Signature
pd.log(entry: LogEntry): Promise<void>Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
entry.promptId | string | Yes | The promptId from pd.get() or pd.render() |
entry.promptSlug | string | Yes | The promptSlug from the prompt response |
entry.versionId | string | Yes | The versionId from the prompt response |
entry.versionNumber | number | Yes | The versionNumber from the prompt response |
entry.environment | string | Yes | The environment used (e.g. 'production') |
entry.renderedPrompt | string | Yes | The final prompt text sent to the LLM |
entry.output | string | Yes | The LLM’s response text |
entry.latencyMs | number | Yes | Time from request sent to response received (ms) |
entry.tokens.prompt | number | No | Prompt tokens used |
entry.tokens.completion | number | No | Completion tokens used |
entry.score | number | No | Optional quality score (0–1) for evals |
entry.metadata | Record<string, string> | No | Arbitrary key/value pairs attached to this log entry |
Example
const startTime = Date.now()
const rendered = await pd.render('interviewer-system', {
env: 'production',
variables: {
candidate_name: 'Eoin',
job_role: 'Senior Engineer',
difficulty: 'hard',
},
})
const response = await openai.chat.completions.create({
model: rendered.model,
temperature: rendered.temperature,
messages: [
{ role: rendered.role, content: rendered.content },
{ role: 'user', content: userMessage },
],
})
await pd.log({
promptId: rendered.promptId,
promptSlug: rendered.promptSlug,
versionId: rendered.versionId,
versionNumber: rendered.versionNumber,
environment: 'production',
renderedPrompt: rendered.rendered,
output: response.choices[0]?.message.content ?? '',
latencyMs: Date.now() - startTime,
tokens: {
prompt: response.usage?.prompt_tokens ?? 0,
completion: response.usage?.completion_tokens ?? 0,
},
})With metadata
Attach arbitrary metadata to a log entry for filtering in the dashboard:
await pd.log({
promptId: rendered.promptId,
promptSlug: rendered.promptSlug,
versionId: rendered.versionId,
versionNumber: rendered.versionNumber,
environment: 'production',
renderedPrompt: rendered.rendered,
output: responseText,
latencyMs: elapsed,
metadata: {
userId: 'user_abc123',
sessionId: 'sess_xyz',
region: 'eu-west-1',
},
})Notes
pd.log()resolves immediately — the network request runs in the background. Your app does not wait for it.- If the log request fails (network error, service outage), the failure is silently swallowed. It will not throw or affect your application.
- Cost estimation (visible in the dashboard) is computed server-side from token counts + model name. Provide
tokens.promptandtokens.completionfor accurate cost tracking.
Log entries are stored in ClickHouse and queryable from the dashboard. High-volume applications can safely call pd.log() on every request.