Adapters

HyperDX Adapter

Send wide events to HyperDX via OTLP/HTTP using HyperDX’s documented OpenTelemetry endpoint and authorization header. Zero-config setup with environment variables.

HyperDX is an open-source observability platform. The evlog HyperDX adapter sends your wide events to HyperDX using OTLP over HTTP, with defaults aligned to HyperDX’s OpenTelemetry documentation.

Prompt
Add the HyperDX drain adapter to send evlog wide events to HyperDX.

1. Identify which framework I'm using and follow its evlog integration pattern
2. Install evlog if not already installed
3. Import createHyperDXDrain from 'evlog/hyperdx'
4. Wire createHyperDXDrain() into my framework's drain configuration
5. Set HYPERDX_API_KEY environment variable in .env
6. Test by triggering a request and checking HyperDX

Adapter docs: https://www.evlog.dev/adapters/hyperdx
Framework setup: https://www.evlog.dev/frameworks

Installation

The HyperDX adapter comes bundled with evlog:

import { createHyperDXDrain } from 'evlog/hyperdx'

Quick Start

1. Get your ingestion API key

  1. Open the HyperDX dashboard for your team
  2. Copy your ingestion API key (HyperDX documents this as the value for the authorization header in their OpenTelemetry examples)

2. Set environment variables

.env
HYPERDX_API_KEY=<YOUR_HYPERDX_API_KEY_HERE>

3. Wire the drain to your framework

// server/plugins/evlog-drain.ts
import { createHyperDXDrain } from 'evlog/hyperdx'

export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('evlog:drain', createHyperDXDrain())
})

That's it! Your wide events will now appear in HyperDX.

Configuration

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_*)

Environment Variables

VariableNuxt aliasDescription
HYPERDX_API_KEYNUXT_HYPERDX_API_KEYIngestion API key (sent as the authorization header)
HYPERDX_OTLP_ENDPOINTNUXT_HYPERDX_OTLP_ENDPOINTOTLP HTTP base URL (default: https://in-otel.hyperdx.io)
HYPERDX_SERVICE_NAMENUXT_HYPERDX_SERVICE_NAMEOverride service.name

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

VariableDescription
OTEL_SERVICE_NAMEFallback for service name (HyperDX SDK examples use this)
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:

nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    hyperdx: {
      apiKey: '', // Set via NUXT_HYPERDX_API_KEY
      // endpoint: '', // Set via NUXT_HYPERDX_OTLP_ENDPOINT
    },
  },
})

You can also nest keys under runtimeConfig.evlog.hyperdx; both match how the adapter resolves Nuxt runtime config.

Override Options

Pass options directly to override any configuration:

const drain = createHyperDXDrain({
  apiKey: process.env.HYPERDX_API_KEY!,
  endpoint: 'https://in-otel.hyperdx.io',
  timeout: 10000,
})

For self-hosted HyperDX, set endpoint to your OTLP HTTP base URL (same role as endpoint in HyperDX’s otlphttp exporter example).

Full Configuration Reference

OptionTypeDefaultDescription
apiKeystring-Ingestion API key (required). Sent as the authorization header value
endpointstringhttps://in-otel.hyperdx.ioOTLP HTTP base URL (evlog appends /v1/logs)
serviceNamestring-Override service.name resource attribute
resourceAttributesobject-Additional OTLP resource attributes
timeoutnumber5000Request timeout in milliseconds
retriesnumber2Retry attempts on transient failures

How It Works

Under the hood, createHyperDXDrain() maps your HyperDX settings to the shared OTLP adapter and calls sendBatchToOTLP():

  • Endpoint: OTLP HTTP base URL, defaulting to https://in-otel.hyperdx.io (evlog posts to {endpoint}/v1/logs)
  • Auth: authorization header set to your API key (same as HyperDX’s documented otlphttp exporter)
  • Format: Standard OTLP JSON ExportLogsServiceRequest with severity, trace context when present, and structured attributes

Official HyperDX OpenTelemetry reference

From HyperDX — OpenTelemetry:

Our OpenTelemetry HTTP endpoint is hosted at https://in-otel.hyperdx.io (gRPC at port 4317), and requires the authorization header to be set to your API key.

HyperDX documents this collector configuration (HTTP and gRPC exporters):

exporters:
  # HTTP setup
  otlphttp/hdx:
    endpoint: 'https://in-otel.hyperdx.io'
    headers:
      authorization: <YOUR_HYPERDX_API_KEY_HERE>
    compression: gzip

  # gRPC setup (alternative)
  otlp/hdx:
    endpoint: 'in-otel.hyperdx.io:4317'
    headers:
      authorization: <YOUR_HYPERDX_API_KEY_HERE>
    compression: gzip

evlog uses the HTTP path: JSON to {endpoint}/v1/logs with Content-Type: application/json and the authorization header above. The collector may enable compression: gzip; evlog sends uncompressed JSON bodies like typical OTLP HTTP clients.

Querying logs in HyperDX

Use the HyperDX UI to search and explore wide events:

  • Search: Filter by fields from your wide events (level, service, path, custom attributes, etc.)
  • Live tail: Stream incoming logs
  • Dashboards: Build views on top of structured log data

Troubleshooting

Missing apiKey error

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

Make sure your environment variables are set and the server was restarted after adding them.

401 Unauthorized or ingest rejected

Your API key may be invalid or not permitted to ingest. Confirm the key in HyperDX matches the ingestion key used in their OpenTelemetry examples (authorization: <YOUR_HYPERDX_API_KEY_HERE>).

Direct API Usage

For advanced use cases, you can use the lower-level functions:

server/utils/hyperdx.ts
import { sendToHyperDX, sendBatchToHyperDX } from 'evlog/hyperdx'

// Send a single event
await sendToHyperDX(event, {
  apiKey: process.env.HYPERDX_API_KEY!,
})

// Send multiple events in one request
await sendBatchToHyperDX(events, {
  apiKey: process.env.HYPERDX_API_KEY!,
  endpoint: 'https://in-otel.hyperdx.io',
})

Next Steps