nestjs-otel 5.1.5 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
package/README.md CHANGED
@@ -25,10 +25,18 @@ Please read this [comprehensive whitepaper](https://github.com/cncf/tag-observab
25
25
 
26
26
  ![observability-signals](https://user-images.githubusercontent.com/24193764/121773601-55f86b80-cb53-11eb-8c8b-262a5aad781f.png)
27
27
 
28
+
29
+ ## Examples
30
+
31
+ A full working examples are available. This includes a nestjs application fully integrated with prometheus, grafana, loki and tempo:
32
+
33
+ - [nestjs-otel-prom-grafana-tempo](https://github.com/pragmaticivan/nestjs-otel-prom-grafana-tempo )
34
+
35
+
28
36
  ## Installation
29
37
 
30
38
  ```bash
31
- $ npm i nestjs-otel @opentelemetry/sdk-node --save
39
+ npm i nestjs-otel @opentelemetry/sdk-node --save
32
40
  ```
33
41
 
34
42
  ## Setup
@@ -58,10 +66,9 @@ import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-ho
58
66
  import * as process from 'process';
59
67
 
60
68
  const otelSDK = new NodeSDK({
61
- metricExporter: new PrometheusExporter({
69
+ metricReader: new PrometheusExporter({
62
70
  port: 8081,
63
71
  }),
64
- metricInterval: 1000,
65
72
  spanProcessor: new BatchSpanProcessor(new JaegerExporter()),
66
73
  contextManager: new AsyncLocalStorageContextManager(),
67
74
  textMapPropagator: new CompositePropagator({
@@ -126,6 +133,7 @@ const OpenTelemetryModuleConfig = OpenTelemetryModule.forRoot({
126
133
  },
127
134
  ignoreRoutes: ['/favicon.ico'], // You can ignore specific routes (See https://docs.nestjs.com/middleware#excluding-routes for options)
128
135
  ignoreUndefinedRoutes: false, //Records metrics for all URLs, even undefined ones
136
+ prefix: 'my_prefix', // Add a custom prefix to all API metrics
129
137
  },
130
138
  },
131
139
  });
@@ -315,11 +323,6 @@ export const loggerOptions: LoggerOptions = {
315
323
  export const logger: Logger = Pino(loggerOptions);
316
324
  ```
317
325
 
318
- ## Examples
319
-
320
- A full working examples are available. This includes a nestjs application fully integrated with prometheus, grafana, loki and tempo:
321
-
322
- * [nestjs-otel-prom-grafana-tempo](https://github.com/pragmaticivan/nestjs-otel-prom-grafana-tempo )
323
326
  ## Stargazers over time
324
327
 
325
328
  [![Stargazers over time](https://starchart.cc/pragmaticivan/nestjs-otel.svg)](https://starchart.cc/pragmaticivan/nestjs-otel)
package/lib/index.js CHANGED
@@ -1,23 +1,10 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
2
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./opentelemetry.module"), exports);
18
- __exportStar(require("./tracing/decorators/span"), exports);
19
- __exportStar(require("./tracing/trace.service"), exports);
20
- __exportStar(require("./metrics/metric.service"), exports);
21
- __exportStar(require("./metrics/injector"), exports);
22
- __exportStar(require("./metrics/decorators"), exports);
23
- __exportStar(require("./opentelemetry.constants"), exports);
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./opentelemetry.module"), exports);
5
+ tslib_1.__exportStar(require("./tracing/decorators/span"), exports);
6
+ tslib_1.__exportStar(require("./tracing/trace.service"), exports);
7
+ tslib_1.__exportStar(require("./metrics/metric.service"), exports);
8
+ tslib_1.__exportStar(require("./metrics/injector"), exports);
9
+ tslib_1.__exportStar(require("./metrics/decorators"), exports);
10
+ tslib_1.__exportStar(require("./opentelemetry.constants"), exports);
@@ -1,17 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
2
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./opentelemetry-options.interface"), exports);
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./opentelemetry-options.interface"), exports);
@@ -0,0 +1,7 @@
1
+ import { MetricOptions } from '@opentelemetry/api';
2
+ export interface OtelMetricOptions extends MetricOptions {
3
+ /**
4
+ * A prefix to add to the name of the metric.
5
+ */
6
+ prefix?: string;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,25 +1,49 @@
1
1
  import { ModuleMetadata, Type, Abstract } from '@nestjs/common';
2
- import { MetricAttributes } from '@opentelemetry/api';
2
+ import { Attributes } from '@opentelemetry/api';
3
3
  import { RouteInfo } from '@nestjs/common/interfaces';
4
4
  export type OpenTelemetryModuleOptions = {
5
+ /**
6
+ * OpenTelemetry Metrics Setup
7
+ */
5
8
  metrics?: OpenTelemetryMetrics;
6
9
  };
7
10
  export interface OpenTelemetryOptionsFactory {
8
11
  createOpenTelemetryOptions(): Promise<OpenTelemetryModuleOptions> | OpenTelemetryModuleOptions;
9
12
  }
13
+ /**
14
+ * The options for the asynchronous Terminus module creation
15
+ *
16
+ * @publicApi
17
+ */
10
18
  export interface OpenTelemetryModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
19
+ /**
20
+ * The name of the module
21
+ */
11
22
  name?: string;
23
+ /**
24
+ * The class which should be used to provide the Terminus options
25
+ */
12
26
  useClass?: Type<OpenTelemetryOptionsFactory>;
27
+ /**
28
+ * Import existing providers from other module
29
+ */
13
30
  useExisting?: Type<OpenTelemetryOptionsFactory>;
31
+ /**
32
+ * The factory which should be used to provide the Terminus options
33
+ */
14
34
  useFactory?: (...args: any[]) => Promise<OpenTelemetryModuleOptions> | OpenTelemetryModuleOptions;
35
+ /**
36
+ * The providers which should get injected
37
+ */
15
38
  inject?: (string | symbol | Function | Type<any> | Abstract<any>)[];
16
39
  }
17
40
  export type OpenTelemetryMetrics = {
18
41
  hostMetrics?: boolean;
19
42
  apiMetrics?: {
20
43
  enable?: boolean;
21
- defaultAttributes?: MetricAttributes;
44
+ defaultAttributes?: Attributes;
22
45
  ignoreRoutes?: (string | RouteInfo)[];
23
46
  ignoreUndefinedRoutes?: boolean;
47
+ prefix?: string;
24
48
  };
25
49
  };
@@ -1,5 +1,13 @@
1
- import { MetricOptions } from '@opentelemetry/api';
2
- export declare const OtelInstanceCounter: (options?: MetricOptions) => <T extends new (...args: any[]) => {}>(originalClass: T) => {
1
+ import { OtelMetricOptions } from '../../interfaces/metric-options.interface';
2
+ /**
3
+ * Create and increment a counter when a new instance is created
4
+ *
5
+ * @param originalClass
6
+ */
7
+ export declare const OtelInstanceCounter: (options?: OtelMetricOptions) => <T extends new (...args: any[]) => {}>(originalClass: T) => {
3
8
  new (...args: any[]): {};
4
9
  } & T;
5
- export declare const OtelMethodCounter: (options?: MetricOptions) => (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<(...args: any[]) => any>) => void;
10
+ /**
11
+ * Create and increment a counter when the method is called
12
+ */
13
+ export declare const OtelMethodCounter: (options?: OtelMetricOptions) => (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<(...args: any[]) => any>) => void;
@@ -3,6 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OtelMethodCounter = exports.OtelInstanceCounter = void 0;
4
4
  const opentelemetry_utils_1 = require("../../opentelemetry.utils");
5
5
  const metric_data_1 = require("../metric-data");
6
+ /**
7
+ * Create and increment a counter when a new instance is created
8
+ *
9
+ * @param originalClass
10
+ */
6
11
  const OtelInstanceCounter = (options) => (originalClass) => {
7
12
  const name = `app_${originalClass.name}_instances_total`;
8
13
  const description = `app_${originalClass.name} object instances total`;
@@ -20,6 +25,9 @@ const OtelInstanceCounter = (options) => (originalClass) => {
20
25
  return wrappedClass;
21
26
  };
22
27
  exports.OtelInstanceCounter = OtelInstanceCounter;
28
+ /**
29
+ * Create and increment a counter when the method is called
30
+ */
23
31
  const OtelMethodCounter = (options) => (target, propertyKey, descriptor) => {
24
32
  const className = target.constructor.name;
25
33
  const name = `app_${className}_${propertyKey.toString()}_calls_total`;
@@ -31,6 +39,7 @@ const OtelMethodCounter = (options) => (target, propertyKey, descriptor) => {
31
39
  counterMetric = (0, metric_data_1.getOrCreateCounter)(name, { description, ...options });
32
40
  }
33
41
  counterMetric.add(1);
42
+ // @ts-ignore
34
43
  return originalFunction.apply(this, args);
35
44
  };
36
45
  descriptor.value = wrappedFunction;
@@ -1,14 +1,6 @@
1
1
  "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
12
4
  require("reflect-metadata");
13
5
  const common_1 = require("@nestjs/common");
14
6
  const common_2 = require("./common");
@@ -16,14 +8,14 @@ const TestDecoratorThatSetsMetadata = () => (0, common_1.SetMetadata)('some-meta
16
8
  let TestClass = class TestClass {
17
9
  method() { }
18
10
  };
19
- __decorate([
11
+ tslib_1.__decorate([
20
12
  TestDecoratorThatSetsMetadata(),
21
13
  (0, common_2.OtelMethodCounter)(),
22
- __metadata("design:type", Function),
23
- __metadata("design:paramtypes", []),
24
- __metadata("design:returntype", void 0)
14
+ tslib_1.__metadata("design:type", Function),
15
+ tslib_1.__metadata("design:paramtypes", []),
16
+ tslib_1.__metadata("design:returntype", void 0)
25
17
  ], TestClass.prototype, "method", null);
26
- TestClass = __decorate([
18
+ TestClass = tslib_1.__decorate([
27
19
  (0, common_2.OtelInstanceCounter)(),
28
20
  TestDecoratorThatSetsMetadata()
29
21
  ], TestClass);
@@ -1,20 +1,7 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
2
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./common"), exports);
18
- __exportStar(require("./counter"), exports);
19
- __exportStar(require("./histogram"), exports);
20
- __exportStar(require("./observable"), exports);
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./common"), exports);
5
+ tslib_1.__exportStar(require("./counter"), exports);
6
+ tslib_1.__exportStar(require("./histogram"), exports);
7
+ tslib_1.__exportStar(require("./observable"), exports);
@@ -1,4 +1,5 @@
1
- import { Counter, MetricOptions, UpDownCounter, Histogram, ObservableGauge, ObservableCounter, ObservableUpDownCounter } from '@opentelemetry/api';
1
+ import { Counter, UpDownCounter, Histogram, ObservableGauge, ObservableCounter, ObservableUpDownCounter } from '@opentelemetry/api';
2
+ import { OtelMetricOptions } from '../interfaces/metric-options.interface';
2
3
  export type GenericMetric = Counter | UpDownCounter | Histogram | ObservableGauge | ObservableCounter | ObservableUpDownCounter;
3
4
  export declare enum MetricType {
4
5
  'Counter' = "Counter",
@@ -9,9 +10,9 @@ export declare enum MetricType {
9
10
  'ObservableUpDownCounter' = "ObservableUpDownCounter"
10
11
  }
11
12
  export declare const meterData: Map<string, GenericMetric>;
12
- export declare function getOrCreateHistogram(name: string, options?: MetricOptions): Histogram;
13
- export declare function getOrCreateCounter(name: string, options?: MetricOptions): Counter;
14
- export declare function getOrCreateUpDownCounter(name: string, options?: MetricOptions): UpDownCounter;
15
- export declare function getOrCreateObservableGauge(name: string, options?: MetricOptions): ObservableGauge;
16
- export declare function getOrCreateObservableCounter(name: string, options?: MetricOptions): ObservableCounter;
17
- export declare function getOrCreateObservableUpDownCounter(name: string, options?: MetricOptions): ObservableUpDownCounter;
13
+ export declare function getOrCreateHistogram(name: string, options?: OtelMetricOptions): Histogram;
14
+ export declare function getOrCreateCounter(name: string, options?: OtelMetricOptions): Counter;
15
+ export declare function getOrCreateUpDownCounter(name: string, options?: OtelMetricOptions): UpDownCounter;
16
+ export declare function getOrCreateObservableGauge(name: string, options?: OtelMetricOptions): ObservableGauge;
17
+ export declare function getOrCreateObservableCounter(name: string, options?: OtelMetricOptions): ObservableCounter;
18
+ export declare function getOrCreateObservableUpDownCounter(name: string, options?: OtelMetricOptions): ObservableUpDownCounter;
@@ -13,63 +13,37 @@ var MetricType;
13
13
  MetricType["ObservableUpDownCounter"] = "ObservableUpDownCounter";
14
14
  })(MetricType || (exports.MetricType = MetricType = {}));
15
15
  exports.meterData = new Map();
16
- function getOrCreateHistogram(name, options = {}) {
17
- if (exports.meterData.has(name)) {
18
- return exports.meterData.get(name);
16
+ function getOrCreate(name, options = {}, type) {
17
+ const nameWithPrefix = options.prefix ? `${options.prefix}.${name}` : name;
18
+ let metric = exports.meterData.get(nameWithPrefix);
19
+ if (metric === undefined) {
20
+ const meter = api_1.metrics.getMeterProvider().getMeter(opentelemetry_constants_1.OTEL_METER_NAME);
21
+ metric = meter[`create${type}`](nameWithPrefix, options);
22
+ exports.meterData.set(nameWithPrefix, metric);
19
23
  }
20
- const meter = api_1.metrics.getMeterProvider().getMeter(opentelemetry_constants_1.OTEL_METER_NAME);
21
- const histogram = meter.createHistogram(name, options);
22
- exports.meterData.set(name, histogram);
23
- return histogram;
24
+ return metric;
25
+ }
26
+ function getOrCreateHistogram(name, options = {}) {
27
+ return getOrCreate(name, options, MetricType.Histogram);
24
28
  }
25
29
  exports.getOrCreateHistogram = getOrCreateHistogram;
26
30
  function getOrCreateCounter(name, options = {}) {
27
- if (exports.meterData.has(name)) {
28
- return exports.meterData.get(name);
29
- }
30
- const meter = api_1.metrics.getMeterProvider().getMeter(opentelemetry_constants_1.OTEL_METER_NAME);
31
- const counter = meter.createCounter(name, options);
32
- exports.meterData.set(name, counter);
33
- return counter;
31
+ return getOrCreate(name, options, MetricType.Counter);
34
32
  }
35
33
  exports.getOrCreateCounter = getOrCreateCounter;
36
34
  function getOrCreateUpDownCounter(name, options = {}) {
37
- if (exports.meterData.has(name)) {
38
- return exports.meterData.get(name);
39
- }
40
- const meter = api_1.metrics.getMeterProvider().getMeter(opentelemetry_constants_1.OTEL_METER_NAME);
41
- const upDownCounter = meter.createUpDownCounter(name, options);
42
- exports.meterData.set(name, upDownCounter);
43
- return upDownCounter;
35
+ return getOrCreate(name, options, MetricType.UpDownCounter);
44
36
  }
45
37
  exports.getOrCreateUpDownCounter = getOrCreateUpDownCounter;
46
38
  function getOrCreateObservableGauge(name, options = {}) {
47
- if (exports.meterData.has(name)) {
48
- return exports.meterData.get(name);
49
- }
50
- const meter = api_1.metrics.getMeterProvider().getMeter(opentelemetry_constants_1.OTEL_METER_NAME);
51
- const observableGauge = meter.createObservableGauge(name, options);
52
- exports.meterData.set(name, observableGauge);
53
- return observableGauge;
39
+ return getOrCreate(name, options, MetricType.ObservableGauge);
54
40
  }
55
41
  exports.getOrCreateObservableGauge = getOrCreateObservableGauge;
56
42
  function getOrCreateObservableCounter(name, options = {}) {
57
- if (exports.meterData.has(name)) {
58
- return exports.meterData.get(name);
59
- }
60
- const meter = api_1.metrics.getMeterProvider().getMeter(opentelemetry_constants_1.OTEL_METER_NAME);
61
- const observableCounter = meter.createObservableCounter(name, options);
62
- exports.meterData.set(name, observableCounter);
63
- return observableCounter;
43
+ return getOrCreate(name, options, MetricType.ObservableCounter);
64
44
  }
65
45
  exports.getOrCreateObservableCounter = getOrCreateObservableCounter;
66
46
  function getOrCreateObservableUpDownCounter(name, options = {}) {
67
- if (exports.meterData.has(name)) {
68
- return exports.meterData.get(name);
69
- }
70
- const meter = api_1.metrics.getMeterProvider().getMeter(opentelemetry_constants_1.OTEL_METER_NAME);
71
- const observableCounter = meter.createObservableCounter(name, options);
72
- exports.meterData.set(name, observableCounter);
73
- return observableCounter;
47
+ return getOrCreate(name, options, MetricType.ObservableUpDownCounter);
74
48
  }
75
49
  exports.getOrCreateObservableUpDownCounter = getOrCreateObservableUpDownCounter;
@@ -1,9 +1,9 @@
1
- import { MetricOptions } from '@opentelemetry/api';
1
+ import { OtelMetricOptions } from '../interfaces/metric-options.interface';
2
2
  export declare class MetricService {
3
- getCounter(name: string, options?: MetricOptions): import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
4
- getUpDownCounter(name: string, options?: MetricOptions): import("@opentelemetry/api").UpDownCounter<import("@opentelemetry/api").Attributes>;
5
- getHistogram(name: string, options?: MetricOptions): import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
6
- getObservableCounter(name: string, options?: MetricOptions): import("@opentelemetry/api").ObservableCounter;
7
- getObservableGauge(name: string, options?: MetricOptions): import("@opentelemetry/api").ObservableGauge;
8
- getObservableUpDownCounter(name: string, options?: MetricOptions): import("@opentelemetry/api").ObservableUpDownCounter;
3
+ getCounter(name: string, options?: OtelMetricOptions): import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
4
+ getUpDownCounter(name: string, options?: OtelMetricOptions): import("@opentelemetry/api").UpDownCounter<import("@opentelemetry/api").Attributes>;
5
+ getHistogram(name: string, options?: OtelMetricOptions): import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
6
+ getObservableCounter(name: string, options?: OtelMetricOptions): import("@opentelemetry/api").ObservableCounter;
7
+ getObservableGauge(name: string, options?: OtelMetricOptions): import("@opentelemetry/api").ObservableGauge;
8
+ getObservableUpDownCounter(name: string, options?: OtelMetricOptions): import("@opentelemetry/api").ObservableUpDownCounter;
9
9
  }
@@ -1,15 +1,10 @@
1
1
  "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
2
  Object.defineProperty(exports, "__esModule", { value: true });
9
3
  exports.MetricService = void 0;
4
+ const tslib_1 = require("tslib");
10
5
  const common_1 = require("@nestjs/common");
11
6
  const metric_data_1 = require("./metric-data");
12
- let MetricService = exports.MetricService = class MetricService {
7
+ let MetricService = class MetricService {
13
8
  getCounter(name, options) {
14
9
  return (0, metric_data_1.getOrCreateCounter)(name, options);
15
10
  }
@@ -29,6 +24,7 @@ let MetricService = exports.MetricService = class MetricService {
29
24
  return (0, metric_data_1.getOrCreateObservableUpDownCounter)(name, options);
30
25
  }
31
26
  };
32
- exports.MetricService = MetricService = __decorate([
27
+ exports.MetricService = MetricService;
28
+ exports.MetricService = MetricService = tslib_1.__decorate([
33
29
  (0, common_1.Injectable)()
34
30
  ], MetricService);
@@ -1 +1,4 @@
1
+ /**
2
+ * @public
3
+ */
1
4
  export declare function getToken(name: string): string;
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getToken = void 0;
4
+ /**
5
+ * @public
6
+ */
4
7
  function getToken(name) {
5
8
  return `OTEL_METRIC_${name.toUpperCase()}`;
6
9
  }
@@ -4,7 +4,7 @@ import { MetricService } from '../metrics/metric.service';
4
4
  export declare class ApiMetricsMiddleware implements NestMiddleware {
5
5
  private readonly metricService;
6
6
  private readonly options;
7
- private defaultMetricAttributes;
7
+ private defaultAttributes;
8
8
  private httpServerRequestCount;
9
9
  private httpServerResponseCount;
10
10
  private httpServerDuration;
@@ -1,67 +1,67 @@
1
1
  "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
- var __param = (this && this.__param) || function (paramIndex, decorator) {
12
- return function (target, key) { decorator(target, key, paramIndex); }
13
- };
14
2
  Object.defineProperty(exports, "__esModule", { value: true });
15
3
  exports.ApiMetricsMiddleware = void 0;
4
+ const tslib_1 = require("tslib");
16
5
  const common_1 = require("@nestjs/common");
17
- const responseTime = require("response-time");
18
- const urlParser = require("url");
6
+ const response_time_1 = tslib_1.__importDefault(require("response-time"));
7
+ const urlParser = tslib_1.__importStar(require("url"));
19
8
  const metric_service_1 = require("../metrics/metric.service");
20
9
  const opentelemetry_constants_1 = require("../opentelemetry.constants");
21
- let ApiMetricsMiddleware = exports.ApiMetricsMiddleware = class ApiMetricsMiddleware {
10
+ let ApiMetricsMiddleware = class ApiMetricsMiddleware {
22
11
  constructor(metricService, options = {}) {
23
12
  this.metricService = metricService;
24
13
  this.options = options;
25
- const { defaultAttributes = {}, ignoreUndefinedRoutes = false, } = options?.metrics?.apiMetrics ?? {};
26
- this.defaultMetricAttributes = defaultAttributes;
14
+ const { defaultAttributes = {}, ignoreUndefinedRoutes = false, prefix, } = options?.metrics?.apiMetrics ?? {};
15
+ this.defaultAttributes = defaultAttributes;
27
16
  this.ignoreUndefinedRoutes = ignoreUndefinedRoutes;
17
+ // Semantic Convention
28
18
  this.httpServerRequestCount = this.metricService.getCounter('http.server.request.count', {
29
19
  description: 'Total number of HTTP requests',
30
20
  unit: 'requests',
21
+ prefix,
31
22
  });
32
23
  this.httpServerResponseCount = this.metricService.getCounter('http.server.response.count', {
33
24
  description: 'Total number of HTTP responses',
34
25
  unit: 'responses',
26
+ prefix,
35
27
  });
36
28
  this.httpServerAbortCount = this.metricService.getCounter('http.server.abort.count', {
37
29
  description: 'Total number of data transfers aborted',
38
30
  unit: 'requests',
31
+ prefix,
39
32
  });
40
33
  this.httpServerDuration = this.metricService.getHistogram('http.server.duration', {
41
34
  description: 'The duration of the inbound HTTP request',
42
35
  unit: 'ms',
36
+ prefix,
43
37
  });
44
38
  this.httpServerRequestSize = this.metricService.getHistogram('http.server.request.size', {
45
39
  description: 'Size of incoming bytes',
46
40
  unit: 'By',
41
+ prefix,
47
42
  });
48
43
  this.httpServerResponseSize = this.metricService.getHistogram('http.server.response.size', {
49
44
  description: 'Size of outgoing bytes',
50
45
  unit: 'By',
46
+ prefix,
51
47
  });
48
+ // Helpers
52
49
  this.httpServerResponseSuccessCount = this.metricService.getCounter('http.server.response.success.count', {
53
50
  description: 'Total number of all successful responses',
54
51
  unit: 'responses',
52
+ prefix,
55
53
  });
56
54
  this.httpServerResponseErrorCount = this.metricService.getCounter('http.server.response.error.count', {
57
55
  description: 'Total number of all response errors',
56
+ prefix,
58
57
  });
59
58
  this.httpClientRequestErrorCount = this.metricService.getCounter('http.client.request.error.count', {
60
59
  description: 'Total number of client error requests',
60
+ prefix,
61
61
  });
62
62
  }
63
63
  use(req, res, next) {
64
- responseTime((req, res, time) => {
64
+ (0, response_time_1.default)((req, res, time) => {
65
65
  const { route, url, method } = req;
66
66
  let path;
67
67
  if (route) {
@@ -78,7 +78,10 @@ let ApiMetricsMiddleware = exports.ApiMetricsMiddleware = class ApiMetricsMiddle
78
78
  const responseLength = parseInt(res.getHeader('Content-Length'), 10) || 0;
79
79
  const status = res.statusCode || 500;
80
80
  const attributes = {
81
- method, status, path, ...this.defaultMetricAttributes,
81
+ method,
82
+ status,
83
+ path,
84
+ ...this.defaultAttributes,
82
85
  };
83
86
  this.httpServerRequestSize.record(requestLength, attributes);
84
87
  this.httpServerResponseSize.record(responseLength, attributes);
@@ -90,6 +93,7 @@ let ApiMetricsMiddleware = exports.ApiMetricsMiddleware = class ApiMetricsMiddle
90
93
  this.httpServerResponseSuccessCount.add(1);
91
94
  break;
92
95
  case 'redirect':
96
+ // TODO: Review what should be appropriate for redirects.
93
97
  this.httpServerResponseSuccessCount.add(1);
94
98
  break;
95
99
  case 'client_error':
@@ -118,9 +122,10 @@ let ApiMetricsMiddleware = exports.ApiMetricsMiddleware = class ApiMetricsMiddle
118
122
  return 'server_error';
119
123
  }
120
124
  };
121
- exports.ApiMetricsMiddleware = ApiMetricsMiddleware = __decorate([
125
+ exports.ApiMetricsMiddleware = ApiMetricsMiddleware;
126
+ exports.ApiMetricsMiddleware = ApiMetricsMiddleware = tslib_1.__decorate([
122
127
  (0, common_1.Injectable)(),
123
- __param(0, (0, common_1.Inject)(metric_service_1.MetricService)),
124
- __param(1, (0, common_1.Inject)(opentelemetry_constants_1.OPENTELEMETRY_MODULE_OPTIONS)),
125
- __metadata("design:paramtypes", [metric_service_1.MetricService, Object])
128
+ tslib_1.__param(0, (0, common_1.Inject)(metric_service_1.MetricService)),
129
+ tslib_1.__param(1, (0, common_1.Inject)(opentelemetry_constants_1.OPENTELEMETRY_MODULE_OPTIONS)),
130
+ tslib_1.__metadata("design:paramtypes", [metric_service_1.MetricService, Object])
126
131
  ], ApiMetricsMiddleware);
@@ -1,17 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
2
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./api-metrics.middleware"), exports);
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./api-metrics.middleware"), exports);
@@ -1,13 +1,39 @@
1
1
  import { DynamicModule, MiddlewareConsumer, OnApplicationBootstrap } from '@nestjs/common';
2
2
  import { OpenTelemetryModuleAsyncOptions, OpenTelemetryModuleOptions } from './interfaces';
3
+ /**
4
+ * The internal OpenTelemetry Module which handles the integration
5
+ * with the third party OpenTelemetry library and Nest
6
+ *
7
+ * @internal
8
+ */
3
9
  export declare class OpenTelemetryCoreModule implements OnApplicationBootstrap {
4
10
  private readonly options;
5
11
  private readonly logger;
6
12
  constructor(options?: OpenTelemetryModuleOptions);
13
+ /**
14
+ * Bootstraps the internal OpenTelemetry Module with the given options
15
+ * synchronously and sets the correct providers
16
+ * @param options The options to bootstrap the module synchronously
17
+ */
7
18
  static forRoot(options?: OpenTelemetryModuleOptions): DynamicModule;
19
+ /**
20
+ * Bootstraps the internal OpenTelemetry Module with the given
21
+ * options asynchronously and sets the correct providers
22
+ * @param options The options to bootstrap the module
23
+ */
8
24
  static forRootAsync(options: OpenTelemetryModuleAsyncOptions): DynamicModule;
9
25
  configure(consumer: MiddlewareConsumer): void;
10
26
  onApplicationBootstrap(): Promise<void>;
27
+ /**
28
+ * Returns the asynchrnous OpenTelemetry options providers depending on the
29
+ * given module options
30
+ * @param options Options for the asynchrnous OpenTelemetry module
31
+ */
11
32
  private static createAsyncOptionsProvider;
33
+ /**
34
+ * Returns the asynchrnous providers depending on the given module
35
+ * options
36
+ * @param options Options for the asynchrnous OpenTelemetry module
37
+ */
12
38
  private static createAsyncProviders;
13
39
  }
@@ -1,19 +1,8 @@
1
1
  "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
- var __param = (this && this.__param) || function (paramIndex, decorator) {
12
- return function (target, key) { decorator(target, key, paramIndex); }
13
- };
14
2
  var OpenTelemetryCoreModule_1;
15
3
  Object.defineProperty(exports, "__esModule", { value: true });
16
4
  exports.OpenTelemetryCoreModule = void 0;
5
+ const tslib_1 = require("tslib");
17
6
  const common_1 = require("@nestjs/common");
18
7
  const host_metrics_1 = require("@opentelemetry/host-metrics");
19
8
  const api_1 = require("@opentelemetry/api");
@@ -21,11 +10,22 @@ const metric_service_1 = require("./metrics/metric.service");
21
10
  const middleware_1 = require("./middleware");
22
11
  const opentelemetry_constants_1 = require("./opentelemetry.constants");
23
12
  const trace_service_1 = require("./tracing/trace.service");
24
- let OpenTelemetryCoreModule = exports.OpenTelemetryCoreModule = OpenTelemetryCoreModule_1 = class OpenTelemetryCoreModule {
13
+ /**
14
+ * The internal OpenTelemetry Module which handles the integration
15
+ * with the third party OpenTelemetry library and Nest
16
+ *
17
+ * @internal
18
+ */
19
+ let OpenTelemetryCoreModule = OpenTelemetryCoreModule_1 = class OpenTelemetryCoreModule {
25
20
  constructor(options = {}) {
26
21
  this.options = options;
27
22
  this.logger = new common_1.Logger('OpenTelemetryModule');
28
23
  }
24
+ /**
25
+ * Bootstraps the internal OpenTelemetry Module with the given options
26
+ * synchronously and sets the correct providers
27
+ * @param options The options to bootstrap the module synchronously
28
+ */
29
29
  static forRoot(options = {}) {
30
30
  const openTelemetryModuleOptions = {
31
31
  provide: opentelemetry_constants_1.OPENTELEMETRY_MODULE_OPTIONS,
@@ -33,38 +33,32 @@ let OpenTelemetryCoreModule = exports.OpenTelemetryCoreModule = OpenTelemetryCor
33
33
  };
34
34
  return {
35
35
  module: OpenTelemetryCoreModule_1,
36
- providers: [
37
- openTelemetryModuleOptions,
38
- trace_service_1.TraceService,
39
- metric_service_1.MetricService,
40
- ],
41
- exports: [
42
- trace_service_1.TraceService,
43
- metric_service_1.MetricService,
44
- ],
36
+ providers: [openTelemetryModuleOptions, trace_service_1.TraceService, metric_service_1.MetricService],
37
+ exports: [trace_service_1.TraceService, metric_service_1.MetricService],
45
38
  };
46
39
  }
40
+ /**
41
+ * Bootstraps the internal OpenTelemetry Module with the given
42
+ * options asynchronously and sets the correct providers
43
+ * @param options The options to bootstrap the module
44
+ */
47
45
  static forRootAsync(options) {
48
46
  const asyncProviders = this.createAsyncProviders(options);
49
47
  return {
50
48
  module: OpenTelemetryCoreModule_1,
51
49
  imports: [...(options.imports || [])],
52
- providers: [
53
- ...asyncProviders,
54
- trace_service_1.TraceService,
55
- metric_service_1.MetricService,
56
- ],
57
- exports: [
58
- trace_service_1.TraceService,
59
- metric_service_1.MetricService,
60
- ],
50
+ providers: [...asyncProviders, trace_service_1.TraceService, metric_service_1.MetricService],
51
+ exports: [trace_service_1.TraceService, metric_service_1.MetricService],
61
52
  };
62
53
  }
63
54
  configure(consumer) {
64
- const { apiMetrics = { enable: false }, } = this.options?.metrics ?? {};
55
+ const { apiMetrics = { enable: false } } = this.options?.metrics ?? {};
65
56
  if (apiMetrics.enable === true) {
66
57
  if (apiMetrics?.ignoreRoutes && apiMetrics?.ignoreRoutes.length > 0) {
67
- consumer.apply(middleware_1.ApiMetricsMiddleware).exclude(...apiMetrics.ignoreRoutes).forRoutes('*');
58
+ consumer
59
+ .apply(middleware_1.ApiMetricsMiddleware)
60
+ .exclude(...apiMetrics.ignoreRoutes)
61
+ .forRoutes('*');
68
62
  }
69
63
  else {
70
64
  consumer.apply(middleware_1.ApiMetricsMiddleware).forRoutes('*');
@@ -74,8 +68,8 @@ let OpenTelemetryCoreModule = exports.OpenTelemetryCoreModule = OpenTelemetryCor
74
68
  async onApplicationBootstrap() {
75
69
  let hostMetrics = false;
76
70
  if (this.options?.metrics) {
77
- hostMetrics = this.options.metrics.hostMetrics
78
- !== undefined ? this.options.metrics.hostMetrics : false;
71
+ hostMetrics =
72
+ this.options.metrics.hostMetrics !== undefined ? this.options.metrics.hostMetrics : false;
79
73
  }
80
74
  const meterProvider = api_1.metrics.getMeterProvider();
81
75
  if (hostMetrics) {
@@ -83,6 +77,11 @@ let OpenTelemetryCoreModule = exports.OpenTelemetryCoreModule = OpenTelemetryCor
83
77
  host.start();
84
78
  }
85
79
  }
80
+ /**
81
+ * Returns the asynchrnous OpenTelemetry options providers depending on the
82
+ * given module options
83
+ * @param options Options for the asynchrnous OpenTelemetry module
84
+ */
86
85
  static createAsyncOptionsProvider(options) {
87
86
  if (options.useFactory) {
88
87
  return {
@@ -103,6 +102,11 @@ let OpenTelemetryCoreModule = exports.OpenTelemetryCoreModule = OpenTelemetryCor
103
102
  }
104
103
  throw new Error();
105
104
  }
105
+ /**
106
+ * Returns the asynchrnous providers depending on the given module
107
+ * options
108
+ * @param options Options for the asynchrnous OpenTelemetry module
109
+ */
106
110
  static createAsyncProviders(options) {
107
111
  if (options.useFactory || options.useExisting) {
108
112
  return [this.createAsyncOptionsProvider(options)];
@@ -117,9 +121,10 @@ let OpenTelemetryCoreModule = exports.OpenTelemetryCoreModule = OpenTelemetryCor
117
121
  ];
118
122
  }
119
123
  };
120
- exports.OpenTelemetryCoreModule = OpenTelemetryCoreModule = OpenTelemetryCoreModule_1 = __decorate([
124
+ exports.OpenTelemetryCoreModule = OpenTelemetryCoreModule;
125
+ exports.OpenTelemetryCoreModule = OpenTelemetryCoreModule = OpenTelemetryCoreModule_1 = tslib_1.__decorate([
121
126
  (0, common_1.Global)(),
122
127
  (0, common_1.Module)({}),
123
- __param(0, (0, common_1.Inject)(opentelemetry_constants_1.OPENTELEMETRY_MODULE_OPTIONS)),
124
- __metadata("design:paramtypes", [Object])
128
+ tslib_1.__param(0, (0, common_1.Inject)(opentelemetry_constants_1.OPENTELEMETRY_MODULE_OPTIONS)),
129
+ tslib_1.__metadata("design:paramtypes", [Object])
125
130
  ], OpenTelemetryCoreModule);
@@ -1,6 +1,20 @@
1
1
  import { DynamicModule } from '@nestjs/common';
2
2
  import { OpenTelemetryModuleAsyncOptions, OpenTelemetryModuleOptions } from './interfaces';
3
+ /**
4
+ * The NestJS module for OpenTelemetry
5
+ *
6
+ * @publicApi
7
+ */
3
8
  export declare class OpenTelemetryModule {
9
+ /**
10
+ * Bootstraps the OpenTelemetry Module synchronously
11
+ * @param options The options for the OpenTelemetry Module
12
+ */
4
13
  static forRoot(options?: OpenTelemetryModuleOptions): DynamicModule;
14
+ /**
15
+ * Bootstrap the OpenTelemetry Module asynchronously
16
+ * @see https://dev.to/nestjs/advanced-nestjs-how-to-build-completely-dynamic-nestjs-modules-1370
17
+ * @param options The options for the OpenTelemetry module
18
+ */
5
19
  static forRootAsync(options: OpenTelemetryModuleAsyncOptions): DynamicModule;
6
20
  }
@@ -1,22 +1,31 @@
1
1
  "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
2
  var OpenTelemetryModule_1;
9
3
  Object.defineProperty(exports, "__esModule", { value: true });
10
4
  exports.OpenTelemetryModule = void 0;
5
+ const tslib_1 = require("tslib");
11
6
  const common_1 = require("@nestjs/common");
12
7
  const opentelemetry_core_module_1 = require("./opentelemetry-core.module");
13
- let OpenTelemetryModule = exports.OpenTelemetryModule = OpenTelemetryModule_1 = class OpenTelemetryModule {
8
+ /**
9
+ * The NestJS module for OpenTelemetry
10
+ *
11
+ * @publicApi
12
+ */
13
+ let OpenTelemetryModule = OpenTelemetryModule_1 = class OpenTelemetryModule {
14
+ /**
15
+ * Bootstraps the OpenTelemetry Module synchronously
16
+ * @param options The options for the OpenTelemetry Module
17
+ */
14
18
  static forRoot(options) {
15
19
  return {
16
20
  module: OpenTelemetryModule_1,
17
21
  imports: [opentelemetry_core_module_1.OpenTelemetryCoreModule.forRoot(options)],
18
22
  };
19
23
  }
24
+ /**
25
+ * Bootstrap the OpenTelemetry Module asynchronously
26
+ * @see https://dev.to/nestjs/advanced-nestjs-how-to-build-completely-dynamic-nestjs-modules-1370
27
+ * @param options The options for the OpenTelemetry module
28
+ */
20
29
  static forRootAsync(options) {
21
30
  return {
22
31
  module: OpenTelemetryModule_1,
@@ -24,6 +33,7 @@ let OpenTelemetryModule = exports.OpenTelemetryModule = OpenTelemetryModule_1 =
24
33
  };
25
34
  }
26
35
  };
27
- exports.OpenTelemetryModule = OpenTelemetryModule = OpenTelemetryModule_1 = __decorate([
36
+ exports.OpenTelemetryModule = OpenTelemetryModule;
37
+ exports.OpenTelemetryModule = OpenTelemetryModule = OpenTelemetryModule_1 = tslib_1.__decorate([
28
38
  (0, common_1.Module)({})
29
39
  ], OpenTelemetryModule);
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.copyMetadataFromFunctionToFunction = void 0;
4
4
  const copyMetadataFromFunctionToFunction = (originalFunction, newFunction) => {
5
+ // Get the current metadata and set onto the wrapper
6
+ // to ensure other decorators ( ie: NestJS EventPattern / RolesGuard )
7
+ // won't be affected by the use of this instrumentation
5
8
  Reflect.getMetadataKeys(originalFunction).forEach(metadataKey => {
6
9
  Reflect.defineMetadata(metadataKey, Reflect.getMetadata(metadataKey, originalFunction), newFunction);
7
10
  });
@@ -1,2 +1,2 @@
1
1
  import { SpanOptions } from '@opentelemetry/api';
2
- export declare function Span(name?: string, options?: SpanOptions): (target: any, propertyKey: string, propertyDescriptor: PropertyDescriptor) => void;
2
+ export declare function Span(name?: string, options?: SpanOptions): (target: any, propertyKey: PropertyKey, propertyDescriptor: PropertyDescriptor) => void;
@@ -12,24 +12,29 @@ function Span(name, options = {}) {
12
12
  const originalFunction = propertyDescriptor.value;
13
13
  const wrappedFunction = function PropertyDescriptor(...args) {
14
14
  const tracer = api_1.trace.getTracer('default');
15
- const spanName = name || `${target.constructor.name}.${propertyKey}`;
15
+ const spanName = name || `${target.constructor.name}.${String(propertyKey)}`;
16
16
  return tracer.startActiveSpan(spanName, options, span => {
17
17
  if (originalFunction.constructor.name === 'AsyncFunction') {
18
- return originalFunction
18
+ return (originalFunction
19
+ // @ts-ignore
19
20
  .apply(this, args)
21
+ // @ts-ignore
20
22
  .catch(error => {
21
23
  recordException(span, error);
24
+ // Throw error to propagate it further
22
25
  throw error;
23
26
  })
24
27
  .finally(() => {
25
28
  span.end();
26
- });
29
+ }));
27
30
  }
28
31
  try {
32
+ // @ts-ignore
29
33
  return originalFunction.apply(this, args);
30
34
  }
31
35
  catch (error) {
32
36
  recordException(span, error);
37
+ // Throw error to propagate it further
33
38
  throw error;
34
39
  }
35
40
  finally {
@@ -1,20 +1,14 @@
1
1
  "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
2
+ var _a;
11
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
+ const tslib_1 = require("tslib");
12
5
  require("reflect-metadata");
13
6
  const api_1 = require("@opentelemetry/api");
14
7
  const sdk_trace_node_1 = require("@opentelemetry/sdk-trace-node");
15
8
  const common_1 = require("@nestjs/common");
16
9
  const span_1 = require("./span");
17
10
  const TestDecoratorThatSetsMetadata = () => (0, common_1.SetMetadata)('some-metadata', true);
11
+ const symbol = Symbol('testSymbol');
18
12
  class TestSpan {
19
13
  singleSpan() { }
20
14
  doubleSpan() {
@@ -25,38 +19,45 @@ class TestSpan {
25
19
  throw new Error('hello world');
26
20
  }
27
21
  metadata() { }
22
+ [_a = symbol]() { }
28
23
  }
29
- __decorate([
24
+ tslib_1.__decorate([
30
25
  (0, span_1.Span)(),
31
- __metadata("design:type", Function),
32
- __metadata("design:paramtypes", []),
33
- __metadata("design:returntype", void 0)
26
+ tslib_1.__metadata("design:type", Function),
27
+ tslib_1.__metadata("design:paramtypes", []),
28
+ tslib_1.__metadata("design:returntype", void 0)
34
29
  ], TestSpan.prototype, "singleSpan", null);
35
- __decorate([
30
+ tslib_1.__decorate([
36
31
  (0, span_1.Span)(),
37
- __metadata("design:type", Function),
38
- __metadata("design:paramtypes", []),
39
- __metadata("design:returntype", void 0)
32
+ tslib_1.__metadata("design:type", Function),
33
+ tslib_1.__metadata("design:paramtypes", []),
34
+ tslib_1.__metadata("design:returntype", void 0)
40
35
  ], TestSpan.prototype, "doubleSpan", null);
41
- __decorate([
36
+ tslib_1.__decorate([
42
37
  (0, span_1.Span)('foo', { kind: api_1.SpanKind.PRODUCER }),
43
- __metadata("design:type", Function),
44
- __metadata("design:paramtypes", []),
45
- __metadata("design:returntype", void 0)
38
+ tslib_1.__metadata("design:type", Function),
39
+ tslib_1.__metadata("design:paramtypes", []),
40
+ tslib_1.__metadata("design:returntype", void 0)
46
41
  ], TestSpan.prototype, "fooProducerSpan", null);
47
- __decorate([
42
+ tslib_1.__decorate([
48
43
  (0, span_1.Span)(),
49
- __metadata("design:type", Function),
50
- __metadata("design:paramtypes", []),
51
- __metadata("design:returntype", void 0)
44
+ tslib_1.__metadata("design:type", Function),
45
+ tslib_1.__metadata("design:paramtypes", []),
46
+ tslib_1.__metadata("design:returntype", void 0)
52
47
  ], TestSpan.prototype, "error", null);
53
- __decorate([
48
+ tslib_1.__decorate([
54
49
  (0, span_1.Span)(),
55
50
  TestDecoratorThatSetsMetadata(),
56
- __metadata("design:type", Function),
57
- __metadata("design:paramtypes", []),
58
- __metadata("design:returntype", void 0)
51
+ tslib_1.__metadata("design:type", Function),
52
+ tslib_1.__metadata("design:paramtypes", []),
53
+ tslib_1.__metadata("design:returntype", void 0)
59
54
  ], TestSpan.prototype, "metadata", null);
55
+ tslib_1.__decorate([
56
+ (0, span_1.Span)(),
57
+ tslib_1.__metadata("design:type", Function),
58
+ tslib_1.__metadata("design:paramtypes", []),
59
+ tslib_1.__metadata("design:returntype", void 0)
60
+ ], TestSpan.prototype, _a, null);
60
61
  describe('Span', () => {
61
62
  let instance;
62
63
  let traceExporter;
@@ -111,6 +112,7 @@ describe('Span', () => {
111
112
  expect(instance.error).toThrowError('hello world');
112
113
  const spans = traceExporter.getFinishedSpans();
113
114
  expect(spans).toHaveLength(1);
115
+ // Contain one exception event
114
116
  expect(spans[0].events).toHaveLength(1);
115
117
  expect(spans[0].events[0]).toEqual({
116
118
  name: 'exception',
@@ -119,4 +121,10 @@ describe('Span', () => {
119
121
  time: expect.anything(),
120
122
  });
121
123
  });
124
+ it('should handle symbols', () => {
125
+ instance[symbol]();
126
+ const spans = traceExporter.getFinishedSpans();
127
+ expect(spans).toHaveLength(1);
128
+ expect(spans.map(span => span.name)).toEqual(['TestSpan.Symbol(testSymbol)']);
129
+ });
122
130
  });
@@ -1,15 +1,10 @@
1
1
  "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
2
  Object.defineProperty(exports, "__esModule", { value: true });
9
3
  exports.TraceService = void 0;
4
+ const tslib_1 = require("tslib");
10
5
  const api_1 = require("@opentelemetry/api");
11
6
  const common_1 = require("@nestjs/common");
12
- let TraceService = exports.TraceService = class TraceService {
7
+ let TraceService = class TraceService {
13
8
  getTracer() {
14
9
  return api_1.trace.getTracer('default');
15
10
  }
@@ -20,6 +15,7 @@ let TraceService = exports.TraceService = class TraceService {
20
15
  return this.getTracer().startSpan(name);
21
16
  }
22
17
  };
23
- exports.TraceService = TraceService = __decorate([
18
+ exports.TraceService = TraceService;
19
+ exports.TraceService = TraceService = tslib_1.__decorate([
24
20
  (0, common_1.Injectable)()
25
21
  ], TraceService);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nestjs-otel",
3
- "version": "5.1.5",
3
+ "version": "6.1.0",
4
4
  "description": "NestJS OpenTelemetry Library",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index",
@@ -8,8 +8,8 @@
8
8
  "prebuild": "rimraf lib",
9
9
  "prepare": "husky install",
10
10
  "build": "tsc",
11
- "lint": "eslint . --ext .js,ts",
12
- "format": "eslint . --ext .js,ts --fix",
11
+ "lint": "prettier --check ./**/*.{js,json,ts}",
12
+ "format": "prettier --write ./**/*.{js,json,ts}",
13
13
  "test": "npm run test:unit && npm run test:e2e",
14
14
  "test:coverage": "jest --coverage",
15
15
  "test:unit": "jest --passWithNoTests",
@@ -36,40 +36,36 @@
36
36
  },
37
37
  "homepage": "https://github.com/pragmaticivan/nestjs-otel#readme",
38
38
  "dependencies": {
39
- "@opentelemetry/api": "^1.4.1",
40
- "@opentelemetry/host-metrics": "^0.32.2",
39
+ "@opentelemetry/api": "^1.8.0",
40
+ "@opentelemetry/host-metrics": "^0.35.1",
41
41
  "response-time": "^2.3.2"
42
42
  },
43
43
  "devDependencies": {
44
- "@commitlint/cli": "^17.6.6",
45
- "@commitlint/config-conventional": "^17.6.6",
46
- "@nestjs/common": "^10.0.5",
47
- "@nestjs/core": "^10.0.5",
48
- "@nestjs/platform-express": "^10.0.5",
49
- "@nestjs/platform-fastify": "^10.0.5",
50
- "@nestjs/testing": "^10.0.5",
51
- "@opentelemetry/exporter-prometheus": "^0.40.0",
52
- "@opentelemetry/sdk-metrics": "^1.14.0",
53
- "@opentelemetry/sdk-trace-node": "^1.14.0",
54
- "@types/jest": "^29.5.2",
55
- "@types/node": "^20.3.3",
56
- "@types/supertest": "^2.0.12",
57
- "@typescript-eslint/eslint-plugin": "5.61.0",
58
- "@typescript-eslint/parser": "5.61.0",
44
+ "@commitlint/cli": "^19.3.0",
45
+ "@commitlint/config-conventional": "^19.2.2",
46
+ "@nestjs/common": "^10.3.8",
47
+ "@nestjs/core": "^10.3.8",
48
+ "@nestjs/platform-express": "^10.3.8",
49
+ "@nestjs/platform-fastify": "^10.3.8",
50
+ "@nestjs/testing": "^10.3.8",
51
+ "@opentelemetry/exporter-prometheus": "^0.51.1",
52
+ "@opentelemetry/sdk-metrics": "^1.24.1",
53
+ "@opentelemetry/sdk-trace-node": "^1.24.1",
54
+ "@types/jest": "^29.5.12",
55
+ "@types/node": "^20.12.10",
56
+ "@types/response-time": "^2.3.8",
57
+ "@types/supertest": "^6.0.2",
59
58
  "ansi-regex": "",
60
- "eslint": "^8.44.0",
61
- "eslint-config-airbnb-base": "^15.0.0",
62
- "eslint-config-airbnb-typescript": "^17.0.0",
63
- "eslint-plugin-import": "^2.27.5",
64
- "husky": "^8.0.3",
65
- "jest": "^29.6.0",
66
- "lint-staged": "^13.2.3",
67
- "reflect-metadata": "^0.1.13",
68
- "rimraf": "^5.0.1",
59
+ "husky": "^9.0.11",
60
+ "jest": "^29.7.0",
61
+ "lint-staged": "^15.2.2",
62
+ "prettier": "^3.2.5",
63
+ "reflect-metadata": "^0.2.2",
64
+ "rimraf": "^5.0.5",
69
65
  "rxjs": "^7.8.1",
70
- "supertest": "^6.3.3",
71
- "ts-jest": "^29.1.1",
72
- "typescript": "5.1.6"
66
+ "supertest": "^7.0.0",
67
+ "ts-jest": "^29.1.2",
68
+ "typescript": "5.4.5"
73
69
  },
74
70
  "peerDependencies": {
75
71
  "@nestjs/common": "^9.0.0 || ^10.0.0",
@@ -94,7 +90,9 @@
94
90
  "testEnvironment": "node"
95
91
  },
96
92
  "lint-staged": {
97
- "!(examples/**/*)*.{js,ts}": "eslint --cache --fix"
93
+ "**/*.{js,ts,json}": [
94
+ "prettier --write"
95
+ ]
98
96
  },
99
97
  "commitlint": {
100
98
  "extends": [