1
0

instrumentation.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
  2. import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks';
  3. import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-proto';
  4. import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
  5. import { resourceFromAttributes } from '@opentelemetry/resources';
  6. import {
  7. BatchLogRecordProcessor,
  8. ConsoleLogRecordExporter,
  9. SimpleLogRecordProcessor,
  10. } from '@opentelemetry/sdk-logs';
  11. import { NodeSDKConfiguration } from '@opentelemetry/sdk-node';
  12. import { BatchSpanProcessor, ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
  13. // Deep import is intentional: otherwise unwanted code (such as instrumented classes) will get
  14. // loaded too early before the Otel instrumentation has had a chance to do its thing.
  15. import { ENABLE_INSTRUMENTATION_ENV_VAR } from '@vendure/core/dist/common/instrument-decorator';
  16. const traceExporter = new OTLPTraceExporter();
  17. const logExporter = new OTLPLogExporter();
  18. /**
  19. * @description
  20. * Options for configuring the OpenTelemetry Node SDK.
  21. *
  22. * @docsCategory core plugins/TelemetryPlugin
  23. * @docsPage getSdkConfiguration
  24. */
  25. export interface SdkConfigurationOptions {
  26. /**
  27. * @description
  28. * When set to `true`, the SDK will log spans to the console instead of sending them to an
  29. * exporter. This should just be used for debugging purposes.
  30. *
  31. * @default false
  32. */
  33. logToConsole?: boolean;
  34. /**
  35. * @description
  36. * The configuration object for the OpenTelemetry Node SDK.
  37. */
  38. config: Partial<NodeSDKConfiguration>;
  39. }
  40. /**
  41. * @description
  42. * Creates a configuration object for the OpenTelemetry Node SDK. This is used to set up a custom
  43. * preload script which must be run before the main Vendure server is loaded by means of the
  44. * Node.js `--require` flag.
  45. *
  46. * @example
  47. * ```ts
  48. * // instrumentation.ts
  49. * import { OTLPLogExporter } from '\@opentelemetry/exporter-logs-otlp-proto';
  50. * import { OTLPTraceExporter } from '\@opentelemetry/exporter-trace-otlp-http';
  51. * import { BatchLogRecordProcessor } from '\@opentelemetry/sdk-logs';
  52. * import { NodeSDK } from '\@opentelemetry/sdk-node';
  53. * import { BatchSpanProcessor } from '\@opentelemetry/sdk-trace-base';
  54. * import { getSdkConfiguration } from '\@vendure/telemetry-plugin/preload';
  55. *
  56. * process.env.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://localhost:3100/otlp';
  57. * process.env.OTEL_LOGS_EXPORTER = 'otlp';
  58. * process.env.OTEL_RESOURCE_ATTRIBUTES = 'service.name=vendure-dev-server';
  59. *
  60. * const traceExporter = new OTLPTraceExporter({
  61. * url: 'http://localhost:4318/v1/traces',
  62. * });
  63. * const logExporter = new OTLPLogExporter();
  64. *
  65. * const config = getSdkConfiguration({
  66. * config: {
  67. * spanProcessors: [new BatchSpanProcessor(traceExporter)],
  68. * logRecordProcessors: [new BatchLogRecordProcessor(logExporter)],
  69. * },
  70. * });
  71. *
  72. * const sdk = new NodeSDK(config);
  73. *
  74. * sdk.start();
  75. * ```
  76. *
  77. * This would them be run as:
  78. * ```bash
  79. * node --require ./dist/instrumentation.js ./dist/server.js
  80. * ```
  81. *
  82. * @docsCategory core plugins/TelemetryPlugin
  83. * @docsPage getSdkConfiguration
  84. * @docsWeight 0
  85. */
  86. export function getSdkConfiguration(options?: SdkConfigurationOptions): Partial<NodeSDKConfiguration> {
  87. // This environment variable is used to enable instrumentation in the Vendure core code.
  88. // Without setting this env var, no instrumentation will be applied to any Vendure classes.
  89. process.env[ENABLE_INSTRUMENTATION_ENV_VAR] = 'true';
  90. const { spanProcessors, logRecordProcessors, ...rest } = options?.config ?? {};
  91. const devModeAwareConfig: Partial<NodeSDKConfiguration> = options?.logToConsole
  92. ? {
  93. spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())],
  94. logRecordProcessors: [new SimpleLogRecordProcessor(new ConsoleLogRecordExporter())],
  95. }
  96. : {
  97. spanProcessors: spanProcessors ?? [new BatchSpanProcessor(traceExporter)],
  98. logRecordProcessors: logRecordProcessors ?? [new BatchLogRecordProcessor(logExporter)],
  99. };
  100. return {
  101. resource: resourceFromAttributes({
  102. 'service.name': 'vendure',
  103. 'service.namespace': 'vendure',
  104. 'service.environment': process.env.NODE_ENV || 'development',
  105. }),
  106. ...devModeAwareConfig,
  107. contextManager: new AsyncLocalStorageContextManager(),
  108. instrumentations: [getNodeAutoInstrumentations()],
  109. ...rest,
  110. };
  111. }