@tramvai/module-opentelemetry 5.22.0 → 5.40.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.
@@ -0,0 +1,12 @@
1
+ /// <reference types="node" />
2
+ export declare const providers: import("@tramvai/core").Provider<{
3
+ tracer: import("../tokens").TramvaiTracer & {
4
+ __type?: "base token" | undefined;
5
+ };
6
+ request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>> & {
7
+ __type?: "base token" | undefined;
8
+ };
9
+ }, import("@tinkoff/router").RouterPlugin & {
10
+ __type?: "multi token" | undefined;
11
+ }>[];
12
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1,115 @@
1
+ import { isRedirectFoundError, isNotFoundError } from '@tinkoff/errors';
2
+ import { provide } from '@tramvai/core';
3
+ import { ROUTER_PLUGIN } from '@tramvai/tokens-router';
4
+ import { SpanKind } from '@opentelemetry/api';
5
+ import { ATTR_URL_PATH, ATTR_HTTP_ROUTE, ATTR_URL_QUERY, ATTR_URL_FULL } from '@opentelemetry/semantic-conventions';
6
+ import { FASTIFY_REQUEST } from '@tramvai/tokens-server-private';
7
+ import { OPENTELEMETRY_TRACER_TOKEN } from '../tokens.es.js';
8
+ import { REQUEST_SPAN } from './server.es.js';
9
+
10
+ function skipError(error) {
11
+ return isRedirectFoundError(error) || isNotFoundError(error);
12
+ }
13
+ class OpentelemetryRouterPlugin {
14
+ constructor({ tracer, request }) {
15
+ this.tracer = tracer;
16
+ this.request = request;
17
+ }
18
+ apply(router) {
19
+ router.navigateHook.wrap(async (_, payload, next) => {
20
+ return this.tracer.trace(`navigate`, { kind: SpanKind.SERVER }, async (span) => {
21
+ const url = typeof payload.navigateOptions === 'string'
22
+ ? payload.navigateOptions
23
+ : payload.navigateOptions.url;
24
+ span.setAttribute('tramvai.scope', 'router');
25
+ if (url) {
26
+ span.setAttribute(ATTR_URL_PATH, url);
27
+ }
28
+ await next(payload);
29
+ }, { skipError });
30
+ });
31
+ // TODO: is updateCurrentRoute tracing necessary at server-side?
32
+ // router.updateHook.wrap(async (_, payload, next) => {
33
+ // return this.tracer.trace(`update`, { kind: SpanKind.SERVER }, async (span) => {
34
+ // span.setAttribute('tramvai.scope', 'router');
35
+ // await next(payload);
36
+ // });
37
+ // });
38
+ router.runNavigateHook.wrap(async (_, payload, next) => {
39
+ return this.tracer.trace(`run navigate`, { kind: SpanKind.SERVER }, async (span) => {
40
+ span.setAttribute('tramvai.scope', 'router');
41
+ if (payload.navigation.to && payload.navigation.url) {
42
+ const { path } = payload.navigation.to;
43
+ const { pathname, search, href } = payload.navigation.url;
44
+ span.setAttribute(ATTR_HTTP_ROUTE, path);
45
+ span.setAttribute(ATTR_URL_PATH, pathname);
46
+ span.setAttribute(ATTR_URL_QUERY, search.replace('?', ''));
47
+ span.setAttribute(ATTR_URL_FULL, href);
48
+ // bubble current page route to root server request span
49
+ if (this.request[REQUEST_SPAN]) {
50
+ this.request[REQUEST_SPAN].setAttribute(ATTR_HTTP_ROUTE, path);
51
+ }
52
+ }
53
+ await next(payload);
54
+ });
55
+ });
56
+ router.redirectHook.wrap(async (_, payload, next) => {
57
+ return this.tracer.trace(`redirect`, { kind: SpanKind.SERVER }, async (span) => {
58
+ span.setAttribute('tramvai.scope', 'router');
59
+ if (payload.navigation.url) {
60
+ // TODO не корректный урл, как будто уже после модификации
61
+ span.setAttribute('tramvai.router.redirect.from', payload.navigation.fromUrl.href);
62
+ span.setAttribute('tramvai.router.redirect.to', payload.navigation.url.href);
63
+ if (payload.navigation.code) {
64
+ span.setAttribute('tramvai.router.redirect.code', payload.navigation.code);
65
+ }
66
+ }
67
+ await next(payload);
68
+ });
69
+ });
70
+ router.notfoundHook.wrap(async (_, payload, next) => {
71
+ return this.tracer.trace(`notfound`, { kind: SpanKind.SERVER }, async (span) => {
72
+ span.setAttribute('tramvai.scope', 'router');
73
+ if (payload.navigation.url) {
74
+ span.setAttribute('tramvai.router.notfound.url', payload.navigation.url.href);
75
+ }
76
+ await next(payload);
77
+ });
78
+ });
79
+ router.blockHook.wrap(async (_, payload, next) => {
80
+ return this.tracer.trace(`block`, { kind: SpanKind.SERVER }, async (span) => {
81
+ span.setAttribute('tramvai.scope', 'router');
82
+ if (payload.navigation.url) {
83
+ span.setAttribute('tramvai.router.block.url', payload.navigation.url.href);
84
+ }
85
+ await next(payload);
86
+ });
87
+ });
88
+ for (const [hookName, hook] of router.hooks.entries()) {
89
+ hook.wrap(async (_, payload, next) => {
90
+ return this.tracer.trace(`${hookName} hooks`, { kind: SpanKind.SERVER }, async (span) => {
91
+ span.setAttribute('tramvai.scope', 'router');
92
+ await next(payload);
93
+ });
94
+ });
95
+ }
96
+ router.guards.wrap(async (_, payload, next) => {
97
+ return this.tracer.trace(`guards`, { kind: SpanKind.SERVER }, async (span) => {
98
+ span.setAttribute('tramvai.scope', 'router');
99
+ await next(payload);
100
+ });
101
+ });
102
+ }
103
+ }
104
+ const providers = [
105
+ provide({
106
+ provide: ROUTER_PLUGIN,
107
+ useClass: OpentelemetryRouterPlugin,
108
+ deps: {
109
+ tracer: OPENTELEMETRY_TRACER_TOKEN,
110
+ request: FASTIFY_REQUEST,
111
+ },
112
+ }),
113
+ ];
114
+
115
+ export { providers };
@@ -0,0 +1,119 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var errors = require('@tinkoff/errors');
6
+ var core = require('@tramvai/core');
7
+ var tokensRouter = require('@tramvai/tokens-router');
8
+ var api = require('@opentelemetry/api');
9
+ var semanticConventions = require('@opentelemetry/semantic-conventions');
10
+ var tokensServerPrivate = require('@tramvai/tokens-server-private');
11
+ var tokens = require('../tokens.js');
12
+ var server = require('./server.js');
13
+
14
+ function skipError(error) {
15
+ return errors.isRedirectFoundError(error) || errors.isNotFoundError(error);
16
+ }
17
+ class OpentelemetryRouterPlugin {
18
+ constructor({ tracer, request }) {
19
+ this.tracer = tracer;
20
+ this.request = request;
21
+ }
22
+ apply(router) {
23
+ router.navigateHook.wrap(async (_, payload, next) => {
24
+ return this.tracer.trace(`navigate`, { kind: api.SpanKind.SERVER }, async (span) => {
25
+ const url = typeof payload.navigateOptions === 'string'
26
+ ? payload.navigateOptions
27
+ : payload.navigateOptions.url;
28
+ span.setAttribute('tramvai.scope', 'router');
29
+ if (url) {
30
+ span.setAttribute(semanticConventions.ATTR_URL_PATH, url);
31
+ }
32
+ await next(payload);
33
+ }, { skipError });
34
+ });
35
+ // TODO: is updateCurrentRoute tracing necessary at server-side?
36
+ // router.updateHook.wrap(async (_, payload, next) => {
37
+ // return this.tracer.trace(`update`, { kind: SpanKind.SERVER }, async (span) => {
38
+ // span.setAttribute('tramvai.scope', 'router');
39
+ // await next(payload);
40
+ // });
41
+ // });
42
+ router.runNavigateHook.wrap(async (_, payload, next) => {
43
+ return this.tracer.trace(`run navigate`, { kind: api.SpanKind.SERVER }, async (span) => {
44
+ span.setAttribute('tramvai.scope', 'router');
45
+ if (payload.navigation.to && payload.navigation.url) {
46
+ const { path } = payload.navigation.to;
47
+ const { pathname, search, href } = payload.navigation.url;
48
+ span.setAttribute(semanticConventions.ATTR_HTTP_ROUTE, path);
49
+ span.setAttribute(semanticConventions.ATTR_URL_PATH, pathname);
50
+ span.setAttribute(semanticConventions.ATTR_URL_QUERY, search.replace('?', ''));
51
+ span.setAttribute(semanticConventions.ATTR_URL_FULL, href);
52
+ // bubble current page route to root server request span
53
+ if (this.request[server.REQUEST_SPAN]) {
54
+ this.request[server.REQUEST_SPAN].setAttribute(semanticConventions.ATTR_HTTP_ROUTE, path);
55
+ }
56
+ }
57
+ await next(payload);
58
+ });
59
+ });
60
+ router.redirectHook.wrap(async (_, payload, next) => {
61
+ return this.tracer.trace(`redirect`, { kind: api.SpanKind.SERVER }, async (span) => {
62
+ span.setAttribute('tramvai.scope', 'router');
63
+ if (payload.navigation.url) {
64
+ // TODO не корректный урл, как будто уже после модификации
65
+ span.setAttribute('tramvai.router.redirect.from', payload.navigation.fromUrl.href);
66
+ span.setAttribute('tramvai.router.redirect.to', payload.navigation.url.href);
67
+ if (payload.navigation.code) {
68
+ span.setAttribute('tramvai.router.redirect.code', payload.navigation.code);
69
+ }
70
+ }
71
+ await next(payload);
72
+ });
73
+ });
74
+ router.notfoundHook.wrap(async (_, payload, next) => {
75
+ return this.tracer.trace(`notfound`, { kind: api.SpanKind.SERVER }, async (span) => {
76
+ span.setAttribute('tramvai.scope', 'router');
77
+ if (payload.navigation.url) {
78
+ span.setAttribute('tramvai.router.notfound.url', payload.navigation.url.href);
79
+ }
80
+ await next(payload);
81
+ });
82
+ });
83
+ router.blockHook.wrap(async (_, payload, next) => {
84
+ return this.tracer.trace(`block`, { kind: api.SpanKind.SERVER }, async (span) => {
85
+ span.setAttribute('tramvai.scope', 'router');
86
+ if (payload.navigation.url) {
87
+ span.setAttribute('tramvai.router.block.url', payload.navigation.url.href);
88
+ }
89
+ await next(payload);
90
+ });
91
+ });
92
+ for (const [hookName, hook] of router.hooks.entries()) {
93
+ hook.wrap(async (_, payload, next) => {
94
+ return this.tracer.trace(`${hookName} hooks`, { kind: api.SpanKind.SERVER }, async (span) => {
95
+ span.setAttribute('tramvai.scope', 'router');
96
+ await next(payload);
97
+ });
98
+ });
99
+ }
100
+ router.guards.wrap(async (_, payload, next) => {
101
+ return this.tracer.trace(`guards`, { kind: api.SpanKind.SERVER }, async (span) => {
102
+ span.setAttribute('tramvai.scope', 'router');
103
+ await next(payload);
104
+ });
105
+ });
106
+ }
107
+ }
108
+ const providers = [
109
+ core.provide({
110
+ provide: tokensRouter.ROUTER_PLUGIN,
111
+ useClass: OpentelemetryRouterPlugin,
112
+ deps: {
113
+ tracer: tokens.OPENTELEMETRY_TRACER_TOKEN,
114
+ request: tokensServerPrivate.FASTIFY_REQUEST,
115
+ },
116
+ }),
117
+ ];
118
+
119
+ exports.providers = providers;
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { type Span } from '@opentelemetry/api';
3
- declare const REQUEST_SPAN: unique symbol;
3
+ export declare const REQUEST_SPAN: unique symbol;
4
4
  declare module 'fastify' {
5
5
  interface FastifyRequest {
6
6
  [REQUEST_SPAN]?: Span;
@@ -16,10 +16,12 @@ export declare const providers: (import("@tramvai/core").Provider<{
16
16
  tracesExcludePaths: string & {
17
17
  __type?: "multi token" | undefined;
18
18
  };
19
+ envManager: import("@tramvai/tokens-common").EnvironmentManager & {
20
+ __type?: "base token" | undefined;
21
+ };
19
22
  }, import("@tramvai/tokens-server-private").FASTIFY_APP_INIT_HANDLER & {
20
23
  __type?: "multi token" | undefined;
21
24
  }> | import("@tramvai/core").Provider<{}, import("@tramvai/tokens-server-private").FASTIFY_APP_ERROR_HANDLER & {
22
25
  __type?: "multi token" | undefined;
23
26
  }>)[];
24
- export {};
25
27
  //# sourceMappingURL=server.d.ts.map
@@ -1,4 +1,4 @@
1
- import { ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_ROUTE, ATTR_URL_PATH, ATTR_URL_QUERY, ATTR_URL_SCHEME, ATTR_URL_FULL, ATTR_HTTP_RESPONSE_STATUS_CODE } from '@opentelemetry/semantic-conventions';
1
+ import { ATTR_HTTP_REQUEST_METHOD, ATTR_SERVER_ADDRESS, ATTR_SERVER_PORT, ATTR_HTTP_ROUTE, ATTR_URL_PATH, ATTR_URL_QUERY, ATTR_URL_SCHEME, ATTR_URL_FULL, ATTR_HTTP_RESPONSE_STATUS_CODE } from '@opentelemetry/semantic-conventions';
2
2
  import { propagation, ROOT_CONTEXT, SpanKind, SpanStatusCode } from '@opentelemetry/api';
3
3
  import pathToRegexp from 'path-to-regexp';
4
4
  import flatten from '@tinkoff/utils/array/flatten';
@@ -6,13 +6,14 @@ import { isNotFoundError, isHttpError } from '@tinkoff/errors';
6
6
  import { provide } from '@tramvai/core';
7
7
  import { UTILITY_SERVER_PATHS } from '@tramvai/tokens-server';
8
8
  import { WEB_FASTIFY_APP_INIT_TOKEN, WEB_FASTIFY_APP_TOKEN, WEB_FASTIFY_APP_AFTER_ERROR_TOKEN } from '@tramvai/tokens-server-private';
9
+ import { ENV_MANAGER_TOKEN } from '@tramvai/tokens-common';
9
10
  import { OPENTELEMETRY_TRACER_TOKEN } from '../tokens.es.js';
10
11
 
11
12
  const REQUEST_SPAN = Symbol('opentelemetry.tramvai.server.request.span');
12
13
  const providers = [
13
14
  provide({
14
15
  provide: WEB_FASTIFY_APP_INIT_TOKEN,
15
- useFactory: ({ app, tracer, tracesExcludePaths }) => {
16
+ useFactory: ({ app, tracer, tracesExcludePaths, envManager }) => {
16
17
  return () => {
17
18
  // todo copypaste from @tinkoff/measure-fastify-requests
18
19
  const excludePatterns = flatten(tracesExcludePaths).map((p) => pathToRegexp(p));
@@ -50,6 +51,8 @@ const providers = [
50
51
  span.setAttribute('tramvai.server.framework', 'fastify');
51
52
  // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/attributes-registry/http.md
52
53
  span.setAttribute(ATTR_HTTP_REQUEST_METHOD, httpMethod);
54
+ span.setAttribute(ATTR_SERVER_ADDRESS, req.headers['x-original-host'] || req.headers.host || envManager.get('PORT'));
55
+ span.setAttribute(ATTR_SERVER_PORT, envManager.get('PORT'));
53
56
  // route should have low-cardinality - https://github.com/open-telemetry/semantic-conventions/blob/main/docs/attributes-registry/http.md
54
57
  span.setAttribute(ATTR_HTTP_ROUTE, httpRoute);
55
58
  span.setAttribute(ATTR_URL_PATH, parsedUrl.pathname);
@@ -76,6 +79,7 @@ const providers = [
76
79
  app: WEB_FASTIFY_APP_TOKEN,
77
80
  tracer: OPENTELEMETRY_TRACER_TOKEN,
78
81
  tracesExcludePaths: UTILITY_SERVER_PATHS,
82
+ envManager: ENV_MANAGER_TOKEN,
79
83
  },
80
84
  }),
81
85
  provide({
@@ -116,4 +120,4 @@ const providers = [
116
120
  }),
117
121
  ];
118
122
 
119
- export { providers };
123
+ export { REQUEST_SPAN, providers };
@@ -10,6 +10,7 @@ var errors = require('@tinkoff/errors');
10
10
  var core = require('@tramvai/core');
11
11
  var tokensServer = require('@tramvai/tokens-server');
12
12
  var tokensServerPrivate = require('@tramvai/tokens-server-private');
13
+ var tokensCommon = require('@tramvai/tokens-common');
13
14
  var tokens = require('../tokens.js');
14
15
 
15
16
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -21,7 +22,7 @@ const REQUEST_SPAN = Symbol('opentelemetry.tramvai.server.request.span');
21
22
  const providers = [
22
23
  core.provide({
23
24
  provide: tokensServerPrivate.WEB_FASTIFY_APP_INIT_TOKEN,
24
- useFactory: ({ app, tracer, tracesExcludePaths }) => {
25
+ useFactory: ({ app, tracer, tracesExcludePaths, envManager }) => {
25
26
  return () => {
26
27
  // todo copypaste from @tinkoff/measure-fastify-requests
27
28
  const excludePatterns = flatten__default["default"](tracesExcludePaths).map((p) => pathToRegexp__default["default"](p));
@@ -59,6 +60,8 @@ const providers = [
59
60
  span.setAttribute('tramvai.server.framework', 'fastify');
60
61
  // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/attributes-registry/http.md
61
62
  span.setAttribute(semanticConventions.ATTR_HTTP_REQUEST_METHOD, httpMethod);
63
+ span.setAttribute(semanticConventions.ATTR_SERVER_ADDRESS, req.headers['x-original-host'] || req.headers.host || envManager.get('PORT'));
64
+ span.setAttribute(semanticConventions.ATTR_SERVER_PORT, envManager.get('PORT'));
62
65
  // route should have low-cardinality - https://github.com/open-telemetry/semantic-conventions/blob/main/docs/attributes-registry/http.md
63
66
  span.setAttribute(semanticConventions.ATTR_HTTP_ROUTE, httpRoute);
64
67
  span.setAttribute(semanticConventions.ATTR_URL_PATH, parsedUrl.pathname);
@@ -85,6 +88,7 @@ const providers = [
85
88
  app: tokensServerPrivate.WEB_FASTIFY_APP_TOKEN,
86
89
  tracer: tokens.OPENTELEMETRY_TRACER_TOKEN,
87
90
  tracesExcludePaths: tokensServer.UTILITY_SERVER_PATHS,
91
+ envManager: tokensCommon.ENV_MANAGER_TOKEN,
88
92
  },
89
93
  }),
90
94
  core.provide({
@@ -125,4 +129,5 @@ const providers = [
125
129
  }),
126
130
  ];
127
131
 
132
+ exports.REQUEST_SPAN = REQUEST_SPAN;
128
133
  exports.providers = providers;
package/lib/server.es.js CHANGED
@@ -2,8 +2,8 @@ import { __decorate } from 'tslib';
2
2
  import { Module, provide, commandLineListTokens, optional, APP_INFO_TOKEN } from '@tramvai/core';
3
3
  import { NodeTracerProvider, SimpleSpanProcessor, ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node';
4
4
  import { Resource } from '@opentelemetry/resources';
5
- import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
6
- import { LOGGER_TOKEN } from '@tramvai/tokens-common';
5
+ import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
6
+ import { LOGGER_TOKEN, ENV_MANAGER_TOKEN } from '@tramvai/tokens-common';
7
7
  import { OPENTELEMETRY_PROVIDER_TOKEN, OPENTELEMETRY_PROVIDER_CONFIG_TOKEN, OPENTELEMETRY_PROVIDER_RESOURCE_TOKEN, OPENTELEMETRY_PROVIDER_SPAN_PROCESSOR_TOKEN, OPENTELEMETRY_PROVIDER_RESOURCE_ATTRIBUTES_TOKEN, OPENTELEMETRY_TRACER_TOKEN } from './tokens.es.js';
8
8
  export { OPENTELEMETRY_PROVIDER_CONFIG_TOKEN, OPENTELEMETRY_PROVIDER_RESOURCE_ATTRIBUTES_TOKEN, OPENTELEMETRY_PROVIDER_RESOURCE_TOKEN, OPENTELEMETRY_PROVIDER_SPAN_PROCESSOR_TOKEN, OPENTELEMETRY_PROVIDER_TOKEN, OPENTELEMETRY_TRACER_TOKEN } from './tokens.es.js';
9
9
  import { TramvaiTracerImpl } from './tracer/tracer.es.js';
@@ -11,6 +11,7 @@ import { providers } from './instrumentation/server.es.js';
11
11
  import { providers as providers$1 } from './instrumentation/httpClient.es.js';
12
12
  import { providers as providers$2 } from './instrumentation/logs.es.js';
13
13
  import { providers as providers$3 } from './instrumentation/commandLineRunner.es.js';
14
+ import { providers as providers$4 } from './instrumentation/router.es.js';
14
15
 
15
16
  let OpenTelemetryModule = class OpenTelemetryModule {
16
17
  };
@@ -22,6 +23,7 @@ OpenTelemetryModule = __decorate([
22
23
  ...providers$1,
23
24
  ...providers$2,
24
25
  ...providers$3,
26
+ ...providers$4,
25
27
  provide({
26
28
  provide: commandLineListTokens.init,
27
29
  useFactory: ({ provider }) => {
@@ -89,20 +91,22 @@ OpenTelemetryModule = __decorate([
89
91
  }),
90
92
  provide({
91
93
  provide: OPENTELEMETRY_PROVIDER_RESOURCE_ATTRIBUTES_TOKEN,
92
- useFactory: ({ appInfo }) => {
94
+ useFactory: ({ appInfo, envManager }) => {
93
95
  return {
94
96
  [ATTR_SERVICE_NAME]: appInfo.appName,
97
+ [ATTR_SERVICE_VERSION]: envManager.get('APP_VERSION'),
95
98
  };
96
99
  },
97
100
  deps: {
98
101
  appInfo: APP_INFO_TOKEN,
102
+ envManager: ENV_MANAGER_TOKEN,
99
103
  },
100
104
  }),
101
105
  provide({
102
106
  provide: OPENTELEMETRY_TRACER_TOKEN,
103
107
  useFactory: ({ provider }) => {
104
108
  const tracer = provider.getTracer('tramvai', '1.0.0');
105
- return new TramvaiTracerImpl(tracer);
109
+ return new TramvaiTracerImpl({ tracer });
106
110
  },
107
111
  deps: {
108
112
  provider: OPENTELEMETRY_PROVIDER_TOKEN,
package/lib/server.js CHANGED
@@ -14,6 +14,7 @@ var server = require('./instrumentation/server.js');
14
14
  var httpClient = require('./instrumentation/httpClient.js');
15
15
  var logs = require('./instrumentation/logs.js');
16
16
  var commandLineRunner = require('./instrumentation/commandLineRunner.js');
17
+ var router = require('./instrumentation/router.js');
17
18
 
18
19
  exports.OpenTelemetryModule = class OpenTelemetryModule {
19
20
  };
@@ -25,6 +26,7 @@ exports.OpenTelemetryModule = tslib.__decorate([
25
26
  ...httpClient.providers,
26
27
  ...logs.providers,
27
28
  ...commandLineRunner.providers,
29
+ ...router.providers,
28
30
  core.provide({
29
31
  provide: core.commandLineListTokens.init,
30
32
  useFactory: ({ provider }) => {
@@ -92,20 +94,22 @@ exports.OpenTelemetryModule = tslib.__decorate([
92
94
  }),
93
95
  core.provide({
94
96
  provide: tokens.OPENTELEMETRY_PROVIDER_RESOURCE_ATTRIBUTES_TOKEN,
95
- useFactory: ({ appInfo }) => {
97
+ useFactory: ({ appInfo, envManager }) => {
96
98
  return {
97
99
  [semanticConventions.ATTR_SERVICE_NAME]: appInfo.appName,
100
+ [semanticConventions.ATTR_SERVICE_VERSION]: envManager.get('APP_VERSION'),
98
101
  };
99
102
  },
100
103
  deps: {
101
104
  appInfo: core.APP_INFO_TOKEN,
105
+ envManager: tokensCommon.ENV_MANAGER_TOKEN,
102
106
  },
103
107
  }),
104
108
  core.provide({
105
109
  provide: tokens.OPENTELEMETRY_TRACER_TOKEN,
106
110
  useFactory: ({ provider }) => {
107
111
  const tracer$1 = provider.getTracer('tramvai', '1.0.0');
108
- return new tracer.TramvaiTracerImpl(tracer$1);
112
+ return new tracer.TramvaiTracerImpl({ tracer: tracer$1 });
109
113
  },
110
114
  deps: {
111
115
  provider: tokens.OPENTELEMETRY_PROVIDER_TOKEN,
package/lib/tokens.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import type { Context, Span, SpanOptions } from '@opentelemetry/api';
2
2
  import type { SpanProcessor, TracerConfig, BasicTracerProvider } from '@opentelemetry/sdk-trace-node';
3
3
  import type { Resource } from '@opentelemetry/resources';
4
+ export type TraceParams = {
5
+ skipError?: (error: Error) => boolean;
6
+ };
4
7
  /**
5
8
  * API inspired by:
6
9
  * - https://github.com/DataDog/dd-trace-js/blob/59e9a2a75f4256755b4e6c9951a0bdf8d39b4015/index.d.ts#L9
@@ -12,10 +15,10 @@ export interface TramvaiTracer {
12
15
  startActiveSpan<F extends (span: Span) => unknown>(name: string, options: SpanOptions, fn: F): ReturnType<F>;
13
16
  startActiveSpan<F extends (span: Span) => unknown>(name: string, options: SpanOptions, context: Context, fn: F): ReturnType<F>;
14
17
  getActiveSpan(): Span | undefined;
15
- trace<T>(name: string, fn: (span: Span) => Promise<T>): Promise<T>;
16
- trace<T>(name: string, fn: (span: Span) => T): T;
17
- trace<T>(name: string, options: SpanOptions, fn: (span: Span) => Promise<T>): Promise<T>;
18
- trace<T>(name: string, options: SpanOptions, fn: (span: Span) => T): T;
18
+ trace<T>(name: string, fn: (span: Span) => Promise<T>, params?: TraceParams): Promise<T>;
19
+ trace<T>(name: string, fn: (span: Span) => T, params?: TraceParams): T;
20
+ trace<T>(name: string, options: SpanOptions, fn: (span: Span) => Promise<T>, params?: TraceParams): Promise<T>;
21
+ trace<T>(name: string, options: SpanOptions, fn: (span: Span) => T, params?: TraceParams): T;
19
22
  }
20
23
  export declare const OPENTELEMETRY_PROVIDER_TOKEN: BasicTracerProvider & {
21
24
  __type?: "base token" | undefined;
@@ -1,16 +1,18 @@
1
1
  import type { Context, Span, SpanOptions, Tracer } from '@opentelemetry/api';
2
- import type { TramvaiTracer } from '../tokens';
2
+ import type { TraceParams, TramvaiTracer } from '../tokens';
3
3
  export declare class TramvaiTracerImpl implements TramvaiTracer {
4
4
  private tracer;
5
- constructor(tracer: Tracer);
5
+ constructor({ tracer }: {
6
+ tracer: Tracer;
7
+ });
6
8
  startSpan(...args: any[]): Span;
7
9
  startActiveSpan<F extends (span: Span) => unknown>(name: string, fn: F): ReturnType<F>;
8
10
  startActiveSpan<F extends (span: Span) => unknown>(name: string, options: SpanOptions, fn: F): ReturnType<F>;
9
11
  startActiveSpan<F extends (span: Span) => unknown>(name: string, options: SpanOptions, ctx: Context, fn: F): ReturnType<F>;
10
12
  getActiveSpan(): Span | undefined;
11
- trace<T>(name: string, fn: (span: Span) => Promise<T>): Promise<T>;
12
- trace<T>(name: string, fn: (span: Span) => T): T;
13
- trace<T>(name: string, options: SpanOptions, fn: (span: Span) => Promise<T>): Promise<T>;
14
- trace<T>(name: string, options: SpanOptions, fn: (span: Span) => T): T;
13
+ trace<T>(name: string, fn: (span: Span) => Promise<T>, params?: TraceParams): Promise<T>;
14
+ trace<T>(name: string, fn: (span: Span) => T, params?: TraceParams): T;
15
+ trace<T>(name: string, options: SpanOptions, fn: (span: Span) => Promise<T>, params?: TraceParams): Promise<T>;
16
+ trace<T>(name: string, options: SpanOptions, fn: (span: Span, params?: TraceParams) => T): T;
15
17
  }
16
18
  //# sourceMappingURL=tracer.d.ts.map
@@ -1,18 +1,21 @@
1
1
  import isPromise from '@tinkoff/utils/is/promise';
2
2
  import { trace, context, ROOT_CONTEXT, SpanStatusCode } from '@opentelemetry/api';
3
+ import { isSilentError } from '@tinkoff/errors';
3
4
 
4
5
  /* eslint-disable prefer-destructuring */
5
- function recordAndThrowError(span, error) {
6
+ function recordAndThrowError(span, error, { skipError = () => false }) {
6
7
  span.recordException(error);
7
- span.setStatus({
8
- code: SpanStatusCode.ERROR,
9
- message: error?.message ?? 'Unknown error',
10
- });
8
+ if (!(skipError(error) || isSilentError(error))) {
9
+ span.setStatus({
10
+ code: SpanStatusCode.ERROR,
11
+ message: error?.message ?? 'Unknown error',
12
+ });
13
+ }
11
14
  span.end();
12
15
  throw error;
13
16
  }
14
17
  class TramvaiTracerImpl {
15
- constructor(tracer) {
18
+ constructor({ tracer }) {
16
19
  this.tracer = tracer;
17
20
  }
18
21
  startSpan(...args) {
@@ -30,13 +33,16 @@ class TramvaiTracerImpl {
30
33
  const name = args[0];
31
34
  let fn;
32
35
  let options;
33
- if (args.length === 2) {
36
+ let params;
37
+ if (args.length === 2 || (args.length === 3 && typeof args[2] === 'object')) {
34
38
  fn = args[1];
35
39
  options = {};
40
+ params = args[2] || {};
36
41
  }
37
42
  else {
38
43
  fn = args[2];
39
44
  options = args[1];
45
+ params = args[3] || {};
40
46
  }
41
47
  const activeSpan = trace.getSpan(context.active());
42
48
  const spanContext = activeSpan ? trace.setSpan(context.active(), activeSpan) : undefined;
@@ -52,7 +58,7 @@ class TramvaiTracerImpl {
52
58
  return res;
53
59
  })
54
60
  .catch((error) => {
55
- recordAndThrowError(span, error);
61
+ recordAndThrowError(span, error, params);
56
62
  });
57
63
  }
58
64
  // otherwise, end span immediately
@@ -60,7 +66,7 @@ class TramvaiTracerImpl {
60
66
  return result;
61
67
  }
62
68
  catch (error) {
63
- recordAndThrowError(span, error);
69
+ recordAndThrowError(span, error, params);
64
70
  }
65
71
  });
66
72
  }
@@ -4,23 +4,26 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var isPromise = require('@tinkoff/utils/is/promise');
6
6
  var api = require('@opentelemetry/api');
7
+ var errors = require('@tinkoff/errors');
7
8
 
8
9
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
10
 
10
11
  var isPromise__default = /*#__PURE__*/_interopDefaultLegacy(isPromise);
11
12
 
12
13
  /* eslint-disable prefer-destructuring */
13
- function recordAndThrowError(span, error) {
14
+ function recordAndThrowError(span, error, { skipError = () => false }) {
14
15
  span.recordException(error);
15
- span.setStatus({
16
- code: api.SpanStatusCode.ERROR,
17
- message: error?.message ?? 'Unknown error',
18
- });
16
+ if (!(skipError(error) || errors.isSilentError(error))) {
17
+ span.setStatus({
18
+ code: api.SpanStatusCode.ERROR,
19
+ message: error?.message ?? 'Unknown error',
20
+ });
21
+ }
19
22
  span.end();
20
23
  throw error;
21
24
  }
22
25
  class TramvaiTracerImpl {
23
- constructor(tracer) {
26
+ constructor({ tracer }) {
24
27
  this.tracer = tracer;
25
28
  }
26
29
  startSpan(...args) {
@@ -38,13 +41,16 @@ class TramvaiTracerImpl {
38
41
  const name = args[0];
39
42
  let fn;
40
43
  let options;
41
- if (args.length === 2) {
44
+ let params;
45
+ if (args.length === 2 || (args.length === 3 && typeof args[2] === 'object')) {
42
46
  fn = args[1];
43
47
  options = {};
48
+ params = args[2] || {};
44
49
  }
45
50
  else {
46
51
  fn = args[2];
47
52
  options = args[1];
53
+ params = args[3] || {};
48
54
  }
49
55
  const activeSpan = api.trace.getSpan(api.context.active());
50
56
  const spanContext = activeSpan ? api.trace.setSpan(api.context.active(), activeSpan) : undefined;
@@ -60,7 +66,7 @@ class TramvaiTracerImpl {
60
66
  return res;
61
67
  })
62
68
  .catch((error) => {
63
- recordAndThrowError(span, error);
69
+ recordAndThrowError(span, error, params);
64
70
  });
65
71
  }
66
72
  // otherwise, end span immediately
@@ -68,7 +74,7 @@ class TramvaiTracerImpl {
68
74
  return result;
69
75
  }
70
76
  catch (error) {
71
- recordAndThrowError(span, error);
77
+ recordAndThrowError(span, error, params);
72
78
  }
73
79
  });
74
80
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tramvai/module-opentelemetry",
3
- "version": "5.22.0",
3
+ "version": "5.40.0",
4
4
  "description": "Интеграция OpenTelemetry",
5
5
  "browser": "lib/browser.js",
6
6
  "main": "lib/server.js",
@@ -28,18 +28,19 @@
28
28
  "@opentelemetry/sdk-trace-node": "^1.28.0",
29
29
  "@opentelemetry/semantic-conventions": "^1.28.0",
30
30
  "path-to-regexp": "0.1.7",
31
- "@tramvai/tokens-common": "5.22.0",
32
- "@tramvai/tokens-metrics": "5.22.0",
33
- "@tramvai/tokens-http-client": "5.22.0",
34
- "@tramvai/tokens-server": "5.22.0",
35
- "@tramvai/tokens-server-private": "5.22.0",
31
+ "@tramvai/tokens-common": "5.40.0",
32
+ "@tramvai/tokens-metrics": "5.40.0",
33
+ "@tramvai/tokens-http-client": "5.40.0",
34
+ "@tramvai/tokens-server": "5.40.0",
35
+ "@tramvai/tokens-router": "5.40.0",
36
+ "@tramvai/tokens-server-private": "5.40.0",
36
37
  "@tinkoff/utils": "^2.1.2",
37
38
  "@tinkoff/errors": "0.6.2"
38
39
  },
39
40
  "devDependencies": {},
40
41
  "peerDependencies": {
41
42
  "@tinkoff/dippy": "0.11.3",
42
- "@tramvai/core": "5.22.0",
43
+ "@tramvai/core": "5.40.0",
43
44
  "tslib": "^2.4.0"
44
45
  }
45
46
  }