@logtide/elysia
v0.13.0
Published
LogTide SDK plugin for Elysia — request tracing and error capture via lifecycle hooks
Downloads
475
Readme
Features
- Automatic request spans via version-specific Elysia lifecycle hooks
- Error capture with full request context
- W3C Trace Context propagation (
traceparentin/out) - Breadcrumbs for HTTP requests
- Global plugin — traces all routes automatically
- Designed for Bun — works with Elysia's native runtime
- Full TypeScript support with strict types
Installation
npm install @logtide/elysia
# or
pnpm add @logtide/elysia
# or
bun add @logtide/elysiaQuick Start
Use the root export with Elysia 1.x:
import { Elysia } from 'elysia';
import { logtide } from '@logtide/elysia';
const app = new Elysia()
.use(logtide({
dsn: 'https://[email protected]',
// Or use apiUrl + apiKey instead of dsn:
// apiUrl: 'https://your-instance.com',
// apiKey: 'lp_your_key',
service: 'my-elysia-api',
environment: 'production',
}))
.get('/hello', () => 'Hello World')
.listen(3000);Use the isolated next export with Elysia 2.x:
import { Elysia } from 'elysia';
import { logtide } from '@logtide/elysia/next';
const app = new Elysia()
.use(logtide({
dsn: 'https://[email protected]',
service: 'my-elysia-api',
environment: 'production',
}))
.get('/hello', () => 'Hello World')
.listen(3000);Do not mix the root and next exports: they intentionally target the incompatible Elysia 1.4 and 2.x contracts respectively.
Version support
| Elysia version | Import | Support |
| --- | --- | --- |
| 1.0 to 1.4 | @logtide/elysia | Supported |
| 2.0.0 prereleases from beta.4 | @logtide/elysia/next | Supported |
| Stable 2.x | @logtide/elysia/next | Supported |
| 3.x | — | Not supported |
npm semver can only match a prerelease when a range names its exact major.minor.patch tuple. The 2.0.0-beta.4 range therefore accepts later 2.0.0 prereleases, but not a prerelease on a future 2.x patch or minor. We add support for a new prerelease line after validating it.
How It Works
The two plugins hook into the Elysia app differently, because Elysia 2 replaced the lifecycle contract the 1.4 plugin was built on:
| | Elysia 1.4 (@logtide/elysia) | Elysia 2 (@logtide/elysia/next) |
|-------|---------------------------------|-------------------------------------|
| Span start | onRequest | wrap |
| Span finish and traceparent | onAfterHandle | wrap |
| Error capture | onError | error |
On Elysia 1.4 the request hook extracts an incoming traceparent and creates a span, and the response hook injects traceparent and finishes the span using the final mapped status.
On Elysia 2 both ends live in a single wrap around the app's fetch handler. Wrapping is what makes the span survive paths the hooks never see: client aborts, responses returned early by other plugins, WebSocket upgrades, and routes registered before the plugin. The error hook captures failures with HTTP context, while responses Elysia produced deliberately (status(), NotFound, validation failures, tagged HTTPErrors) with a 4xx status stay normal request telemetry. The 1.4 plugin reports every error, 4xx included.
Instrumentation failures are swallowed on both plugins: a broken transport or integration leaves a request untraced, it never breaks the response.
Each plugin is registered with .as('global') so it applies to all routes.
Configuration
All ClientOptions from @logtide/core are supported:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| dsn | string | required | DSN string: https://lp_KEY@host/PROJECT |
| service | string | required | Service name for log attribution |
| environment | string | — | Environment (e.g. production, staging) |
| release | string | — | Release / version identifier |
| debug | boolean | false | Enable debug logging |
| tracesSampleRate | number | 1.0 | Sample rate for traces (0.0 to 1.0) |
See @logtide/core README for the full list of options.
Error Handling
Errors thrown by handlers are automatically captured:
const app = new Elysia()
.use(logtide({ dsn: '...', service: 'my-api' }))
.get('/boom', () => {
throw new Error('Something broke');
// Automatically captured with:
// - http.url, http.method
// - Error message and stack trace
// - Span marked as 'error'
});Distributed Tracing
Incoming traceparent headers are extracted and used as parent context:
# Client sends a traced request
curl -H "traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" \
http://localhost:3000/api/dataThe span created by the plugin will use the same trace ID, enabling end-to-end distributed tracing across services.
Outgoing responses include a traceparent header with the span's context.
Exports
// Elysia 1.4
import { logtide } from '@logtide/elysia';
import type { LogtideElysiaOptions } from '@logtide/elysia';
// Elysia 2.x
import { logtide } from '@logtide/elysia/next';
import type { LogtideElysiaOptions } from '@logtide/elysia/next';License
MIT License - see LICENSE for details.
