edsger-logs
v0.1.0
Published
Send product logs to Edsger for user behavior analytics
Maintainers
Readme
edsger-logs
Send product logs to Edsger for user behavior analytics and product improvement.
Installation
npm install edsger-logsQuick Start (Recommended)
Use createLogger() for non-blocking, fire-and-forget logging that never interferes with your product's normal flow:
import { createLogger } from 'edsger-logs'
const logger = createLogger({
productId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
userId: 'user-uuid',
sessionId: 'sess_abc123',
})
// Fire-and-forget — no await, no try/catch, no this-binding issues
logger.log('page_view', 'User viewed feature list', { metadata: { page: '/features' } })
logger.log('button_click', 'Clicked create feature')
// Safe to destructure
const { log, flush, dispose } = logger
log('search', 'Searched for auth')
// Create a scoped child logger with different context (immutable)
const adminLogger = logger.withContext({ userId: 'admin-uuid' })
adminLogger.log('settings_changed', 'Updated notification preferences')
// On app shutdown
await flush()
dispose()API
createLogger(options) (Recommended)
Closure-based non-blocking logger. No this, no classes, safe to destructure. Buffers logs in memory and flushes to server every 5 seconds or when buffer reaches 50 entries.
const logger = createLogger({
productId: 'xxx', // Required
userId: 'user-id', // Optional: default user for all logs
sessionId: 'sess-id', // Optional: default session for all logs
endpoint: '...', // Optional: custom endpoint
flushInterval: 5000, // Optional: flush every N ms (default: 5000)
maxBufferSize: 50, // Optional: auto-flush at N entries (default: 50)
onError: (err) => {}, // Optional: error callback (silent by default)
})
logger.log('event', 'message') // Non-blocking, never throws
logger.log('event', 'msg', { metadata }) // With metadata
logger.log('event', 'msg', { userId }) // Override user per-call
const child = logger.withContext({ sessionId: 'new-sess' }) // Immutable child
await logger.flush() // Manual flush (e.g. on shutdown)
logger.dispose() // Stop timer, release resourcessendLog(options)
Low-level async function. Send a single log entry. Returns Promise<SendLogResult>.
Note: This is async and throws on error — use createLogger() instead for non-blocking usage.
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| productId | string | Yes | Product UUID |
| logType | string | Yes | Event type (max 50 chars), e.g. page_view, button_click, error |
| message | string | Yes | Human-readable description (max 5000 chars) |
| userId | string | No | Authenticated user UUID |
| sessionId | string | No | Session identifier to group related events |
| metadata | object | No | Structured data for the event |
Returns:
{ id: string; createdAt: string }sendLogs(options)
Send multiple log entries in a single request. Returns Promise<BatchSendLogResult>.
import { sendLogs } from 'edsger-logs'
await sendLogs({
logs: [
{ productId: '...', logType: 'page_view', message: 'Viewed home' },
{ productId: '...', logType: 'button_click', message: 'Clicked create' },
],
})Max 100 logs per batch. Returns { count: number }.
Error Handling
import { sendLog, LogError } from 'edsger-logs'
try {
await sendLog({ ... })
} catch (err) {
if (err instanceof LogError) {
console.error(err.message, err.statusCode)
}
}Requirements
- Node.js >= 18 (uses native
fetch)
License
ISC
