| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- import { Inject } from '@nestjs/common';
- import { ENABLE_INSTRUMENTATION_ENV_VAR, PluginCommonModule, VendurePlugin } from '@vendure/core';
- import { defaultMethodHooks } from './config/default-method-hooks';
- import { OtelInstrumentationStrategy } from './config/otel-instrumentation-strategy';
- import { OtelLogger } from './config/otel-logger';
- import { TELEMETRY_PLUGIN_OPTIONS } from './constants';
- import { MethodHooksService } from './service/method-hooks.service';
- import { TelemetryPluginOptions } from './types';
- /**
- * @description
- * The TelemetryPlugin is used to instrument the Vendure application and collect telemetry data using
- * [OpenTelemetry](https://opentelemetry.io/).
- *
- * ## Installation
- *
- * ```
- * npm install \@vendure/telemetry-plugin
- * ```
- *
- * :::info
- * For a complete guide to setting up and working with Open Telemetry, see
- * the [Implementing Open Telemetry guide](/guides/how-to/telemetry/).
- * :::
- *
- * ## Configuration
- *
- * The plugin is configured via the `TelemetryPlugin.init()` method. This method accepts an options object
- * which defines the OtelLogger options and method hooks.
- *
- * @example
- * ```ts
- * import { VendureConfig } from '\@vendure/core';
- * import { TelemetryPlugin, registerMethodHooks } from '\@vendure/telemetry-plugin';
- *
- * export const config: VendureConfig = {
- * // ...
- * plugins: [
- * TelemetryPlugin.init({
- * loggerOptions: {
- * // Log to the console at the verbose level
- * console: LogLevel.Verbose,
- * },
- * }),
- * ],
- * };
- * ```
- *
- * ## Preloading the SDK
- *
- * In order to use the OpenTelemetry SDK, you must preload it before the Vendure server is started.
- * This is done by using the `--require` flag when starting the server with a custom preload script.
- *
- * Create a file named `instrumentation.ts` in the root of your project and add the following code:
- *
- * ```ts
- * import { OTLPLogExporter } from '\@opentelemetry/exporter-logs-otlp-proto';
- * import { OTLPTraceExporter } from '\@opentelemetry/exporter-trace-otlp-http';
- * import { BatchLogRecordProcessor } from '\@opentelemetry/sdk-logs';
- * import { NodeSDK } from '\@opentelemetry/sdk-node';
- * import { BatchSpanProcessor } from '\@opentelemetry/sdk-trace-base';
- * import { getSdkConfiguration } from '\@vendure/telemetry-plugin/preload';
- *
- * // In this example we are using Loki as the OTLP endpoint for logging
- * process.env.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://localhost:3100/otlp';
- * process.env.OTEL_LOGS_EXPORTER = 'otlp';
- * process.env.OTEL_RESOURCE_ATTRIBUTES = 'service.name=vendure-dev-server';
- *
- * // We are using Jaeger as the OTLP endpoint for tracing
- * const traceExporter = new OTLPTraceExporter({
- * url: 'http://localhost:4318/v1/traces',
- * });
- * const logExporter = new OTLPLogExporter();
- *
- * // The getSdkConfiguration method returns a configuration object for the OpenTelemetry Node SDK.
- * // It also performs other configuration tasks such as setting a special environment variable
- * // to enable instrumentation in the Vendure core code.
- * const config = getSdkConfiguration({
- * config: {
- * // Pass in any custom configuration options for the Node SDK here
- * spanProcessors: [new BatchSpanProcessor(traceExporter)],
- * logRecordProcessors: [new BatchLogRecordProcessor(logExporter)],
- * },
- * });
- *
- * const sdk = new NodeSDK(config);
- *
- * sdk.start();
- * ```
- *
- * The server would then be started with the following command:
- *
- * ```bash
- * node --require ./dist/instrumentation.js ./dist/server.js
- * ```
- *
- * or for development with ts-node:
- *
- * ```bash
- * npx ts-node --require ./src/instrumentation.ts ./src/server.ts
- * ```
- *
- * @since 3.3.0
- * @docsCategory core plugins/TelemetryPlugin
- */
- @VendurePlugin({
- imports: [PluginCommonModule],
- providers: [
- MethodHooksService,
- {
- provide: TELEMETRY_PLUGIN_OPTIONS,
- useFactory: () => TelemetryPlugin.options,
- },
- ],
- configuration: config => {
- config.systemOptions.instrumentationStrategy = new OtelInstrumentationStrategy();
- config.logger = new OtelLogger(TelemetryPlugin.options.loggerOptions ?? {});
- return config;
- },
- compatibility: '>=3.3.0',
- })
- export class TelemetryPlugin {
- static options: TelemetryPluginOptions = {};
- constructor(
- methodHooksService: MethodHooksService,
- @Inject(TELEMETRY_PLUGIN_OPTIONS) options: TelemetryPluginOptions,
- ) {
- if (process.env[ENABLE_INSTRUMENTATION_ENV_VAR]) {
- const allMethodHooks = [...defaultMethodHooks, ...(options.methodHooks ?? [])];
- for (const methodHook of allMethodHooks) {
- methodHooksService.registerHooks(methodHook.target, methodHook.hooks);
- }
- }
- }
- static init(options: TelemetryPluginOptions) {
- TelemetryPlugin.options = options;
- return TelemetryPlugin;
- }
- }
|