Axiom Adapter
Axiom is a cloud-native logging platform with powerful querying capabilities. The evlog Axiom adapter sends your wide events directly to Axiom datasets.
Installation
The Axiom adapter comes bundled with evlog:
import { createAxiomDrain } from 'evlog/axiom'
Quick Start
1. Get your Axiom credentials
- Create an Axiom account
- Create a dataset for your logs
- Generate an API token with ingest permissions
2. Set environment variables
AXIOM_TOKEN=xaat-your-token-here
AXIOM_DATASET=your-dataset-name
3. Wire the drain to your framework
// server/plugins/evlog-drain.ts
import { createAxiomDrain } from 'evlog/axiom'
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('evlog:drain', createAxiomDrain())
})
import { createAxiomDrain } from 'evlog/axiom'
app.use(evlog({ drain: createAxiomDrain() }))
import { createAxiomDrain } from 'evlog/axiom'
app.use(evlog({ drain: createAxiomDrain() }))
import { createAxiomDrain } from 'evlog/axiom'
await app.register(evlog, { drain: createAxiomDrain() })
import { createAxiomDrain } from 'evlog/axiom'
app.use(evlog({ drain: createAxiomDrain() }))
import { createAxiomDrain } from 'evlog/axiom'
EvlogModule.forRoot({ drain: createAxiomDrain() })
import { createAxiomDrain } from 'evlog/axiom'
initLogger({ drain: createAxiomDrain() })
That's it! Your logs will now appear in Axiom.
Configuration
The adapter reads configuration from multiple sources (highest priority first):
- Overrides passed to
createAxiomDrain() - Runtime config at
runtimeConfig.axiom(Nuxt/Nitro only) - Environment variables (
AXIOM_*orNUXT_AXIOM_*)
Environment Variables
| Variable | Nuxt alias | Description |
|---|---|---|
AXIOM_TOKEN | NUXT_AXIOM_TOKEN | API token with ingest permissions |
AXIOM_DATASET | NUXT_AXIOM_DATASET | Dataset name to ingest logs into |
AXIOM_ORG_ID | NUXT_AXIOM_ORG_ID | Organization ID (required for Personal Access Tokens) |
AXIOM_EDGE_URL | NUXT_AXIOM_EDGE_URL | Edge base URL for ingest/query (for edge deployments) |
AXIOM_URL | NUXT_AXIOM_URL | API base URL (legacy/default ingest endpoint) |
NUXT_ prefix so values are available via useRuntimeConfig(). In all other frameworks, use the unprefixed variables.Runtime Config (Nuxt only)
Configure via nuxt.config.ts for type-safe configuration:
export default defineNuxtConfig({
runtimeConfig: {
axiom: {
token: '', // Set via NUXT_AXIOM_TOKEN
dataset: '', // Set via NUXT_AXIOM_DATASET
},
},
})
Override Options
Pass options directly to override any configuration:
const drain = createAxiomDrain({
dataset: 'production-logs',
timeout: 10000,
})
Full Configuration Reference
| Option | Type | Default | Description |
|---|---|---|---|
token | string | - | API token (required) |
dataset | string | - | Dataset name (required) |
orgId | string | - | Organization ID (for PAT tokens) |
edgeUrl | string | - | Edge URL for ingest. Uses /v1/ingest/{dataset} when no path is provided; custom paths are used as-is (trailing slash trimmed). Mutually exclusive with baseUrl |
baseUrl | string | https://api.axiom.co | API base URL (/v1/datasets/{dataset}/ingest), mutually exclusive with edgeUrl |
timeout | number | 5000 | Request timeout in milliseconds |
Querying Logs in Axiom
evlog sends structured wide events that are perfect for Axiom's APL query language:
// Find slow requests
['your-dataset']
| where duration > 1000
| project timestamp, path, duration, status
// Error rate by endpoint
['your-dataset']
| where level == "error"
| summarize count() by path
| order by count_ desc
// Request volume over time
['your-dataset']
| summarize count() by bin(timestamp, 1h)
| render timechart
Troubleshooting
Missing dataset or token error
[evlog/axiom] Missing dataset or token. Set AXIOM_DATASET and AXIOM_TOKEN
Make sure your environment variables are set and the server was restarted after adding them.
401 Unauthorized
Your token may be invalid or expired. Generate a new token in the Axiom dashboard with Ingest permissions.
403 Forbidden with PAT tokens
Personal Access Tokens require an organization ID:
AXIOM_ORG_ID=your-org-id
Direct API Usage
For advanced use cases, you can use the lower-level functions:
import { sendToAxiom, sendBatchToAxiom } from 'evlog/axiom'
// Send a single event
await sendToAxiom(event, {
token: 'xaat-xxx',
dataset: 'logs',
})
// Send multiple events in one request
await sendBatchToAxiom(events, {
token: 'xaat-xxx',
dataset: 'logs',
})
Next Steps
- OTLP Adapter - Send logs via OpenTelemetry Protocol
- PostHog Adapter - Send logs to PostHog
- Custom Adapters - Build your own adapter
- Best Practices - Security and production tips