npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rebrandly-otel

v0.4.19

Published

NodeJS OTEL wrapper by Rebrandly

Downloads

1,459

Readme

rebrandly-otel (Node.js)

OpenTelemetry SDK for Rebrandly Node.js services.

Installation

npm install rebrandly-otel

Environment Variables

| Variable | Required | Description | |----------|----------|-------------| | OTEL_SERVICE_NAME | Yes | Service identifier | | OTEL_SERVICE_APPLICATION | Yes | Application namespace (groups services) | | OTEL_EXPORTER_OTLP_ENDPOINT | Yes | OTLP collector endpoint | | OTEL_REPO_NAME | No | Repository name | | OTEL_COMMIT_ID | No | Commit ID for version tracking |

Lambda Handler

const { lambdaHandler, logger } = require('rebrandly-otel');

exports.handler = lambdaHandler({ name: 'my-function' })(async (event) => {
    logger.info('Processing', { eventId: event.id });
    return { statusCode: 200 };
});

AWS Message Handler

const { awsMessageHandler } = require('rebrandly-otel');

const processRecord = awsMessageHandler({ name: 'process-message' })(async (record) => {
    // trace context automatically extracted from message
    return { success: true };
});

Framework Middleware

Express

const express = require('express');
const { otel, setupExpress } = require('rebrandly-otel');

const app = express();
setupExpress(otel, app);

app.get('/api/users', (req, res) => res.json({ users: [] }));

Fastify

const fastify = require('fastify')();
const { otel, setupFastify } = require('rebrandly-otel');

setupFastify(otel, fastify);

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

Custom Instrumentation

Manual Spans

const { otel } = require('rebrandly-otel');

await otel.span('operation-name', { 'user.id': userId }, async (span) => {
    // your code
});

Structured Logging

const { logger } = require('rebrandly-otel');

logger.info('Order processed', { orderId, amount });

HTTP Client Tracing

Using fetch

const { fetchWithTracing } = require('rebrandly-otel');

const response = await fetchWithTracing('https://api.rebrandly.com/v1/links', {
    method: 'GET',
    headers: { 'Content-Type': 'application/json' }
});

Using axios

const axios = require('axios');
const { axiosWithTracing } = require('rebrandly-otel');

const tracedAxios = axiosWithTracing(axios.create());
const response = await tracedAxios.get('https://api.rebrandly.com/v1/links');

Manual Header Injection

const { injectTraceparent } = require('rebrandly-otel');

const headers = { 'Content-Type': 'application/json' };
injectTraceparent(headers);
// headers now includes traceparent

Custom Metrics

const { meter } = require('rebrandly-otel');

// Counter
const requestCounter = meter.meter.createCounter('http.requests.total', {
    description: 'Total HTTP requests'
});
requestCounter.add(1, { method: 'GET', endpoint: '/api/users' });

// Histogram
const duration = meter.meter.createHistogram('http.request.duration', {
    description: 'Request duration in ms',
    unit: 'ms'
});
duration.record(123, { endpoint: '/api/users' });

// Gauge
const gauge = meter.meter.createGauge('queue.size', {
    description: 'Current queue size'
});
gauge.record(42);

Database Instrumentation

Knex.js

const knex = require('knex');
const { instrumentKnex } = require('rebrandly-otel');

const db = knex({ client: 'postgresql', connection: { /* config */ } });
instrumentKnex(db);

// All queries now automatically traced
const users = await db('users').select('*');

AWS Message Handling (SQS/SNS)

Sending with Trace Context

const { getAwsMessageAttributes } = require('rebrandly-otel');

await sqs.send(new SendMessageCommand({
    QueueUrl: url,
    MessageBody: JSON.stringify(data),
    MessageAttributes: getAwsMessageAttributes()
}));

Receiving with Context Extraction

Use the awsMessageHandler wrapper (see AWS Message Handler above) - trace context is automatically extracted from message attributes.

Force Flush (Critical for Lambda)

const { forceFlush, shutdown } = require('rebrandly-otel');

// Before Lambda exits
await forceFlush(5000);
await shutdown();

Span Status Convenience Functions

Standalone functions for setting span status (following Python SDK pattern):

const { setSpanError, setSpanSuccess, setSpanUnset, getCurrentSpan } = require('rebrandly-otel');

// Set ERROR status on current span
setSpanError('Operation failed');           // String message
setSpanError(error);                        // Error object (records exception)
setSpanError('Failed', { exception: err }); // Message + exception

// Set ERROR on specific span
setSpanError('Failed', { span: mySpan });
setSpanError(error, { span: mySpan });

// Set OK status
setSpanSuccess();                           // Current span
setSpanSuccess(mySpan);                     // Specific span

// Set UNSET status (neutral/default)
setSpanUnset();                             // Current span
setSpanUnset(mySpan);                       // Specific span

Usage in Error Handling

const { lambdaHandler, setSpanError } = require('rebrandly-otel');

exports.handler = lambdaHandler({ name: 'my-function' })(async (event) => {
    try {
        const result = await processOrder(event);
        return { statusCode: 200, body: JSON.stringify(result) };
    } catch (error) {
        // Record error on current span
        setSpanError(error);
        throw error;
    }
});

Usage with Custom Spans

const { otel, setSpanError, setSpanSuccess } = require('rebrandly-otel');

await otel.span('database-query', async (span) => {
    try {
        const result = await db.query('SELECT * FROM users');
        setSpanSuccess(span);  // Explicit success
        return result;
    } catch (error) {
        setSpanError(error, { span });  // Record error on this span
        throw error;
    }
});

Cost Optimization (Errors-Only Filtering)

For high-volume services, filter out successful spans to reduce costs by 90-99%:

export OTEL_SPAN_ATTRIBUTES="span.filter=errors-only"

This adds the filter attribute to all spans. The OTEL Gateway drops successful spans while keeping all errors. Metrics are still generated from 100% of traces at the agent level.

Tips

  • Always call forceFlush() before Lambda exits
  • Use OTEL_DEBUG=true for local debugging
  • Keep metric cardinality low (< 1000 combinations)
  • Add 2-3 seconds buffer to Lambda timeout for flush

Troubleshooting

No Data Exported:

  • Verify OTEL_EXPORTER_OTLP_ENDPOINT is set
  • Enable OTEL_DEBUG=true for console output
  • Check network connectivity to collector

Missing Traces in Lambda:

  • Ensure forceFlush() is called before exit
  • Add 2-3s buffer to Lambda timeout
  • Use lambdaHandler with default auto-flush

Context Not Propagating:

  • Sending: Use getAwsMessageAttributes() for SQS/SNS
  • HTTP: Use injectTraceparent(headers) before requests
  • Receiving: Use awsMessageHandler wrapper

Best Practices

Do:

  • Use meaningful span names (fetch-user-profile, not handler)
  • Add business context (order.id, user.id) to spans
  • Flush telemetry before Lambda exits
  • Use bounded attribute values in metrics

Don't:

  • Store large payloads in span attributes (< 1KB)
  • Use high-cardinality attributes in metrics (user_id, request_id)
  • Hardcode service names (use env vars)
  • Skip error recording in catch blocks - use setSpanError(error) to capture exceptions