From 6119b2da3c3e32d20550daf41e57a35058575f62 Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Tue, 16 Mar 2021 23:57:39 +0100 Subject: [PATCH 01/15] feature(monolith-service): barebones traceId passing --- .../AccountContext/AccountContextModule.ts | 6 ++++++ .../monolith/src/Core/Logger/PinoLogger.ts | 15 ++++++++----- .../NestJs/OpenTracingInterceptor.ts | 21 +++++++++++++++++++ .../monolith/src/Core/OpenTracing/index.ts | 1 + .../src/Core/OpenTracing/tracingStorage.ts | 3 +++ 5 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 services/monolith/src/Core/OpenTracing/NestJs/OpenTracingInterceptor.ts create mode 100644 services/monolith/src/Core/OpenTracing/index.ts create mode 100644 services/monolith/src/Core/OpenTracing/tracingStorage.ts diff --git a/services/monolith/src/AccountContext/AccountContextModule.ts b/services/monolith/src/AccountContext/AccountContextModule.ts index ec0bda4..794d0fb 100644 --- a/services/monolith/src/AccountContext/AccountContextModule.ts +++ b/services/monolith/src/AccountContext/AccountContextModule.ts @@ -1,9 +1,11 @@ import { MikroOrmModule, MikroOrmModuleSyncOptions } from '@mikro-orm/nestjs'; import { DynamicModule, Module } from '@nestjs/common'; +import { APP_INTERCEPTOR } from '@nestjs/core'; import { EVENT_BUS, EventBus, EventBusCompositeCoordinator, nestJsInMemoryEventBusProvider } from '../Core/EventBus'; import { LOGGER, Logger, NestJsLoggerAdapter, nestJsLoggerProvider } from '../Core/Logger'; import { intermediateModule } from '../Core/NestJs'; +import { OpenTracingInterceptor } from '../Core/OpenTracing'; import { OutboxMessageEntity, OutboxModule, RegisterOutboxWorker } from '../Core/Outbox/'; import { AccountContextGateway } from './AccountContextGateway'; @@ -62,6 +64,10 @@ export class AccountContextModule { ConfirmAccountService, CreateAccountService, SendAccountCreatedEmail, + { + provide: APP_INTERCEPTOR, + useClass: OpenTracingInterceptor, + }, { provide: ACCOUNT_REPOSITORY, useClass: SqliteAccountRepository, diff --git a/services/monolith/src/Core/Logger/PinoLogger.ts b/services/monolith/src/Core/Logger/PinoLogger.ts index fabdfbb..9a27710 100644 --- a/services/monolith/src/Core/Logger/PinoLogger.ts +++ b/services/monolith/src/Core/Logger/PinoLogger.ts @@ -1,5 +1,7 @@ import { Logger as PinoInstance } from 'pino'; +import { tracingStorage } from '../OpenTracing/tracingStorage'; + import { Logger } from './Logger'; /** @@ -28,10 +30,13 @@ export class PinoLogger implements Logger { } private _doLog(logType: string, message: string, obj?: Record): void { - if(obj) { - this.pino[logType](obj, message); - } else { - this.pino[logType](message); - } + const tracingStore = tracingStorage.getStore() ?? {}; + + const logObj = { + ...tracingStore, + ...obj, + }; + + this.pino[logType](logObj, message); } } diff --git a/services/monolith/src/Core/OpenTracing/NestJs/OpenTracingInterceptor.ts b/services/monolith/src/Core/OpenTracing/NestJs/OpenTracingInterceptor.ts new file mode 100644 index 0000000..a243fd1 --- /dev/null +++ b/services/monolith/src/Core/OpenTracing/NestJs/OpenTracingInterceptor.ts @@ -0,0 +1,21 @@ +import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common'; +import { Observable } from 'rxjs'; +import { v4 as uuid } from 'uuid'; + +import { tracingStorage } from '../tracingStorage'; + +@Injectable() +export class OpenTracingInterceptor implements NestInterceptor { + public intercept(context: ExecutionContext, next: CallHandler): Promise> { + const traceId = uuid(); + + let promise; + tracingStorage.run({ traceId }, () => { + promise = next + .handle() + .toPromise(); + }); + + return promise; + } +} diff --git a/services/monolith/src/Core/OpenTracing/index.ts b/services/monolith/src/Core/OpenTracing/index.ts new file mode 100644 index 0000000..ace14ec --- /dev/null +++ b/services/monolith/src/Core/OpenTracing/index.ts @@ -0,0 +1 @@ +export * from './NestJs/OpenTracingInterceptor'; diff --git a/services/monolith/src/Core/OpenTracing/tracingStorage.ts b/services/monolith/src/Core/OpenTracing/tracingStorage.ts new file mode 100644 index 0000000..6ae6d60 --- /dev/null +++ b/services/monolith/src/Core/OpenTracing/tracingStorage.ts @@ -0,0 +1,3 @@ +import { AsyncLocalStorage } from 'async_hooks'; + +export const tracingStorage = new AsyncLocalStorage<{traceId: string}>(); From 1a61618ac61d2e0f375bd803fb0b952c33b123c4 Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Wed, 17 Mar 2021 21:11:00 +0100 Subject: [PATCH 02/15] feature(monolith-service): install & configure core opentelemetry packages --- common/config/rush/pnpm-lock.yaml | 148 ++++++++++++++++++++++++++++- services/monolith/package.json | 8 +- services/monolith/src/index.ts | 1 + services/monolith/src/telemetry.ts | 26 +++++ 4 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 services/monolith/src/telemetry.ts diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 22e052d..93c3499 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -5,6 +5,12 @@ dependencies: '@nestjs/core': 7.6.11_6084d9907887ddaa2cd60f6f8e89001f '@nestjs/platform-express': 7.6.11_@nestjs+core@7.6.11 '@nestjs/testing': 7.6.11_5493a482b6326ce7617b54c4270e8fab + '@opentelemetry/api': 1.0.0-rc.0 + '@opentelemetry/instrumentation': 0.18.0 + '@opentelemetry/node': 0.18.0 + '@opentelemetry/plugin-express': 0.14.0 + '@opentelemetry/plugin-http': 0.18.0 + '@opentelemetry/tracing': 0.18.0 '@rush-temp/eslint-config': file:projects/eslint-config.tgz_eslint@7.20.0 '@rush-temp/monolith-service': file:projects/monolith-service.tgz '@rush-temp/tsconfig': file:projects/tsconfig.tgz @@ -910,6 +916,114 @@ packages: hasBin: true resolution: integrity: sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA== + /@opentelemetry/api-metrics/0.18.0: + dependencies: + '@opentelemetry/api': 0.18.1 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-5MGIP1Bb97yiRBLeHdfgDaMnoKE5+IOhUvE3FGRqiTMjun0cDt35gY4k5+w5pmqpcHFkt0/ih25YTKjF0tJLHg== + /@opentelemetry/api/0.18.1: + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-pKNxHe3AJ5T2N5G3AlT9gx6FyF5K2FS9ZNc+FipC+f1CpVF/EY+JHTJ749dnM2kWIgZTbDJFiGMuc0FYjNSCOg== + /@opentelemetry/api/1.0.0-rc.0: + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-iXKByCMfrlO5S6Oh97BuM56tM2cIBB0XsL/vWF/AtJrJEKx4MC/Xdu0xDsGXMGcNWpqF7ujMsjjnp0+UHBwnDQ== + /@opentelemetry/context-async-hooks/0.18.0: + dependencies: + '@opentelemetry/api': 0.18.1 + dev: false + engines: + node: '>=8.1.0' + resolution: + integrity: sha512-PD1aHXyniFtZIXbLuCr+KaZiufrGJPuEZ6eMZggQRi7+AC3alAfAVRz88sLmeR49pd7lRRFiKzymzVqJRMEmjw== + /@opentelemetry/core/0.18.0: + dependencies: + '@opentelemetry/api': 0.18.1 + semver: 7.3.2 + dev: false + engines: + node: '>=8.5.0' + resolution: + integrity: sha512-Kg+LBIAPK70tEtpIAdZomkUmbABK+EwfnjFfvJ1rVZ8e0NApDx14Sq92RbGDIf67TK5mBgIvvY27W+ic354UZQ== + /@opentelemetry/instrumentation/0.18.0: + dependencies: + '@opentelemetry/api': 0.18.1 + '@opentelemetry/api-metrics': 0.18.0 + require-in-the-middle: 5.1.0 + semver: 7.3.2 + shimmer: 1.2.1 + dev: false + resolution: + integrity: sha512-YFrCnSWS9jJLChg5I8g7EuvpWqPZGa2EXyO8KwRJApuLPCqJSBkcymYieedWNupS0FAXntocpIb/b0SEVaZbEg== + /@opentelemetry/node/0.18.0: + dependencies: + '@opentelemetry/api': 0.18.1 + '@opentelemetry/context-async-hooks': 0.18.0 + '@opentelemetry/core': 0.18.0 + '@opentelemetry/tracing': 0.18.0 + semver: 7.3.2 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-KjN6O+BvNmBwjQHKpcIRyxebrRuEMUzyS4Y13ZMH684fBMwRTju45aDz7ILCFndGECvbtl8nDY0US7+HCimpXw== + /@opentelemetry/plugin-express/0.14.0: + dependencies: + '@opentelemetry/api': 0.18.1 + '@opentelemetry/core': 0.18.0 + shimmer: 1.2.1 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-jVGZvRxMm5wLYhNNHs3pENnLX7TuH466ip+tJD3BsI7D2WdF5FVUG+I1Fl+yP56zqhUjCZB4XWjYPV0mJqqe+Q== + /@opentelemetry/plugin-http/0.18.0: + dependencies: + '@opentelemetry/api': 0.18.1 + '@opentelemetry/core': 0.18.0 + '@opentelemetry/semantic-conventions': 0.18.0 + semver: 7.3.2 + shimmer: 1.2.1 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-+g4H+XKlDAAkNGHQcO2BJ25UtfdYO9te8xq/vILUDYKXXejcsrEjLwLe6xgSX6n936QyJjXi3sJmblBMHVx9ug== + /@opentelemetry/resources/0.18.0: + dependencies: + '@opentelemetry/api': 0.18.1 + '@opentelemetry/core': 0.18.0 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-Mko4HpoI5cCYplhSyiCuMFi0QEG1Nw/YwHFyAK+A67r+sgmo1wVpM6Pengb+XlxJrrO8WgmLsDS3RHqoMWhWNQ== + /@opentelemetry/semantic-conventions/0.18.0: + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-02Wi/zFq+RWfY4llRicMashGhyZvUtMfXu9UlfXMJiDbGOgkdua4AeOCv9lDqv1GIz11xr5qS4tFjLp7WnlU+Q== + /@opentelemetry/tracing/0.18.0: + dependencies: + '@opentelemetry/api': 0.18.1 + '@opentelemetry/core': 0.18.0 + '@opentelemetry/resources': 0.18.0 + '@opentelemetry/semantic-conventions': 0.18.0 + lodash.merge: 4.6.2 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-k7UAebuHBLPafS8rnkpZqNuM8nfwOg6OCmppekCMxdQzkuZS1attgelqyEIlX6NYh46DndyZ7BxBkiXF4S0Xwg== /@rushstack/eslint-patch/1.0.6: dev: false resolution: @@ -4414,6 +4528,10 @@ packages: node: '>=8' resolution: integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + /lodash.merge/4.6.2: + dev: false + resolution: + integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== /lodash.sortby/4.7.0: dev: false resolution: @@ -4597,6 +4715,10 @@ packages: hasBin: true resolution: integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + /module-details-from-path/1.0.3: + dev: false + resolution: + integrity: sha1-EUyUlnPiqKNenTV4hSeqN7Z52is= /mri/1.1.4: dev: false engines: @@ -5595,6 +5717,14 @@ packages: node: '>=0.10.0' resolution: integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + /require-in-the-middle/5.1.0: + dependencies: + debug: 4.3.1 + module-details-from-path: 1.0.3 + resolve: 1.19.0 + dev: false + resolution: + integrity: sha512-M2rLKVupQfJ5lf9OvqFGIT+9iVLnTmjgbOmpil12hiSQNn5zJTKGPoIisETNjfK+09vP3rpm1zJajmErpr2sEQ== /require-main-filename/2.0.0: dev: false resolution: @@ -5840,6 +5970,10 @@ packages: optional: true resolution: integrity: sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + /shimmer/1.2.1: + dev: false + resolution: + integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== /signal-exit/3.0.3: dev: false resolution: @@ -6944,6 +7078,12 @@ packages: '@nestjs/platform-express': 7.6.11_10f9c32d5705e6d2dea73f1d25c08abc '@nestjs/swagger': 4.7.13_81a1937ed9aace8fb18846d898b8f16a '@nestjs/testing': 7.6.11_ed6e60f1b18d44b976a1a0f51d940b9c + '@opentelemetry/api': 1.0.0-rc.0 + '@opentelemetry/instrumentation': 0.18.0 + '@opentelemetry/node': 0.18.0 + '@opentelemetry/plugin-express': 0.14.0 + '@opentelemetry/plugin-http': 0.18.0 + '@opentelemetry/tracing': 0.18.0 '@types/bcrypt': 3.0.0 '@types/express': 4.17.11 '@types/jest': 26.0.20 @@ -6975,7 +7115,7 @@ packages: dev: false name: '@rush-temp/monolith-service' resolution: - integrity: sha512-7tLEyXYOIdSmmDx3Yu55jLG7Sq2H6aWRehoaSGzvQRYYI4zVYU6vXsRvw0GdaodZar2f6cHboiPx9r+h51fJGg== + integrity: sha512-FuEZCu6VDmzV5Ad9FrFXqGpweLdUqRiMvoJqfHacGd2RxdHUPAJ+RWBEj0UpwkdclZxE/D9A4qPKkBH0VrXhJw== tarball: file:projects/monolith-service.tgz version: 0.0.0 file:projects/tsconfig.tgz: @@ -7017,6 +7157,12 @@ specifiers: '@nestjs/core': ^7.5.1 '@nestjs/platform-express': ^7.5.1 '@nestjs/testing': ~7.6.11 + '@opentelemetry/api': ~1.0.0-rc.0 + '@opentelemetry/instrumentation': ~0.18.0 + '@opentelemetry/node': ~0.18.0 + '@opentelemetry/plugin-express': ~0.14.0 + '@opentelemetry/plugin-http': ~0.18.0 + '@opentelemetry/tracing': ~0.18.0 '@rush-temp/eslint-config': file:./projects/eslint-config.tgz '@rush-temp/monolith-service': file:./projects/monolith-service.tgz '@rush-temp/tsconfig': file:./projects/tsconfig.tgz diff --git a/services/monolith/package.json b/services/monolith/package.json index 840f915..1d74faa 100644 --- a/services/monolith/package.json +++ b/services/monolith/package.json @@ -32,7 +32,13 @@ "swagger-ui-express": "~4.1.6", "jose": "~3.6.2", "dotenv": "~8.2.0", - "pino-std-serializers": "~3.2.0" + "pino-std-serializers": "~3.2.0", + "@opentelemetry/api": "~1.0.0-rc.0", + "@opentelemetry/node": "~0.18.0", + "@opentelemetry/tracing": "~0.18.0", + "@opentelemetry/plugin-http": "~0.18.0", + "@opentelemetry/plugin-express": "~0.14.0", + "@opentelemetry/instrumentation": "~0.18.0" }, "devDependencies": { "@abitia/eslint-config": "~1.1.0", diff --git a/services/monolith/src/index.ts b/services/monolith/src/index.ts index 01511bd..b58fc8d 100644 --- a/services/monolith/src/index.ts +++ b/services/monolith/src/index.ts @@ -1,3 +1,4 @@ +import './telemetry'; import { once } from 'events'; import * as path from 'path'; diff --git a/services/monolith/src/telemetry.ts b/services/monolith/src/telemetry.ts new file mode 100644 index 0000000..a318db3 --- /dev/null +++ b/services/monolith/src/telemetry.ts @@ -0,0 +1,26 @@ +import { registerInstrumentations } from '@opentelemetry/instrumentation'; +import { NodeTracerProvider } from '@opentelemetry/node'; +import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/tracing'; + +const provider = new NodeTracerProvider({ +}); + +provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); + +provider.register(); + +registerInstrumentations({ + tracerProvider: provider, + instrumentations: [ + { + plugins: { + express: { + enabled: true, + path: '@opentelemetry/plugin-express', + }, + }, + }, + ], +}); + +console.log('OpenTelemetry initialized'); From 7199f4e36096ec3c68bd8a6021260b79c6035b38 Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Wed, 17 Mar 2021 22:08:51 +0100 Subject: [PATCH 03/15] feature(monolith-service): configure OpenTelemetry async hooks --- common/config/rush/pnpm-lock.yaml | 5 ++++- services/monolith/package.json | 3 ++- services/monolith/src/telemetry.ts | 15 ++++++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 93c3499..08087b7 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -6,6 +6,7 @@ dependencies: '@nestjs/platform-express': 7.6.11_@nestjs+core@7.6.11 '@nestjs/testing': 7.6.11_5493a482b6326ce7617b54c4270e8fab '@opentelemetry/api': 1.0.0-rc.0 + '@opentelemetry/context-async-hooks': 0.18.0 '@opentelemetry/instrumentation': 0.18.0 '@opentelemetry/node': 0.18.0 '@opentelemetry/plugin-express': 0.14.0 @@ -7079,6 +7080,7 @@ packages: '@nestjs/swagger': 4.7.13_81a1937ed9aace8fb18846d898b8f16a '@nestjs/testing': 7.6.11_ed6e60f1b18d44b976a1a0f51d940b9c '@opentelemetry/api': 1.0.0-rc.0 + '@opentelemetry/context-async-hooks': 0.18.0 '@opentelemetry/instrumentation': 0.18.0 '@opentelemetry/node': 0.18.0 '@opentelemetry/plugin-express': 0.14.0 @@ -7115,7 +7117,7 @@ packages: dev: false name: '@rush-temp/monolith-service' resolution: - integrity: sha512-FuEZCu6VDmzV5Ad9FrFXqGpweLdUqRiMvoJqfHacGd2RxdHUPAJ+RWBEj0UpwkdclZxE/D9A4qPKkBH0VrXhJw== + integrity: sha512-1v2sGriK4J5bXlfn3NtlAdphduYaX6GujvUcCJ9djMbE6jK1IOBUFJ3qbWBCao2vy8t86B136DNGABzSh4FMRA== tarball: file:projects/monolith-service.tgz version: 0.0.0 file:projects/tsconfig.tgz: @@ -7158,6 +7160,7 @@ specifiers: '@nestjs/platform-express': ^7.5.1 '@nestjs/testing': ~7.6.11 '@opentelemetry/api': ~1.0.0-rc.0 + '@opentelemetry/context-async-hooks': ~0.18.0 '@opentelemetry/instrumentation': ~0.18.0 '@opentelemetry/node': ~0.18.0 '@opentelemetry/plugin-express': ~0.14.0 diff --git a/services/monolith/package.json b/services/monolith/package.json index 1d74faa..6fe6581 100644 --- a/services/monolith/package.json +++ b/services/monolith/package.json @@ -38,7 +38,8 @@ "@opentelemetry/tracing": "~0.18.0", "@opentelemetry/plugin-http": "~0.18.0", "@opentelemetry/plugin-express": "~0.14.0", - "@opentelemetry/instrumentation": "~0.18.0" + "@opentelemetry/instrumentation": "~0.18.0", + "@opentelemetry/context-async-hooks": "~0.18.0" }, "devDependencies": { "@abitia/eslint-config": "~1.1.0", diff --git a/services/monolith/src/telemetry.ts b/services/monolith/src/telemetry.ts index a318db3..216a3f7 100644 --- a/services/monolith/src/telemetry.ts +++ b/services/monolith/src/telemetry.ts @@ -1,13 +1,18 @@ +import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { NodeTracerProvider } from '@opentelemetry/node'; import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/tracing'; -const provider = new NodeTracerProvider({ -}); +const provider = new NodeTracerProvider(); provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); -provider.register(); +const contextManager = new AsyncLocalStorageContextManager(); +contextManager.enable(); + +provider.register({ + contextManager, +}); registerInstrumentations({ tracerProvider: provider, @@ -24,3 +29,7 @@ registerInstrumentations({ }); console.log('OpenTelemetry initialized'); + +export { + contextManager, +}; From 6a05f158902b7505f19c4998265515ea6375b32a Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Wed, 17 Mar 2021 22:09:12 +0100 Subject: [PATCH 04/15] feature(monolith-service): take logging traceId/spanId/traceFlags from opentelemetry --- services/monolith/src/Core/Logger/PinoLogger.ts | 8 +++++--- services/monolith/src/Core/OpenTracing/getActiveSpan.ts | 6 ++++++ services/monolith/src/Core/OpenTracing/index.ts | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 services/monolith/src/Core/OpenTracing/getActiveSpan.ts diff --git a/services/monolith/src/Core/Logger/PinoLogger.ts b/services/monolith/src/Core/Logger/PinoLogger.ts index 9a27710..bbff632 100644 --- a/services/monolith/src/Core/Logger/PinoLogger.ts +++ b/services/monolith/src/Core/Logger/PinoLogger.ts @@ -1,6 +1,6 @@ import { Logger as PinoInstance } from 'pino'; -import { tracingStorage } from '../OpenTracing/tracingStorage'; +import { getActiveSpan } from '../OpenTracing'; import { Logger } from './Logger'; @@ -30,10 +30,12 @@ export class PinoLogger implements Logger { } private _doLog(logType: string, message: string, obj?: Record): void { - const tracingStore = tracingStorage.getStore() ?? {}; + const spanContext = getActiveSpan(); const logObj = { - ...tracingStore, + traceId: spanContext?.traceId, + spanId: spanContext?.spanId, + traceFlags: spanContext?.traceFlags, ...obj, }; diff --git a/services/monolith/src/Core/OpenTracing/getActiveSpan.ts b/services/monolith/src/Core/OpenTracing/getActiveSpan.ts new file mode 100644 index 0000000..aba640f --- /dev/null +++ b/services/monolith/src/Core/OpenTracing/getActiveSpan.ts @@ -0,0 +1,6 @@ +import { getSpanContext, SpanContext } from '@opentelemetry/api'; + +import { contextManager } from '../../telemetry'; + +export const getActiveSpan = (): SpanContext | undefined => + getSpanContext(contextManager.active()); diff --git a/services/monolith/src/Core/OpenTracing/index.ts b/services/monolith/src/Core/OpenTracing/index.ts index ace14ec..8b1920d 100644 --- a/services/monolith/src/Core/OpenTracing/index.ts +++ b/services/monolith/src/Core/OpenTracing/index.ts @@ -1 +1,2 @@ export * from './NestJs/OpenTracingInterceptor'; +export * from './getActiveSpan'; From 8c9f31d918484aff946cce0f99162542e69ca6bf Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Wed, 17 Mar 2021 22:31:06 +0100 Subject: [PATCH 05/15] refactor(monolith-service): use global otel context manager --- .../src/Core/OpenTracing/getActiveSpan.ts | 6 ++---- services/monolith/src/telemetry.ts | 17 +++++++---------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/services/monolith/src/Core/OpenTracing/getActiveSpan.ts b/services/monolith/src/Core/OpenTracing/getActiveSpan.ts index aba640f..48c28a9 100644 --- a/services/monolith/src/Core/OpenTracing/getActiveSpan.ts +++ b/services/monolith/src/Core/OpenTracing/getActiveSpan.ts @@ -1,6 +1,4 @@ -import { getSpanContext, SpanContext } from '@opentelemetry/api'; - -import { contextManager } from '../../telemetry'; +import { getSpanContext, SpanContext, context } from '@opentelemetry/api'; export const getActiveSpan = (): SpanContext | undefined => - getSpanContext(contextManager.active()); + getSpanContext(context.active()); diff --git a/services/monolith/src/telemetry.ts b/services/monolith/src/telemetry.ts index 216a3f7..117a7d8 100644 --- a/services/monolith/src/telemetry.ts +++ b/services/monolith/src/telemetry.ts @@ -1,18 +1,19 @@ -import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks'; +import { context } from '@opentelemetry/api'; +import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { NodeTracerProvider } from '@opentelemetry/node'; import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/tracing'; +const contextManager = new AsyncHooksContextManager(); +contextManager.enable(); + const provider = new NodeTracerProvider(); provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); -const contextManager = new AsyncLocalStorageContextManager(); -contextManager.enable(); +provider.register({ contextManager }); -provider.register({ - contextManager, -}); +context.setGlobalContextManager(contextManager); registerInstrumentations({ tracerProvider: provider, @@ -29,7 +30,3 @@ registerInstrumentations({ }); console.log('OpenTelemetry initialized'); - -export { - contextManager, -}; From 8b663240cfdd3329877e8f62904f6faee671ccdf Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Wed, 17 Mar 2021 23:40:40 +0100 Subject: [PATCH 06/15] feature(monolith-service): add otel to outbox/eventbus --- .../src/Core/EventBus/InMemoryEventBus.ts | 11 ++++++ .../src/Core/OpenTracing/getActiveSpan.ts | 4 +- .../Core/Outbox/MikroOrm/MikroOrmOutbox.ts | 4 +- .../Outbox/MikroOrm/MikroOrmOutboxWorker.ts | 38 ++++++++++++++----- services/monolith/src/telemetry.ts | 4 +- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/services/monolith/src/Core/EventBus/InMemoryEventBus.ts b/services/monolith/src/Core/EventBus/InMemoryEventBus.ts index bdce901..fedf1a7 100644 --- a/services/monolith/src/Core/EventBus/InMemoryEventBus.ts +++ b/services/monolith/src/Core/EventBus/InMemoryEventBus.ts @@ -1,4 +1,7 @@ +import { context, SpanKind, SpanStatusCode } from '@opentelemetry/api'; + import { Logger } from '../Logger'; +import { tracer } from '../OpenTracing'; import { Event } from './Event'; import { EventBus, EventBusSubscriber } from './EventBus'; @@ -22,10 +25,18 @@ export class InMemoryEventBus implements EventBus { const eventSubscribers = this.subscribers[event.constructor.name] ?? []; for(const subscriber of eventSubscribers) { + const span = tracer.startSpan('event-handler', { + kind: SpanKind.CONSUMER, + }, context.active()); + span.setAttribute('event.name', event.name); try { await subscriber(event); + span.setStatus({ code: SpanStatusCode.OK }); } catch (error) { this.logger?.error(`Failed to run subscriber for event ${event.name}`, error); + span.setStatus({ code: SpanStatusCode.ERROR, message: error?.message }); + } finally { + span.end(); } } } diff --git a/services/monolith/src/Core/OpenTracing/getActiveSpan.ts b/services/monolith/src/Core/OpenTracing/getActiveSpan.ts index 48c28a9..328a35e 100644 --- a/services/monolith/src/Core/OpenTracing/getActiveSpan.ts +++ b/services/monolith/src/Core/OpenTracing/getActiveSpan.ts @@ -1,4 +1,6 @@ -import { getSpanContext, SpanContext, context } from '@opentelemetry/api'; +import { getSpanContext, SpanContext, context, trace } from '@opentelemetry/api'; + +export const tracer = trace.getTracer('monolith'); export const getActiveSpan = (): SpanContext | undefined => getSpanContext(context.active()); diff --git a/services/monolith/src/Core/Outbox/MikroOrm/MikroOrmOutbox.ts b/services/monolith/src/Core/Outbox/MikroOrm/MikroOrmOutbox.ts index 85e80e6..dbd8aed 100644 --- a/services/monolith/src/Core/Outbox/MikroOrm/MikroOrmOutbox.ts +++ b/services/monolith/src/Core/Outbox/MikroOrm/MikroOrmOutbox.ts @@ -2,6 +2,7 @@ import { EntityManager } from '@mikro-orm/core'; import { Event } from '../../EventBus'; import { Logger } from '../../Logger'; +import { getActiveSpan } from '../../OpenTracing'; import { Outbox } from '../Outbox'; import { newOutboxMessageId, OutboxMessageEntity } from './OutboxMessageEntity'; @@ -29,10 +30,11 @@ export class MikroOrmOutbox implements Outbox { this.logger?.info(`Persisting event ${event.name}`); } + const tracingContext = getActiveSpan(); const message = new OutboxMessageEntity( newOutboxMessageId(), event.name, - JSON.stringify(event), + JSON.stringify({ tracingContext, event }), ); this.em.persist(message); diff --git a/services/monolith/src/Core/Outbox/MikroOrm/MikroOrmOutboxWorker.ts b/services/monolith/src/Core/Outbox/MikroOrm/MikroOrmOutboxWorker.ts index 8b51cff..24d08b3 100644 --- a/services/monolith/src/Core/Outbox/MikroOrm/MikroOrmOutboxWorker.ts +++ b/services/monolith/src/Core/Outbox/MikroOrm/MikroOrmOutboxWorker.ts @@ -1,24 +1,31 @@ import { EntityManager } from '@mikro-orm/core'; +import { context, ROOT_CONTEXT, setSpanContext, SpanKind } from '@opentelemetry/api'; import { Event, EventBus } from '../../EventBus'; import { Logger } from '../../Logger'; +import { tracer } from '../../OpenTracing'; import { OutboxMessageEntity } from './OutboxMessageEntity'; const sleep = (ms: number): Promise => new Promise(resolve => setTimeout(resolve, ms)); -const adaptMessageToEvent = (message: OutboxMessageEntity): Event => { - const payload = JSON.parse(message.eventPayload); +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const adaptMessageToEvent = (eventName: string, event: any): Event => { + Object.defineProperty(event, 'name', { + value: eventName, + enumerable: false, + writable: false, + }); - Object.defineProperty(payload, 'constructor', { + Object.defineProperty(event, 'constructor', { value: { - name: message.eventName, + name: eventName, }, enumerable: false, writable: false, }); - return payload; + return event; }; type MikroOrmOutboxWorkerOptions = { @@ -81,12 +88,25 @@ export class MikroOrmOutboxWorker { } for(const message of messages) { - const event = adaptMessageToEvent(message); + const payload = JSON.parse(message.eventPayload); + const rootCtx = setSpanContext(ROOT_CONTEXT, payload.tracingContext); + + await context.with(rootCtx, async () => { + const span = tracer.startSpan('outbox-worker', { + kind: SpanKind.CONSUMER, + }); + + const event = adaptMessageToEvent(message.eventName, payload.event); + + span.setAttribute('event.name', event.name); + + this.eventBus.publish(event); - this.eventBus.publish(event); + message.markAsProcessed(); + await this.em.persistAndFlush(message); - message.markAsProcessed(); - await this.em.persistAndFlush(message); + span.end(); + }); } } } diff --git a/services/monolith/src/telemetry.ts b/services/monolith/src/telemetry.ts index 117a7d8..81120ec 100644 --- a/services/monolith/src/telemetry.ts +++ b/services/monolith/src/telemetry.ts @@ -1,4 +1,4 @@ -import { context } from '@opentelemetry/api'; +import { context, trace } from '@opentelemetry/api'; import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { NodeTracerProvider } from '@opentelemetry/node'; @@ -15,6 +15,8 @@ provider.register({ contextManager }); context.setGlobalContextManager(contextManager); +trace.setGlobalTracerProvider(provider); + registerInstrumentations({ tracerProvider: provider, instrumentations: [ From df57f38b0cd3aff1c0f749d2d625545b90e7e2ed Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Sat, 20 Mar 2021 18:13:49 +0100 Subject: [PATCH 07/15] feature(monolith-service): add LoggerSpanExporter for otel --- .../Core/OpenTracing/LoggerSpanExporter.ts | 40 +++++++++++++++++++ .../monolith/src/Core/OpenTracing/index.ts | 1 + services/monolith/src/index.ts | 13 +++++- services/monolith/src/telemetry.ts | 6 ++- 4 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 services/monolith/src/Core/OpenTracing/LoggerSpanExporter.ts diff --git a/services/monolith/src/Core/OpenTracing/LoggerSpanExporter.ts b/services/monolith/src/Core/OpenTracing/LoggerSpanExporter.ts new file mode 100644 index 0000000..3754a96 --- /dev/null +++ b/services/monolith/src/Core/OpenTracing/LoggerSpanExporter.ts @@ -0,0 +1,40 @@ +import { ReadableSpan, SpanExporter } from '@opentelemetry/tracing'; + +import { Logger } from '../Logger'; + +const CODE_OK = 1; + +export class LoggerSpanExporter implements SpanExporter { + public constructor(private readonly logger: Logger) {} + + public export(spans: ReadableSpan[], resultCallback: (result) => void): void { + for (const span of spans) { + this.logger.info(span.name, this.exportInfo(span)); + } + + resultCallback({ code: CODE_OK }); + } + + public shutdown(): Promise { + return Promise.resolve(); + } + + private exportInfo(span): Record { + return { + traceId: span.spanContext.traceId, + parentId: span.parentSpanId, + name: span.name, + id: span.spanContext.spanId, + kind: span.kind, + timestamp: this.hrTimeToMicroseconds(span.startTime), + duration: this.hrTimeToMicroseconds(span.duration), + attributes: span.attributes, + status: span.status, + events: span.events, + }; + } + + private hrTimeToMicroseconds(hrTime): number { + return Math.round(hrTime[0] * 1e6 + hrTime[1] / 1e3); + } +} diff --git a/services/monolith/src/Core/OpenTracing/index.ts b/services/monolith/src/Core/OpenTracing/index.ts index 8b1920d..ffa965f 100644 --- a/services/monolith/src/Core/OpenTracing/index.ts +++ b/services/monolith/src/Core/OpenTracing/index.ts @@ -1,2 +1,3 @@ export * from './NestJs/OpenTracingInterceptor'; export * from './getActiveSpan'; +export * from './LoggerSpanExporter'; diff --git a/services/monolith/src/index.ts b/services/monolith/src/index.ts index b58fc8d..44bed4f 100644 --- a/services/monolith/src/index.ts +++ b/services/monolith/src/index.ts @@ -1,4 +1,6 @@ -import './telemetry'; +// open telemetry doesn't register express.js handlers if import is not on top +// eslint-disable-next-line import/order +import { provider as otelProvider } from './telemetry'; import { once } from 'events'; import * as path from 'path'; @@ -9,12 +11,15 @@ import { AbstractHttpAdapter } from '@nestjs/core'; import { NestFactoryStatic } from '@nestjs/core/nest-factory'; import { ExpressAdapter } from '@nestjs/platform-express'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; +import { SimpleSpanProcessor } from '@opentelemetry/tracing'; import { config as configureDotenv } from 'dotenv'; import { AccountContextModule } from './AccountContext/AccountContextModule'; import { AuctionContextModule } from './AuctionContext/AuctionContextModule'; import { EVENT_BUS, EventBus, EventBusCompositeCoordinator } from './Core/EventBus'; -import { NestJsLoggerAdapter } from './Core/Logger'; +import { NestJsLoggerAdapter, PinoLogger } from './Core/Logger'; +import { pinoFactory } from './Core/Logger/pinoFactory'; +import { LoggerSpanExporter } from './Core/OpenTracing'; patchNestjsSwagger(); @@ -86,6 +91,10 @@ async function createModule( throw error; } + const logger = new PinoLogger(pinoFactory()); + const spanExporter = new LoggerSpanExporter(logger); + otelProvider.addSpanProcessor(new SimpleSpanProcessor(spanExporter)); + const factoryOptions = { abortOnError: true }; const express = new ExpressAdapter(); diff --git a/services/monolith/src/telemetry.ts b/services/monolith/src/telemetry.ts index 81120ec..59809e0 100644 --- a/services/monolith/src/telemetry.ts +++ b/services/monolith/src/telemetry.ts @@ -9,8 +9,6 @@ contextManager.enable(); const provider = new NodeTracerProvider(); -provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); - provider.register({ contextManager }); context.setGlobalContextManager(contextManager); @@ -32,3 +30,7 @@ registerInstrumentations({ }); console.log('OpenTelemetry initialized'); + +export { + provider, +}; From b5f92b1ec255c7884a269cf71301833681cc0f8a Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Sat, 20 Mar 2021 18:15:06 +0100 Subject: [PATCH 08/15] refactor(monolith-service): remove OpenTracingInterceptor.ts --- .../AccountContext/AccountContextModule.ts | 5 ----- .../NestJs/OpenTracingInterceptor.ts | 21 ------------------- .../monolith/src/Core/OpenTracing/index.ts | 1 - 3 files changed, 27 deletions(-) delete mode 100644 services/monolith/src/Core/OpenTracing/NestJs/OpenTracingInterceptor.ts diff --git a/services/monolith/src/AccountContext/AccountContextModule.ts b/services/monolith/src/AccountContext/AccountContextModule.ts index 794d0fb..5348829 100644 --- a/services/monolith/src/AccountContext/AccountContextModule.ts +++ b/services/monolith/src/AccountContext/AccountContextModule.ts @@ -5,7 +5,6 @@ import { APP_INTERCEPTOR } from '@nestjs/core'; import { EVENT_BUS, EventBus, EventBusCompositeCoordinator, nestJsInMemoryEventBusProvider } from '../Core/EventBus'; import { LOGGER, Logger, NestJsLoggerAdapter, nestJsLoggerProvider } from '../Core/Logger'; import { intermediateModule } from '../Core/NestJs'; -import { OpenTracingInterceptor } from '../Core/OpenTracing'; import { OutboxMessageEntity, OutboxModule, RegisterOutboxWorker } from '../Core/Outbox/'; import { AccountContextGateway } from './AccountContextGateway'; @@ -64,10 +63,6 @@ export class AccountContextModule { ConfirmAccountService, CreateAccountService, SendAccountCreatedEmail, - { - provide: APP_INTERCEPTOR, - useClass: OpenTracingInterceptor, - }, { provide: ACCOUNT_REPOSITORY, useClass: SqliteAccountRepository, diff --git a/services/monolith/src/Core/OpenTracing/NestJs/OpenTracingInterceptor.ts b/services/monolith/src/Core/OpenTracing/NestJs/OpenTracingInterceptor.ts deleted file mode 100644 index a243fd1..0000000 --- a/services/monolith/src/Core/OpenTracing/NestJs/OpenTracingInterceptor.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common'; -import { Observable } from 'rxjs'; -import { v4 as uuid } from 'uuid'; - -import { tracingStorage } from '../tracingStorage'; - -@Injectable() -export class OpenTracingInterceptor implements NestInterceptor { - public intercept(context: ExecutionContext, next: CallHandler): Promise> { - const traceId = uuid(); - - let promise; - tracingStorage.run({ traceId }, () => { - promise = next - .handle() - .toPromise(); - }); - - return promise; - } -} diff --git a/services/monolith/src/Core/OpenTracing/index.ts b/services/monolith/src/Core/OpenTracing/index.ts index ffa965f..af58399 100644 --- a/services/monolith/src/Core/OpenTracing/index.ts +++ b/services/monolith/src/Core/OpenTracing/index.ts @@ -1,3 +1,2 @@ -export * from './NestJs/OpenTracingInterceptor'; export * from './getActiveSpan'; export * from './LoggerSpanExporter'; From e433510fa4407c74565b190a4a02666f06d8b962 Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Sat, 20 Mar 2021 18:30:16 +0100 Subject: [PATCH 09/15] feature(monolith-service): add zipkin docker compose --- services/monolith/docker-compose.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 services/monolith/docker-compose.yaml diff --git a/services/monolith/docker-compose.yaml b/services/monolith/docker-compose.yaml new file mode 100644 index 0000000..ced6f0d --- /dev/null +++ b/services/monolith/docker-compose.yaml @@ -0,0 +1,6 @@ +version: "3.8" +services: + zipkin: + image: openzipkin/zipkin-slim:2.23.2 + ports: + - '9411:9411' From 7d7bab71e84633db4b30c88a5d68fdb252052ecf Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Sat, 20 Mar 2021 18:30:23 +0100 Subject: [PATCH 10/15] feature(monolith-service): add zipkin exporter --- common/config/rush/pnpm-lock.yaml | 16 +++++++++++++++- services/monolith/package.json | 3 ++- services/monolith/src/telemetry.ts | 12 +++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 08087b7..62779bb 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -7,6 +7,7 @@ dependencies: '@nestjs/testing': 7.6.11_5493a482b6326ce7617b54c4270e8fab '@opentelemetry/api': 1.0.0-rc.0 '@opentelemetry/context-async-hooks': 0.18.0 + '@opentelemetry/exporter-zipkin': 0.18.0 '@opentelemetry/instrumentation': 0.18.0 '@opentelemetry/node': 0.18.0 '@opentelemetry/plugin-express': 0.14.0 @@ -954,6 +955,17 @@ packages: node: '>=8.5.0' resolution: integrity: sha512-Kg+LBIAPK70tEtpIAdZomkUmbABK+EwfnjFfvJ1rVZ8e0NApDx14Sq92RbGDIf67TK5mBgIvvY27W+ic354UZQ== + /@opentelemetry/exporter-zipkin/0.18.0: + dependencies: + '@opentelemetry/api': 0.18.1 + '@opentelemetry/core': 0.18.0 + '@opentelemetry/resources': 0.18.0 + '@opentelemetry/tracing': 0.18.0 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-hDP7jPwUXS9i5W0LKW7nLqEEauEeGsphEHXM2ANWk+iR8oIVIlYFPSzF9KuoqTzuZhPQl7mRzmXjzxacr/6SsA== /@opentelemetry/instrumentation/0.18.0: dependencies: '@opentelemetry/api': 0.18.1 @@ -7081,6 +7093,7 @@ packages: '@nestjs/testing': 7.6.11_ed6e60f1b18d44b976a1a0f51d940b9c '@opentelemetry/api': 1.0.0-rc.0 '@opentelemetry/context-async-hooks': 0.18.0 + '@opentelemetry/exporter-zipkin': 0.18.0 '@opentelemetry/instrumentation': 0.18.0 '@opentelemetry/node': 0.18.0 '@opentelemetry/plugin-express': 0.14.0 @@ -7117,7 +7130,7 @@ packages: dev: false name: '@rush-temp/monolith-service' resolution: - integrity: sha512-1v2sGriK4J5bXlfn3NtlAdphduYaX6GujvUcCJ9djMbE6jK1IOBUFJ3qbWBCao2vy8t86B136DNGABzSh4FMRA== + integrity: sha512-8W2+4KcSxhHvlbzcjeBLLbFsAwWfqPE80YUAQLKO2DWibvBWSI878X+1lvsvDCN6lEseQPHYB9VMthTNy2uRLQ== tarball: file:projects/monolith-service.tgz version: 0.0.0 file:projects/tsconfig.tgz: @@ -7161,6 +7174,7 @@ specifiers: '@nestjs/testing': ~7.6.11 '@opentelemetry/api': ~1.0.0-rc.0 '@opentelemetry/context-async-hooks': ~0.18.0 + '@opentelemetry/exporter-zipkin': ~0.18.0 '@opentelemetry/instrumentation': ~0.18.0 '@opentelemetry/node': ~0.18.0 '@opentelemetry/plugin-express': ~0.14.0 diff --git a/services/monolith/package.json b/services/monolith/package.json index 6fe6581..807fcca 100644 --- a/services/monolith/package.json +++ b/services/monolith/package.json @@ -39,7 +39,8 @@ "@opentelemetry/plugin-http": "~0.18.0", "@opentelemetry/plugin-express": "~0.14.0", "@opentelemetry/instrumentation": "~0.18.0", - "@opentelemetry/context-async-hooks": "~0.18.0" + "@opentelemetry/context-async-hooks": "~0.18.0", + "@opentelemetry/exporter-zipkin": "~0.18.0" }, "devDependencies": { "@abitia/eslint-config": "~1.1.0", diff --git a/services/monolith/src/telemetry.ts b/services/monolith/src/telemetry.ts index 59809e0..d4106a7 100644 --- a/services/monolith/src/telemetry.ts +++ b/services/monolith/src/telemetry.ts @@ -1,14 +1,24 @@ import { context, trace } from '@opentelemetry/api'; import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; +import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { NodeTracerProvider } from '@opentelemetry/node'; -import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/tracing'; +import { BatchSpanProcessor } from '@opentelemetry/tracing'; const contextManager = new AsyncHooksContextManager(); contextManager.enable(); const provider = new NodeTracerProvider(); +provider.addSpanProcessor( + new BatchSpanProcessor( + new ZipkinExporter({ + serviceName: 'monolith', + url: 'http://localhost:9411/api/v2/spans', + }), + ), +); + provider.register({ contextManager }); context.setGlobalContextManager(contextManager); From 265c6f5afa9df62a5a7f92a68b998e7c8ec4c0d6 Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Fri, 26 Mar 2021 22:07:32 +0100 Subject: [PATCH 11/15] chore(monolith-service): register LoggerSpanExporter only in non-prod env --- services/monolith/src/Core/OpenTracing/tracingStorage.ts | 3 --- services/monolith/src/index.ts | 9 ++++++--- 2 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 services/monolith/src/Core/OpenTracing/tracingStorage.ts diff --git a/services/monolith/src/Core/OpenTracing/tracingStorage.ts b/services/monolith/src/Core/OpenTracing/tracingStorage.ts deleted file mode 100644 index 6ae6d60..0000000 --- a/services/monolith/src/Core/OpenTracing/tracingStorage.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { AsyncLocalStorage } from 'async_hooks'; - -export const tracingStorage = new AsyncLocalStorage<{traceId: string}>(); diff --git a/services/monolith/src/index.ts b/services/monolith/src/index.ts index 8aeab30..a54c7d5 100644 --- a/services/monolith/src/index.ts +++ b/services/monolith/src/index.ts @@ -92,9 +92,12 @@ async function createModule( throw error; } - const logger = new PinoLogger(pinoFactory()); - const spanExporter = new LoggerSpanExporter(logger); - otelProvider.addSpanProcessor(new SimpleSpanProcessor(spanExporter)); + const isProd = process.env.NODE_ENV === 'production'; + if(!isProd) { + const logger = new PinoLogger(pinoFactory()); + const spanExporter = new LoggerSpanExporter(logger); + otelProvider.addSpanProcessor(new SimpleSpanProcessor(spanExporter)); + } const factoryOptions = { abortOnError: true }; const express = new ExpressAdapter(); From 74f13912566836f6819c0a0cd1028dbdd8bcec30 Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Fri, 26 Mar 2021 22:42:09 +0100 Subject: [PATCH 12/15] tests(monolith-service): adjust tests --- .../src/Core/Outbox/MikroOrm/__tests__/MikroOrmOutbox.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/monolith/src/Core/Outbox/MikroOrm/__tests__/MikroOrmOutbox.test.ts b/services/monolith/src/Core/Outbox/MikroOrm/__tests__/MikroOrmOutbox.test.ts index b638232..9e627b6 100644 --- a/services/monolith/src/Core/Outbox/MikroOrm/__tests__/MikroOrmOutbox.test.ts +++ b/services/monolith/src/Core/Outbox/MikroOrm/__tests__/MikroOrmOutbox.test.ts @@ -26,6 +26,6 @@ it('should serialize and persist the event', async () => { id: expect.any(String), createdAt: expect.any(Date), eventName: 'DummyEvent', - eventPayload: JSON.stringify(event), + eventPayload: JSON.stringify({ event }), } as OutboxMessageEntity); }); From 35579ceca753137a3ad209d73d4ae150eeeef8e3 Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Fri, 26 Mar 2021 22:55:00 +0100 Subject: [PATCH 13/15] tests(monolith-service): adjust tests --- .../Core/Outbox/MikroOrm/__tests__/MikroOrmOutboxWorker.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/monolith/src/Core/Outbox/MikroOrm/__tests__/MikroOrmOutboxWorker.test.ts b/services/monolith/src/Core/Outbox/MikroOrm/__tests__/MikroOrmOutboxWorker.test.ts index db70a49..b302d1c 100644 --- a/services/monolith/src/Core/Outbox/MikroOrm/__tests__/MikroOrmOutboxWorker.test.ts +++ b/services/monolith/src/Core/Outbox/MikroOrm/__tests__/MikroOrmOutboxWorker.test.ts @@ -20,7 +20,7 @@ const eventBusMock = { const dummyMessage = new OutboxMessageEntity( 'test-id', 'TestEvent', - JSON.stringify({ prop1: 'test' }), + JSON.stringify({ event: { prop1: 'test' } }), ); const logger = new TestLogger(); From bb1e2b4bd679519b77a53600b86586956b093e0c Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Sun, 28 Mar 2021 01:20:23 +0100 Subject: [PATCH 14/15] test xray exporter [ci skip] --- common/config/rush/pnpm-lock.yaml | 336 ++++++++++++++++++++++++++++- services/monolith/package.json | 5 +- services/monolith/src/telemetry.ts | 40 ++-- 3 files changed, 366 insertions(+), 15 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 62779bb..a520a6c 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -1,4 +1,6 @@ dependencies: + '@aws/otel-aws-xray-id-generator': 0.13.1 + '@aws/otel-aws-xray-propagator': 0.13.0 '@mikro-orm/core': 4.4.2_@mikro-orm+sqlite@4.4.2 '@mikro-orm/nestjs': 4.2.0_1b5398639b57f63400336f42f56eb406 '@mikro-orm/sqlite': 4.4.2_@mikro-orm+core@4.4.2 @@ -7,6 +9,7 @@ dependencies: '@nestjs/testing': 7.6.11_5493a482b6326ce7617b54c4270e8fab '@opentelemetry/api': 1.0.0-rc.0 '@opentelemetry/context-async-hooks': 0.18.0 + '@opentelemetry/exporter-collector-grpc': 0.18.0 '@opentelemetry/exporter-zipkin': 0.18.0 '@opentelemetry/instrumentation': 0.18.0 '@opentelemetry/node': 0.18.0 @@ -50,6 +53,22 @@ dependencies: zod: 3.0.0-alpha.4 lockfileVersion: 5.2 packages: + /@aws/otel-aws-xray-id-generator/0.13.1: + dependencies: + '@opentelemetry/core': 0.13.0 + dev: false + resolution: + integrity: sha512-ca75WEyWBgYyO6SAj67vVflZGFnE/H+/t+VXEYbrfD2F4e6GoQIcHsV6pN1RyQrykHo8ztOz1JIRMm73b3CsOA== + /@aws/otel-aws-xray-propagator/0.13.0: + dependencies: + '@opentelemetry/api': 0.13.0 + '@opentelemetry/context-base': 0.13.0 + '@opentelemetry/core': 0.13.0 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-TE3eJuRwoXc8ihkoPDw4+AnihmGXm7O8RiQxLVWfNfKoThmRZ+LZ6laUe5NiELdr0MZn9hqUo/sHrSskFRduaA== /@babel/code-frame/7.10.1: dependencies: '@babel/highlight': 7.10.1 @@ -377,6 +396,15 @@ packages: node: ^10.12.0 || >=12.0.0 resolution: integrity: sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg== + /@grpc/proto-loader/0.5.6: + dependencies: + lodash.camelcase: 4.3.0 + protobufjs: 6.10.2 + dev: false + engines: + node: '>=6' + resolution: + integrity: sha512-DT14xgw3PSzPxwS13auTEwxhMMOoz33DPUKNtmYK/QYbBSpLXJy78FGGs5yVoxVobEqPm4iW9MOIoz0A3bLTRQ== /@hapi/bourne/2.0.0: dev: false resolution: @@ -926,6 +954,14 @@ packages: node: '>=8.0.0' resolution: integrity: sha512-5MGIP1Bb97yiRBLeHdfgDaMnoKE5+IOhUvE3FGRqiTMjun0cDt35gY4k5+w5pmqpcHFkt0/ih25YTKjF0tJLHg== + /@opentelemetry/api/0.13.0: + dependencies: + '@opentelemetry/context-base': 0.13.0 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-3F5zuMBhL1cQIGTFGuuGofS9/2bfhoJxT9sWLfHtx7A/vN6HSA6YiotPjWFK/aTiLjZA4YYnIjeA3di151xJrw== /@opentelemetry/api/0.18.1: dev: false engines: @@ -946,6 +982,22 @@ packages: node: '>=8.1.0' resolution: integrity: sha512-PD1aHXyniFtZIXbLuCr+KaZiufrGJPuEZ6eMZggQRi7+AC3alAfAVRz88sLmeR49pd7lRRFiKzymzVqJRMEmjw== + /@opentelemetry/context-base/0.13.0: + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-y4qNA0JA9ab0B0ppnOokAxzJDplBWCLdTVJrH8a8SMiWubkuGOIGJpe3ZoJzPLrg3BWKZ9CIk9vHiyBFYgYgWg== + /@opentelemetry/core/0.13.0: + dependencies: + '@opentelemetry/api': 0.13.0 + '@opentelemetry/context-base': 0.13.0 + semver: 7.3.2 + dev: false + engines: + node: '>=8.5.0' + resolution: + integrity: sha512-SFHr4uRnSSWqTLu1J1hadn92aGoGVb2WrPHvOgNIttSKYkUXNVyABO1pdtUN2AHE4/YBmk9eLwTUqwmFjVfZWQ== /@opentelemetry/core/0.18.0: dependencies: '@opentelemetry/api': 0.18.1 @@ -955,6 +1007,34 @@ packages: node: '>=8.5.0' resolution: integrity: sha512-Kg+LBIAPK70tEtpIAdZomkUmbABK+EwfnjFfvJ1rVZ8e0NApDx14Sq92RbGDIf67TK5mBgIvvY27W+ic354UZQ== + /@opentelemetry/exporter-collector-grpc/0.18.0: + dependencies: + '@grpc/proto-loader': 0.5.6 + '@opentelemetry/api': 0.18.1 + '@opentelemetry/core': 0.18.0 + '@opentelemetry/exporter-collector': 0.18.0 + '@opentelemetry/metrics': 0.18.0 + '@opentelemetry/resources': 0.18.0 + '@opentelemetry/tracing': 0.18.0 + grpc: 1.24.6 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-fmZdlt+Y7nHb9VhfgAT2/+4sVGXIo6dNoAVTqE2orWmpI7bzzFYydmSTOM43XMByEjqJrONHV8l8NtCWHWvc3w== + /@opentelemetry/exporter-collector/0.18.0: + dependencies: + '@opentelemetry/api': 0.18.1 + '@opentelemetry/api-metrics': 0.18.0 + '@opentelemetry/core': 0.18.0 + '@opentelemetry/metrics': 0.18.0 + '@opentelemetry/resources': 0.18.0 + '@opentelemetry/tracing': 0.18.0 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-AMurbTrkhIDy+hCs7Iz3MdhRCUbhzQC3rUOIDwusnUDBOah7zD9OLm/6yS529jrYNfljzxHjeczV0oOsu9AcKQ== /@opentelemetry/exporter-zipkin/0.18.0: dependencies: '@opentelemetry/api': 0.18.1 @@ -976,6 +1056,18 @@ packages: dev: false resolution: integrity: sha512-YFrCnSWS9jJLChg5I8g7EuvpWqPZGa2EXyO8KwRJApuLPCqJSBkcymYieedWNupS0FAXntocpIb/b0SEVaZbEg== + /@opentelemetry/metrics/0.18.0: + dependencies: + '@opentelemetry/api': 0.18.1 + '@opentelemetry/api-metrics': 0.18.0 + '@opentelemetry/core': 0.18.0 + '@opentelemetry/resources': 0.18.0 + lodash.merge: 4.6.2 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-BH1P97bY6ZHBPNlW/0gV+Bc384Gqpu0KOdKWy2ZcntxGemhZ+byguL1AlqqS5ip+AaoCvgAmaY7JzuXq7YKo4A== /@opentelemetry/node/0.18.0: dependencies: '@opentelemetry/api': 0.18.1 @@ -1037,6 +1129,49 @@ packages: node: '>=8.0.0' resolution: integrity: sha512-k7UAebuHBLPafS8rnkpZqNuM8nfwOg6OCmppekCMxdQzkuZS1attgelqyEIlX6NYh46DndyZ7BxBkiXF4S0Xwg== + /@protobufjs/aspromise/1.1.2: + dev: false + resolution: + integrity: sha1-m4sMxmPWaafY9vXQiToU00jzD78= + /@protobufjs/base64/1.1.2: + dev: false + resolution: + integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + /@protobufjs/codegen/2.0.4: + dev: false + resolution: + integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + /@protobufjs/eventemitter/1.1.0: + dev: false + resolution: + integrity: sha1-NVy8mLr61ZePntCV85diHx0Ga3A= + /@protobufjs/fetch/1.1.0: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + dev: false + resolution: + integrity: sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= + /@protobufjs/float/1.0.2: + dev: false + resolution: + integrity: sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= + /@protobufjs/inquire/1.1.0: + dev: false + resolution: + integrity: sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= + /@protobufjs/path/1.1.2: + dev: false + resolution: + integrity: sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= + /@protobufjs/pool/1.1.0: + dev: false + resolution: + integrity: sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= + /@protobufjs/utf8/1.1.0: + dev: false + resolution: + integrity: sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= /@rushstack/eslint-patch/1.0.6: dev: false resolution: @@ -1093,6 +1228,13 @@ packages: dev: false resolution: integrity: sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== + /@types/bytebuffer/5.0.42: + dependencies: + '@types/long': 4.0.1 + '@types/node': 14.14.25 + dev: false + resolution: + integrity: sha512-lEgKojWUAc/MG2t649oZS5AfYFP2xRNPoDuwDBlBMjHXd8MaGPgFgtCXUK7inZdBOygmVf10qxc1Us8GXC96aw== /@types/color-name/1.1.1: dev: false resolution: @@ -1161,6 +1303,10 @@ packages: dev: false resolution: integrity: sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + /@types/long/4.0.1: + dev: false + resolution: + integrity: sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== /@types/mime/1.3.2: dev: false resolution: @@ -1172,6 +1318,10 @@ packages: dev: false resolution: integrity: sha512-fbjI6ja0N5ZA8TV53RUqzsKNkl9fv8Oj3T7zxW7FGv1GSH7gwJaNF8dzCjrqKaxKeUpTz4yT1DaJFq/omNpGfw== + /@types/node/13.13.48: + dev: false + resolution: + integrity: sha512-z8wvSsgWQzkr4sVuMEEOvwMdOQjiRY2Y/ZW4fDfjfe3+TfQrZqFKOthBgk2RnVEmtOKrkwdZ7uTvsxTBLjKGDQ== /@types/node/14.14.25: dev: false resolution: @@ -1587,6 +1737,13 @@ packages: node: '>= 0.4' resolution: integrity: sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== + /ascli/1.0.1: + dependencies: + colour: 0.7.1 + optjs: 3.2.2 + dev: false + resolution: + integrity: sha1-vPpZdKYvGOgcq660lzKrSoj5Brw= /asn1/0.2.4: dependencies: safer-buffer: 2.1.2 @@ -1844,6 +2001,14 @@ packages: node: '>=0.8.0' resolution: integrity: sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= + /bytebuffer/5.0.1: + dependencies: + long: 3.2.0 + dev: false + engines: + node: '>=0.8' + resolution: + integrity: sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0= /bytes/3.1.0: dev: false engines: @@ -1872,6 +2037,12 @@ packages: node: '>=6' resolution: integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + /camelcase/2.1.1: + dev: false + engines: + node: '>=0.10.0' + resolution: + integrity: sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= /camelcase/5.0.0: dev: false engines: @@ -1950,6 +2121,14 @@ packages: node: '>=0.10.0' resolution: integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + /cliui/3.2.0: + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + wrap-ansi: 2.1.0 + dev: false + resolution: + integrity: sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= /cliui/6.0.0: dependencies: string-width: 4.2.0 @@ -2016,6 +2195,12 @@ packages: dev: false resolution: integrity: sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== + /colour/0.7.1: + dev: false + engines: + node: '>=0.8' + resolution: + integrity: sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g= /combined-stream/1.0.8: dependencies: delayed-stream: 1.0.0 @@ -3262,6 +3447,20 @@ packages: optional: true resolution: integrity: sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + /grpc/1.24.6: + dependencies: + '@types/bytebuffer': 5.0.42 + lodash.camelcase: 4.3.0 + lodash.clone: 4.5.0 + nan: 2.14.2 + node-pre-gyp: 0.16.0 + protobufjs: 5.0.3 + dev: false + engines: + node: '>=4' + requiresBuild: true + resolution: + integrity: sha512-BtifKdClMYU0ZEo0Pdr2WV9ZH54AoEdIcp2BfJkh87g2R3HoNPLYKHRYefw/ByxrCdVDTAy3hkraFISpqsRcrw== /har-schema/2.0.0: dev: false engines: @@ -3484,6 +3683,12 @@ packages: node: '>= 0.10' resolution: integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + /invert-kv/1.0.0: + dev: false + engines: + node: '>=0.10.0' + resolution: + integrity: sha1-EEqOSqym09jNFXqO+L+rLXo//bY= /ip-regex/2.1.0: dev: false engines: @@ -4464,6 +4669,14 @@ packages: optional: true resolution: integrity: sha512-kAt58lRwjzqwedApKF7luYPa7HsLb0oDiczwKrkZcekIzTmSow5YGK149S2C8HjH63R3NcOBo9+1rjvWnC1Paw== + /lcid/1.0.0: + dependencies: + invert-kv: 1.0.0 + dev: false + engines: + node: '>=0.10.0' + resolution: + integrity: sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= /leven/2.1.0: dev: false engines: @@ -4541,6 +4754,14 @@ packages: node: '>=8' resolution: integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + /lodash.camelcase/4.3.0: + dev: false + resolution: + integrity: sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + /lodash.clone/4.5.0: + dev: false + resolution: + integrity: sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y= /lodash.merge/4.6.2: dev: false resolution: @@ -4553,6 +4774,16 @@ packages: dev: false resolution: integrity: sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + /long/3.2.0: + dev: false + engines: + node: '>=0.6' + resolution: + integrity: sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s= + /long/4.0.0: + dev: false + resolution: + integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== /make-dir/3.1.0: dependencies: semver: 6.3.0 @@ -4765,6 +4996,10 @@ packages: node: '>= 0.10.0' resolution: integrity: sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg== + /nan/2.14.2: + dev: false + resolution: + integrity: sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== /nanomatch/1.2.13: dependencies: arr-diff: 4.0.0 @@ -4901,6 +5136,23 @@ packages: hasBin: true resolution: integrity: sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA== + /node-pre-gyp/0.16.0: + dependencies: + detect-libc: 1.0.3 + mkdirp: 0.5.5 + needle: 2.6.0 + nopt: 4.0.3 + npm-packlist: 1.4.8 + npmlog: 4.1.2 + rc: 1.2.8 + rimraf: 2.6.3 + semver: 5.7.1 + tar: 4.4.13 + deprecated: 'Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future' + dev: false + hasBin: true + resolution: + integrity: sha512-4efGA+X/YXAHLi1hN8KaPrILULaUn2nWecFrn1k2I+99HpoyvcOGEbtcOxpDiUwPF2ZANMJDh32qwOUPenuR1g== /nopt/3.0.6: dependencies: abbrev: 1.1.1 @@ -5139,12 +5391,24 @@ packages: node: '>= 0.8.0' resolution: integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + /optjs/3.2.2: + dev: false + resolution: + integrity: sha1-aabOicRCpEQDFBrS+bNwvVu29O4= /os-homedir/1.0.2: dev: false engines: node: '>=0.10.0' resolution: integrity: sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + /os-locale/1.4.0: + dependencies: + lcid: 1.0.0 + dev: false + engines: + node: '>=0.10.0' + resolution: + integrity: sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= /os-tmpdir/1.0.2: dev: false engines: @@ -5468,6 +5732,38 @@ packages: node: '>= 6' resolution: integrity: sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ== + /protobufjs/5.0.3: + dependencies: + ascli: 1.0.1 + bytebuffer: 5.0.1 + glob: 7.1.6 + yargs: 3.32.0 + dev: false + engines: + node: '>=0.8' + hasBin: true + resolution: + integrity: sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA== + /protobufjs/6.10.2: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/long': 4.0.1 + '@types/node': 13.13.48 + long: 4.0.0 + dev: false + hasBin: true + requiresBuild: true + resolution: + integrity: sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ== /proxy-addr/2.0.6: dependencies: forwarded: 0.1.2 @@ -6958,12 +7254,28 @@ packages: dev: false resolution: integrity: sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + /window-size/0.1.4: + dev: false + engines: + node: '>= 0.10.0' + hasBin: true + resolution: + integrity: sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY= /word-wrap/1.2.3: dev: false engines: node: '>=0.10.0' resolution: integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + /wrap-ansi/2.1.0: + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + dev: false + engines: + node: '>=0.10.0' + resolution: + integrity: sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= /wrap-ansi/6.2.0: dependencies: ansi-styles: 4.2.1 @@ -7015,6 +7327,10 @@ packages: node: '>=0.4' resolution: integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + /y18n/3.2.2: + dev: false + resolution: + integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== /y18n/4.0.0: dev: false resolution: @@ -7056,6 +7372,18 @@ packages: node: '>=8' resolution: integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + /yargs/3.32.0: + dependencies: + camelcase: 2.1.1 + cliui: 3.2.0 + decamelize: 1.2.0 + os-locale: 1.4.0 + string-width: 1.0.2 + window-size: 0.1.4 + y18n: 3.2.2 + dev: false + resolution: + integrity: sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU= /yn/3.1.1: dev: false engines: @@ -7083,6 +7411,8 @@ packages: version: 0.0.0 file:projects/monolith-service.tgz: dependencies: + '@aws/otel-aws-xray-id-generator': 0.13.1 + '@aws/otel-aws-xray-propagator': 0.13.0 '@mikro-orm/core': 4.4.2_@mikro-orm+sqlite@4.4.2 '@mikro-orm/nestjs': 4.2.0_f16047f1be058b4f78bced1d248b322a '@mikro-orm/sqlite': 4.4.2_@mikro-orm+core@4.4.2 @@ -7093,6 +7423,7 @@ packages: '@nestjs/testing': 7.6.11_ed6e60f1b18d44b976a1a0f51d940b9c '@opentelemetry/api': 1.0.0-rc.0 '@opentelemetry/context-async-hooks': 0.18.0 + '@opentelemetry/exporter-collector-grpc': 0.18.0 '@opentelemetry/exporter-zipkin': 0.18.0 '@opentelemetry/instrumentation': 0.18.0 '@opentelemetry/node': 0.18.0 @@ -7130,7 +7461,7 @@ packages: dev: false name: '@rush-temp/monolith-service' resolution: - integrity: sha512-8W2+4KcSxhHvlbzcjeBLLbFsAwWfqPE80YUAQLKO2DWibvBWSI878X+1lvsvDCN6lEseQPHYB9VMthTNy2uRLQ== + integrity: sha512-Gdf/T9rf3Jh9pPGLtxKVnYZuMYf0yo2aVjrs5X9L8QCbP2xSeDBAN/mEm18rwdmErrXspFn7grV3OsPG1qvSWA== tarball: file:projects/monolith-service.tgz version: 0.0.0 file:projects/tsconfig.tgz: @@ -7166,6 +7497,8 @@ packages: version: 0.0.0 registry: '' specifiers: + '@aws/otel-aws-xray-id-generator': ~0.13.1 + '@aws/otel-aws-xray-propagator': ~0.13.0 '@mikro-orm/core': ~4.4.2 '@mikro-orm/nestjs': ~4.2.0 '@mikro-orm/sqlite': ~4.4.2 @@ -7174,6 +7507,7 @@ specifiers: '@nestjs/testing': ~7.6.11 '@opentelemetry/api': ~1.0.0-rc.0 '@opentelemetry/context-async-hooks': ~0.18.0 + '@opentelemetry/exporter-collector-grpc': ~0.18.0 '@opentelemetry/exporter-zipkin': ~0.18.0 '@opentelemetry/instrumentation': ~0.18.0 '@opentelemetry/node': ~0.18.0 diff --git a/services/monolith/package.json b/services/monolith/package.json index 16487a0..f5b1cdb 100644 --- a/services/monolith/package.json +++ b/services/monolith/package.json @@ -41,7 +41,10 @@ "@opentelemetry/plugin-express": "~0.14.0", "@opentelemetry/instrumentation": "~0.18.0", "@opentelemetry/context-async-hooks": "~0.18.0", - "@opentelemetry/exporter-zipkin": "~0.18.0" + "@opentelemetry/exporter-zipkin": "~0.18.0", + "@opentelemetry/exporter-collector-grpc": "~0.18.0", + "@aws/otel-aws-xray-propagator": "~0.13.0", + "@aws/otel-aws-xray-id-generator": "~0.13.1" }, "devDependencies": { "@abitia/eslint-config": "~1.1.0", diff --git a/services/monolith/src/telemetry.ts b/services/monolith/src/telemetry.ts index d4106a7..a91efce 100644 --- a/services/monolith/src/telemetry.ts +++ b/services/monolith/src/telemetry.ts @@ -1,23 +1,37 @@ -import { context, trace } from '@opentelemetry/api'; +import { AwsXRayIdGenerator } from '@aws/otel-aws-xray-id-generator'; +import { AWSXRayPropagator } from '@aws/otel-aws-xray-propagator'; +import { context, trace, propagation } from '@opentelemetry/api'; import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; -import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'; +import { CollectorTraceExporter } from '@opentelemetry/exporter-collector-grpc'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { NodeTracerProvider } from '@opentelemetry/node'; -import { BatchSpanProcessor } from '@opentelemetry/tracing'; +import { SimpleSpanProcessor } from '@opentelemetry/tracing'; const contextManager = new AsyncHooksContextManager(); contextManager.enable(); -const provider = new NodeTracerProvider(); - -provider.addSpanProcessor( - new BatchSpanProcessor( - new ZipkinExporter({ - serviceName: 'monolith', - url: 'http://localhost:9411/api/v2/spans', - }), - ), -); +// provider.addSpanProcessor( +// new BatchSpanProcessor( +// new ZipkinExporter({ +// serviceName: 'monolith', +// url: 'http://localhost:9411/api/v2/spans', +// }), +// ), +// ); + +propagation.setGlobalPropagator(new AWSXRayPropagator()); +// create a provider for activating and tracking with AWS IdGenerator +const tracerConfig = { + idGenerator: new AwsXRayIdGenerator(), +}; +const provider = new NodeTracerProvider(tracerConfig); +// add OTLP exporter +const otlpExporter = new CollectorTraceExporter({ + serviceName: 'monolith', + // port configured in the Collector config, defaults to 55680 + url: 'localhost:4317', +}); +provider.addSpanProcessor(new SimpleSpanProcessor(otlpExporter)); provider.register({ contextManager }); From cccd641418a47b7e90e2c7c54607486e60cbdd44 Mon Sep 17 00:00:00 2001 From: kbkk <6276426+kbkk@users.noreply.github.com> Date: Wed, 31 Mar 2021 22:19:15 +0200 Subject: [PATCH 15/15] chore(monolith-service): wip dockerfiles [ci skip] --- .dockerignore | 4 ++++ Dockerfile | 6 ++++++ services/monolith/Dockerfile | 8 ++++++++ 3 files changed, 18 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 services/monolith/Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..d0cc26a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.github +.run +common/temp +**/node_modules diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..97429e1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM node:14.16.0-alpine3.10 + +WORKDIR /usr/src/app +COPY . ./ +RUN node common/scripts/install-run-rush.js install +RUN node common/scripts/install-run-rush.js build diff --git a/services/monolith/Dockerfile b/services/monolith/Dockerfile new file mode 100644 index 0000000..b243261 --- /dev/null +++ b/services/monolith/Dockerfile @@ -0,0 +1,8 @@ +FROM 14.16.0-alpine3.10 as builder + +WORKDIR /usr/src/app +COPY package.json ./ +COPY .babelrc ./ +RUN npm install +COPY ./src ./src +RUN npm run build \ No newline at end of file