Official Node.js SDK for LogTide with automatic batching, retry logic, circuit breaker, query API, live streaming, and middleware support.
- Automatic batching with configurable size and interval
- Retry logic with exponential backoff
- Circuit breaker pattern for fault tolerance
- Max buffer size with drop policy to prevent memory leaks
- Query API for searching and filtering logs
- Live tail with Server-Sent Events (SSE)
- Trace ID context for distributed tracing
- Global metadata added to all logs
- Structured error serialization
- Internal metrics (logs sent, errors, latency, etc.)
- Express & Fastify middleware for auto-logging HTTP requests
- Full TypeScript support with strict types
npm install @logtide/sdk-node
# or
pnpm add @logtide/sdk-node
# or
yarn add @logtide/sdk-nodeimport { LogTideClient } from '@logtide/sdk-node';
const client = new LogTideClient({
apiUrl: 'http://localhost:8080',
apiKey: 'lp_your_api_key_here',
});
// Send logs
client.info('api-gateway', 'Server started', { port: 3000 });
client.error('database', 'Connection failed', new Error('Timeout'));
// Graceful shutdown
process.on('SIGINT', async () => {
await client.close();
process.exit(0);
});| Option | Type | Default | Description |
|---|---|---|---|
apiUrl |
string |
required | Base URL of your LogTide instance |
apiKey |
string |
required | Project API key (starts with lp_) |
batchSize |
number |
100 |
Number of logs to batch before sending |
flushInterval |
number |
5000 |
Interval in ms to auto-flush logs |
| Option | Type | Default | Description |
|---|---|---|---|
maxBufferSize |
number |
10000 |
Max logs in buffer (prevents memory leak) |
maxRetries |
number |
3 |
Max retry attempts on failure |
retryDelayMs |
number |
1000 |
Initial retry delay (exponential backoff) |
circuitBreakerThreshold |
number |
5 |
Failures before opening circuit |
circuitBreakerResetMs |
number |
30000 |
Time before retrying after circuit opens |
enableMetrics |
boolean |
true |
Track internal metrics |
debug |
boolean |
false |
Enable debug logging to console |
globalMetadata |
object |
{} |
Metadata added to all logs |
autoTraceId |
boolean |
false |
Auto-generate trace IDs for logs |
const client = new LogTideClient({
apiUrl: 'http://localhost:8080',
apiKey: 'lp_your_api_key_here',
// Batching
batchSize: 100,
flushInterval: 5000,
// Buffer management
maxBufferSize: 10000,
// Retry with exponential backoff (1s -> 2s -> 4s)
maxRetries: 3,
retryDelayMs: 1000,
// Circuit breaker
circuitBreakerThreshold: 5,
circuitBreakerResetMs: 30000,
// Metrics & debugging
enableMetrics: true,
debug: true,
// Global context
globalMetadata: {
env: process.env.NODE_ENV,
version: '1.0.0',
hostname: process.env.HOSTNAME,
},
// Auto trace IDs
autoTraceId: false,
});client.debug('service-name', 'Debug message');
client.info('service-name', 'Info message', { userId: 123 });
client.warn('service-name', 'Warning message');
client.error('service-name', 'Error message', { custom: 'data' });
client.critical('service-name', 'Critical message');The SDK automatically serializes Error objects:
try {
throw new Error('Database timeout');
} catch (error) {
// Automatically serializes error with stack trace
client.error('database', 'Query failed', error);
}Generated log metadata:
{
"error": {
"name": "Error",
"message": "Database timeout",
"stack": "Error: Database timeout\n at ..."
}
}client.log({
service: 'custom-service',
level: 'info',
message: 'Custom log',
time: new Date().toISOString(),
metadata: { key: 'value' },
trace_id: 'custom-trace-id',
});Track requests across services with trace IDs.
client.setTraceId('request-123');
client.info('api', 'Request received');
client.info('database', 'Querying users');
client.info('api', 'Response sent');
client.setTraceId(null); // Clear contextclient.withTraceId('request-456', () => {
client.info('api', 'Processing in context');
client.warn('cache', 'Cache miss');
});
// Trace ID automatically restored after blockclient.withNewTraceId(() => {
client.info('worker', 'Background job started');
client.info('worker', 'Job completed');
});Search and retrieve logs programmatically.
const result = await client.query({
service: 'api-gateway',
level: 'error',
from: new Date(Date.now() - 24 * 60 * 60 * 1000), // Last 24h
to: new Date(),
limit: 100,
offset: 0,
});
console.log(`Found ${result.total} logs`);
console.log(result.logs);const result = await client.query({
q: 'timeout',
limit: 50,
});const logs = await client.getByTraceId('trace-123');
console.log(`Trace has ${logs.length} logs`);const stats = await client.getAggregatedStats({
from: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // Last 7 days
to: new Date(),
interval: '1h', // '1m' | '5m' | '1h' | '1d'
service: 'api-gateway', // Optional
});
console.log(stats.timeseries); // Time-bucketed counts
console.log(stats.top_services); // Top services by log count
console.log(stats.top_errors); // Most common errorsStream logs in real-time using Server-Sent Events.
const cleanup = client.stream({
service: 'api-gateway', // Optional filter
level: 'error', // Optional filter
onLog: (log) => {
console.log(`[${log.time}] ${log.level}: ${log.message}`);
},
onError: (error) => {
console.error('Stream error:', error);
},
});
// Stop streaming when done
setTimeout(() => {
cleanup();
}, 60000);Track SDK performance and health.
const metrics = client.getMetrics();
console.log(metrics.logsSent); // Total logs sent
console.log(metrics.logsDropped); // Logs dropped (buffer full)
console.log(metrics.errors); // Send errors
console.log(metrics.retries); // Retry attempts
console.log(metrics.avgLatencyMs); // Average send latency
console.log(metrics.circuitBreakerTrips); // Circuit breaker openings
// Get circuit breaker state
console.log(client.getCircuitBreakerState()); // 'CLOSED' | 'OPEN' | 'HALF_OPEN'
// Reset metrics
client.resetMetrics();LogTide provides ready-to-use middleware for popular frameworks.
Auto-log all HTTP requests and responses.
import express from 'express';
import { LogTideClient, logTideMiddleware } from '@logtide/sdk-node';
const app = express();
const logger = new LogTideClient({
apiUrl: 'http://localhost:8080',
apiKey: 'lp_your_api_key_here',
});
app.use(
logTideMiddleware({
client: logger,
serviceName: 'express-api',
logRequests: true,
logResponses: true,
logErrors: true,
includeHeaders: false,
includeBody: false,
skipHealthCheck: true,
skipPaths: ['/metrics'],
}),
);
app.get('/', (req, res) => {
res.json({ message: 'Hello' });
});
app.listen(3000);Logged automatically:
- Request:
GET /users/123 - Response:
GET /users/123 200 (45ms) - Errors:
Request error: Internal Server Error
import Fastify from 'fastify';
import { LogTideClient, logTideFastifyPlugin } from '@logtide/sdk-node';
const fastify = Fastify();
const logger = new LogTideClient({
apiUrl: 'http://localhost:8080',
apiKey: 'lp_your_api_key_here',
});
await fastify.register(logTideFastifyPlugin, {
client: logger,
serviceName: 'fastify-api',
logRequests: true,
logResponses: true,
logErrors: true,
skipHealthCheck: true,
});
fastify.get('/', async () => ({ message: 'Hello' }));
await fastify.listen({ port: 3000 });See the examples/ directory for complete working examples:
- basic.ts - Simple usage
- advanced.ts - All advanced features
- express-middleware.ts - Express integration
- fastify-plugin.ts - Fastify integration
process.on('SIGINT', async () => {
await client.close(); // Flushes buffered logs
process.exit(0);
});
process.on('SIGTERM', async () => {
await client.close();
process.exit(0);
});const client = new LogTideClient({
apiUrl: 'http://localhost:8080',
apiKey: 'lp_your_api_key_here',
globalMetadata: {
env: process.env.NODE_ENV,
version: require('./package.json').version,
region: process.env.AWS_REGION,
pod: process.env.HOSTNAME,
},
});const client = new LogTideClient({
apiUrl: 'http://localhost:8080',
apiKey: 'lp_your_api_key_here',
debug: process.env.NODE_ENV === 'development',
});setInterval(() => {
const metrics = client.getMetrics();
if (metrics.logsDropped > 0) {
console.warn(`Logs dropped: ${metrics.logsDropped}`);
}
if (metrics.circuitBreakerTrips > 0) {
console.error('Circuit breaker is OPEN!');
}
}, 60000);Fully typed with strict TypeScript support:
import type {
LogTideClient,
LogEntry,
QueryOptions,
LogsResponse,
ClientMetrics,
} from '@logtide/sdk-node';Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
MIT License - see LICENSE for details.
