Back to Frameworks
💻

Node.js

Server-side analytics for Node.js with Express and Fastify middleware.

Installation

npm install @dwellcount/node

Basic Setup

Create a ServerTracker instance with your configuration:

import { ServerTracker } from '@dwellcount/node';

const tracker = new ServerTracker({
  siteId: 'YOUR_SITE_ID',
  endpoint: 'https://your-dashboard.com/api/ingest',
  serviceName: 'api-server',
  version: '2.1.0',        // Backend version (semver)
  commit: 'abc123',        // Git commit hash
});

// Track custom events
tracker.track('order_processed', {
  orderId: '123',
  total: 99.99,
});

// Flush before shutdown
process.on('SIGTERM', async () => {
  await tracker.flush();
  process.exit(0);
});

Express Middleware

Auto-track all HTTP requests with the Express middleware:

import express from 'express';
import { ServerTracker, expressMiddleware } from '@dwellcount/node';

const app = express();

const tracker = new ServerTracker({
  siteId: 'YOUR_SITE_ID',
  endpoint: 'https://your-dashboard.com/api/ingest',
  version: '2.1.0',
});

// Add middleware - automatically tracks all requests
app.use(expressMiddleware(tracker));

app.get('/api/users', (req, res) => {
  // Request timing and status automatically tracked
  res.json({ users: [] });
});

app.listen(3000);

Fastify Plugin

For Fastify apps, use the plugin:

import Fastify from 'fastify';
import { ServerTracker, fastifyPlugin } from '@dwellcount/node';

const fastify = Fastify();

const tracker = new ServerTracker({
  siteId: 'YOUR_SITE_ID',
  endpoint: 'https://your-dashboard.com/api/ingest',
  version: '2.1.0',
});

// Register plugin
fastify.register(fastifyPlugin(tracker));

fastify.get('/api/users', async (request, reply) => {
  return { users: [] };
});

fastify.listen({ port: 3000 });

Tracking Metrics

Track performance metrics and custom measurements:

// Track database query performance
const startTime = Date.now();
const users = await db.users.findMany();
tracker.trackQuery('users.findMany', Date.now() - startTime);

// Track API call performance
const apiStart = Date.now();
const response = await fetch('https://external-api.com/data');
tracker.trackApiCall('external-api', Date.now() - apiStart, response.status);

// Custom metrics
tracker.counter('api_requests', 1, { endpoint: '/users' });
tracker.gauge('active_connections', connectionPool.size);
tracker.histogram('response_time_ms', 45);

Logging Integration

Send structured logs to Dwellcount:

// Structured logging with levels
tracker.log('info', 'User logged in', { userId: '123' });
tracker.log('warn', 'Rate limit approaching', { current: 95, limit: 100 });
tracker.log('error', 'Payment failed', { error: 'Card declined', orderId: '456' });
tracker.log('debug', 'Cache miss', { key: 'user:123' });

// Convenience methods
tracker.info('Order processed successfully', { orderId: '789' });
tracker.warn('Low inventory', { productId: '123', remaining: 5 });
tracker.error('Database connection failed', { error: err.message });
tracker.debug('Query executed', { sql: 'SELECT * FROM users' });

Exposing Version Headers

Add version headers to responses for frontend correlation:

// Express middleware to add version headers
app.use((req, res, next) => {
  res.setHeader('X-App-Version', process.env.APP_VERSION || '1.0.0');
  res.setHeader('X-App-Commit', process.env.GIT_COMMIT || 'unknown');
  next();
});

// Frontend can capture these headers:
// const version = response.headers.get('X-App-Version');
// setBackendVersion({ version });

ServerTracker API

MethodDescription
track(event, props?)Track a custom event
trackQuery(name, durationMs)Track database query performance
trackApiCall(name, durationMs, status)Track external API call
counter(name, value, tags?)Increment a counter metric
gauge(name, value, tags?)Set a gauge metric
histogram(name, value, tags?)Record a histogram value
log(level, message, meta?)Log a structured message
flush()Flush pending events