Event Fields
Send useful events.
Every event must include a message.
Everything else is optional, but adding the right fields makes searching, filtering, and creating alerts much easier.
Complete example
await log.error({
message: "Stripe payment failed.",
importance: "high",
service: "billing",
subsystem: "stripe",
operation: "create-payment",
track: {
user_id: "user_123",
custom: {
payment_intent_id: "pi_123",
},
},
security: {
ip_address: "203.0.113.10",
},
metrics: {
custom: {
response_time_ms: 3200,
},
},
});Core fields
| Field | Type | Required | Purpose |
|---|---|---|---|
| type | error | warning | info | audit | metric | debug | success | Set by method | The kind of event. Logger methods set this for you. |
| message | string | Yes | Human-readable explanation of what happened |
| importance | low | medium | high | critical | No | Controls how serious the event is |
| service | string | No | The part of your system that produced the event |
| subsystem | string | No | A provider, module, or smaller component |
| operation | string | No | The action being performed |
| track | LogTrack | No | Business and user-related context |
| security | LogSecurity | No | Security-related context |
| metrics | LogMetrics | No | Numeric measurements and performance data |
| timestamps | LogTimestamps | No | Event timing when you need to provide your own event time |
message
Use a short sentence that someone can understand immediately.
message: "Stripe payment failed."Good
message: "Database connection timed out"
message: "User signed in"
message: "Invoice generation failed"Avoid vague messages
message: "Something went wrong"
message: "Error"
message: "Failed"importance
Use importance to show how urgently an event needs attention.
importance: "critical"| Value | Use it for |
|---|---|
| low | Minor events that usually need no action |
| medium | Unexpected events worth reviewing |
| high | Important failures that may affect users |
| critical | Serious failures requiring immediate attention |
Alerts can match this field, which makes it useful for production issues you care about immediately.
service
Use service to identify the main area of your application.
service: "billing"subsystem
Use subsystem for a provider, library, or smaller component inside the service.
subsystem: "stripe"operation
Use operation to describe the action being performed.
operation: "create-payment"track
Use track for searchable business context.
track: {
user_id: "user_123",
role: "user",
custom: {
order_id: "order_456",
payment_intent_id: "pi_789",
},
}This is the best place for identifiers that help you follow one user, request, order, or workflow.
Built-in track fields are user_id, role, ip, user_agent, and geo. Put product-specific identifiers inside custom.
Custom values can be strings, numbers, booleans, or null.
Privacy note
Avoid storing sensitive personal data unless your organization has approved it. Stable IDs are usually safer than raw emails or names.
security
Use security for security-related details.
security: {
ip_address: "203.0.113.10",
auth_status: "failed",
suspicious: true,
tags: ["checkout", "stripe"],
custom: {
reason: "payment-auth-failed",
},
}auth_status can be success, failed, or expired.
- Failed login attempts
- Suspicious requests
- Permission failures
- Blocked actions
- Rate-limit events
metrics
Use metrics for numeric values.
metrics: {
latency_ms: 3200,
db_query_count: 3,
custom: {
response_time_ms: 3200,
amount: 49.99,
},
}These values can help you understand performance and internal business behavior.
Built-in metric fields are latency_ms and db_query_count. Add your own numeric measurements inside custom.
Automatically added fields
You usually do not need to manually send these fields:
type
Set by logger methods such as log.info(), log.warn(), and log.error().
appName
Added from the logger configuration.
environment
Added from the logger configuration.
timestamps.event_time
Optional. Send this only when the event happened earlier than the moment you log it.
ingested_at
Internal receive time. You normally do not need to send this.
Recommended naming
Use lowercase, consistent values for top-level strings.
service: "billing"
subsystem: "stripe"
operation: "create-payment"Avoid mixing styles.
service: "Billing"
service: "billing-service"
service: "BILLING"Consistency makes filters and alerts reliable.
Inside track, security, metrics, and custom, use snake_case names.
track: {
user_id: "user_123",
custom: {
payment_intent_id: "pi_123",
},
}Start simple
A beginner does not need every field.
await log.error({
message: "Payment failed",
service: "billing",
importance: "high",
});Add more context only when it helps you search, investigate, or alert.