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

@cobre-npm/library-nodejs-telemetry

v1.4.0

Published

Nodejs Cobre telemetry library with OpenTelemetry

Readme

Telemetry library Node.js

A specialized Node.js library for OpenTelemetry-based telemetry and observability. This library provides comprehensive tracing and logging capabilities using OpenTelemetry, designed to streamline observability across your Node.js applications.

Features

  • Distributed Tracing - Complete OpenTelemetry tracing with AWS X-Ray, W3C Trace Context, and Baggage propagation
  • Structured Logging - OpenTelemetry-based logging with automatic context propagation
  • FaaS Metrics - Opt-in faas.* golden signals for AWS Lambda handlers, matching the Python telemetry library
  • AWS Integration - Built-in support for AWS Lambda, AWS SDK, Express, and HTTP instrumentation
  • OTLP Export - Native support for OTLP (OpenTelemetry Protocol) exporters for traces and logs

Installation

npm install @cobre-npm/library-nodejs-telemetry
# or
pnpm install @cobre-npm/library-nodejs-telemetry

Examples

Tracing

Initialize OpenTelemetry tracing in your application to enable distributed tracing across your services.

import { TracingAdapter } from '@cobre-npm/library-nodejs-telemetry/dist'
import packageJson from './package.json'

const serviceName = 'my-service'
const serviceVersion = packageJson.version

// Initialize tracing with service configuration
TracingAdapter.init({ serviceName, serviceVersion })

// Graceful shutdown
process.on('SIGTERM', async () => {
  await TracingAdapter.shutdown()
  process.exit(0)
})

Features:

  • Automatic instrumentation for HTTP, Express, AWS Lambda, and AWS SDK
  • AWS X-Ray propagation support
  • W3C Trace Context and Baggage propagation
  • OTLP HTTP exporter for traces

Supported Instrumentations:

  • @opentelemetry/instrumentation-http - HTTP requests
  • @opentelemetry/instrumentation-express - Express.js framework
  • @opentelemetry/instrumentation-aws-lambda - AWS Lambda functions
  • @opentelemetry/instrumentation-aws-sdk - AWS SDK calls

FaaS Metrics

TracingAdapter.init wires an OTLP metric exporter, but instruments have to be recorded explicitly. withFaasMetrics wraps an AWS Lambda handler and records the faas.* golden signals the New Relic "Golden Signals - FaaS (Lambda)" dashboard queries by name.

Opt-in and additive: an unwrapped handler behaves exactly as before, and tracing is untouched — AwsLambdaInstrumentation still owns the invocation span.

import { withFaasMetrics } from '@cobre-npm/library-nodejs-telemetry/dist'

const handler = async (event, context) => {
  return { statusCode: 200, body: 'ok' }
}

// Apply outermost, on the function AWS invokes
exports.handler = withFaasMetrics(handler)

Metrics recorded per invocation:

| Metric | Type | Unit | When | | ------ | ---- | ---- | ---- | | faas.invoke_duration | histogram | s | always | | faas.invocations | counter | — | handler succeeded | | faas.errors | counter | — | handler threw, or returned a 5xx statusCode | | faas.coldstarts | counter | — | first invocation in the container |

Attributes on every data point:

faas.trigger (http, pubsub, datasource, timer or other), inferred from the event shape. HTTP triggers — API Gateway v1 and v2, Function URLs and Application Load Balancer — add http.request.method and http.route; SQS and SNS triggers add the messaging.* attributes.

http.route is the route template (/v1/items/{id}), taken from resource on v1 or routeKey on v2, and is omitted when the event carries no template. The resolved path is never used: as a metric dimension it produces one time series per path parameter value. Put the resolved path on the span instead, where cardinality is free.

Every invocation also adds http.response.status_code when the handler returned one, and error.type when it failed. These land on faas.invoke_duration as well as on the counters, so the histogram is partitioned by status code and error class — useful for reading the latency of 5xx responses separately, at the cost of extra series on the highest-volume instrument.

Metrics are force-flushed before the handler returns, since a Lambda container freezes immediately afterwards and the periodic reader would never export them. That flush is a request to the collector, so it adds to the invocation's billed duration.

Requirements:

  • TracingAdapter.init must have run before the first invocation. Instruments are created lazily for this reason — creating them earlier would bind them to the API's no-op provider.
  • Set COBRE_ENV on the function, or deployment.environment.name is reported as UNKNOWN and the dashboard's environment filter will not list the service.

Metric temporality needs no configuration on Lambda: TracingAdapter.init defaults OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE to delta when AWS_LAMBDA_FUNCTION_NAME is present, because New Relic expects delta and cumulative counters reset unpredictably as Lambda recycles containers. Setting the variable explicitly still wins, and long-lived services outside Lambda keep the exporter's own default.

flushFaasMetrics() and getFaasInstruments() are also exported, for handlers that record their own data points onto the same series outside the wrapper.

Logging

The logging utility provides structured logging capabilities with OpenTelemetry support. It follows RFC5424 severity levels:

  • emerg: 0 - Emergency
  • alert: 1 - Alert
  • crit: 2 - Critical
  • error: 3 - Error
  • warning: 4 - Warning
  • notice: 5 - Notice
  • info: 6 - Informational
  • debug: 7 - Debug

Basic Usage

import { log } from '@cobre-npm/library-nodejs-telemetry/dist'

// Log different severity levels
log.info({ message: 'Application started', content: { port: 3000 } })
log.error({ message: 'Failed to connect', content: { error: 'Connection timeout' } })
log.warning({ message: 'Rate limit approaching', content: { remaining: 10 } })
log.debug({ message: 'Processing request', content: { requestId: '123' } })

Initialize OpenTelemetry Logging

Initialize OpenTelemetry logging with your service name and version:

import { log } from '@cobre-npm/library-nodejs-telemetry/dist'
import packageJson from './package.json'

const serviceName = 'my-service'
const serviceVersion = packageJson.version

// Initialize OpenTelemetry logging
log.initOpentelemetry(serviceName, serviceVersion)

// Or use automatic initialization with default values
log.initializeLogger()

// Or specify custom service name and version
log.initializeLogger('my-service', '1.0.0')

Express Middleware

Use the built-in Express middleware to automatically extract and store user context from JWT tokens:

import express from 'express'
import { log } from '@cobre-npm/library-nodejs-telemetry/dist'

const app = express()

// Add logging middleware before your routes
app.use(log.loggerMiddleware)

app.get('/api/users', (req, res) => {
  // User context (email, userId, clientId) is automatically available in logs
  log.info({ message: 'Fetching users' })
  res.json({ users: [] })
})

The middleware automatically extracts:

  • email - User email from JWT token
  • name (userId) - User name/ID from JWT token
  • client_id - Client ID from request headers

All subsequent logs will include this context automatically.

Logging with Attributes

Add custom attributes to your logs:

import { log } from '@cobre-npm/library-nodejs-telemetry/dist'

log.info({
  message: 'User action performed',
  content: { action: 'purchase', amount: 100 },
  attrs: { 
    userId: 'user123',
    sessionId: 'session456',
    feature: 'checkout'
  }
})

Complete Setup Example

Here's a complete example of setting up both tracing and logging in an Express application:

import express from 'express'
import dotenv from 'dotenv'
import { TracingAdapter, log } from '@cobre-npm/library-nodejs-telemetry/dist'
import packageJson from './package.json'

// Load environment variables
dotenv.config()

const app = express()
const serviceName = 'my-service'
const serviceVersion = packageJson.version

// Initialize OpenTelemetry Tracing
TracingAdapter.init({ serviceName, serviceVersion })

// Initialize OpenTelemetry Logging
log.initOpentelemetry(serviceName, serviceVersion)
// Or use automatic initialization
log.initializeLogger(serviceName, serviceVersion)

// Add logging middleware
app.use(log.loggerMiddleware)

// Your routes
app.get('/health', (req, res) => {
  log.info({ message: 'Health check requested' })
  res.json({ status: 'ok' })
})

// Graceful shutdown
process.on('SIGTERM', async () => {
  log.info({ message: 'Shutting down gracefully' })
  await TracingAdapter.shutdown()
  process.exit(0)
})

app.listen(3000, () => {
  log.info({ message: 'Server started', content: { port: 3000 } })
})

logMaskedObject

Utility function to mask sensitive data in logs while keeping a portion of the original value for identification purposes.

import { logMaskedObject } from '@cobre-npm/library-nodejs-telemetry/dist'

logMaskedObject(
  {
    username: 'DanielHernandez',
    email: '[email protected]',
    creditCard: '1234567890123456',
    phone: '+1234567890'
  },
  5  // Keep last 5 characters
)

Output (logged as info):

{
  "username": "*****-*****-*****-*****andez",
  "email": "*****-*****-*****-*****@example.com",
  "creditCard": "*****-*****-*****-3456",
  "phone": "*****-*****-*****-67890"
}

Environment Variables

This library uses OpenTelemetry for all telemetry operations. None of the variables below are required — the library falls back to a default service configuration when they are absent.

| Variable | Read by | Effect | | -------- | ------- | ------ | | COBRE_ENV | tracing, logging | Value of the deployment.environment.name resource attribute. Defaults to UNKNOWN. | | OTEL_EXPORTER_OTLP_ENDPOINT | OTLP exporters | Collector to export traces, logs and metrics to. | | OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | metric exporter | Defaults to delta on AWS Lambda, set by TracingAdapter.init. See FaaS Metrics. | | OTEL_SEMCONV_STABILITY_OPT_IN | HTTP instrumentation | Defaults to http when unset. | | NODE_ENV | logging | When it contains local, logs are also mirrored to the console. |

Architecture

Tracing Module

src/tracing/
├── adapter/
│   ├── tracing.adapter.ts    # Main tracing adapter
│   └── config.ts              # Service configuration
├── domain/
│   └── port/
│       └── out/
│           └── tracing.port   # Port interface
└── entrypoints/
    └── index.ts               # Public exports

Metrics Module

src/metrics/
├── adapter/
│   ├── faasMeters.ts          # faas.* instruments and force flush
│   └── faasMetrics.adapter.ts # withFaasMetrics handler wrapper
├── utils/
│   └── faasAttributes.utils.ts # Trigger classification and attribute keys
└── entrypoints/
    └── index.ts               # Public exports

Logging Module

src/logging/
├── adapter/
│   └── logging.adapter.ts     # Main logging adapter
├── domain/
│   ├── interfaces/
│   │   └── tokenDecoded.interface.ts  # Token interface
│   └── loggerProps.ts         # Logger properties
└── entrypoints/
    └── index.ts               # Public exports

Dependencies

OpenTelemetry Packages

  • @opentelemetry/api - Core OpenTelemetry API
  • @opentelemetry/api-logs - Logging API
  • @opentelemetry/sdk-node - Node.js SDK
  • @opentelemetry/sdk-logs - Logging SDK
  • @opentelemetry/exporter-trace-otlp-http - OTLP HTTP trace exporter
  • @opentelemetry/exporter-logs-otlp-proto - OTLP Proto log exporter
  • @opentelemetry/instrumentation-* - Various instrumentations
  • @opentelemetry/propagator-aws-xray-lambda - AWS X-Ray propagation
  • @opentelemetry/resources - Resource detection
  • @opentelemetry/semantic-conventions - Semantic conventions

Other Dependencies

  • jwt-decode - JWT token decoding

Build

npm run build

This will create the compiled output in the dist/ directory.

License

ISC