### Start Grafana + OpenTelemetry Docker Compose Source: https://github.com/zonneplan/open-telemetry-js/blob/main/docker-compose/README.md This command initiates the entire Grafana and OpenTelemetry stack defined in the docker-compose file. Ensure Docker is installed and running. No input parameters are required; it starts all services and makes them accessible on predefined ports. ```bash docker-compose up ``` -------------------------------- ### Install OpenTelemetry Node.js Package Source: https://github.com/zonneplan/open-telemetry-js/blob/main/packages/open-telemetry-node/README.md Installs the necessary OpenTelemetry Node.js package using npm. This is the first step to integrate OpenTelemetry into your Node.js application. ```bash npm install @zonneplan/open-telemetry-node ``` -------------------------------- ### Custom OpenTelemetry Configuration (TypeScript) Source: https://context7.com/zonneplan/open-telemetry-js/llms.txt Configures the OpenTelemetry SDK with custom instrumentations, samplers, and exporters. This example demonstrates adding MySQL and NestJS instrumentations, using an AlwaysOnSampler, OTLP exporters for traces, logs, and metrics, and configuring batch span processing and periodic metric export. ```typescript import { OpenTelemetryBuilder } from '@zonneplan/open-telemetry-node'; import { MySQLInstrumentation } from '@opentelemetry/instrumentation-mysql'; import { NestInstrumentation } from '@opentelemetry/instrumentation-nestjs-core'; import { AlwaysOnSampler, BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http'; import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'; import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'; new OpenTelemetryBuilder('custom-service') .withInstrumentation( new MySQLInstrumentation({ enabled: true }), new NestInstrumentation({ enabled: true }) ) .withSampler(new AlwaysOnSampler()) .withSpanExporter(new OTLPTraceExporter()) .withSpanProcessor((exporter) => new BatchSpanProcessor(exporter)) .withLogging((options) => options.withLogRecordExporter(new OTLPLogExporter()) ) .withMetrics((options) => options.withMetricReader( new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter(), exportIntervalMillis: 1000 }) ) ) .start(); ``` -------------------------------- ### Install OpenTelemetry Zonneplan Package (npm) Source: https://github.com/zonneplan/open-telemetry-js/blob/main/packages/open-telemetry-zonneplan/README.md This snippet shows how to install the OpenTelemetry Zonneplan JavaScript package using npm. This is the first step to integrating Zonneplan's OpenTelemetry capabilities into your Node.js application. ```bash npm install @zonneplan/open-telemetry-zonneplan ``` -------------------------------- ### Metrics Creation and Management (TypeScript) Source: https://context7.com/zonneplan/open-telemetry-js/llms.txt Illustrates how to create and use type-safe OpenTelemetry metrics, including Counter, Gauge, and Histogram. It shows how to get or create metrics and record values with attributes. ```typescript import { getOrCreateMetric, Gauge } from '@zonneplan/open-telemetry-node'; import { ValueType } from '@opentelemetry/api'; // Create a custom Gauge metric for process boot time const bootTimeGauge = getOrCreateMetric({ name: 'process_boot_time', unit: 's', type: 'Gauge', description: 'Time when the process started', valueType: ValueType.INT, }); bootTimeGauge?.setToCurrentTime(); // Create a Counter for HTTP requests const requestCounter = getOrCreateMetric({ type: 'Counter', name: 'http_request', // automatically suffixed with '_total' by OTEL description: 'Total number of HTTP requests', unit: 'requests', valueType: ValueType.INT, }); requestCounter?.add(1, { method: 'GET', path: '/api/users', status: '200' }); // Create a Histogram for request duration const durationHistogram = getOrCreateMetric({ type: 'Histogram', name: 'http_request_duration', description: 'HTTP request duration in seconds', unit: 's', valueType: ValueType.DOUBLE, }); const startTime = Date.now(); // ... handle request ... const duration = (Date.now() - startTime) / 1000; durationHistogram?.record(duration, { method: 'POST', endpoint: '/api/data' }); ``` -------------------------------- ### Install OpenTelemetry NestJS Package Source: https://github.com/zonneplan/open-telemetry-js/blob/main/packages/open-telemetry-nest/README.md Installs the @zonneplan/open-telemetry-nest package, which provides utilities for integrating OpenTelemetry metrics into NestJS applications. No external dependencies are required beyond npm or yarn. ```bash npm install @zonneplan/open-telemetry-nest ``` -------------------------------- ### Export Prometheus Metrics for NestJS Source: https://context7.com/zonneplan/open-telemetry-js/llms.txt Explains how to export metrics in Prometheus format using a built-in controller and exporter provided by `@zonneplan/open-telemetry-nest`. This setup requires configuring the OpenTelemetry builder with the `PrometheusNestExporter` and creating a controller to expose the metrics endpoint. ```typescript import { Module, Controller, Get, Header } from '@nestjs/common'; import { PrometheusNestExporter } from '@zonneplan/open-telemetry-nest'; import otel = require('@zonneplan/open-telemetry-node'); // Configure during OpenTelemetry initialization new otel.OpenTelemetryBuilder('my-service') .withMetrics((options) => options.withMetricReader(new PrometheusNestExporter()) ) .start(); // Create a controller to expose metrics endpoint @Controller('metrics') export class MetricsController { constructor(private readonly prometheusExporter: PrometheusNestExporter) {} @Get() @Header('Content-Type', 'text/plain') async getMetrics(): Promise { // Returns both default Prometheus metrics and OpenTelemetry metrics return await this.prometheusExporter.getMetricsResponseInPlainText(); } } @Module({ controllers: [MetricsController], providers: [ { provide: PrometheusNestExporter, useFactory: () => { // Access the exporter from global providers if needed return new PrometheusNestExporter(); }, }, ], }) export class MonitoringModule {} ``` -------------------------------- ### Configure OpenTelemetry with Default Options in TypeScript Source: https://context7.com/zonneplan/open-telemetry-js/llms.txt Shows how to quickly set up OpenTelemetry with pre-configured default options for tracing, logging, and metrics using the Zonneplan OpenTelemetry builder. This simplifies integration by including common instrumentations and exporters. ```typescript import otel = require('@zonneplan/open-telemetry-node'); import zonneplan = require('@zonneplan/open-telemetry-zonneplan'); // DefaultTracingOptions includes: // - Node.js auto-instrumentations (HTTP, Express, etc.) // - Winston logging instrumentation // - MySQL instrumentation // - NestJS core instrumentation // - KafkaJS instrumentation // - AlwaysOnSampler // - OTLP exporter with batch processor // DefaultLoggingOptions includes: // - OTLP log exporter // - Batch log processor // DefaultMetricsOptions includes: // - OTLP metric exporter // - Periodic metric reader with 1-second interval // - Default Prometheus metrics collection new otel.OpenTelemetryBuilder('quick-start-service') .withTracing(zonneplan.DefaultTracingOptions) .withLogging(zonneplan.DefaultLoggingOptions) .withMetrics(zonneplan.DefaultMetricsOptions) .start(); // Application code here console.log('OpenTelemetry configured with sensible defaults'); ``` -------------------------------- ### Initialize OpenTelemetry with Defaults (TypeScript) Source: https://context7.com/zonneplan/open-telemetry-js/llms.txt Initializes the OpenTelemetry SDK using a fluent builder pattern with pre-configured defaults for tracing, logging, and metrics. It supports adding custom metric readers like the PrometheusNestExporter and diagnostic logging. Ensure your application is bootstrapped after OpenTelemetry initialization. ```typescript import otel = require('@zonneplan/open-telemetry-node'); import nest = require('@zonneplan/open-telemetry-nest'); import zonneplan = require('@zonneplan/open-telemetry-zonneplan'); // Initialize with pre-configured defaults new otel.OpenTelemetryBuilder('my-service-name') .withTracing(zonneplan.DefaultTracingOptions) .withLogging(zonneplan.DefaultLoggingOptions) .withMetrics(zonneplan.DefaultMetricsOptions) .withMetrics((options) => options.withMetricReader(new nest.PrometheusNestExporter()) ) .withDiagLogging(otel.DiagLogLevel.WARN) .start(); // Bootstrap your application after OpenTelemetry initialization async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(3000); } bootstrap(); ``` -------------------------------- ### Manual Span Creation with Disposable Pattern (TypeScript) Source: https://context7.com/zonneplan/open-telemetry-js/llms.txt Demonstrates manual span creation using TypeScript's 'using' keyword for automatic disposal or manual lifecycle management. It covers setting attributes, status codes, and recording exceptions. ```typescript import { startSpan, setAttributeOnActiveSpan } from '@zonneplan/open-telemetry-node'; import { SpanStatusCode } from '@opentelemetry/api'; export class DataProcessor { // Automatic span disposal with 'using' keyword public processWithDisposable() { using span = startSpan('process-data'); span.setAttribute('operation', 'process'); span.setAttribute('batch.size', 100); // Span automatically ends when leaving scope return { success: true }; } // Manual span lifecycle management public processWithManualControl() { const span = startSpan('manual-process', { 'operation.type': 'manual', 'priority': 'high' }); try { const result = this.performOperation(); span.setStatus({ code: SpanStatusCode.OK, message: 'Operation completed successfully' }); return result; } catch (error) { span.setStatus({ code: SpanStatusCode.ERROR, message: error.message }); span.recordException(error); throw error; } finally { span.end(); } } private performOperation() { return { data: 'processed' }; } } ``` -------------------------------- ### Initialize OpenTelemetry with Custom Configuration Source: https://github.com/zonneplan/open-telemetry-js/blob/main/packages/open-telemetry-node/README.md Initializes OpenTelemetry with custom instrumentation, samplers, exporters, and readers for tracing, logging, and metrics. This approach provides fine-grained control over the telemetry pipeline. ```typescript import { AlwaysOnSampler, BatchSpanProcessor, OTLPLogExporter, OTLPMetricsExporter, OTLPTraceExporter, PeriodicExportingMetricReader, SpanStatusCode, } from '@opentelemetry/sdk-trace-base'; import { MySQLInstrumentation, NestInstrumentation, } from '@opentelemetry/instrumentation'; import otel = require('@zonneplan/open-telemetry-node'); new otel.OpenTelemetryBuilder('nest-example') .withInstrumentation( new MySQLInstrumentation({ enabled: true }), new NestInstrumentation({ enabled: true }), ) .withSampler(new AlwaysOnSampler()) .withSpanExporter(new OTLPTraceExporter()) .withSpanProcessor((exporter) => new BatchSpanProcessor(exporter)) .withLogging((options) => options .withLogRecordExporter(new OTLPLogExporter()) ) .withMetrics((options) => options .withMetricReader( new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter(), exportIntervalMillis: 1000 }) ) ) .start(); ``` -------------------------------- ### Working with Metrics Source: https://github.com/zonneplan/open-telemetry-js/blob/main/packages/open-telemetry-node/README.md Demonstrates creating and interacting with different types of metrics (Gauge, Counter, Histogram) using `getOrCreateMetric`. Also shows the `@metricIncrement` decorator for automatic counter updates. ```typescript // We provide our own Gauge instance here to mimic the behaviour of a Prometheus Gauge (from prom-client) // this is mainly because we use gauages for tracking time-related tasks, so we provide a simple utility to set the gauge to the current time. const gauge = getOrCreateMetric({ name: 'process_boot_time', unit: 's', type: 'Gauge', description: 'Time when the process started', valueType: ValueType.INT, }) gauge.setToCurrentTime(); const counter = getOrCreateMetric({ type: 'Counter', name: 'http_request', // automatically suffixed with '_total' by OTEL description: 'Total number of HTTP requests', }) counter.add(1); const histogram = getOrCreateMetric({ type: 'Histogram', name: 'http_request_duration', }) histogram.record(0.5); Classes can also be decorated with the `metricIncrement` decorator to automatically increment a counter on a method call. ```typescript class MyClass { @metricIncrement('my_class_method_calls') public myMethod() { // ... } } ``` ``` -------------------------------- ### Inject NestJS Metrics with Dependency Injection Source: https://context7.com/zonneplan/open-telemetry-js/llms.txt Demonstrates how to use NestJS dependency injection to inject OpenTelemetry metrics into services with type safety. It requires `@zonneplan/open-telemetry-nest` and `@zonneplan/open-telemetry-node` packages. The snippet shows registering a counter metric and injecting it into a service for recording user actions. ```typescript import { Module, Injectable } from '@nestjs/common'; import { createCounterProvider, InjectMetric } from '@zonneplan/open-telemetry-nest'; import { Counter, metricIncrement } from '@zonneplan/open-telemetry-node'; import { ValueType } from '@opentelemetry/api'; const MY_METRIC = 'user_actions_total'; // Register metric provider in module @Module({ providers: [ createCounterProvider({ name: MY_METRIC, description: 'Total number of user actions', unit: 'actions', valueType: ValueType.INT, }), UserService ], }) export class UserModule {} // Inject and use the metric in service @Injectable() export class UserService { constructor( @InjectMetric(MY_METRIC) private readonly userActionsCounter: Counter ) {} public recordUserAction(userId: string, action: string) { this.userActionsCounter.add(1, { user_id: userId, action_type: action }); return { recorded: true }; } /** * Alternative: Use decorator for automatic increment */ @metricIncrement(MY_METRIC) public performAction() { return { success: true }; } } ``` -------------------------------- ### NestJS Structured Logging with OpenTelemetry Context Source: https://context7.com/zonneplan/open-telemetry-js/llms.txt Illustrates how to use the NestJS-integrated logger service for structured logging that automatically includes OpenTelemetry context. This feature, provided by `@zonneplan/open-telemetry-nest`, ensures logs are correlated with the active trace span, simplifying debugging and monitoring. ```typescript import { Injectable } from '@nestjs/common'; import { LoggerService } from '@zonneplan/open-telemetry-nest'; import { span } from '@zonneplan/open-telemetry-node'; @Injectable() export class OrderService { constructor(private readonly logger: LoggerService) { // Set the context for all logs from this service this.logger.setContext(OrderService.name); } @span() async createOrder(userId: string, items: string[]) { // Logs are automatically correlated with the active span this.logger.log('Creating order', { userId, itemCount: items.length, timestamp: new Date().toISOString() }); try { const order = await this.processOrder(userId, items); this.logger.log('Order created successfully', { orderId: order.id, userId, total: order.total }); return order; } catch (error) { this.logger.error('Failed to create order', { userId, error: error.message, stack: error.stack }); throw error; } } private async processOrder(userId: string, items: string[]) { this.logger.debug('Processing order items', { userId, items }); return { id: 'order-123', userId, items, total: 99.99, createdAt: new Date() }; } } ``` -------------------------------- ### Initialize OpenTelemetry with Default Options Source: https://github.com/zonneplan/open-telemetry-js/blob/main/packages/open-telemetry-node/README.md Initializes OpenTelemetry with predefined tracing, logging, and metrics options, and integrates with Prometheus for NestJS applications. This configuration is suitable for common use cases. ```typescript import otel = require('@zonneplan/open-telemetry-node'); import nest = require('@zonneplan/open-telemetry-nest'); import zonneplan = require('@zonneplan/open-telemetry-zonneplan'); new otel.OpenTelemetryBuilder('nest-example') .withTracing(zonneplan.DefaultTracingOptions) .withLogging(zonneplan.DefaultLoggingOptions) .withMetrics(zonneplan.DefaultMetricsOptions) .withMetrics((options) => options.withMetricReader(new nest.PrometheusNestExporter())) .start(); ``` -------------------------------- ### Configure and Use OpenTelemetry Counters in NestJS Source: https://github.com/zonneplan/open-telemetry-js/blob/main/packages/open-telemetry-nest/README.md Demonstrates how to register a counter provider in a NestJS module and inject it into a service for incrementing. Supports default metric methods and a custom increment decorator. Requires TypeScript and NestJS. ```typescript import { createCounterProvider, Counter, InjectMetric, metricIncrement } from '@zonneplan/open-telemetry-nest'; import { Module, Injectable } from '@nestjs/common'; const MY_METRIC = 'my_metric'; // my-module.ts @Module({ providers: [ /** * Registers a counter provider, which can be injected in services. */ createCounterProvider({ name: MY_METRIC, description: 'My metric description', unit: 'occurrences', valueType: ValueType.INT, }) ] }) export class MyModule {} // my-service.ts @Injectable() export class MyService { constructor( /** * Inject the metric in the service. */ @InjectMetric(MY_METRIC) private readonly myMetric: Counter ) {} /** * Using the default metric methods. */ public myMethod() { this.myMetric.add(1); } /** * Using the metric increment decorator. */ @metricIncrement(MY_METRIC) public myMetricIncrementDecorator() { } } ``` -------------------------------- ### Automatic Spans with Decorators Source: https://github.com/zonneplan/open-telemetry-js/blob/main/packages/open-telemetry-node/README.md Demonstrates using the `@span` decorator for automatic span creation on methods, and `@spanAttribute` for setting span attributes from method parameters. Requires experimental decorators in tsconfig.json. ```typescript import { Injectable } from '@nestjs/common'; import { setAttributeOnActiveSpan, setSpanError, span, spanAttribute, startSpan, } from './set-attributes-on-active-span'; import { Span, SpanStatusCode } from '@opentelemetry/api'; @Injectable() export class MyService { /** * Instead of manually starting a span, you can use the {@link span} decorator to automatically start a span for the given method. * Alternatively, use the `startSpan` method using the disposable pattern / manually ending it. * The span name can be overwritten, but defaults to AppService::getData. * * @note decorators require the following config options in the `tsconfig.json`: * "emitDecoratorMetadata": true, * "experimentalDecorators": true */ @span() /** * Span attributes can be manually set in the method, by using the `setAttributeOnActiveSpan` method. * However, if you only want to set some input parameters as span attributes, you can use the {@link spanAttribute} decorator. * * @note primitive values (string, numbers and booleans) don't need a function for parsing. Other's do, because they are not valid span attribute values. * the name is automatically inferred, but technically does not match the Open telemetry spec, so it's recommended to always provide a name. */ public methodWithSpanDecorator(@spanAttribute((val: Date) => val.toISOString()) date: Date, @spanAttribute() name: string) { setAttributeOnActiveSpan('name', name); setSpanError('This is an error'); } public methodWithSpan() { const span = startSpan('methodWithSpan'); span.setAttribute('name', 'John Doe'); span.setStatus({ code: SpanStatusCode.ERROR, message: 'This is an error' }); span.end(); } public methodWithDisposableSpan() { let span: Span; if (true) { using span = startSpan('methodWithDisposableSpan'); span.end(); } span.isRecording(); // false } } ``` -------------------------------- ### Set Span Attributes and Status in TypeScript Source: https://context7.com/zonneplan/open-telemetry-js/llms.txt Demonstrates how to add custom attributes and set the status (OK or ERROR) for the currently active span using the OpenTelemetry Node.js SDK. This includes setting individual and multiple attributes, as well as handling success and error scenarios within a payment processing context. ```typescript import { setAttributeOnActiveSpan, setAttributesOnActiveSpan, setSpanOk, setSpanError, setSpanStatus, span } from '@zonneplan/open-telemetry-node'; import { SpanStatusCode } from '@opentelemetry/api'; export class PaymentProcessor { @span('process-payment') async processPayment(userId: string, amount: number, currency: string) { // Set individual attributes setAttributeOnActiveSpan('user.id', userId); setAttributeOnActiveSpan('payment.amount', amount); setAttributeOnActiveSpan('payment.currency', currency); // Or set multiple attributes at once setAttributesOnActiveSpan({ 'payment.processor': 'stripe', 'payment.method': 'credit_card', 'payment.timestamp': Date.now(), }); try { const result = await this.executePayment(amount); if (result.success) { setSpanOk(); // Sets status to OK setAttributeOnActiveSpan('payment.transaction_id', result.transactionId); return result; } else { setSpanError('Payment declined'); // Sets status to ERROR with message setAttributeOnActiveSpan('payment.decline_reason', result.reason); throw new Error('Payment declined'); } } catch (error) { // Set custom error status setSpanStatus(SpanStatusCode.ERROR, `Payment failed: ${error.message}`); setAttributeOnActiveSpan('error.type', error.constructor.name); throw error; } } private async executePayment(amount: number) { return { success: true, transactionId: 'txn_' + Date.now(), amount }; } } ``` -------------------------------- ### Span Decorator for Automatic Tracing (TypeScript) Source: https://context7.com/zonneplan/open-telemetry-js/llms.txt Demonstrates using the `@span()` decorator to automatically create spans around class methods in NestJS applications. It supports adding custom span attributes using `@spanAttribute` and manually setting span errors. The decorator simplifies manual span management and enhances context propagation. ```typescript import { Injectable } from '@nestjs/common'; import { span, spanAttribute, setAttributeOnActiveSpan, setSpanError } from '@zonneplan/open-telemetry-node'; @Injectable() export class AppService { /** * Automatically creates a span named "AppService::getData" * with automatic handling of async operations and span lifecycle */ @span() getData( @spanAttribute((val: Date) => val.toISOString()) date: Date, @spanAttribute() name: string ) { // Add custom attributes to the active span setAttributeOnActiveSpan('user.name', name); setAttributeOnActiveSpan('request.timestamp', date.getTime()); try { const result = this.processData(name, date); return { message: `Hello ${name}, today is ${date.toDateString()}`, result }; } catch (error) { setSpanError('Failed to process data'); throw error; } } /** * Custom span name instead of default ClassName::methodName */ @span('custom-operation') processData(name: string, date: Date) { return { processed: true, timestamp: Date.now() }; } } ``` -------------------------------- ### Metric Increment Decorator (TypeScript) Source: https://context7.com/zonneplan/open-telemetry-js/llms.txt Shows how to use the '@metricIncrement' decorator to automatically increment counters when methods are invoked. This works for both synchronous and asynchronous methods and supports custom increment values. ```typescript import { Injectable } from '@nestjs/common'; import { metricIncrement, getOrCreateMetric } from '@zonneplan/open-telemetry-node'; // Create the metric first const myMethodCounter = getOrCreateMetric({ type: 'Counter', name: 'my_class_method_calls', description: 'Number of times myMethod is called', }); @Injectable() export class MyService { /** * Automatically increments the counter by 1 each time the method is called * Works with both sync and async methods */ @metricIncrement('my_class_method_calls') public myMethod() { return { status: 'success' }; } /** * Increment by custom value */ @metricIncrement('batch_operations', 10) public batchOperation() { // Process batch of 10 items return { processed: 10 }; } /** * Works with async methods too */ @metricIncrement('async_operations') public async asyncOperation() { await new Promise(resolve => setTimeout(resolve, 100)); return { completed: true }; } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.