Log Types
This page documents all log types, the LogEntry structure, and how custom types work.
Log Level
Controls the severity of a log entry.
| Value | Description |
|---|---|
debug | Low-level diagnostic information |
info | Normal operational events (default) |
error | Error conditions that require attention |
Categories and Types
Log types are organized into named categories. Categories are resolved automatically from the type field during ingestion.
AiLogType
Types in the ai category for AI/LLM tracing:
| Type | Description |
|---|---|
llm | LLM API call -- input, output, model, token usage |
interaction | User interaction event |
step | A discrete step in a workflow or agent loop |
action | An action taken by an agent or system |
response | A response produced -- to the user or to another system |
summary | A summary or rollup of a session or process |
HttpLogType
Types in the http category:
| Type | Description |
|---|---|
request | An inbound HTTP request |
response | An outbound HTTP response |
SystemLogType
Types in the system category:
| Type | Description |
|---|---|
error | An error event with structured context |
debug | Debug-specific output |
info | Informational event |
warn | Warning -- non-fatal but noteworthy |
log | Generic log entry (default type) |
BuiltInLogType
The union of all built-in types:
type BuiltInLogType = AiLogType | HttpLogType | SystemLogTypeCustom Types
Any type string not matching a built-in type is assigned the custom category. The type field accepts any non-empty string.
LogPayload
The request body sent when ingesting a log entry:
interface LogPayload {
message: string // Required, min 1 character
level?: 'debug' | 'info' | 'error' // Defaults to 'info'
type?: string // Defaults to 'log', any non-empty string
sessionId?: string // Groups related logs in a session
data?: Record<string, unknown> // Arbitrary structured metadata
timestamp?: number // Unix milliseconds, defaults to Date.now()
}Example:
{
"message": "Model inference completed",
"level": "info",
"type": "llm",
"sessionId": "sess_abc123",
"data": {
"model": "claude-3",
"tokens": 512,
"latencyMs": 890
},
"timestamp": 1709812800000
}LogEntry
The internal representation used by the client SDK:
interface LogEntry {
projectId: string
sessionId: string
message: string
level: 'debug' | 'info' | 'error'
type: string
data?: Record<string, unknown>
timestamp: number
}LogRecord
The shape stored in D1 and returned by query endpoints:
interface LogRecord {
id: number
project_id: string
session_id: string | null
type: string
category: string | null // Resolved: 'ai' | 'http' | 'system' | 'custom'
level: string
message: string
timestamp: number // Unix milliseconds
data: string | null // JSON-serialized string of the original data object
}Category Resolution
Categories are resolved server-side using the resolveCategory() function from src/types/categories.ts:
const LOG_CATEGORIES = {
ai: ['llm', 'interaction', 'step', 'action', 'response', 'summary'],
http: ['request', 'response'],
system: ['error', 'debug', 'info', 'warn', 'log'],
} as const
function resolveCategory(type: string): LogCategory | 'custom' {
return categoryByType.get(type) ?? 'custom'
}The function checks the type against a pre-built map of all built-in types. If no match is found, it returns 'custom'.
Ambiguous types
The response type appears in both ai and http categories. It maps to ai (first match). Use the category filter in queries if you need to distinguish between them.
See Also
- Log Categories Guide -- Usage guide with SDK examples
- API Reference: Ingest -- Ingestion endpoint
- API Reference: Query -- Query endpoint