Better Stack Adapter
Better Stack is a DX-first log management platform with powerful search, alerting, and dashboards. The evlog Better Stack adapter sends your wide events to the Better Stack HTTP ingestion API.
Installation
The Better Stack adapter comes bundled with evlog:
import { createBetterStackDrain } from 'evlog/better-stack'
Quick Start
1. Get your source token
- Create a Better Stack account
- Go to Telemetry > Sources and create a new source
- Copy the Source Token
2. Set environment variables
NUXT_BETTER_STACK_SOURCE_TOKEN=your-source-token-here
3. Create the drain plugin
import { createBetterStackDrain } from 'evlog/better-stack'
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('evlog:drain', createBetterStackDrain())
})
That's it! Your logs will now appear in Better Stack.
Configuration
The adapter reads configuration from multiple sources (highest priority first):
- Overrides passed to
createBetterStackDrain() - Runtime config at
runtimeConfig.evlog.betterStack - Runtime config at
runtimeConfig.betterStack - Environment variables (
NUXT_BETTER_STACK_*orBETTER_STACK_*)
Environment Variables
| Variable | Description |
|---|---|
NUXT_BETTER_STACK_SOURCE_TOKEN | Better Stack source token (required) |
NUXT_BETTER_STACK_ENDPOINT | Custom ingestion endpoint |
You can also use BETTER_STACK_SOURCE_TOKEN and BETTER_STACK_ENDPOINT as fallbacks.
Runtime Config
Configure via nuxt.config.ts for type-safe configuration:
export default defineNuxtConfig({
runtimeConfig: {
betterStack: {
sourceToken: '', // Set via NUXT_BETTER_STACK_SOURCE_TOKEN
},
},
})
Override Options
Pass options directly to override any configuration:
import { createBetterStackDrain } from 'evlog/better-stack'
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('evlog:drain', createBetterStackDrain({
sourceToken: 'my-token',
timeout: 10000, // 10 seconds
}))
})
Full Configuration Reference
| Option | Type | Default | Description |
|---|---|---|---|
sourceToken | string | - | Better Stack source token (required) |
endpoint | string | https://in.logs.betterstack.com | Ingestion endpoint |
timeout | number | 5000 | Request timeout in milliseconds |
Log Transformation
evlog wide events are transformed using toBetterStackEvent():
- Timestamp:
timestampis mapped todt(Better Stack's expected ISO-8601 timestamp field) - All other fields: Spread as-is into the event body
Better Stack accepts arbitrary JSON fields, so all your wide event context (level, service, action, user data, etc.) is automatically searchable.
Querying Logs in Better Stack
Better Stack provides a powerful log search interface:
- Live tail: Stream logs in real time
- Full-text search: Search across all fields
- Structured queries: Filter by
level:error,service:my-app, or any wide event field - Dashboards: Create custom dashboards from your wide event data
- Alerts: Set up alerts based on log patterns or thresholds
Troubleshooting
Missing source token error
[evlog/better-stack] Missing source token. Set NUXT_BETTER_STACK_SOURCE_TOKEN env var or pass to createBetterStackDrain()
Make sure your environment variable is set and the server was restarted after adding it.
401 Unauthorized
Your source token may be invalid or revoked. Generate a new source token in Telemetry > Sources in the Better Stack dashboard.
403 Forbidden
The source may be archived or deleted. Create a new source in Better Stack.
Direct API Usage
For advanced use cases, you can use the lower-level functions:
import { sendToBetterStack, sendBatchToBetterStack } from 'evlog/better-stack'
// Send a single event
await sendToBetterStack(event, {
sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN!,
})
// Send multiple events in one request
await sendBatchToBetterStack(events, {
sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN!,
})
Next Steps
- Axiom Adapter - Send logs to Axiom for querying and dashboards
- OTLP Adapter - Send logs via OpenTelemetry Protocol
- Custom Adapters - Build your own adapter