JSPM

@atrim/instrument-node

0.7.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 360
  • Score
    100M100P100Q103079F
  • License MIT

OpenTelemetry instrumentation for Node.js with centralized YAML configuration

Package Exports

  • @atrim/instrument-node
  • @atrim/instrument-node/effect

Readme

@atrim/instrument-node

Configuration layer for OpenTelemetry Node.js

npm version License: MIT

Built on @opentelemetry/auto-instrumentations-node, this package adds centralized YAML configuration, pattern-based span filtering, and first-class Effect-TS integration.

What This Package Adds

Feature Description
Pattern-based span filtering Control which spans are created via YAML config (unique to this package)
Centralized configuration Load instrumentation config from file, URL, or environment variable
Effect-TS integration Typed layers, annotation helpers for Effect users
Smart defaults Auto-detects service name, configures graceful shutdown

Note: Auto-instrumentation for Express, HTTP, Fastify, etc. comes from the underlying OpenTelemetry packages. This library configures and extends that functionality.

Installation

# Required
npm install @atrim/instrument-node @opentelemetry/api

# Optional: Effect-TS integration
npm install effect @effect/opentelemetry @effect/platform @effect/platform-node

Quick Start

import { initializeInstrumentation } from '@atrim/instrument-node'

await initializeInstrumentation()
// Done! Traces go to http://localhost:4318

Remote collector:

await initializeInstrumentation({
  otlp: { endpoint: 'https://otel-collector.company.com:4318' }
})

What gets auto-configured:

  • Service name from package.json
  • OTLP endpoint
  • Auto-instrumentation (HTTP, Express, Fastify, etc.)
  • Graceful shutdown

Effect-TS Integration

import { Effect, Layer } from 'effect'
import { EffectInstrumentationLive } from '@atrim/instrument-node/effect'

const program = Effect.gen(function* () {
  yield* myOperation.pipe(Effect.withSpan('app.operation'))
}).pipe(Effect.provide(EffectInstrumentationLive))

await Effect.runPromise(program)

Span annotation helpers:

import { annotateUser, annotateBatch, annotateCache } from '@atrim/instrument-node/effect'

const process = Effect.gen(function* () {
  yield* annotateUser('user-123', 'user@example.com')
  yield* annotateBatch(100, 10)
  yield* annotateCache(true, 'user:123')
  // ...
}).pipe(Effect.withSpan('batch.process'))

Available: annotateUser, annotateBatch, annotateDataSize, annotateLLM, annotateQuery, annotateHttpRequest, annotateError, annotatePriority, annotateCache

Effect Fiber Metadata Extraction

To add Effect fiber metadata (fiber ID, status, parent span info) to your spans, you must explicitly call the enrichment functions:

import { autoEnrichSpan, withAutoEnrichedSpan } from '@atrim/instrument-node/effect'

// Option 1: Call autoEnrichSpan() inside a span
const operation = Effect.gen(function* () {
  yield* autoEnrichSpan()  // Adds fiber metadata to current span
  // ... your logic
}).pipe(Effect.withSpan('app.operation'))

// Option 2: Use the convenience wrapper
const operation = withAutoEnrichedSpan('app.operation')(
  Effect.gen(function* () {
    // ... your logic (fiber metadata added automatically)
  })
)

Extracted metadata:

  • effect.fiber.id - Unique fiber thread name
  • effect.fiber.status - Current fiber status
  • effect.operation.root / effect.operation.nested - Operation hierarchy
  • effect.parent.span.id, effect.parent.span.name, effect.parent.trace.id - Parent span info

Note: The auto_extract_metadata config option is currently not implemented. Metadata extraction requires explicit calls as shown above. See [#issue] for tracking automatic extraction support.

Configuration (Optional)

Create instrumentation.yaml in your project root:

version: "1.0"
instrumentation:
  enabled: true
  instrument_patterns:
    - pattern: "^app\\."      # Trace app operations
  ignore_patterns:
    - pattern: "^health\\."   # Skip health checks
  http_filtering:
    enabled: true
    ignore_routes:
      - pattern: "^/health$"
      - pattern: "^/metrics$"

Priority order: Explicit config > ATRIM_INSTRUMENTATION_CONFIG env var > ./instrumentation.yaml > defaults

Runtimes & Frameworks

Runtime Version
Node.js 20+
Bun 1.0+
Deno 1.40+
Framework Support
Express Auto-instrumented (via OTel)
Fastify Auto-instrumented (via OTel)
Koa Auto-instrumented (via OTel)
Hono Manual spans
Effect-TS First-class integration (unique)

Version Compatibility

@atrim/instrument-node @opentelemetry/api effect
0.6.x ^1.0.0 (1.0 - 1.9+) ^3.0.0 (optional)

Notes:

  • @opentelemetry/api is the only required peer dependency
  • Effect packages are optional - core features work without them
  • The library is tested with @opentelemetry/api 1.9.x in CI

Troubleshooting

No traces? Check collector: docker run -p 4318:4318 otel/opentelemetry-collector

Too many traces? Add HTTP filtering patterns for health checks, metrics, OTLP exports.

Effect spans missing? Ensure you're using Effect.withSpan() and providing EffectInstrumentationLive.

Documentation

License

MIT