LogTide

Elysia SDK

@logtide/elysia is a Bun-optimized Elysia plugin for automatic request logging, scoped context, lifecycle hooks, and W3C trace propagation.

Installation

bun add @logtide/elysia

Quick Start

import { Elysia } from 'elysia';
import * as Logtide from '@logtide/core';
import { logtidePlugin } from '@logtide/elysia';

Logtide.init({
  dsn: 'https://[email protected]',
  service: 'elysia-api',
  environment: 'production',
});

const app = new Elysia()
  .use(logtidePlugin().as('global'))
  .get('/users/:id', ({ params, store }) => {
    store.logtideScope.setTag('userId', params.id);

    Logtide.captureLog('info', 'Fetching user', {
      userId: params.id,
    });

    return { id: params.id, name: 'Alice' };
  })
  .listen(3000);

Use .as('global') to apply the plugin to all routes, including those registered after the plugin.

Plugin Options

app.use(logtidePlugin({
  // Log requests automatically (default: true)
  logRequests: true,

  // Include request headers (default: false)
  logHeaders: false,

  // Skip paths
  skip: (ctx) => ctx.path === '/health',

  // Custom log level
  getLogLevel: (ctx, status) => {
    if (status >= 500) return 'error';
    if (status >= 400) return 'warn';
    return 'info';
  },
}).as('global'));

Lifecycle Hooks

The plugin hooks into Elysia's lifecycle:

Hook Behavior
onRequestCreates scope, extracts traceparent, starts span
afterResponseLogs request completion with duration, finishes span
onErrorCaptures errors with full request context
onStopFlushes pending events on server shutdown

Scoped Context

app
  .use(logtidePlugin().as('global'))
  .derive(({ store, headers }) => {
    // Set user context for the request
    store.logtideScope.setUser({
      id: headers['x-user-id'],
    });
    store.logtideScope.setTag('tenant', headers['x-tenant-id']);
    return {};
  })
  .get('/orders', ({ store }) => {
    // Logs include user + tenant automatically
    Logtide.captureLog('info', 'Listing orders');
    return { orders: [] };
  });

Error Handling

app
  .use(logtidePlugin().as('global'))
  .onError(({ code, error, store }) => {
    // Error is already captured by the plugin
    // Customize the response
    return new Response(JSON.stringify({
      error: error.message,
      traceId: store.logtideTraceId,
    }), {
      status: code === 'NOT_FOUND' ? 404 : 500,
      headers: { 'Content-Type': 'application/json' },
    });
  });

API Reference

Export Description
logtidePlugin(options?)Elysia plugin — use with .as('global') for all routes
store.logtideScopePer-request scope for tags, user, extras
store.logtideTraceIdCurrent trace ID for the request

See the JavaScript SDK core docs for the full @logtide/core API.