Logs
Structured log shipping with automatic trace correlation
logs ships structured records to POST {endpoint}/v1/logs/intake. It batches on the same dual trigger as the other queues (5s interval OR 100 queued), retries with backoff, and beacons the queue on pagehide — the error that breaks a page is usually the last thing that happens before the user leaves, so an interval flush alone loses precisely the records worth having.
Every record is stamped with the active trace id when tracing is initialised, so a log opens the trace it belongs to with no extra wiring. Emission never throws: a record that cannot be delivered is dropped rather than propagated into your request handler.
Setup
import { logs } from '@foredeck/sdk-js';
logs.init({
endpoint: 'https://events.example.com',
sdkKey: process.env.FOREDECK_SDK_KEY,
service: 'checkout-api',
env: 'prod',
level: 'info', // 'debug' / 'trace' are dropped before they leave
captureErrors: true, // window.onerror + unhandledrejection (browser)
});Recording
logs.info('checkout started', { 'cart.items': 3 });
logs.warn('slow downstream', { 'peer.service': 'payments' });
// An Error is unpacked into error.type / error.message / error.stack.
logs.error(new Error('charge declined'), { 'user.id': unitId });
// Full form
logs.log({
message: 'refund issued',
status: 'info',
attributes: { 'refund.amount_cents': 1299 },
tags: ['team:payments'],
unitId, // enables the exposure join for flag attribution
});
await logs.close(); // flush on shutdownSeverity
status is one of emergency, alert, critical, error, warn, info, debug, trace; anything else falls back to info. Records below the configured level (default info) are dropped in-process and never cost you bandwidth or ingest quota.
Trace correlation
The trace id is taken from tracing.currentTraceId() unless you pass one. Pass traceId: null to opt a single record out.
tracing.init({ endpoint, sdkKey, service: 'checkout-api', env: 'prod' });
await tracing.withSpan('POST /checkout', async () => {
logs.info('validating cart'); // carries this span's trace id
await charge();
});Options
endpoint,sdkKey— events API and bearer key.service,env,host,source— stamped on every record.tags,attributes— defaults merged under per-record values, so a call site can always override.level— minimum severity shipped (defaultinfo).flushIntervalMs(default 5000,0disables),maxBatch(default 100, server cap 1000).captureErrors— browserwindow.onerrorandunhandledrejectioncapture (default on in browsers).fetch— custom implementation for tests and proxies.