Event Logs #
HappyView maintains an internal event log that records system activity — lexicon changes, record operations, Lua script executions and errors, user actions, API key events, backfill jobs, and Tap connectivity. Events are stored in a Postgres table and queryable via the admin API.
Event types #
Events follow a category.action naming convention. Each event has a severity level (info, warn, or error), an optional actor_did (the user who triggered it), an optional subject (what was affected), and a detail JSON object with event-specific data.
Lexicon events #
| Event Type | Severity | Subject | Detail |
|---|---|---|---|
lexicon.created |
info | Lexicon NSID | revision, has_script, source |
lexicon.updated |
info | Lexicon NSID | revision, has_script, source |
lexicon.deleted |
info | Lexicon NSID | — |
Logged when lexicons are uploaded, updated, or deleted via the admin API. The actor_did is the user who performed the action.
Record events #
| Event Type | Severity | Subject | Detail |
|---|---|---|---|
record.created |
info | Record AT URI | collection, did, rkey |
record.deleted |
info | Record AT URI | collection, did, rkey |
Logged when records are received from Tap and stored or removed from the local database. These are system-triggered events (actor_did is null). If a database error occurs during the operation, the same event type is logged with error severity and the error message is included in the detail.
Script events #
| Event Type | Severity | Subject | Detail |
|---|---|---|---|
script.executed |
info | Method NSID | method, caller_did, duration_ms |
script.error |
error | Method NSID | error, script_source, input, caller_did, method |
Logged when Lua scripts run for XRPC query or procedure endpoints. Script errors capture the full context needed to reproduce and debug the issue: the error message, the complete Lua script source, the input that triggered it, and the caller's DID.
:::note
For query scripts (unauthenticated), caller_did and input are omitted from the detail since queries don't have an authenticated user or request body.
:::
User events #
| Event Type | Severity | Subject | Detail |
|---|---|---|---|
user.created |
info | New user DID | template (if used) |
user.deleted |
info | Removed user ID | — |
user.bootstrapped |
info | Bootstrapped user DID | — |
user.permissions_updated |
info | User ID | granted, revoked |
user.super_transferred |
warn | New super user ID | from_user_id |
The user.bootstrapped event is logged when the first user is auto-promoted to super user (see Auth - Auto-bootstrap).
Auth events #
| Event Type | Severity | Subject | Detail |
|---|---|---|---|
auth.permission_denied |
error | Endpoint path | required_permission, user_id |
Logged when a user attempts to access an endpoint they don't have permission for.
API Key events #
| Event Type | Severity | Subject | Detail |
|---|---|---|---|
api_key.created |
info | Key ID | name, permissions |
api_key.revoked |
info | Key ID | name |
Script Variable events #
| Event Type | Severity | Subject | Detail |
|---|---|---|---|
script_variable.upserted |
info | Variable key | — |
script_variable.deleted |
info | Variable key | — |
Hook events #
| Event Type | Severity | Subject | Detail |
|---|---|---|---|
hook.executed |
info | Record AT URI | lexicon_id |
hook.dead_lettered |
error | Record AT URI | lexicon_id, error |
Logged when index hooks run. Dead-lettered events indicate a hook failed all retry attempts.
Backfill events #
| Event Type | Severity | Subject | Detail |
|---|---|---|---|
backfill.started |
info | Collection NSID | job_id |
backfill.completed |
info | Collection NSID | job_id, total_repos |
backfill.failed |
error | Collection NSID | job_id, error |
See Backfill for background on backfill jobs.
Tap events #
| Event Type | Severity | Subject | Detail |
|---|---|---|---|
tap.connected |
info | — | url |
tap.disconnected |
warn | — | reason |
Logged when the WebSocket connection to Tap is established or lost.
Querying events #
Use the admin API to query event logs with filters:
# Get all errors
curl "http://localhost:3000/admin/events?severity=error" -H "$AUTH"
# Get script errors for a specific lexicon
curl "http://localhost:3000/admin/events?event_type=script.error&subject=com.example.feed.like" -H "$AUTH"
# Get all lexicon-related events
curl "http://localhost:3000/admin/events?category=lexicon" -H "$AUTH"
# Paginate through results
curl "http://localhost:3000/admin/events?limit=20&cursor=2026-03-01T11:59:00Z" -H "$AUTH"
See the Admin API reference for full parameter documentation.
Retention #
Event logs are automatically cleaned up based on the EVENT_LOG_RETENTION_DAYS environment variable (default: 30 days). A background task runs hourly to delete events older than the configured retention period.
Set EVENT_LOG_RETENTION_DAYS=0 to disable automatic cleanup and keep logs indefinitely.
See Configuration for all environment variables.