فهرست منبع

feat: add xray to syncing server and files

Karol Sójko 1 سال پیش
والد
کامیت
6583ff6cd9

+ 2 - 0
.pnp.cjs

@@ -6053,6 +6053,7 @@ const RAW_RUNTIME_STATE =
           ["@types/uuid", "npm:9.0.3"],\
           ["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
           ["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
+          ["aws-xray-sdk", "npm:3.5.2"],\
           ["connect-busboy", "npm:1.0.0"],\
           ["cors", "npm:2.8.5"],\
           ["dayjs", "npm:1.11.7"],\
@@ -6380,6 +6381,7 @@ const RAW_RUNTIME_STATE =
           ["@types/uuid", "npm:9.0.3"],\
           ["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
           ["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
+          ["aws-xray-sdk", "npm:3.5.2"],\
           ["axios", "npm:1.4.0"],\
           ["cors", "npm:2.8.5"],\
           ["dotenv", "npm:16.1.3"],\

+ 17 - 0
packages/files/bin/server.ts

@@ -10,6 +10,7 @@ import helmet from 'helmet'
 import * as cors from 'cors'
 import { urlencoded, json, raw, Request, Response, NextFunction } from 'express'
 import * as winston from 'winston'
+import * as AWSXRay from 'aws-xray-sdk'
 // eslint-disable-next-line @typescript-eslint/no-var-requires
 const robots = require('express-robots-txt')
 
@@ -17,15 +18,27 @@ import { InversifyExpressServer } from 'inversify-express-utils'
 import { ContainerConfigLoader } from '../src/Bootstrap/Container'
 import TYPES from '../src/Bootstrap/Types'
 import { Env } from '../src/Bootstrap/Env'
+import { ServiceIdentifier } from '@standardnotes/domain-core'
 
 const container = new ContainerConfigLoader()
 void container.load().then((container) => {
   const env: Env = new Env()
   env.load()
 
+  const isConfiguredForAWSProduction =
+    env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
+
+  if (isConfiguredForAWSProduction) {
+    AWSXRay.config([AWSXRay.plugins.ECSPlugin])
+  }
+
   const server = new InversifyExpressServer(container)
 
   server.setConfig((app) => {
+    if (isConfiguredForAWSProduction) {
+      app.use(AWSXRay.express.openSegment(ServiceIdentifier.NAMES.Files))
+    }
+
     app.use((_request: Request, response: Response, next: NextFunction) => {
       response.setHeader('X-Files-Version', container.get(TYPES.Files_VERSION))
       next()
@@ -90,6 +103,10 @@ void container.load().then((container) => {
 
   const serverInstance = server.build()
 
+  if (isConfiguredForAWSProduction) {
+    serverInstance.use(AWSXRay.express.closeSegment())
+  }
+
   serverInstance.listen(env.get('PORT'))
 
   logger.info(`Server started on port ${process.env.PORT}`)

+ 9 - 0
packages/files/bin/worker.ts

@@ -8,6 +8,7 @@ import { Env } from '../src/Bootstrap/Env'
 import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
 import * as dayjs from 'dayjs'
 import * as utc from 'dayjs/plugin/utc'
+import * as AWSXRay from 'aws-xray-sdk'
 
 const container = new ContainerConfigLoader()
 void container.load().then((container) => {
@@ -16,6 +17,14 @@ void container.load().then((container) => {
   const env: Env = new Env()
   env.load()
 
+  const isConfiguredForAWSProduction =
+    env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
+
+  if (isConfiguredForAWSProduction) {
+    AWSXRay.enableManualMode()
+    AWSXRay.config([AWSXRay.plugins.ECSPlugin])
+  }
+
   const logger: Logger = container.get(TYPES.Files_Logger)
 
   logger.info('Starting worker...')

+ 1 - 0
packages/files/package.json

@@ -37,6 +37,7 @@
     "@standardnotes/sncrypto-common": "^1.13.4",
     "@standardnotes/sncrypto-node": "workspace:*",
     "@standardnotes/time": "workspace:*",
+    "aws-xray-sdk": "^3.5.2",
     "connect-busboy": "^1.0.0",
     "cors": "^2.8.5",
     "dayjs": "^1.11.6",

+ 24 - 5
packages/files/src/Bootstrap/Container.ts

@@ -1,5 +1,6 @@
 import * as winston from 'winston'
 import Redis from 'ioredis'
+import { captureAWSv3Client } from 'aws-xray-sdk'
 import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns'
 import { SQSClient, SQSClientConfig } from '@aws-sdk/client-sqs'
 import { S3Client, S3ClientConfig } from '@aws-sdk/client-s3'
@@ -19,7 +20,7 @@ import {
   SNSDomainEventPublisher,
   SQSDomainEventSubscriberFactory,
   SQSEventMessageHandler,
-  SQSNewRelicEventMessageHandler,
+  SQSXRayEventMessageHandler,
 } from '@standardnotes/domain-events-infra'
 import { StreamDownloadFile } from '../Domain/UseCase/StreamDownloadFile/StreamDownloadFile'
 import { FileDownloaderInterface } from '../Domain/Services/FileDownloaderInterface'
@@ -53,6 +54,7 @@ import { S3FileMover } from '../Infra/S3/S3FileMover'
 import { FSFileMover } from '../Infra/FS/FSFileMover'
 import { MoveFile } from '../Domain/UseCase/MoveFile/MoveFile'
 import { SharedVaultValetTokenAuthMiddleware } from '../Infra/InversifyExpress/Middleware/SharedVaultValetTokenAuthMiddleware'
+import { ServiceIdentifier } from '@standardnotes/domain-core'
 
 export class ContainerConfigLoader {
   async load(configuration?: {
@@ -83,7 +85,9 @@ export class ContainerConfigLoader {
       .toConstantValue(env.get('FILE_UPLOAD_PATH', true) ?? `${__dirname}/../../uploads`)
 
     const isConfiguredForHomeServer = env.get('MODE', true) === 'home-server'
+    const isConfiguredForSelfHosting = env.get('MODE', true) === 'self-hosted'
     const isConfiguredForInMemoryCache = env.get('CACHE_TYPE', true) === 'memory'
+    const isConfiguredForAWSProduction = !isConfiguredForHomeServer && !isConfiguredForSelfHosting
 
     let logger: winston.Logger
     if (configuration?.logger) {
@@ -149,7 +153,11 @@ export class ContainerConfigLoader {
             secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
           }
         }
-        container.bind<SNSClient>(TYPES.Files_SNS).toConstantValue(new SNSClient(snsConfig))
+        let snsClient = new SNSClient(snsConfig)
+        if (isConfiguredForAWSProduction) {
+          snsClient = captureAWSv3Client(snsClient)
+        }
+        container.bind<SNSClient>(TYPES.Files_SNS).toConstantValue(snsClient)
       }
 
       if (env.get('SQS_QUEUE_URL', true)) {
@@ -165,7 +173,11 @@ export class ContainerConfigLoader {
             secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
           }
         }
-        container.bind<SQSClient>(TYPES.Files_SQS).toConstantValue(new SQSClient(sqsConfig))
+        let sqsClient = new SQSClient(sqsConfig)
+        if (isConfiguredForAWSProduction) {
+          sqsClient = captureAWSv3Client(sqsClient)
+        }
+        container.bind<SQSClient>(TYPES.Files_SQS).toConstantValue(sqsClient)
       }
 
       container
@@ -185,7 +197,10 @@ export class ContainerConfigLoader {
       if (env.get('S3_ENDPOINT', true)) {
         s3Opts.endpoint = env.get('S3_ENDPOINT', true)
       }
-      const s3Client = new S3Client(s3Opts)
+      let s3Client = new S3Client(s3Opts)
+      if (isConfiguredForAWSProduction) {
+        s3Client = captureAWSv3Client(s3Client)
+      }
       container.bind<S3Client>(TYPES.Files_S3).toConstantValue(s3Client)
       container.bind<FileDownloaderInterface>(TYPES.Files_FileDownloader).to(S3FileDownloader)
       container.bind<FileUploaderInterface>(TYPES.Files_FileUploader).to(S3FileUploader)
@@ -292,7 +307,11 @@ export class ContainerConfigLoader {
         .bind<DomainEventMessageHandlerInterface>(TYPES.Files_DomainEventMessageHandler)
         .toConstantValue(
           env.get('NEW_RELIC_ENABLED', true) === 'true'
-            ? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Files_Logger))
+            ? new SQSXRayEventMessageHandler(
+                ServiceIdentifier.NAMES.FilesWorker,
+                eventHandlers,
+                container.get(TYPES.Files_Logger),
+              )
             : new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Files_Logger)),
         )
       container

+ 17 - 0
packages/syncing-server/bin/server.ts

@@ -11,20 +11,33 @@ import helmet from 'helmet'
 import * as cors from 'cors'
 import { urlencoded, json, Request, Response, NextFunction } from 'express'
 import * as winston from 'winston'
+import * as AWSXRay from 'aws-xray-sdk'
 
 import { InversifyExpressServer } from 'inversify-express-utils'
 import TYPES from '../src/Bootstrap/Types'
 import { Env } from '../src/Bootstrap/Env'
 import { ContainerConfigLoader } from '../src/Bootstrap/Container'
+import { ServiceIdentifier } from '@standardnotes/domain-core'
 
 const container = new ContainerConfigLoader()
 void container.load().then((container) => {
   const env: Env = new Env()
   env.load()
 
+  const isConfiguredForAWSProduction =
+    env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
+
+  if (isConfiguredForAWSProduction) {
+    AWSXRay.config([AWSXRay.plugins.ECSPlugin])
+  }
+
   const server = new InversifyExpressServer(container)
 
   server.setConfig((app) => {
+    if (isConfiguredForAWSProduction) {
+      app.use(AWSXRay.express.openSegment(ServiceIdentifier.NAMES.SyncingServer))
+    }
+
     app.use((_request: Request, response: Response, next: NextFunction) => {
       response.setHeader('X-SSJS-Version', container.get(TYPES.Sync_VERSION))
       next()
@@ -73,6 +86,10 @@ void container.load().then((container) => {
 
   const serverInstance = server.build()
 
+  if (isConfiguredForAWSProduction) {
+    serverInstance.use(AWSXRay.express.closeSegment())
+  }
+
   serverInstance.listen(env.get('PORT'))
 
   logger.info(`Server started on port ${process.env.PORT}`)

+ 9 - 0
packages/syncing-server/bin/worker.ts

@@ -1,6 +1,7 @@
 import 'reflect-metadata'
 
 import { Logger } from 'winston'
+import * as AWSXRay from 'aws-xray-sdk'
 
 import TYPES from '../src/Bootstrap/Types'
 import { Env } from '../src/Bootstrap/Env'
@@ -12,6 +13,14 @@ void container.load().then((container) => {
   const env: Env = new Env()
   env.load()
 
+  const isConfiguredForAWSProduction =
+    env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
+
+  if (isConfiguredForAWSProduction) {
+    AWSXRay.enableManualMode()
+    AWSXRay.config([AWSXRay.plugins.ECSPlugin])
+  }
+
   const logger: Logger = container.get(TYPES.Sync_Logger)
 
   logger.info('Starting worker...')

+ 1 - 0
packages/syncing-server/package.json

@@ -40,6 +40,7 @@
     "@standardnotes/settings": "workspace:*",
     "@standardnotes/sncrypto-node": "workspace:*",
     "@standardnotes/time": "workspace:*",
+    "aws-xray-sdk": "^3.5.2",
     "axios": "^1.1.3",
     "cors": "2.8.5",
     "dotenv": "^16.0.1",

+ 21 - 2
packages/syncing-server/src/Bootstrap/Container.ts

@@ -5,6 +5,7 @@ import { Container, interfaces } from 'inversify'
 import { Env } from './Env'
 import TYPES from './Types'
 import { AppDataSource } from './DataSource'
+import { captureAWSv3Client } from 'aws-xray-sdk'
 import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns'
 import { ItemRepositoryInterface } from '../Domain/Item/ItemRepositoryInterface'
 import { SQLLegacyItemRepository } from '../Infra/TypeORM/SQLLegacyItemRepository'
@@ -16,7 +17,7 @@ import {
   SNSDomainEventPublisher,
   SQSDomainEventSubscriberFactory,
   SQSEventMessageHandler,
-  SQSNewRelicEventMessageHandler,
+  SQSXRayEventMessageHandler,
 } from '@standardnotes/domain-events-infra'
 import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
 import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
@@ -63,6 +64,7 @@ import {
   ControllerContainer,
   ControllerContainerInterface,
   MapperInterface,
+  ServiceIdentifier,
   SharedVaultUser,
 } from '@standardnotes/domain-core'
 import { BaseItemsController } from '../Infra/InversifyExpressUtils/Base/BaseItemsController'
@@ -231,6 +233,7 @@ export class ContainerConfigLoader {
 
     const isConfiguredForHomeServer = env.get('MODE', true) === 'home-server'
     const isConfiguredForSelfHosting = env.get('MODE', true) === 'self-hosted'
+    const isConfiguredForAWSProduction = !isConfiguredForHomeServer && !isConfiguredForSelfHosting
     const isConfiguredForHomeServerOrSelfHosting = isConfiguredForHomeServer || isConfiguredForSelfHosting
     const isSecondaryDatabaseEnabled = env.get('SECONDARY_DB_ENABLED', true) === 'true'
     const isConfiguredForInMemoryCache = env.get('CACHE_TYPE', true) === 'memory'
@@ -282,6 +285,10 @@ export class ContainerConfigLoader {
           }
         }
 
+        if (isConfiguredForAWSProduction) {
+          captureAWSv3Client(new SNSClient(snsConfig))
+        }
+
         return new SNSClient(snsConfig)
       })
 
@@ -310,6 +317,10 @@ export class ContainerConfigLoader {
           }
         }
 
+        if (isConfiguredForAWSProduction) {
+          captureAWSv3Client(new SQSClient(sqsConfig))
+        }
+
         return new SQSClient(sqsConfig)
       })
 
@@ -322,6 +333,10 @@ export class ContainerConfigLoader {
             apiVersion: 'latest',
             region: env.get('S3_AWS_REGION', true),
           })
+
+          if (isConfiguredForAWSProduction) {
+            captureAWSv3Client(s3Client)
+          }
         }
 
         return s3Client
@@ -1158,7 +1173,11 @@ export class ContainerConfigLoader {
         .bind<DomainEventMessageHandlerInterface>(TYPES.Sync_DomainEventMessageHandler)
         .toConstantValue(
           env.get('NEW_RELIC_ENABLED', true) === 'true'
-            ? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Sync_Logger))
+            ? new SQSXRayEventMessageHandler(
+                ServiceIdentifier.NAMES.SyncingServerWorker,
+                eventHandlers,
+                container.get(TYPES.Sync_Logger),
+              )
             : new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Sync_Logger)),
         )
     }

+ 2 - 0
yarn.lock

@@ -4947,6 +4947,7 @@ __metadata:
     "@types/uuid": "npm:^9.0.3"
     "@typescript-eslint/eslint-plugin": "npm:^6.5.0"
     "@typescript-eslint/parser": "npm:^6.5.0"
+    aws-xray-sdk: "npm:^3.5.2"
     connect-busboy: "npm:^1.0.0"
     cors: "npm:^2.8.5"
     dayjs: "npm:^1.11.6"
@@ -5277,6 +5278,7 @@ __metadata:
     "@types/uuid": "npm:^9.0.3"
     "@typescript-eslint/eslint-plugin": "npm:^6.5.0"
     "@typescript-eslint/parser": "npm:^6.5.0"
+    aws-xray-sdk: "npm:^3.5.2"
     axios: "npm:^1.1.3"
     cors: "npm:2.8.5"
     dotenv: "npm:^16.0.1"