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
BETTER_STACK_SOURCE_TOKEN=your-source-token-here
3. Wire the drain to your framework
// server/plugins/evlog-drain.ts
import { createBetterStackDrain } from 'evlog/better-stack'
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('evlog:drain', createBetterStackDrain())
})
import { createBetterStackDrain } from 'evlog/better-stack'
app.use(evlog({ drain: createBetterStackDrain() }))
import { createBetterStackDrain } from 'evlog/better-stack'
app.use(evlog({ drain: createBetterStackDrain() }))
import { createBetterStackDrain } from 'evlog/better-stack'
await app.register(evlog, { drain: createBetterStackDrain() })
import { createBetterStackDrain } from 'evlog/better-stack'
app.use(evlog({ drain: createBetterStackDrain() }))
import { createBetterStackDrain } from 'evlog/better-stack'
EvlogModule.forRoot({ drain: createBetterStackDrain() })
import { createBetterStackDrain } from 'evlog/better-stack'
initLogger({ 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.betterStack(Nuxt/Nitro only) - Environment variables (
BETTER_STACK_*orNUXT_BETTER_STACK_*)
Environment Variables
| Variable | Nuxt alias | Description |
|---|---|---|
BETTER_STACK_SOURCE_TOKEN | NUXT_BETTER_STACK_SOURCE_TOKEN | Better Stack source token (required) |
BETTER_STACK_ENDPOINT | NUXT_BETTER_STACK_ENDPOINT | Custom ingestion endpoint |
Runtime Config (Nuxt only)
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:
const drain = createBetterStackDrain({
sourceToken: 'my-token',
timeout: 10000,
})
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 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