{"_id":"@bluealba/opentelemetry-nodejs","name":"@bluealba/opentelemetry-nodejs","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@bluealba/opentelemetry-nodejs","version":"1.0.0","description":"OpenTelemetry wrapper for NodeJs Apps","packageManager":"npm@11.6.2","displayName":"Opentelemetry implementation for NodeJs","author":{"name":"Blue Alba"},"private":false,"license":"PolyForm-Noncommercial-1.0.0","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","dev":"tsc --watch","clean":"rm -rf dist","lint":"biome check","lint:fix":"biome check --write","test":"jest","test:watch":"jest --watch","coverage":"jest --coverage"},"dependencies":{"@opentelemetry/api":"^1.9.0","@opentelemetry/auto-instrumentations-node":"^0.64.1","@opentelemetry/exporter-metrics-otlp-proto":"^0.205.0","@opentelemetry/exporter-trace-otlp-proto":"^0.205.0","@opentelemetry/host-metrics":"0.37.0","@opentelemetry/resources":"^2.1.0","@opentelemetry/sdk-metrics":"^2.1.0","@opentelemetry/sdk-node":"^0.201.1","@opentelemetry/sdk-trace-node":"2.0.1","@opentelemetry/semantic-conventions":"^1.37.0"},"devDependencies":{"@changesets/cli":"^2.29.5","@types/jest":"^29.5.2","biome":"^0.3.3","jest":"^29.5.0","pino-pretty":"^11.1.0","ts-jest":"^29.1.0"},"publishConfig":{"@bluealba:registry":"https://registry.npmjs.org/","access":"public"},"_id":"@bluealba/opentelemetry-nodejs@1.0.0","gitHead":"8f638de2350425b485a8721eca3c809112d83de9","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-ch+DrLH38IaMQEDeMI8c3AWrmnFxyETtKgRypYJaW8dFVSJk+NroDK4qXffxd9ds1GoMKJTD2BDLfHhaokyBfw==","shasum":"53c94a125aeb2978040270e595dc9baf5a7d0580","tarball":"https://registry.npmjs.org/@bluealba/opentelemetry-nodejs/-/opentelemetry-nodejs-1.0.0.tgz","fileCount":24,"unpackedSize":56814,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDtPGCZcTqeXOMyuHYK9SLUHUMihXUE6TJF2SreJXcxCgIhAO5ZQ2+k9IRBprTW9NuobgmItIyIiO+ho7KQ/A7kAKMF"}]},"_npmUser":{"name":"bluealba","email":"npm@bluealba.com"},"directories":{},"maintainers":[{"name":"bluealba","email":"npm@bluealba.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/opentelemetry-nodejs_1.0.0_1769179652841_0.47236310405744586"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-23T14:47:32.736Z","1.0.0":"2026-01-23T14:47:33.060Z","modified":"2026-01-23T14:47:33.278Z"},"maintainers":[{"name":"bluealba","email":"npm@bluealba.com"}],"description":"OpenTelemetry wrapper for NodeJs Apps","author":{"name":"Blue Alba"},"license":"PolyForm-Noncommercial-1.0.0","readme":"# @bluealba/opentelemetry-nodejs\n\nOpenTelemetry wrapper for Node.js that simplifies instrumentation and observability of applications.\n\n## Table of Contents\n\n- [Quick Start](#quick-start)\n- [Prerequisites](#prerequisites)\n- [Installation](#installation)\n- [Initial Setup](#initial-setup)\n- [Environment Variables](#environment-variables)\n- [Custom Traces](#custom-traces)\n- [Metrics](#available-metrics)\n- [Framework Examples](#framework-examples)\n- [Development](#development)\n- [Troubleshooting](#troubleshooting)\n- [Additional Resources](#additional-resources)\n\n## Quick Start\n\n```bash\n# 1. Install the package\nnpm install @bluealba/opentelemetry-nodejs\n\n# 2. Set up environment variables\nexport OTEL_ENABLED=true\nexport OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces\n\n# 3. Initialize in your application (must be FIRST import)\n# main.ts\nimport { startOtel } from \"@bluealba/opentelemetry-nodejs\";\nimport { name, version } from \"./package.json\";\n\nstartOtel(name, version);\n\n// Then import the rest of your app\nimport { app } from \"./app\";\n```\n\n## Prerequisites\n\nBefore using this package, you need to have an OpenTelemetry Collector running and listening on the port specified in `OTEL_EXPORTER_OTLP_ENDPOINT`.\n\nWe recommend https://hub.docker.com/r/otel/opentelemetry-collector-contrib as it has support for exporting traces to Datadog: https://docs.datadoghq.com/opentelemetry/setup/collector_exporter/install/\n\n## Installation\n\n```bash\nnpm install @bluealba/opentelemetry-nodejs\n```\n\n## Initial Setup\n\n⚠️ **Important**: OpenTelemetry must be initialized **before** any other imports and before the application bootstraps. It is recommended to be the first line of code executed.\n\n### Example with NestJS\n\n```typescript\n// main.ts\nimport { startOtel } from \"@bluealba/opentelemetry-nodejs\";\nimport { name, version } from \"../package.json\";\n\n// Initialize OpenTelemetry FIRST\nstartOtel(name, version);\n// Or\nstartOtel(name, version, customLoggerInstance);\n// Where customLoggerInstance is optional an can be any logger that support, info, log, warn and error methods\n\n// Then, import and start the application normally\nimport { DocumentBuilder, SwaggerModule } from \"@nestjs/swagger\";\nimport { json } from \"express\";\nimport { NestFactory } from \"@nestjs/core\";\nimport { ValidationPipe } from \"@nestjs/common\";\nimport { AppConfigService } from \"./app-config/app-config.service\";\nimport { AppModule } from \"./app.module\";\n\nasync function bootstrap() {\n  const app = await NestFactory.create(AppModule);\n\n  app.useGlobalPipes(\n    new ValidationPipe({\n      transform: true,\n    })\n  );\n\n  const configService = app.get(AppConfigService);\n  await app.listen(configService.get(\"PORT\"));\n}\n\nbootstrap();\n```\n\n## Environment Variables\n\n### Required Environment Variables\n\n| Variable                      | Description                        | Default                                |\n| ----------------------------- | ---------------------------------- | -------------------------------------- |\n| `OTEL_ENABLED`                | Enables/disables OpenTelemetry     | `false`                                |\n| `OTEL_EXPORTER_OTLP_ENDPOINT` | URL of the OpenTelemetry collector | None (SDK won't initialize if missing) |\n\n**Important**: Both `OTEL_ENABLED=true` AND `OTEL_EXPORTER_OTLP_ENDPOINT` must be set for OpenTelemetry to initialize. If the endpoint is missing, a warning will be logged but your application will continue to run normally.\n\n**What are auto-instrumentations?**  \nhttps://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node\n\nThe `node_autoinstrumentations` are a set of automatic instrumentations for popular Node.js libraries (HTTP, Express, PostgreSQL, MongoDB, Redis, KafkaJs, etc.). When enabled, OpenTelemetry automatically captures traces from these operations without requiring additional code.\n\n### Exporter Configuration\n\n| Variable                      | Description                                                     | Default | Example                              |\n| ----------------------------- | --------------------------------------------------------------- | ------- | ------------------------------------ |\n| `OTEL_EXPORTER_OTLP_ENDPOINT` | URL of the OpenTelemetry collector that will receive the traces | None    | `http://localhost:4318/v1/traces`    |\n| `OTEL_BATCH_EXPORT_TIMEOUT`   | Timeout to export collected traces (in ms)                      | `5000`  | `5000`                               |\n| `OTEL_BATCH_SCHEDULE_DELAY`   | Delay between trace exports (in ms)                             | `2000`  | `2000`                               |\n| `OTEL_BATCH_MAX_SIZE`         | Maximum size of the trace batch to be sent                      | `512`   | `512`                                |\n| `OTEL_QUEUE_SIZE`             | Queue size (number of traces to accumulate before sending them) | `2048`  | `2048`                               |\n\n### Optional Configuration\n\n| Variable                              | Default                         | Description                                                       |\n| ------------------------------------- | ------------------------------- | ----------------------------------------------------------------- |\n| `OTEL_APP_NAME`                       | Service name from `startOtel()` | Override service name                                             |\n| `OTEL_APP_NAMESPACE`                  | `namespace`                     | Service namespace for grouping                                    |\n| `TARGET_ENV`                          | `local`                         | Environment name (dev, staging, prod)                             |\n| `OTEL_NODE_AUTOINSTRUMENTATIONS`      | `false`                         | Enable auto-instrumentations for popular Node.js libraries        |\n| `OTEL_SAMPLING_RATIO`                 | `1`                             | Sampling ratio (0-1) for traces. 1 = 100% sampling               |\n| `OTEL_METRICS_ENABLED`                | `false`                         | Enable metrics exporter                                           |\n| `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` | Falls back to traces endpoint   | Metrics exporter endpoint (uses OTEL_EXPORTER_OTLP_ENDPOINT if not set) |\n| `OTEL_METRICS_EXPORT_INTERVAL`        | `60000`                         | How often metrics are exported (ms)                               |\n| `OTEL_ENABLE_HOST_METRICS`            | `false`                         | Enable host metrics exporter (needs OTEL_METRICS_ENABLED to init) |\n\n### Example `.env` File\n\n```bash\n# OpenTelemetry Configuration\nOTEL_ENABLED=true\nOTEL_NODE_AUTOINSTRUMENTATIONS=true\nOTEL_SAMPLING_RATIO=1\nOTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces\nOTEL_BATCH_EXPORT_TIMEOUT=5000\nOTEL_BATCH_SCHEDULE_DELAY=2000\nOTEL_BATCH_MAX_SIZE=512\nOTEL_QUEUE_SIZE=2048\n\n#Service identity\nOTEL_APP_NAME=your_app_name\nOTEL_APP_NAMESPACE=your_workspace\nTARGET_ENV=dev\n\n# Metrics Configuration\nOTEL_METRICS_ENABLED=true # to enable metrics export\nOTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://localhost:4318/v1/metrics # Specify the otel-collector EP\nOTEL_METRICS_EXPORT_INTERVAL=60000  # How often metrics are going to be exported in milliseconds\nOTEL_ENABLE_HOST_METRICS=true # to export host metrics (cpu metrics from the host running the node process)\n```\n\n## Custom Traces\n\n### `@Span()` Decorator\n\nYou can use the `@Span()` decorator to generate custom spans on specific methods:\n\n```typescript\nimport { Span } from \"@bluealba/opentelemetry-nodejs\";\n\nexport class MyService {\n  // Without arguments: automatically uses the class and method name\n  @Span()\n  async processData(data: any) {\n    // your logic...\n  }\n\n  // With custom name\n  @Span(\"custom-operation-name\")\n  async complexOperation() {\n    // your logic...\n  }\n}\n```\n\n### `withSpan()` Function\n\nFor functional/imperative code, use `withSpan` to manually create spans:\n\n```typescript\nimport { withSpan } from \"@bluealba/opentelemetry-nodejs\";\n\nasync function processOrder(orderId: string) {\n  return withSpan(\"process-order\", async () => {\n    // Your logic here\n    const order = await fetchOrder(orderId);\n    return order;\n  });\n}\n```\n\n### Adding Custom Attributes\n\nYou can add specific attributes to the current span using `setOtelAttribute`:\n\n```typescript\nimport { Span, setOtelAttribute } from \"@bluealba/opentelemetry-nodejs\";\n\nexport class PaymentService {\n  @Span()\n  async handlePayload(payload: any[]) {\n    // Your logic...\n\n    // Add custom attribute to the current span\n    setOtelAttribute(\"payload.count\", payload.length);\n    setOtelAttribute(\"payload.type\", typeof payload);\n\n    // More logic...\n  }\n}\n```\n\nCustom attributes are useful for:\n\n- Adding business context to traces\n- Facilitating filtering and searching in observability tools\n- Debugging and performance analysis\n\n## Available Metrics\n\nWhen `OTEL_METRICS_ENABLED=true`, the following metrics are automatically exported:\n\n### Runtime Metrics (from auto-instrumentations)\n\n- `nodejs_eventloop_delay_*` - Event loop delay (mean, p50, p90, p99)\n- `nodejs_eventloop_utilization` - Event loop utilization (0-1)\n- `v8js_memory_heap_*` - V8 heap memory usage\n- `v8js_gc_duration_*` - Garbage collection duration by type\n- `http_server_duration` - HTTP server request duration\n- `http_client_duration` - HTTP client request duration\n- `db_client_operation_duration` - Database operation duration\n\n### Host Metrics (when `OTEL_ENABLE_HOST_METRICS=true`)\n\n- `process_cpu_time` - Process CPU time (user/system)\n- `process_cpu_utilization` - Process CPU utilization (0-1)\n- `process_resident_memory_bytes` - Resident memory (RSS)\n- `process_heap_bytes` - Heap memory\n\nAll metrics include resource attributes: `service.name`, `service.namespace`, `service.version`, `deployment.environment`\n\n## Framework Examples\n\n### Express.js\n\n```typescript\n// server.ts\nimport { startOtel } from \"@bluealba/opentelemetry-nodejs\";\nimport { name, version } from \"./package.json\";\n\n// Initialize OpenTelemetry FIRST\nstartOtel(name, version);\n\n// Then import Express and other dependencies\nimport express from \"express\";\nimport { Span, setOtelAttribute } from \"@bluealba/opentelemetry-nodejs\";\n\nconst app = express();\napp.use(express.json());\n\n// Routes will be automatically instrumented if OTEL_NODE_AUTOINSTRUMENTATIONS=true\napp.get(\"/api/users/:id\", async (req, res) => {\n  // Add custom attributes to the auto-generated span\n  setOtelAttribute(\"user.id\", req.params.id);\n\n  const user = await getUserById(req.params.id);\n  res.json(user);\n});\n\napp.listen(3000, () => {\n  console.log(\"Server running on port 3000\");\n});\n```\n\n### Fastify\n\n```typescript\n// server.ts\nimport { startOtel } from \"@bluealba/opentelemetry-nodejs\";\nimport { name, version } from \"./package.json\";\n\n// Initialize OpenTelemetry FIRST\nstartOtel(name, version);\n\n// Then import Fastify\nimport Fastify from \"fastify\";\nimport { setOtelAttribute } from \"@bluealba/opentelemetry-nodejs\";\n\nconst fastify = Fastify({ logger: true });\n\nfastify.get(\"/api/health\", async (request, reply) => {\n  setOtelAttribute(\"health.status\", \"ok\");\n  return { status: \"healthy\" };\n});\n\nconst start = async () => {\n  try {\n    await fastify.listen({ port: 3000 });\n  } catch (err) {\n    fastify.log.error(err);\n    process.exit(1);\n  }\n};\n\nstart();\n```\n\n### Standalone Node.js Application\n\n```typescript\n// index.ts\nimport { startOtel, Span, withSpan, setOtelAttribute } from \"@bluealba/opentelemetry-nodejs\";\nimport { name, version } from \"./package.json\";\n\n// Initialize OpenTelemetry FIRST\nstartOtel(name, version);\n\nclass DataProcessor {\n  @Span(\"process-batch\")\n  async processBatch(items: any[]) {\n    setOtelAttribute(\"batch.size\", items.length);\n\n    for (const item of items) {\n      await this.processItem(item);\n    }\n  }\n\n  @Span()\n  async processItem(item: any) {\n    setOtelAttribute(\"item.id\", item.id);\n    // Processing logic...\n  }\n}\n\n// Using withSpan for functional code\nasync function main() {\n  await withSpan(\"main-operation\", async () => {\n    const processor = new DataProcessor();\n    await processor.processBatch([{ id: 1 }, { id: 2 }]);\n  });\n}\n\nmain();\n```\n\n## Development\n\nThis section is for developers who want to contribute to this library or run it locally.\n\n### Setup Development Environment\n\n```bash\n# Clone the repository\ngit clone <repository-url>\ncd opentelemetry-nodejs\n\n# Install dependencies\nnpm install\n\n# Build the project\nnpm run build\n```\n\n### Development Commands\n\n```bash\n# Watch mode for development\nnpm run dev\n\n# Run tests\nnpm test\n\n# Run tests in watch mode\nnpm run test:watch\n\n# Generate coverage report\nnpm run coverage\n\n# Lint code\nnpm run lint\n\n# Auto-fix linting issues\nnpm run lint:fix\n\n# Clean build artifacts\nnpm run clean\n```\n\n### Running Tests\n\nThis project uses Jest for testing. Test files follow the pattern `*.spec.ts` and are located alongside source files in `src/`.\n\n```bash\n# Run all tests\nnpm test\n\n# Run specific test file\nnpm test -- src/otel/otel.spec.ts\n\n# Run tests matching a pattern\nnpm test -- -t \"should initialize SDK\"\n\n# Run with coverage\nnpm run coverage\n```\n\n### Project Structure\n\n```\nsrc/\n├── index.ts                  # Public API exports\n└── otel/\n    ├── otel.ts              # Main initialization logic\n    ├── otel.spec.ts         # Tests for otel.ts\n    ├── otel-config.ts       # Environment variable configuration\n    ├── otel-config.spec.ts  # Tests for otel-config.ts\n    ├── otel.helper.ts       # User-facing utilities (@Span, withSpan, etc.)\n    └── otel.helper.spec.ts  # Tests for otel.helper.ts\n```\n\n### Making Changes\n\n1. Create a new branch for your feature/fix\n2. Make your changes and add tests\n3. Run `npm test` to ensure all tests pass\n4. Run `npm run lint:fix` to format code\n5. Commit your changes following conventional commits\n6. Submit a pull request\n\n## Troubleshooting\n\n### OpenTelemetry is not initializing\n\n**Problem**: No traces are being sent to the collector.\n\n**Solutions**:\n1. Verify `OTEL_ENABLED=true` is set\n2. Verify `OTEL_EXPORTER_OTLP_ENDPOINT` is set and reachable\n3. Check that `startOtel()` is called BEFORE any other imports\n4. Check application logs for initialization warnings\n\n```bash\n# Test if collector is reachable\ncurl -X POST http://localhost:4318/v1/traces \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'\n```\n\n### Spans are not showing custom attributes\n\n**Problem**: Custom attributes added with `setOtelAttribute()` are not visible in traces.\n\n**Solutions**:\n1. Ensure `OTEL_ENABLED=true`\n2. Verify you're calling `setOtelAttribute()` within an active span (inside a `@Span()` decorated method or `withSpan()` callback)\n3. Check that the attribute name and value are valid\n\n### Auto-instrumentation not working\n\n**Problem**: HTTP requests, database queries, etc. are not being traced automatically.\n\n**Solutions**:\n1. Set `OTEL_NODE_AUTOINSTRUMENTATIONS=true`\n2. Ensure `startOtel()` is called BEFORE importing libraries like Express, PostgreSQL clients, etc.\n3. Verify the library you're using is supported by [@opentelemetry/auto-instrumentations-node](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node)\n\n### Metrics not being exported\n\n**Problem**: Metrics are not appearing in your observability platform.\n\n**Solutions**:\n1. Set `OTEL_METRICS_ENABLED=true`\n2. Verify `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` is set (or it will fall back to the traces endpoint)\n3. Check that your collector is configured to receive metrics\n4. For host metrics, ensure `OTEL_ENABLE_HOST_METRICS=true`\n\n### TypeScript compilation errors\n\n**Problem**: Getting type errors when using the library.\n\n**Solutions**:\n1. Ensure you have `@types/node` installed in your project\n2. Check that your `tsconfig.json` includes the necessary compiler options:\n   ```json\n   {\n     \"compilerOptions\": {\n       \"experimentalDecorators\": true,\n       \"emitDecoratorMetadata\": true\n     }\n   }\n   ```\n\n### Initialization order issues\n\n**Problem**: Getting errors or unexpected behavior.\n\n**Solution**: Ensure OpenTelemetry initialization happens FIRST. Common mistake:\n\n```typescript\n// WRONG - imports before initialization\nimport { NestFactory } from \"@nestjs/core\";\nimport { startOtel } from \"@bluealba/opentelemetry-nodejs\";\nstartOtel(\"app\", \"1.0.0\");\n\n// CORRECT - initialization before imports\nimport { startOtel } from \"@bluealba/opentelemetry-nodejs\";\nstartOtel(\"app\", \"1.0.0\");\nimport { NestFactory } from \"@nestjs/core\";\n```\n\n### Collector connection refused\n\n**Problem**: Error connecting to the OpenTelemetry collector.\n\n**Solutions**:\n1. Verify the collector is running: `docker ps` or check your collector service\n2. Check the endpoint URL format: `http://host:port/v1/traces` (note the `/v1/traces` path)\n3. Ensure the port is accessible from your application\n4. Check firewall rules if running in containers or different networks\n\n### Performance impact\n\n**Problem**: Concerned about performance overhead.\n\n**Information**:\n- Adjust `OTEL_SAMPLING_RATIO` to sample fewer traces (e.g., `0.1` for 10%)\n- Increase `OTEL_BATCH_SCHEDULE_DELAY` to batch spans less frequently\n- Disable auto-instrumentations if not needed: `OTEL_NODE_AUTOINSTRUMENTATIONS=false`\n- Disable metrics if only traces are needed: `OTEL_METRICS_ENABLED=false`\n\n## Additional Resources\n\n- [Official OpenTelemetry Documentation](https://opentelemetry.io/docs/)\n- [OpenTelemetry for Node.js](https://opentelemetry.io/docs/instrumentation/js/)\n","readmeFilename":"README.md","_rev":"1-468ab0dd3e522aa03b3817f4816840e8"}