Foredeck
OverviewQuickstartConfig as CodeAPI ReferenceEvaluation SpecExposuresCountersLogsMonitor your servicesSign-in & organizationsAlertingPush notificationsOpenFeature

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 shutdown

Severity

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 (default info).
  • flushIntervalMs (default 5000, 0 disables), maxBatch (default 100, server cap 1000).
  • captureErrors — browser window.onerror and unhandledrejection capture (default on in browsers).
  • fetch — custom implementation for tests and proxies.