Featurely Docs
SDKs

featurely-logger

Structured logging SDK — sends batched log entries to Featurely from any JavaScript or TypeScript application.

featurely-logger

featurely-logger is a structured logging SDK that works in browsers, Node.js, and edge runtimes. Unlike the other Featurely SDKs it requires a logs:write API key permission and is not auto-configured by the CLI.

Installation

npm install featurely-logger

Configuration options

OptionTypeDefaultDescription
apiKeystring—Required. API key with logs:write permission
projectIdstring—Required. Your project ID
apiUrlstringhttps://www.featurely.noCustom API endpoint
sourcestring"sdk"Default source tag on every entry (e.g. "server", "worker")
batchSizenumber10Max entries to accumulate before an automatic flush
flushIntervalnumber5000Milliseconds to wait before flushing a non-full batch
minLevelLogLevel"info"Minimum level to send — entries below this are dropped client-side
autoFlushOnExitbooleantrueFlush pending logs on page unload / process exit

Log levels

LevelNumeric order
trace0 — least severe
debug1
info2
warn3
error4 — most severe

Entries below minLevel are silently dropped without a network request.

Basic usage

import { FeaturelyLogger } from 'featurely-logger';

const logger = new FeaturelyLogger({
  apiKey: process.env.FEATURELY_API_KEY!,
  projectId: process.env.FEATURELY_PROJECT_ID!,
});

logger.info('User signed in', { category: 'auth', userId: 'u_123' });
logger.warn('Payment retry', { category: 'billing', data: { attempt: 2 } });
logger.error('Stripe webhook failed', { category: 'billing', data: { statusCode: 500 } });

Factory function

import { createLogger } from 'featurely-logger';

export const logger = createLogger({
  apiKey: process.env.FEATURELY_API_KEY!,
  projectId: process.env.FEATURELY_PROJECT_ID!,
  source: 'server',
  minLevel: process.env.NODE_ENV === 'production' ? 'info' : 'debug',
});

Log options

Every log method accepts an optional LogOptions object as the second argument:

logger.error('Payment failed', {
  category: 'billing',     // Groups related logs in the dashboard
  userId: 'u_123',         // Filters logs by user in the dashboard
  fingerprint: 'stripe-webhook-500', // Counts occurrences instead of duplicate rows
  data: {                  // Arbitrary structured data
    statusCode: 500,
    retryCount: 3,
  },
});
FieldTypeDescription
categorystringGroup label (e.g. "auth", "payment")
dataRecord<string, unknown>Arbitrary key/value data
userIdstringUser identifier for filtering
fingerprintstringDedup key — same fingerprint = one row with occurrence count

Logging at a dynamic level

const level = determineLevel(error); // 'error' | 'warn' | 'info' | ...
logger.log(level, 'Something happened', { category: 'app' });

Manual flush

The logger batches entries and flushes them automatically. Call flush() to send immediately (e.g. before a lambda returns):

await logger.flush();

Next.js usage

// lib/logger.ts
import { createLogger } from 'featurely-logger';

export const logger = createLogger({
  apiKey: process.env.FEATURELY_API_KEY!,
  projectId: process.env.NEXT_PUBLIC_FEATURELY_PROJECT_ID!,
  source: 'server',
});
// app/api/route.ts
import { logger } from '@/lib/logger';

export async function POST(request: Request) {
  try {
    const data = await request.json();
    logger.info('API request received', { category: 'api', data: { path: '/api/route' } });
    // ...
  } catch (err) {
    logger.error('API handler failed', {
      category: 'api',
      data: { error: String(err) },
    });
    await logger.flush(); // ensure logs are sent before the edge function exits
    return new Response('Internal error', { status: 500 });
  }
}

Environment support

EnvironmentSupport
BrowserFull — auto-flushes on beforeunload and pagehide
Node.jsFull — auto-flushes on beforeExit and SIGTERM
Edge / WorkersManual flush required — call await logger.flush() before returning

TypeScript exports

FeaturelyLogger, createLogger, FeaturelyLoggerConfig, LogOptions, LogLevel