{"_id":"@almasemilius/nest-otel-telemetry","_rev":"3-46a2a4e691ae8248bcbb39006a27c51c","name":"@almasemilius/nest-otel-telemetry","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"@almasemilius/nest-otel-telemetry","version":"1.0.0","keywords":[],"author":"","license":"ISC","_id":"@almasemilius/nest-otel-telemetry@1.0.0","maintainers":[{"name":"almasemilius","email":"almasemilius@gmail.com"}],"dist":{"shasum":"3143219d1a63760976498e8361bacdd991303c35","tarball":"https://registry.npmjs.org/@almasemilius/nest-otel-telemetry/-/nest-otel-telemetry-1.0.0.tgz","fileCount":26,"integrity":"sha512-jJmY2PCgYVgjCyc8Tu8O2tzCfahdn+Ycs64qN54ULWvSwga608m5k4MSXa2iljsr7b7agNmnkU2EhO8E0/lkyQ==","signatures":[{"sig":"MEQCH3ak8zVjSchTX21gC11nbLkJpShIgCDllYqsxK2g0okCIQD69GPxW5yovCAcKGBiqSl1iPyPwD7uVL2Lp5KmTnN6qw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":25072},"main":"index.js","scripts":{"build":"rimraf dist && tsc -p tsconfig.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"almasemilius","email":"almasemilius@gmail.com"},"_npmVersion":"10.8.2","directories":{},"_nodeVersion":"20.19.2","dependencies":{"@nestjs/core":"^11.1.19","@nestjs/common":"^11.1.19","reflect-metadata":"^0.2.2","@opentelemetry/api":"^1.9.1","@opentelemetry/api-logs":"^0.214.0","@opentelemetry/sdk-logs":"^0.214.0","@opentelemetry/sdk-node":"^0.214.0","@opentelemetry/resources":"^2.6.1","@opentelemetry/sdk-metrics":"^2.6.1","@opentelemetry/sdk-trace-node":"^2.6.1","@opentelemetry/exporter-logs-otlp-grpc":"^0.214.0","@opentelemetry/exporter-logs-otlp-proto":"^0.214.0","@opentelemetry/exporter-trace-otlp-grpc":"^0.214.0","@opentelemetry/exporter-trace-otlp-proto":"^0.214.0","@opentelemetry/auto-instrumentations-node":"^0.72.0","@opentelemetry/exporter-metrics-otlp-grpc":"^0.214.0","@opentelemetry/exporter-metrics-otlp-proto":"^0.214.0"},"_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.1.3","typescript":"^6.0.2","@types/node":"^25.6.0"},"_npmOperationalInternal":{"tmp":"tmp/nest-otel-telemetry_1.0.0_1776755282982_0.15395511459134292","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@almasemilius/nest-otel-telemetry","version":"1.0.1","keywords":[],"author":"","license":"ISC","_id":"@almasemilius/nest-otel-telemetry@1.0.1","maintainers":[{"name":"almasemilius","email":"almasemilius@gmail.com"}],"dist":{"shasum":"6201d3d176581fa407a72f9163b6ea944979e019","tarball":"https://registry.npmjs.org/@almasemilius/nest-otel-telemetry/-/nest-otel-telemetry-1.0.1.tgz","fileCount":28,"integrity":"sha512-NLICxpV3t5hlAIPKp7XzhTLEOpDsL+xe9rb6dEpMO3ELQTUjjaLwfrixg30TpSvYs4LD91DWijwwnXlO5PSqVw==","signatures":[{"sig":"MEYCIQCSOIqzDyC6bAeg1fg/6qSagSkwGbzBhHTi16OOXwLj/wIhAIflzyC/BaSe/3jMxgXOjYE13WJMUy4LvAYU04vyq356","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":35205},"main":"index.js","scripts":{"build":"rimraf dist && tsc -p tsconfig.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"almasemilius","email":"almasemilius@gmail.com"},"_npmVersion":"10.8.2","description":"A NestJS package that bootstraps OpenTelemetry for traces, metrics, and logs, and exposes a global `TelemetryService` for app-level instrumentation.","directories":{},"_nodeVersion":"20.19.2","dependencies":{"@nestjs/core":"^11.1.19","@nestjs/common":"^11.1.19","reflect-metadata":"^0.2.2","@opentelemetry/api":"^1.9.1","@opentelemetry/api-logs":"^0.214.0","@opentelemetry/sdk-logs":"^0.214.0","@opentelemetry/sdk-node":"^0.214.0","@opentelemetry/resources":"^2.6.1","@opentelemetry/sdk-metrics":"^2.6.1","@opentelemetry/sdk-trace-node":"^2.6.1","@opentelemetry/exporter-logs-otlp-grpc":"^0.214.0","@opentelemetry/exporter-logs-otlp-proto":"^0.214.0","@opentelemetry/exporter-trace-otlp-grpc":"^0.214.0","@opentelemetry/exporter-trace-otlp-proto":"^0.214.0","@opentelemetry/auto-instrumentations-node":"^0.72.0","@opentelemetry/exporter-metrics-otlp-grpc":"^0.214.0","@opentelemetry/exporter-metrics-otlp-proto":"^0.214.0"},"_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.1.3","typescript":"^6.0.2","@types/node":"^25.6.0"},"_npmOperationalInternal":{"tmp":"tmp/nest-otel-telemetry_1.0.1_1776841734299_0.5576644937259208","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@almasemilius/nest-otel-telemetry","version":"1.0.2","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","require":"./dist/index.js"}},"scripts":{"build":"rimraf dist && tsc -p tsconfig.json","prepublishOnly":"npm run build"},"keywords":[],"author":"","license":"ISC","description":"A NestJS package that bootstraps OpenTelemetry for traces, metrics, and logs, and exposes a global `TelemetryService` for app-level instrumentation.","devDependencies":{"@types/node":"^25.6.0","rimraf":"^6.1.3","typescript":"^6.0.2"},"dependencies":{"@nestjs/common":"^11.1.19","@nestjs/core":"^11.1.19","@opentelemetry/api":"^1.9.1","@opentelemetry/api-logs":"^0.214.0","@opentelemetry/auto-instrumentations-node":"^0.72.0","@opentelemetry/exporter-logs-otlp-grpc":"^0.214.0","@opentelemetry/exporter-logs-otlp-proto":"^0.214.0","@opentelemetry/exporter-metrics-otlp-grpc":"^0.214.0","@opentelemetry/exporter-metrics-otlp-proto":"^0.214.0","@opentelemetry/exporter-trace-otlp-grpc":"^0.214.0","@opentelemetry/exporter-trace-otlp-proto":"^0.214.0","@opentelemetry/resources":"^2.6.1","@opentelemetry/sdk-logs":"^0.214.0","@opentelemetry/sdk-metrics":"^2.6.1","@opentelemetry/sdk-node":"^0.214.0","@opentelemetry/sdk-trace-node":"^2.6.1","reflect-metadata":"^0.2.2"},"_id":"@almasemilius/nest-otel-telemetry@1.0.2","gitHead":"2e099c41f0028190f3c89307b304554d102c5fc5","_nodeVersion":"20.19.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-v9vOv4fafknkmfYiHiinC1ucLqYOeYXBpXijFEQIF9nKcwjoWFdmFz6aewJZI1GjLNuVbpnseHGBogGnVYxt/A==","shasum":"ff30ad4f55b0a1a63bb8cd9912a1d44e350d6b74","tarball":"https://registry.npmjs.org/@almasemilius/nest-otel-telemetry/-/nest-otel-telemetry-1.0.2.tgz","fileCount":29,"unpackedSize":42408,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDuCcGBtcwRGDjkNQWhOEkeW4firqoZTK7OcUUD5Kik3gIgB92J/CA9H+lphp11iDihisCHhAx8RQATLlglb6caLeY="}]},"_npmUser":{"name":"almasemilius","email":"almasemilius@gmail.com"},"directories":{},"maintainers":[{"name":"almasemilius","email":"almasemilius@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nest-otel-telemetry_1.0.2_1776947432965_0.3940425933874263"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-21T07:08:02.849Z","modified":"2026-04-23T12:30:33.232Z","1.0.0":"2026-04-21T07:08:03.131Z","1.0.1":"2026-04-22T07:08:54.445Z","1.0.2":"2026-04-23T12:30:33.131Z"},"license":"ISC","keywords":[],"description":"A NestJS package that bootstraps OpenTelemetry for traces, metrics, and logs, and exposes a global `TelemetryService` for app-level instrumentation.","maintainers":[{"name":"almasemilius","email":"almasemilius@gmail.com"}],"readme":"# @almasemilius/nest-otel-telemetry\n\nA NestJS package that bootstraps OpenTelemetry for traces, metrics, and logs, and exposes a global `TelemetryService` for app-level instrumentation.\n\n## What it provides\n\n- `TelemetryModule.forRoot(...)` for synchronous setup\n- `TelemetryModule.forRootAsync(...)` for config-driven async setup\n- `TelemetryService` with:\n  - `getTracer()`\n  - `getMeter()`\n  - `getLogger()`\n- Graceful SDK shutdown on app close\n\n## Installation\n\n```bash\nnpm install @almasemilius/nest-otel-telemetry\n```\n\n## Quick start\n\n### Option A: `forRoot` (sync config)\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { TelemetryModule } from '@almasemilius/nest-otel-telemetry';\n\n@Module({\n  imports: [\n    TelemetryModule.forRoot({\n      serviceName: 'orders-service',\n      serviceVersion: '1.0.0',\n      endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318',\n      protocol: 'http/protobuf', // 'grpc' or 'http/protobuf'\n      disabled: false,\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n### Option B: `forRootAsync` (ConfigService/env)\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { ConfigModule, ConfigService } from '@nestjs/config';\nimport { TelemetryModule } from '@almasemilius/nest-otel-telemetry';\n\n@Module({\n  imports: [\n    ConfigModule.forRoot({ isGlobal: true }),\n    TelemetryModule.forRootAsync({\n      imports: [ConfigModule],\n      inject: [ConfigService],\n      useFactory: (cfg: ConfigService) => ({\n        serviceName: cfg.get<string>('APP_NAME') || 'unknown-service',\n        serviceVersion: cfg.get<string>('API_VERSION') || '1.0.0',\n        endpoint: cfg.get<string>('OTEL_EXPORTER_OTLP_ENDPOINT') || 'http://localhost:4318',\n        protocol: (cfg.get('OTEL_EXPORTER_OTLP_PROTOCOL') as 'grpc' | 'http/protobuf') || 'grpc',\n        disabled: cfg.get('NODE_ENV') === 'test',\n      }),\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n### Option C: initialize auto-instrumentation early (recommended)\n\nUse `initializeInstrumentation` before Nest boots to enable Node auto-instrumentations.\n\nCreate `src/otel-instrument.ts`:\n\n```ts\nimport { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';\nimport { initializeInstrumentation } from '@almasemilius/nest-otel-telemetry';\n\nif (process.env.OTEL_DEBUG === 'true') {\n  diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);\n}\n\ninitializeInstrumentation({\n  serviceName: process.env.APP_NAME || 'orders-service',\n  serviceVersion: process.env.API_VERSION || '1.0.0',\n  endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318',\n  protocol: (process.env.OTEL_EXPORTER_OTLP_PROTOCOL as 'grpc' | 'http/protobuf') || 'http/protobuf',\n  disabled: process.env.NODE_ENV === 'test',\n});\n```\n\nThen import it first in `src/main.ts`:\n\n```ts\nimport './otel-instrument';\nimport { NestFactory } from '@nestjs/core';\nimport { AppModule } from './app.module';\n```\n\n## Telemetry options\n\n```ts\ninterface TelemetryOptions {\n  serviceName: string;\n  serviceVersion?: string;\n  endpoint: string;\n  protocol?: 'grpc' | 'http/protobuf';\n  disabled?: boolean;\n}\n```\n\n### Protocol notes\n\n- `grpc` endpoint is typically `host:4317` (no `/v1/...` path)\n- `http/protobuf` endpoint is typically a base URL like `http://host:4318`\n- For `http/protobuf`, this package appends:\n  - `/v1/traces`\n  - `/v1/metrics`\n  - `/v1/logs`\n\n## Using TelemetryService\n\n```ts\nimport { Injectable } from '@nestjs/common';\nimport { TelemetryService } from '@almasemilius/nest-otel-telemetry';\n\n@Injectable()\nexport class OrdersService {\n  constructor(private readonly telemetry: TelemetryService) {}\n\n  createOrder() {\n    const tracer = this.telemetry.getTracer();\n    const span = tracer.startSpan('orders.create');\n    try {\n      // business logic\n    } finally {\n      span.end();\n    }\n  }\n}\n```\n\n## Recommended env vars\n\n```env\nAPP_NAME=orders-service\nAPI_VERSION=1.0.0\nOTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318\nOTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf\nOTEL_DEBUG=false\n```\n\n## Enabling OpenTelemetry diagnostic logs\n\nUse OpenTelemetry diagnostics when you need visibility into SDK startup, exporter behavior, and transport errors.\n\n```ts\nimport { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';\n\nif (process.env.OTEL_DEBUG === 'true') {\n  diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);\n}\n```\n\n### Where to put it\n\nCall `diag.setLogger(...)` **before** your telemetry module initializes, so early SDK logs are captured.\n\nExample placement in `main.ts`:\n\n```ts\nimport { NestFactory } from '@nestjs/core';\nimport { AppModule } from './app.module';\nimport { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';\n\nif (process.env.OTEL_DEBUG === 'true') {\n  diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);\n}\n\nasync function bootstrap() {\n  const app = await NestFactory.create(AppModule);\n  await app.listen(3000);\n}\nbootstrap();\n```\n\n### Log levels\n\n- `DiagLogLevel.ERROR`: only critical failures\n- `DiagLogLevel.WARN`: warnings + errors\n- `DiagLogLevel.INFO`: normal operational info\n- `DiagLogLevel.DEBUG`: detailed troubleshooting output\n- `DiagLogLevel.VERBOSE`: very noisy deep diagnostics\n\nRecommended: use `DEBUG` in local/dev troubleshooting, then reduce to `INFO` or `WARN` in regular environments.\n\n## Troubleshooting\n\nIf you do not see telemetry in your backend/Grafana:\n\n- Confirm protocol and endpoint/port match (`grpc` vs `http/protobuf`)\n- Confirm your app can reach the collector endpoint\n- Generate traffic after startup (no spans means nothing to display)\n- Ensure `disabled` is not set to `true`\n- Check datasource and time range in your observability UI\n\n","readmeFilename":"README.md"}