Event Logging
Data model
Persisted event shape and metadata envelope for Event Logging
V1 writes one row per accepted request to NestEventLog.
Schema reference
- Spanner migration:
db/liquibase/changelogs/spanner/nest/118_create_nest_event_log_table.sql - Repository implementation:
services/events/core/repository.py
Column mapping
| Column | Source | Notes |
|---|---|---|
event_id | service-generated | Current implementation uses a UUID string. |
event_name | request.event_name | Trimmed during normalization. |
event_type | request.event_type | Trimmed during normalization. Stored as NULL when omitted. |
actor_id | request.actor_id | Trimmed during normalization. Stored as NULL when omitted. |
event_ts | request.event_ts or service time | Always normalized to UTC. |
value | not populated in v1 | Stored as NULL. |
metadata | normalized caller metadata plus _eventLog | Stored as Spanner JSON. |
ingested_at | Spanner commit timestamp | Generated by the table schema, not by the service. |
_eventLog metadata envelope
Caller metadata is preserved, but the service always reserves _eventLog for
its own bookkeeping. That envelope currently contains:
forwardToStatsig- optional
idempotencyKey - optional
callerobject with the platform caller identity:actorId,principalEmail, andprincipalId
Example persisted metadata:
{
"provider": "password",
"details": {
"plan": "pro",
"seats": 3
},
"_eventLog": {
"forwardToStatsig": true,
"idempotencyKey": "dedupe-1",
"caller": {
"actorId": "checkout@nestveterinary.com",
"principalEmail": "checkout@nestveterinary.com",
"principalId": "principal-123"
}
}
}Metadata constraints
- Top-level keys are capped at
256by protobuf validation. - Canonical serialized JSON is capped at
64 KiBduring normalization. - Nested objects and arrays are allowed.
_eventLogis reserved and rejected if a caller tries to send it._eventLog.calleris service-managed auth metadata and is distinct from the row-levelactor_idcolumn sourced from the request.
Statsig mapping note
The Spanner row keeps nested metadata as JSON. The Statsig adapter is stricter: when forwarding, nested objects and arrays are stringified into deterministic JSON so they can fit Statsig's flatter metadata model.
Last updated on