The @logtide/core package is the foundation
for all LogTide JavaScript SDKs. It provides DSN-based configuration, automatic batching,
distributed tracing (W3C Trace Context), breadcrumbs, scopes, and span management.
Installation
npm install @logtide/core
# or with pnpm
pnpm add @logtide/core
# or with yarn
yarn add @logtide/core
For framework-specific integrations, install the corresponding package instead
(it includes @logtide/core as a dependency):
# Framework packages (pick one)
npm install @logtide/express # Express.js
npm install @logtide/fastify # Fastify
npm install @logtide/nextjs # Next.js
npm install @logtide/nuxt # Nuxt
npm install @logtide/sveltekit # SvelteKit
npm install @logtide/hono # Hono
npm install @logtide/angular # Angular
npm install @logtide/elysia # Elysia Quick Start
import { hub, ConsoleIntegration, GlobalErrorIntegration } from '@logtide/core';
hub.init({
dsn: 'https://[email protected]',
service: 'api-server',
environment: process.env.NODE_ENV,
release: '1.0.0',
integrations: [
new ConsoleIntegration(),
new GlobalErrorIntegration(),
],
});
// Capture logs
hub.captureLog('info', 'Server started', { port: 3000 });
// Capture errors
try {
await riskyOperation();
} catch (error) {
hub.captureError(error);
}
// Graceful shutdown
process.on('SIGINT', async () => {
await hub.close();
process.exit(0);
}); The DSN (Data Source Name) encodes your API host and project key in a single connection string. You can find it in your LogTide project settings.
Configuration
import { hub, ConsoleIntegration, GlobalErrorIntegration } from '@logtide/core';
hub.init({
// Required
dsn: 'https://[email protected]',
// Recommended
service: 'api-server',
environment: 'production',
release: '1.2.3',
// Batching
batchSize: 100, // Max logs per batch (default: 100)
flushInterval: 5000, // Flush interval in ms (default: 5000)
maxBufferSize: 10000, // Max logs in buffer (default: 10000)
// Reliability
maxRetries: 3, // Retry attempts (default: 3)
retryDelayMs: 1000, // Initial retry delay in ms (default: 1000)
circuitBreakerThreshold: 5, // Failures before open (default: 5)
circuitBreakerResetMs: 30000, // Reset timeout in ms (default: 30000)
// Tracing
tracesSampleRate: 1.0, // 0.0 to 1.0, sample rate for traces
// Integrations
integrations: [
new ConsoleIntegration(),
new GlobalErrorIntegration(),
],
// Debug
debug: false,
}); Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
dsn | string | — | Data Source Name (required) |
service | string | 'app' | Service name for log grouping |
environment | string | — | Deployment environment (production, staging, etc.) |
release | string | — | App version for release tracking |
batchSize | number | 100 | Max events per batch |
flushInterval | number | 5000 | Flush interval in milliseconds |
maxBufferSize | number | 10000 | Max events in buffer before dropping |
maxRetries | number | 3 | Max retry attempts for failed sends |
retryDelayMs | number | 1000 | Initial retry delay in ms (exponential backoff) |
circuitBreakerThreshold | number | 5 | Consecutive failures before circuit opens |
circuitBreakerResetMs | number | 30000 | Timeout before circuit half-opens (ms) |
tracesSampleRate | number | 1.0 | Trace sampling rate (0.0–1.0) |
maxBreadcrumbs | number | 100 | Max breadcrumbs per scope |
debug | boolean | false | Enable internal debug logging |
Hub API
captureLog
Send a structured log event.
import { hub } from '@logtide/core';
// Log levels: debug, info, warn, error, critical
hub.captureLog('info', 'User signed up', { userId: '123', plan: 'pro' });
hub.captureLog('warn', 'Rate limit approaching', { current: 90, max: 100 });
hub.captureLog('error', 'Query timeout', { query: 'SELECT ...', duration: 5000 }); captureError
Capture an error with full stack trace, context, and breadcrumbs.
try {
await processPayment(orderId);
} catch (error) {
hub.captureError(error, { orderId, amount: 99.99 });
} flush & close
Flush pending events or shut down the SDK.
// Flush pending events
await hub.flush();
// Close the SDK (flushes and disables further capturing)
await hub.close(); Scopes & Context
Scopes let you attach contextual data that gets included with every event within that scope.
Global Scope
Access the global scope to set tags and extras that apply to all events.
import { hub } from '@logtide/core';
const scope = hub.getScope();
scope.setTag('region', 'eu-west-1');
scope.setExtra('userId', 'user-123');
// All events now include the region tag and userId Request Scopes
Framework SDKs create per-request scopes automatically. You can also create scopes manually via the client.
const client = hub.getClient();
const scope = client.createScope();
scope.setTag('handler', 'payment');
scope.setExtra('orderId', '456');
// Pass the scope to captureLog/captureError
client.captureLog('info', 'Processing payment', {}, scope);
client.captureError(new Error('Card declined'), {}, scope); Breadcrumbs
Breadcrumbs record a trail of events leading up to an error, making it easier to debug.
import { hub } from '@logtide/core';
// Add a breadcrumb manually
hub.addBreadcrumb({
type: 'default',
category: 'auth',
message: 'User authenticated',
timestamp: Date.now(),
data: { method: 'oauth', provider: 'github' },
});
hub.addBreadcrumb({
type: 'navigation',
category: 'navigation',
message: 'Navigated to /dashboard',
timestamp: Date.now(),
});
// When an error is captured, breadcrumbs are included automatically
hub.captureError(new Error('Dashboard failed to load'));
// The error event will contain both breadcrumbs above Distributed Tracing
LogTide supports the W3C Trace Context standard for distributed tracing across services.
Spans
import { hub } from '@logtide/core';
const client = hub.getClient();
const span = client.startSpan({
name: 'db.query SELECT users',
attributes: { 'db.statement': 'SELECT * FROM users WHERE id = $1' },
});
try {
const result = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
client.finishSpan(span.spanId, 'ok');
} catch (error) {
client.finishSpan(span.spanId, 'error');
hub.captureError(error);
} Trace Propagation
Framework SDKs automatically extract incoming traceparent headers and inject them into responses for end-to-end trace correlation.
import { createTraceparent, generateTraceId, generateSpanId } from '@logtide/core';
// Create a traceparent header for outgoing requests
const traceId = generateTraceId();
const spanId = generateSpanId();
const header = createTraceparent(traceId, spanId, true);
// → "00-<trace-id>-<span-id>-01"
await fetch('https://api.example.com/data', {
headers: { traceparent: header },
}); Integrations
Console Integration
Automatically captures console.log/warn/error calls and forwards them to LogTide.
import { hub, ConsoleIntegration } from '@logtide/core';
hub.init({
dsn: 'https://[email protected]',
integrations: [
new ConsoleIntegration(),
],
});
// These are now automatically captured:
console.warn('Disk space low'); // → captureLog('warn', ...)
console.error('Connection lost'); // → captureLog('error', ...) Global Error Integration
Captures uncaught exceptions and unhandled promise rejections.
import { hub, GlobalErrorIntegration } from '@logtide/core';
hub.init({
dsn: 'https://[email protected]',
integrations: [
new GlobalErrorIntegration(),
],
});
// Unhandled errors are automatically captured:
// - uncaughtException
// - unhandledRejection Framework Packages
Each framework package wraps @logtide/core with
framework-specific middleware, hooks, and auto-instrumentation.
Middleware, request scoping, traceparent propagation
Plugin registration, lifecycle hooks, request scoping
Instrumentation hook, error boundary, client-side init
Zero-config Nuxt module, runtime config injection
Handle, handleError, handleFetch hooks, client init
Middleware, multi-runtime (Node/Bun/Deno/Workers)
ErrorHandler, HttpInterceptor, standalone & NgModule
Elysia plugin, lifecycle hooks, Bun-optimized
Best Practices
hub.init() as early as possible in your
application entry point, before any other code runs. This ensures global error and console
integrations capture everything.
await hub.close() in your shutdown
handler to flush all pending events before the process exits.
environment and release in
your config. This enables filtering by environment and tracking regressions across releases.