Browse Source

divide instrumentation code

Syunsuke Komma 2 years ago
parent
commit
cb318b75be
2 changed files with 78 additions and 46 deletions
  1. 4 46
      apps/app/src/server/crowi/index.js
  2. 74 0
      apps/app/src/server/crowi/opentelemetry.ts

+ 4 - 46
apps/app/src/server/crowi/index.js

@@ -5,14 +5,6 @@ import path from 'path';
 import { createTerminus } from '@godaddy/terminus';
 import { createTerminus } from '@godaddy/terminus';
 import attachmentRoutes from '@growi/remark-attachment-refs/dist/server';
 import attachmentRoutes from '@growi/remark-attachment-refs/dist/server';
 import lsxRoutes from '@growi/remark-lsx/dist/server/index.cjs';
 import lsxRoutes from '@growi/remark-lsx/dist/server/index.cjs';
-import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
-import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
-import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
-import { Resource } from '@opentelemetry/resources';
-import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
-import { NodeSDK } from '@opentelemetry/sdk-node';
-import { TraceIdRatioBasedSampler } from '@opentelemetry/sdk-trace-node';
-import { SEMRESATTRS_SERVICE_NAME, SEMRESATTRS_SERVICE_INSTANCE_ID, SEMRESATTRS_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
 import mongoose from 'mongoose';
 import mongoose from 'mongoose';
 import next from 'next';
 import next from 'next';
 
 
@@ -48,6 +40,8 @@ import { UserNotificationService } from '../service/user-notification';
 import { instantiateYjsConnectionManager } from '../service/yjs-connection-manager';
 import { instantiateYjsConnectionManager } from '../service/yjs-connection-manager';
 import { getMongoUri, mongoOptions } from '../util/mongoose-utils';
 import { getMongoUri, mongoOptions } from '../util/mongoose-utils';
 
 
+import { OpenTelemetry } from './opentelemetry';
+
 
 
 const logger = loggerFactory('growi:crowi');
 const logger = loggerFactory('growi:crowi');
 const httpErrorHandler = require('../middlewares/http-error-handler');
 const httpErrorHandler = require('../middlewares/http-error-handler');
@@ -466,44 +460,8 @@ Crowi.prototype.start = async function() {
   await this.init();
   await this.init();
   await this.buildServer();
   await this.buildServer();
 
 
-  // setup OpenTelemetry
-  // see: https://opentelemetry.io/docs/languages/js/getting-started/nodejs/#setup
-  const newNodeSDKConfiguration = () => {
-    return {
-      resource: new Resource({
-        [SEMRESATTRS_SERVICE_NAME]: 'next-app',
-        // TODO: 環境変数から入れられるようにしたい
-        [SEMRESATTRS_SERVICE_INSTANCE_ID]: 'growi-app-XXXX',
-        [SEMRESATTRS_SERVICE_VERSION]: this.version,
-      }),
-      // TODO: 宛先を環境変数から設定できるようにしたい
-      traceExporter: new OTLPTraceExporter({ url: 'http://otel-collector:4317' }),
-      metricReader: new PeriodicExportingMetricReader({
-        // TODO: 宛先を環境変数から設定できるようにしたい
-        exporter: new OTLPMetricExporter({ url: 'http://otel-collector:4317' }),
-        exportIntervalMillis: 10000,
-      }),
-      instrumentations: [getNodeAutoInstrumentations({
-        // この module は大量の trace を生成するため、無効化する
-        // see: https://opentelemetry.io/docs/languages/js/libraries/#registration
-        '@opentelemetry/instrumentation-fs': {
-          enabled: false,
-        },
-      })],
-      // 全 trace の半分を出す
-      // see: https://opentelemetry.io/docs/languages/js/sampling/
-      sampler: new TraceIdRatioBasedSampler(0.5),
-    };
-  };
-
-  // setup instrumentation for OpenTelemetry
-  const sdk = new NodeSDK(newNodeSDKConfiguration());
-  await sdk.start();
-  // 以下の restart コードは動かない
-  // span/metrics ともに何も出なくなる
-  // await sdk.shutdown();
-  // const newSdk = new NodeSDK(newNodeSDKConfiguration());
-  // await newSdk.start();
+  const otel = new OpenTelemetry('next-app', 'growi-app-XXX', this.version);
+  otel.startInstrumentation();
 
 
   // setup Next.js
   // setup Next.js
   this.nextApp = next({ dev });
   this.nextApp = next({ dev });

+ 74 - 0
apps/app/src/server/crowi/opentelemetry.ts

@@ -0,0 +1,74 @@
+import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
+import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
+import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
+import { Resource } from '@opentelemetry/resources';
+import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
+import type { NodeSDKConfiguration } from '@opentelemetry/sdk-node';
+import { NodeSDK } from '@opentelemetry/sdk-node';
+import { TraceIdRatioBasedSampler } from '@opentelemetry/sdk-trace-node';
+import { SEMRESATTRS_SERVICE_NAME, SEMRESATTRS_SERVICE_INSTANCE_ID, SEMRESATTRS_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
+
+export class OpenTelemetry {
+
+  name: string;
+
+  instanceId: string;
+
+  version: string;
+
+  sdkInstance: NodeSDK;
+
+  constructor(name: string, instanceId: string, version: string) {
+    this.name = name;
+    this.instanceId = instanceId;
+    this.version = version;
+  }
+
+  private generateNodeSDKConfiguration(): Partial<NodeSDKConfiguration> {
+    return {
+      resource: new Resource({
+        [SEMRESATTRS_SERVICE_NAME]: 'next-app',
+        // TODO: 環境変数から入れられるようにしたい
+        [SEMRESATTRS_SERVICE_INSTANCE_ID]: this.instanceId,
+        [SEMRESATTRS_SERVICE_VERSION]: this.version,
+      }),
+      // TODO: 宛先を環境変数から設定できるようにしたい
+      traceExporter: new OTLPTraceExporter({ url: 'http://otel-collector:4317' }),
+      metricReader: new PeriodicExportingMetricReader({
+        // TODO: 宛先を環境変数から設定できるようにしたい
+        exporter: new OTLPMetricExporter({ url: 'http://otel-collector:4317' }),
+        exportIntervalMillis: 10000,
+      }),
+      instrumentations: [getNodeAutoInstrumentations({
+        // この module は大量の trace を生成するため、無効化する
+        // see: https://opentelemetry.io/docs/languages/js/libraries/#registration
+        '@opentelemetry/instrumentation-fs': {
+          enabled: false,
+        },
+      })],
+      // 全 trace の半分を出す
+      // see: https://opentelemetry.io/docs/languages/js/sampling/
+      sampler: new TraceIdRatioBasedSampler(0.5),
+    };
+  }
+
+  public startInstrumentation(): void {
+    this.sdkInstance = new NodeSDK(this.generateNodeSDKConfiguration());
+    this.sdkInstance.start();
+  }
+
+  public async shutdownInstrumentation(): Promise<void> {
+    await this.sdkInstance.shutdown();
+
+    // メモ: 以下の restart コードは動かない
+    // span/metrics ともに何も出なくなる
+    // そもそも、restart するような使い方が出来なさそう?
+    // see: https://github.com/open-telemetry/opentelemetry-specification/issues/27/
+    // const sdk = new NodeSDK({...});
+    // sdk.start();
+    // await sdk.shutdown().catch(console.error);
+    // const newSdk = new NodeSDK({...});
+    // newSdk.start();
+  }
+
+}