Skip to content

streamlogia/javascript-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Streamlogia JavaScript SDK

A JavaScript client library for sending structured logs to the Streamlogia Log Ingestor API.

Features

  • Structured log ingestion (DEBUG, INFO, WARN, ERROR)
  • Asynchronous batching with configurable flush interval and batch size
  • Winston transport integration
  • Pino destination stream integration
  • Express middleware for automatic request/response logging (method, path, status, duration, response size)
  • Next.js Edge Runtime compatible
  • Works in Node.js 18+ with native fetch — no extra dependencies required

Requirements

Node.js 18 or later (uses native fetch). For older Node.js, pass a custom fetch via the fetch option.

Installation

npm install @streamlogia/javascript-sdk

Quick Start

import { LogIngestorClient } from '@streamlogia/javascript-sdk'

const client = new LogIngestorClient({
  apiKey:    process.env.STREAMLOGIA_API_KEY,
  projectId: process.env.STREAMLOGIA_PROJECT_ID,
  source:    'my-service',
})

await client.info('application started')
await client.info('user signed in', { meta: { userId: 'u_123' }, tags: ['auth'] })

// Flush remaining logs and stop the background timer before exit
await client.close()

Usage

Direct Client Logging

The client exposes a method for each log level:

client.debug('cache miss',             { meta: { key: 'session:42' } })
client.info('order placed',            { meta: { orderId: 'ord_99', total: 49.95 }, tags: ['orders'] })
client.warn('rate limit approaching',  { meta: { remaining: 5 } })
client.error('payment failed',         { meta: { error: err.message }, tags: ['payments'] })

Each method accepts:

  • message — log message string
  • opts.meta — optional key/value metadata object
  • opts.tags — optional string array for filtering
  • opts.source — override the default source for this entry

Winston Integration

createWinstonTransport adapts the client to a Winston transport — analogous to NewSlogHandler in the Go SDK. Pass the Transport base class from winston-transport so the SDK stays free of hard dependencies.

import Transport from 'winston-transport'
import winston from 'winston'
import { LogIngestorClient } from '@streamlogia/javascript-sdk'

const client = new LogIngestorClient({ /* ... */ })
const LogTransport = client.createWinstonTransport(Transport)

const logger = winston.createLogger({
  level: 'debug',
  transports: [
    new winston.transports.Console({ format: winston.format.simple() }),
    new LogTransport(),
  ],
})

logger.info('order placed', { orderId: 'ord_123', amount: 49.99 })
logger.error('payment failed', { customerId: 'c_42', error: err.message })

Adding Console alongside LogTransport fans logs out to both stdout and the ingestor simultaneously — the same pattern as MultiHandler in the Go SDK. Stdout is captured by systemd and visible via journalctl -u your-service -f.

Note: logs sent via logger.* (Winston) go to both destinations. Logs generated by expressMiddleware() are written directly to the client and do not pass through Winston — they reach the console via the client's built-in console mirroring (console: true by default). Set console: false to suppress them:

const client = new LogIngestorClient({ ..., console: false })
Log source Console (stdout) Ingestor
logger.info/warn/error/... ✅ via Winston
expressMiddleware() access logs ✅ via client

Pino Integration

pinoDestination() returns a Writable stream that consumes Pino's NDJSON output and forwards each record to the ingestor:

import pino from 'pino'
import { LogIngestorClient } from '@streamlogia/javascript-sdk'

const client = new LogIngestorClient({ /* ... */ })

const logger = pino({ level: 'debug' }, pino.multistream([
  { stream: process.stdout },             // stdout
  { stream: client.pinoDestination() },   // ingestor
]))

logger.info({ orderId: 'ord_123' }, 'order placed')
logger.error({ customerId: 'c_42', err }, 'payment failed')

Express Middleware

Mount expressMiddleware() once at the top of your Express app. It automatically logs one entry per request — method, path, status code, duration, response size, IP, user agent, and X-Request-Id (if present). No per-route code needed.

import express from 'express'
import { LogIngestorClient } from '@streamlogia/javascript-sdk'

const client = new LogIngestorClient({ /* ... */ })
const app = express()

app.use(express.json())
app.use(client.expressMiddleware())

The log level is determined by the response status code:

Status range Level
2xx / 3xx INFO
4xx WARN
5xx ERROR

Options:

app.use(client.expressMiddleware({ logBody: true }))
Option Default Description
logBody false Include the parsed request body in meta

Next.js Edge Middleware

Place this at the root of your Next.js project as middleware.js. It runs on the Edge Runtime where response lifecycle hooks are not available, so the request is logged on the way in.

// middleware.js
import { NextResponse } from 'next/server'

const API_KEY    = process.env.STREAMLOGIA_API_KEY
const PROJECT_ID = process.env.STREAMLOGIA_PROJECT_ID

export async function middleware(request) {
  const entry = {
    projectId: PROJECT_ID,
    level:     'INFO',
    message:   `${request.method} ${request.nextUrl.pathname}`,
    source:    'nextjs-edge',
    timestamp: new Date().toISOString(),
    tags:      ['http', 'nextjs'],
    meta: {
      method:    request.method,
      path:      request.nextUrl.pathname,
      userAgent: request.headers.get('user-agent'),
    },
  }

  // Fire-and-forget — never let logging block the response
  fetch('https://api.streamlogia.com/v1/ingest', {
    method:  'POST',
    headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
    body:    JSON.stringify([entry]),
  }).catch(() => {})

  return NextResponse.next()
}

export const config = {
  matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
}

See examples/nextjs-middleware.js for the full version.

Configuration

const client = new LogIngestorClient({
  apiKey:          process.env.STREAMLOGIA_API_KEY,
  projectId:       process.env.STREAMLOGIA_PROJECT_ID,
  source:          'order-service',
  batchSize:       50,
  flushIntervalMs: 10_000,
  fetch:           customFetchFn,      // optional: custom fetch implementation
  onError:         (err) => { ... },   // optional: called when an ingest request fails
  console:         true,               // optional: mirror every log to the console
})
Option Default Description
apiKey API key (required)
projectId Project UUID (required)
baseURL "https://api.streamlogia.com" Override the ingestor API base URL
source "unknown" Default source field on every log entry
batchSize 1 Flush automatically after accumulating n entries
flushIntervalMs 5000 Background flush interval in milliseconds
fetch globalThis.fetch Custom fetch implementation
onError console.error Called when an ingest HTTP request fails
console true Mirror every log entry to the console as well

Graceful Shutdown

Call client.close() before your process exits to flush any buffered entries and stop the background timer.

process.on('SIGTERM', async () => {
  await client.close()
  process.exit(0)
})

API Reference

new LogIngestorClient(opts)

Creates the client and starts the background flush timer.

Log methods

Method Description
client.debug(message, opts?) Log at DEBUG level
client.info(message, opts?) Log at INFO level
client.warn(message, opts?) Log at WARN level
client.error(message, opts?) Log at ERROR level

Other methods

Method Description
client.ingest(entries) Send entries immediately, bypassing the queue
client.flush() Drain the internal queue
client.close() Flush and stop the background timer
client.expressMiddleware(opts?) Express middleware for automatic request logging
client.createWinstonTransport(Transport) Returns a Winston transport class bound to this client
client.pinoDestination() Returns a Pino-compatible Writable destination stream

Log entry shape

{
  projectId: string,
  level:     'DEBUG' | 'INFO' | 'WARN' | 'ERROR',
  message:   string,
  source:    string,
  timestamp: string,   // ISO 8601
  tags:      string[],
  meta:      object,
}

Examples

File Description
examples/express-app.js Express app with Winston integration and request middleware
examples/nextjs-middleware.js Next.js Edge Runtime middleware

Run the Express example:

STREAMLOGIA_API_KEY=<key> STREAMLOGIA_PROJECT_ID=<id> node examples/express-app.js

License

MIT

About

Official javascript sdk for utilizing streamlogia logging.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors