Просмотр исходного кода

devide modules and import dynamically

Yuki Takei 1 год назад
Родитель
Сommit
ab9ed28dbd

+ 47 - 0
apps/app/src/features/opentelemetry/server/node-sdk-configuration.ts

@@ -0,0 +1,47 @@
+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 { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, SEMRESATTRS_SERVICE_INSTANCE_ID } from '@opentelemetry/semantic-conventions';
+
+
+export const generateNodeSDKConfiguration = (instanceId: string, version: string): Partial<NodeSDKConfiguration> => {
+  return {
+    resource: new Resource({
+      [ATTR_SERVICE_NAME]: 'growi',
+      [ATTR_SERVICE_VERSION]: version,
+      [SEMRESATTRS_SERVICE_INSTANCE_ID]: instanceId,
+    }),
+    traceExporter: new OTLPTraceExporter(),
+    metricReader: new PeriodicExportingMetricReader({
+      exporter: new OTLPMetricExporter(),
+      exportIntervalMillis: 10000,
+    }),
+    instrumentations: [getNodeAutoInstrumentations({
+      '@opentelemetry/instrumentation-bunyan': {
+        enabled: false,
+      },
+      // disable fs instrumentation since this generates very large amount of traces
+      // see: https://opentelemetry.io/docs/languages/js/libraries/#registration
+      '@opentelemetry/instrumentation-fs': {
+        enabled: false,
+      },
+    })],
+  };
+};
+
+// 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();
+// }

+ 18 - 42
apps/app/src/features/opentelemetry/server/start.ts

@@ -1,48 +1,14 @@
-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 { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, SEMRESATTRS_SERVICE_INSTANCE_ID } from '@opentelemetry/semantic-conventions';
+import type { NodeSDK } from '@opentelemetry/sdk-node';
 
 
 import { configManager } from '~/server/service/config-manager';
 import { configManager } from '~/server/service/config-manager';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
-import { initLogger } from './logger';
 
 
-
-const logger = loggerFactory('growi:opentelemetry');
+const logger = loggerFactory('growi:opentelemetry:server');
 
 
 
 
 let sdkInstance: NodeSDK;
 let sdkInstance: NodeSDK;
 
 
-function generateNodeSDKConfiguration(instanceId: string, version: string): Partial<NodeSDKConfiguration> {
-  return {
-    resource: new Resource({
-      [ATTR_SERVICE_NAME]: 'growi',
-      [ATTR_SERVICE_VERSION]: version,
-      [SEMRESATTRS_SERVICE_INSTANCE_ID]: instanceId,
-    }),
-    traceExporter: new OTLPTraceExporter(),
-    metricReader: new PeriodicExportingMetricReader({
-      exporter: new OTLPMetricExporter(),
-      exportIntervalMillis: 10000,
-    }),
-    instrumentations: [getNodeAutoInstrumentations({
-      '@opentelemetry/instrumentation-bunyan': {
-        enabled: false,
-      },
-      // disable fs instrumentation since this generates very large amount of traces
-      // see: https://opentelemetry.io/docs/languages/js/libraries/#registration
-      '@opentelemetry/instrumentation-fs': {
-        enabled: false,
-      },
-    })],
-  };
-}
-
 /**
 /**
  * Overwrite "OTEL_SDK_DISABLED" env var before sdk.start() is invoked if needed.
  * Overwrite "OTEL_SDK_DISABLED" env var before sdk.start() is invoked if needed.
  * Since otel library sees it.
  * Since otel library sees it.
@@ -54,24 +20,23 @@ function overwriteSdkDisabled(): void {
     process.env.OTEL_SDK_DISABLED === 'true'
     process.env.OTEL_SDK_DISABLED === 'true'
     || process.env.OTEL_SDK_DISABLED === '1'
     || process.env.OTEL_SDK_DISABLED === '1'
   )) {
   )) {
-    logger.warn("OTEL_SDK_DISABLED will be set 'false' since GROWI's 'otel:enabled' config is true.");
+    logger.warn("OTEL_SDK_DISABLED overwritten with 'false' since GROWI's 'otel:enabled' config is true.");
     process.env.OTEL_SDK_DISABLED = 'false';
     process.env.OTEL_SDK_DISABLED = 'false';
     return;
     return;
   }
   }
 
 
   if (!instrumentationEnabled && (
   if (!instrumentationEnabled && (
-    process.env.OTEL_SDK_DISABLED == null
-    || process.env.OTEL_SDK_DISABLED === 'false'
+    process.env.OTEL_SDK_DISABLED === 'false'
     || process.env.OTEL_SDK_DISABLED === '0'
     || process.env.OTEL_SDK_DISABLED === '0'
   )) {
   )) {
-    logger.warn("OTEL_SDK_DISABLED will be set 'true' since GROWI's 'otel:enabled' config is false.");
+    logger.warn("OTEL_SDK_DISABLED is overwritten with 'true' since GROWI's 'otel:enabled' config is false.");
     process.env.OTEL_SDK_DISABLED = 'true';
     process.env.OTEL_SDK_DISABLED = 'true';
     return;
     return;
   }
   }
 
 
 }
 }
 
 
-export const startInstrumentation = (version: string): void => {
+export const startInstrumentation = async(version: string): Promise<void> => {
   if (sdkInstance != null) {
   if (sdkInstance != null) {
     logger.warn('OpenTelemetry instrumentation already started');
     logger.warn('OpenTelemetry instrumentation already started');
     return;
     return;
@@ -81,7 +46,6 @@ export const startInstrumentation = (version: string): void => {
 
 
   const instrumentationEnabled = configManager.getConfig('crowi', 'otel:enabled');
   const instrumentationEnabled = configManager.getConfig('crowi', 'otel:enabled');
   if (instrumentationEnabled) {
   if (instrumentationEnabled) {
-    initLogger();
 
 
     logger.info(`GROWI now collects anonymous telemetry.
     logger.info(`GROWI now collects anonymous telemetry.
 
 
@@ -90,7 +54,19 @@ This data is used to help improve GROWI, but you can opt-out at any time.
 For more information, see https://docs.growi.org/en/admin-guide/telemetry.html.
 For more information, see https://docs.growi.org/en/admin-guide/telemetry.html.
 `);
 `);
 
 
+    // initialize global logger for development
+    const isDev = process.env.NODE_ENV === 'development';
+    if (isDev) {
+      const { initLogger } = await import('./logger');
+      initLogger();
+    }
+
+    // instanciate NodeSDK
+    const { NodeSDK } = await import('@opentelemetry/sdk-node');
+    const { generateNodeSDKConfiguration } = await import('./node-sdk-configuration');
+
     const serviceInstanceId = configManager.getConfig('crowi', 'otel:serviceInstanceId');
     const serviceInstanceId = configManager.getConfig('crowi', 'otel:serviceInstanceId');
+
     sdkInstance = new NodeSDK(generateNodeSDKConfiguration(serviceInstanceId, version));
     sdkInstance = new NodeSDK(generateNodeSDKConfiguration(serviceInstanceId, version));
     sdkInstance.start();
     sdkInstance.start();
   }
   }