Node.js SDK Logging
Server-side logging for Node.js with exponential backoff, zero dependencies, and Express.js integration.
Server-side logging with exponential backoff, zero dependencies, and Express.js integration. Logs appear under Abrova Trace → Logs; they are separate from AbrovaTrace.captureMessage(), which goes to Messages.
A failed batch is retried after 2s → 4s → 8s → ... → 60s max. After 10 failed retries the logs stay in the buffer until the next log or flush.
Default 1000 logs. Oldest dropped when exceeded to prevent memory issues.
setTimeout only runs when buffer has logs. No CPU overhead when idle.
Uses native Node.js http/https modules. No external packages.
Installation#
Add the Abrova registry to .npmrc, then install (see Node.js SDK):
# .npmrc @abrova-trace:registry=https://center.abrova.ir/api/packages/abrova/npm/
npm install @abrova-trace/nodejs-sdk
Basic Usage#
const { LogService, LogLevel } = require('@abrova-trace/nodejs-sdk');
const logger = new LogService({
apiKey: 'ab_live_your_api_key',
sourceId: 'api-server',
sourceName: 'My API Server',
environment: 'production',
});
logger.log('Server started on port 3000', LogLevel.INFO);
logger.log('Database connection slow', LogLevel.WARN, { latency: 2500 });
logger.log('Failed to process payment', LogLevel.ERROR, { orderId: '12345' });
// Graceful shutdown
process.on('SIGTERM', async () => {
await logger.dispose();
process.exit(0);
});If you already call AbrovaTrace.init(), you can log through it instead of creating a LogService yourself. It reuses the API key, environment and release from init(), and attaches the user set with setUser():
const AbrovaTrace = require('@abrova-trace/nodejs-sdk');
AbrovaTrace.enableLogging({ sourceId: 'api-server', sourceName: 'My API Server' }); // flushes every 5s by default
AbrovaTrace.info('Server started on port 3000');
AbrovaTrace.warn('Database connection slow', { latency: 2500 });
AbrovaTrace.logError('Failed to process payment', { orderId: '12345' });
// also: trace(), logDebug(), fatal(), log(message, level, metadata)
await AbrovaTrace.flushLogs(); // sends buffered logs nowBefore the process exits, call await AbrovaTrace.flush(). It sends buffered logs together with pending errors, messages and performance spans, and resolves false if its timeout (default: 5000 ms) passes first. AbrovaTrace.close() also sends buffered logs, then resets the SDK.
Log Levels#
const { LogLevel } = require('@abrova-trace/nodejs-sdk');
logger.log('Detailed trace info', LogLevel.TRACE);
logger.log('Debug information', LogLevel.DEBUG);
logger.log('User action completed', LogLevel.INFO);
logger.log('Approaching rate limit', LogLevel.WARN);
logger.log('Failed to save data', LogLevel.ERROR);
logger.log('App crashed unexpectedly', LogLevel.FATAL);Express.js Integration#
const express = require('express');
const { LogService, LogLevel } = require('@abrova-trace/nodejs-sdk');
const app = express();
const logger = new LogService({
apiKey: 'ab_live_your_api_key',
sourceId: 'express-api',
environment: process.env.NODE_ENV || 'development',
});
// Request logging middleware
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
const level = res.statusCode >= 400 ? LogLevel.ERROR : LogLevel.INFO;
logger.log(`${req.method} ${req.path} ${res.statusCode}`, level, {
method: req.method,
path: req.path,
statusCode: res.statusCode,
duration,
});
});
next();
});
// Error logging middleware
app.use((err, req, res, next) => {
logger.log(err.message, LogLevel.ERROR, {
stack: err.stack,
path: req.path,
});
res.status(500).json({ error: 'Internal Server Error' });
});Metadata & User Context#
// Structured metadata
logger.log('Order placed', LogLevel.INFO, {
orderId: 'ORD-12345',
amount: 4500000,
currency: 'IRR',
});
// Associate logs with a user (4th parameter)
logger.log('Payment declined', LogLevel.ERROR, {
reason: 'insufficient_funds',
}, 'user_abc123');Manual Operations#
// Force flush all buffered logs
await logger.flush();
// Check buffer status
console.log('Pending logs:', logger.bufferSize);
// Dispose when shutting down (flushes remaining logs)
await logger.dispose();Configuration#
const logger = new LogService({
apiKey: 'ab_live_your_api_key', // Required
serverSecret: process.env.ABROVA_SERVER_SECRET, // Optional: ab_srv_..., sent with every request
sourceId: 'api-server', // Needed for batch sending (without it, logs are sent one by one)
sourceName: 'My API Server', // Optional display name
platform: 'nodejs', // Default: 'nodejs'
environment: 'production', // 'development', 'staging', 'production'
release: '1.2.3', // Optional app version
batchSize: 50, // Flush when buffer reaches this size
flushIntervalMs: 30000, // Max time before flush (default: 30000)
maxBufferSize: 1000, // Drop oldest logs when exceeded
debug: false, // Enable console debug output
});| Option | Type | Required | Description |
|---|---|---|---|
| apiKey | string | Yes | Your project API key |
| serverSecret | string | No | Your server secret (ab_srv_xxx), sent with every log request; keep it on the server |
| apiUrl | string | No | Trace API base URL; set it only for a self-hosted Trace API (default: "https://trace.abrova.ir") |
| sourceId | string | No | Source identifier (e.g., "api-server"). Without it, logs are sent one request each and failed sends are not retried |
| sourceName | string | No | Human-readable display name for this source |
| platform | string | No | Platform identifier (default: "nodejs") |
| environment | string | No | Environment name (default: "production") |
| release | string | No | App version identifier |
| batchSize | number | No | Flush at this buffer size (default: 50) |
| flushIntervalMs | number | No | Max ms before flush (default: 30000) |
| maxBufferSize | number | No | Drop oldest when exceeded (default: 1000) |
| debug | boolean | No | Enable console debug output (default: false) |
Best Practices#
Set meaningful sourceId values to identify log sources in the dashboard
Always call dispose() on SIGTERM/SIGINT to flush remaining logs (AbrovaTrace.flush() when you log through AbrovaTrace)
Add request logging middleware early in the Express pipeline
Add error logging middleware after all routes for comprehensive coverage
Include structured metadata (IDs, durations, paths) for better filtering
Pass user IDs to logs for easier debugging of user-specific issues