Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/skills/create-adapter/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Create `packages/evlog/src/adapters/{name}.ts`. Read [references/adapter-templat

The contract is now `defineHttpDrain<TConfig>({ resolve, encode })`. You only ship two pieces of logic:

1. **`resolve()`** — produce a fully-resolved config or `null` to skip. Use `resolveAdapterConfig` for the standard precedence (overrides → `runtimeConfig.evlog.{name}` → `runtimeConfig.{name}` → `NUXT_{NAME}_*` `{NAME}_*`).
1. **`resolve()`** — produce a fully-resolved config or `null` to skip. Use `resolveAdapterConfig` for the standard precedence (overrides → `runtimeConfig.evlog.{name}` → `runtimeConfig.{name}` → env vars). List `NUXT_{NAME}_*` before `{NAME}_*` in `ConfigField.env` for silent Nuxt compat; show only `{NAME}_*` in user-facing messages via `formatPublicEnvKeys`.
2. **`encode(events, config)`** — produce `{ url, headers, body }` for a batch of events (or `null` to skip). HTTP transport, retries, timeout, and error logging are handled by `defineHttpDrain`.

Key rules:
Expand Down
8 changes: 4 additions & 4 deletions .agents/skills/create-adapter/references/adapter-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Replace `{Name}`, `{name}`, and `{NAME}` with the actual service name.
```typescript
import type { WideEvent } from '../types'
import type { ConfigField } from '../shared/config'
import { resolveAdapterConfig } from '../shared/config'
import { formatPublicEnvKeys, resolveAdapterConfig } from '../shared/config'
import { defineHttpDrain } from '../shared/drain'

// --- 1. Config Interface -------------------------------------------------
Expand Down Expand Up @@ -99,13 +99,13 @@ export async function sendBatchTo{Name}(
* 1. Overrides passed to create{Name}Drain()
* 2. runtimeConfig.evlog.{name}
* 3. runtimeConfig.{name}
* 4. Environment variables: NUXT_{NAME}_*, {NAME}_*
* 4. Environment variables: {NAME}_*
*
* @example
* ```ts
* import { create{Name}Drain } from 'evlog/{name}'
*
* // Zero config — set NUXT_{NAME}_API_KEY env var
* // Zero config — set {NAME}_API_KEY env var
* defineEvlog({ drain: create{Name}Drain() })
*
* // With overrides
Expand All @@ -119,7 +119,7 @@ export function create{Name}Drain(overrides?: Partial<{Name}Config>) {
resolve: async () => {
const config = await resolveAdapterConfig<{Name}Config>('{name}', FIELDS, overrides)
if (!config.apiKey) {
console.error('[evlog/{name}] Missing apiKey. Set NUXT_{NAME}_API_KEY env var or pass to create{Name}Drain()')
console.error(`[evlog/{name}] Missing apiKey. Set ${formatPublicEnvKeys(['NUXT_{NAME}_API_KEY', '{NAME}_API_KEY'])} env var or pass to create{Name}Drain()`)
return null
}
return config as {Name}Config
Expand Down
7 changes: 7 additions & 0 deletions .changeset/adapter-env-messages-dx.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"evlog": patch
---

Adapter error and deprecation messages now show canonical environment variable names only (`BETTER_STACK_API_KEY`, `AXIOM_API_KEY`, `SENTRY_DSN`, etc.). `NUXT_*` aliases still resolve silently for backward compatibility, but are no longer mentioned in console output or documentation.

The OTLP adapter now also accepts the shorter `OTLP_ENDPOINT` / `OTLP_HEADERS` env vars as aliases for the standard `OTEL_EXPORTER_OTLP_ENDPOINT` / `OTEL_EXPORTER_OTLP_HEADERS`.
16 changes: 8 additions & 8 deletions apps/docs/content/3.integrate/adapters/01.overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,29 +347,29 @@ Every adapter receives a `DrainContext` with:

All adapters support automatic configuration via environment variables. No code changes needed when deploying to different environments.

Each adapter reads from `NUXT_*` prefixed variables (for Nuxt/Nitro runtimeConfig) and unprefixed fallbacks (for any framework):
Each adapter reads from standard environment variables — the same names work in every framework:

```bash [.env]
# Axiom (NUXT_AXIOM_* or AXIOM_*)
# Axiom
AXIOM_API_KEY=xaat-xxx
AXIOM_DATASET=my-logs

# OTLP (NUXT_OTLP_* or OTEL_*)
# OTLP
OTLP_ENDPOINT=https://otlp.example.com

# HyperDX (NUXT_HYPERDX_* or HYPERDX_*)
# HyperDX
HYPERDX_API_KEY=<YOUR_HYPERDX_API_KEY_HERE>

# PostHog (NUXT_POSTHOG_* or POSTHOG_*)
# PostHog
POSTHOG_API_KEY=phc_xxx

# Sentry (NUXT_SENTRY_* or SENTRY_*)
# Sentry
SENTRY_DSN=https://key@o0.ingest.sentry.io/123

# Better Stack (NUXT_BETTER_STACK_* or BETTER_STACK_*)
# Better Stack
BETTER_STACK_API_KEY=your-source-token

# Datadog (NUXT_DATADOG_* or DATADOG_* or DD_*)
# Datadog
DD_API_KEY=your-api-key
DD_SITE=datadoghq.eu
```
Comment on lines +350 to 375

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Better Stack env-var naming is still inconsistent across the docs.

Both files now mention BETTER_STACK_API_KEY, but the Better Stack tables still list BETTER_STACK_SOURCE_TOKEN. Update the prose/example and the table rows to one public name in both files.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/docs/content/3.integrate/adapters/01.overview.md` around lines 350 -
375, Unify the Better Stack environment variable name across the docs by
choosing a single public name (replace BETTER_STACK_API_KEY with
BETTER_STACK_SOURCE_TOKEN): update the env block example, any prose mentions,
and all Better Stack table rows so they consistently use
BETTER_STACK_SOURCE_TOKEN; ensure any explanatory text that refers to the
variable name is adjusted accordingly (search for BETTER_STACK_API_KEY and
BETTER_STACK_SOURCE_TOKEN and standardize them to the chosen symbol in the code
block and tables).

Expand Down
26 changes: 11 additions & 15 deletions apps/docs/content/3.integrate/adapters/cloud/01.axiom.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,21 +132,17 @@ The adapter reads configuration from multiple sources (highest priority first):

1. **Overrides** passed to `createAxiomDrain()`
2. **Runtime config** at `runtimeConfig.axiom` (Nuxt/Nitro only)
3. **Environment variables** (`AXIOM_*` or `NUXT_AXIOM_*`)
3. **Environment variables** (`AXIOM_*`)

### Environment Variables

| Variable | Nuxt alias | Description |
|----------|------------|-------------|
| `AXIOM_API_KEY` | `NUXT_AXIOM_API_KEY` | Axiom 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) |

::callout{icon="i-lucide-info" color="info"}
In Nuxt/Nitro, use the `NUXT_` prefix so values are available via `useRuntimeConfig()`. In all other frameworks, use the unprefixed variables.
::
| Variable | Description |
|----------|-------------|
| `AXIOM_API_KEY` | Axiom API token with ingest permissions |
| `AXIOM_DATASET` | Dataset name to ingest logs into |
| `AXIOM_ORG_ID` | Organization ID (required for Personal Access Tokens) |
| `AXIOM_EDGE_URL` | Edge base URL for ingest/query (for edge deployments) |
| `AXIOM_URL` | API base URL (legacy/default ingest endpoint) |

### Runtime Config (Nuxt only)

Expand All @@ -156,8 +152,8 @@ Configure via `nuxt.config.ts` for type-safe configuration:
export default defineNuxtConfig({
runtimeConfig: {
axiom: {
apiKey: '', // Set via NUXT_AXIOM_API_KEY
dataset: '', // Set via NUXT_AXIOM_DATASET
apiKey: '', // Set via AXIOM_API_KEY
dataset: '', // Set via AXIOM_DATASET
},
},
})
Expand Down Expand Up @@ -213,7 +209,7 @@ evlog sends structured wide events that are perfect for Axiom's APL query langua
### Missing dataset or apiKey error

```text [Console]
[evlog/axiom] Missing dataset or apiKey. Set NUXT_AXIOM_API_KEY/NUXT_AXIOM_DATASET env vars or pass to createAxiomDrain()
[evlog/axiom] Missing dataset or apiKey. Set AXIOM_API_KEY/AXIOM_DATASET env vars or pass to createAxiomDrain()
```

Make sure your environment variables are set and the server was restarted after adding them.
Expand Down
17 changes: 4 additions & 13 deletions apps/docs/content/3.integrate/adapters/cloud/02.otlp.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,28 +133,19 @@ The adapter reads configuration from multiple sources (highest priority first):

### Environment Variables

| Variable | Nuxt alias | Description |
|----------|------------|-------------|
| `OTLP_ENDPOINT` | `NUXT_OTLP_ENDPOINT` | OTLP HTTP endpoint (e.g., `http://localhost:4318`) |
| `OTLP_SERVICE_NAME` | `NUXT_OTLP_SERVICE_NAME` | Override service name |
| `OTLP_HEADERS` | `NUXT_OTLP_HEADERS` | Custom headers (format: `Key=Value,Key2=Value2`) |
| `OTLP_AUTH` | `NUXT_OTLP_AUTH` | Shortcut for `Authorization` header |

Standard OpenTelemetry variables are also supported as fallbacks:

| Variable | Description |
|----------|-------------|
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP endpoint |
| `OTEL_EXPORTER_OTLP_HEADERS` | Headers in OTEL format |
| `OTEL_SERVICE_NAME` | Service name |
| `OTLP_ENDPOINT` | OTLP HTTP endpoint (e.g., `http://localhost:4318`). The standard `OTEL_EXPORTER_OTLP_ENDPOINT` also works. |
| `OTLP_HEADERS` | Headers as `key=value` pairs, comma-separated. The standard `OTEL_EXPORTER_OTLP_HEADERS` also works. |
| `OTEL_SERVICE_NAME` | Service name override |

### Runtime Config (Nuxt only)

```typescript [nuxt.config.ts]
export default defineNuxtConfig({
runtimeConfig: {
otlp: {
endpoint: '', // Set via NUXT_OTLP_ENDPOINT
endpoint: '', // Set via OTLP_ENDPOINT (or OTEL_EXPORTER_OTLP_ENDPOINT)
},
},
})
Expand Down
14 changes: 7 additions & 7 deletions apps/docs/content/3.integrate/adapters/cloud/03.posthog.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,14 @@ The adapter reads configuration from multiple sources (highest priority first):

1. **Overrides** passed to `createPostHogDrain()`
2. **Runtime config** at `runtimeConfig.posthog` (Nuxt/Nitro only)
3. **Environment variables** (`POSTHOG_*` or `NUXT_POSTHOG_*`)
3. **Environment variables** (`POSTHOG_*`)

### Environment Variables

| Variable | Nuxt alias | Description |
|----------|------------|-------------|
| `POSTHOG_API_KEY` | `NUXT_POSTHOG_API_KEY` | Project API key (starts with `phc_`) |
| `POSTHOG_HOST` | `NUXT_POSTHOG_HOST` | PostHog host URL (for EU or self-hosted) |
| Variable | Description |
|----------|-------------|
| `POSTHOG_API_KEY` | Project API key (starts with `phc_`) |
| `POSTHOG_HOST` | PostHog host URL (for EU or self-hosted) |

### Runtime Config (Nuxt only)

Expand All @@ -145,8 +145,8 @@ Configure via `nuxt.config.ts` for type-safe configuration:
export default defineNuxtConfig({
runtimeConfig: {
posthog: {
apiKey: '', // Set via NUXT_POSTHOG_API_KEY
host: '', // Set via NUXT_POSTHOG_HOST
apiKey: '', // Set via POSTHOG_API_KEY
host: '', // Set via POSTHOG_HOST
},
},
})
Expand Down
14 changes: 7 additions & 7 deletions apps/docs/content/3.integrate/adapters/cloud/04.sentry.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@ The adapter reads configuration from multiple sources (highest priority first):

1. **Overrides** passed to `createSentryDrain()`
2. **Runtime config** at `runtimeConfig.sentry` (Nuxt/Nitro only)
3. **Environment variables** (`SENTRY_*` or `NUXT_SENTRY_*`)
3. **Environment variables** (`SENTRY_*`)

### Environment Variables

| Variable | Nuxt alias | Description |
|----------|------------|-------------|
| `SENTRY_DSN` | `NUXT_SENTRY_DSN` | Sentry DSN (required) |
| `SENTRY_ENVIRONMENT` | `NUXT_SENTRY_ENVIRONMENT` | Environment name override |
| `SENTRY_RELEASE` | `NUXT_SENTRY_RELEASE` | Release version override |
| Variable | Description |
|----------|-------------|
| `SENTRY_DSN` | Sentry DSN (required) |
| `SENTRY_ENVIRONMENT` | Environment name override |
| `SENTRY_RELEASE` | Release version override |

### Runtime Config (Nuxt only)

Expand All @@ -146,7 +146,7 @@ export default defineNuxtConfig({
modules: ['evlog/nuxt'],
evlog: {
sentry: {
dsn: '', // Set via NUXT_SENTRY_DSN
dsn: '', // Set via SENTRY_DSN
environment: 'production',
release: '1.0.0',
},
Expand Down
16 changes: 8 additions & 8 deletions apps/docs/content/3.integrate/adapters/cloud/05.better-stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ BETTER_STACK_API_KEY=your-source-token-here
```

::callout{icon="i-lucide-info" color="info"}
In Better Stack's dashboard this credential is called a **source token**. evlog names the config field `apiKey` for consistency across adapters. Legacy `sourceToken` / `BETTER_STACK_SOURCE_TOKEN` still work until the next major release.
In Better Stack's dashboard this credential is called a **source token**. evlog names the config field `apiKey` for consistency across adapters. The legacy `sourceToken` field still works until the next major release.
::

### 3. Wire the drain to your framework
Expand Down Expand Up @@ -131,14 +131,14 @@ The adapter reads configuration from multiple sources (highest priority first):

1. **Overrides** passed to `createBetterStackDrain()`
2. **Runtime config** at `runtimeConfig.betterStack` (Nuxt/Nitro only)
3. **Environment variables** (`BETTER_STACK_*` or `NUXT_BETTER_STACK_*`)
3. **Environment variables** (`BETTER_STACK_*`)

### Environment Variables

| Variable | Nuxt alias | Description |
|----------|------------|-------------|
| `BETTER_STACK_API_KEY` | `NUXT_BETTER_STACK_API_KEY` | Better Stack source token (required) |
| `BETTER_STACK_ENDPOINT` | `NUXT_BETTER_STACK_ENDPOINT` | Custom ingestion endpoint |
| Variable | Description |
|----------|-------------|
| `BETTER_STACK_API_KEY` | Better Stack source token (required) |
| `BETTER_STACK_ENDPOINT` | Custom ingestion endpoint |

### Runtime Config (Nuxt only)

Expand All @@ -148,7 +148,7 @@ Configure via `nuxt.config.ts` for type-safe configuration:
export default defineNuxtConfig({
runtimeConfig: {
betterStack: {
apiKey: '', // Set via NUXT_BETTER_STACK_API_KEY
apiKey: '', // Set via BETTER_STACK_API_KEY
},
},
})
Expand Down Expand Up @@ -198,7 +198,7 @@ Better Stack provides a powerful log search interface:
### Missing apiKey error

```text [Console]
[evlog/better-stack] Missing apiKey. Set NUXT_BETTER_STACK_API_KEY env var or pass to createBetterStackDrain()
[evlog/better-stack] Missing apiKey. Set BETTER_STACK_API_KEY env var or pass to createBetterStackDrain()
```

Make sure your environment variable is set and the server was restarted after adding it.
Expand Down
16 changes: 8 additions & 8 deletions apps/docs/content/3.integrate/adapters/cloud/06.datadog.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,19 +134,19 @@ The adapter reads configuration from multiple sources (highest priority first):

### Environment Variables

| Variable | Nuxt alias | Description |
|----------|------------|-------------|
| `DD_API_KEY` | `NUXT_DATADOG_API_KEY` | Datadog API key (required). Also: `DATADOG_API_KEY` |
| `DD_SITE` | `NUXT_DATADOG_SITE` | Site hostname (e.g. `datadoghq.com`, `datadoghq.eu`, `us3.datadoghq.com`). Also: `DATADOG_SITE` |
| `DATADOG_LOGS_URL` | `NUXT_DATADOG_LOGS_URL` | Full intake URL — overrides URL derived from `site` |
| Variable | Description |
|----------|-------------|
| `DD_API_KEY` | Datadog API key (required). Also: `DATADOG_API_KEY` |
| `DD_SITE` | Site hostname (e.g. `datadoghq.com`, `datadoghq.eu`, `us3.datadoghq.com`). Also: `DATADOG_SITE` |
| `DATADOG_LOGS_URL` | Full intake URL — overrides URL derived from `site` |

### Runtime Config (Nuxt only)

```typescript [nuxt.config.ts]
export default defineNuxtConfig({
runtimeConfig: {
datadog: {
apiKey: '', // Set via NUXT_DATADOG_API_KEY or DD_API_KEY
apiKey: '', // Set via DD_API_KEY or DATADOG_API_KEY
site: 'datadoghq.eu',
},
},
Expand Down Expand Up @@ -202,7 +202,7 @@ Plain-text lines in Live Tail (e.g. “Form field is empty”) usually come from
### Missing API key

```text [Console]
[evlog/datadog] Missing API key. Set NUXT_DATADOG_API_KEY, DATADOG_API_KEY, or DD_API_KEY...
[evlog/datadog] Missing API key. Set DATADOG_API_KEY, DD_API_KEY...
```

Set `DD_API_KEY` (or unprefixed `DATADOG_API_KEY`) and restart the process.
Expand All @@ -213,7 +213,7 @@ The API key may lack log ingestion permission or belong to the wrong organizatio

### Wrong region / site

If logs never appear, confirm `DD_SITE` matches your Datadog account (e.g. EU: `datadoghq.eu`). For a custom intake URL, set `DATADOG_LOGS_URL` / `NUXT_DATADOG_LOGS_URL`.
If logs never appear, confirm `DD_SITE` matches your Datadog account (e.g. EU: `datadoghq.eu`). For a custom intake URL, set `DATADOG_LOGS_URL`.

## Direct API usage

Expand Down
22 changes: 9 additions & 13 deletions apps/docs/content/3.integrate/adapters/cloud/07.hyperdx.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,26 +126,22 @@ The adapter reads configuration from multiple sources (highest priority first):

1. **Overrides** passed to `createHyperDXDrain()`
2. **Runtime config** at `runtimeConfig.evlog.hyperdx` or `runtimeConfig.hyperdx` (Nuxt/Nitro only)
3. **Environment variables** (`HYPERDX_*` or `NUXT_HYPERDX_*`)
3. **Environment variables** (`HYPERDX_*`)

### Environment Variables

| Variable | Nuxt alias | Description |
|----------|------------|-------------|
| `HYPERDX_API_KEY` | `NUXT_HYPERDX_API_KEY` | Ingestion API key (sent as the `authorization` header) |
| `HYPERDX_OTLP_ENDPOINT` | `NUXT_HYPERDX_OTLP_ENDPOINT` | OTLP HTTP base URL (default: `https://in-otel.hyperdx.io`) |
| `HYPERDX_SERVICE_NAME` | `NUXT_HYPERDX_SERVICE_NAME` | Override `service.name` |
| Variable | Description |
|----------|-------------|
| `HYPERDX_API_KEY` | Ingestion API key (sent as the `authorization` header) |
| `HYPERDX_OTLP_ENDPOINT` | OTLP HTTP base URL (default: `https://in-otel.hyperdx.io`) |
| `HYPERDX_SERVICE_NAME` | Override `service.name` |

The following variable is also read when resolving `serviceName` (same as the OTLP adapter):

| Variable | Description |
|----------|-------------|
| `OTEL_SERVICE_NAME` | Fallback for service name (HyperDX SDK examples use this) |

::callout{icon="i-lucide-info" color="info"}
In Nuxt/Nitro, use the `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:
Expand All @@ -154,8 +150,8 @@ Configure via `nuxt.config.ts` for type-safe configuration:
export default defineNuxtConfig({
runtimeConfig: {
hyperdx: {
apiKey: '', // Set via NUXT_HYPERDX_API_KEY
// endpoint: '', // Set via NUXT_HYPERDX_OTLP_ENDPOINT
apiKey: '', // Set via HYPERDX_API_KEY
// endpoint: '', // Set via HYPERDX_OTLP_ENDPOINT
},
},
})
Expand Down Expand Up @@ -236,7 +232,7 @@ Use the HyperDX UI to search and explore wide events:
### Missing apiKey error

```text [Console]
[evlog/hyperdx] Missing apiKey. Set HYPERDX_API_KEY or NUXT_HYPERDX_API_KEY, or pass to createHyperDXDrain()
[evlog/hyperdx] Missing apiKey. Set HYPERDX_API_KEY, or pass to createHyperDXDrain()
```

Make sure your environment variables are set and the server was restarted after adding them.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,10 @@ createMemoryDrain({ store: 'my-service' })

### Environment Variables

| Variable | Nuxt alias | Description |
|----------|------------|-------------|
| `EVLOG_MEMORY_STORE` | `NUXT_EVLOG_MEMORY_STORE` | Named buffer key (default: `'default'`) |
| `EVLOG_MEMORY_MAX_EVENTS` | `NUXT_EVLOG_MEMORY_MAX_EVENTS` | Ring buffer size (default: `1000`) |
| Variable | Description |
|----------|-------------|
| `EVLOG_MEMORY_STORE` | Named buffer key (default: `'default'`) |
| `EVLOG_MEMORY_MAX_EVENTS` | Ring buffer size (default: `1000`) |

Configuration priority matches other adapters: overrides → `runtimeConfig.evlog.memory` → env vars.

Expand Down
Loading
Loading