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

Merge pull request #9507 from weseek/imprv/start-instrumentation-at-first

imprv: Start instrumentation at first
mergify[bot] 1 год назад
Родитель
Сommit
dc02ae60fb

+ 7 - 3
apps/app/src/features/opentelemetry/server/start.ts

@@ -1,3 +1,4 @@
+import { ConfigSource } from '@growi/core/dist/interfaces';
 import type { NodeSDK } from '@opentelemetry/sdk-node';
 import type { NodeSDK } from '@opentelemetry/sdk-node';
 
 
 import { configManager } from '~/server/service/config-manager';
 import { configManager } from '~/server/service/config-manager';
@@ -14,7 +15,7 @@ let sdkInstance: NodeSDK;
  * Since otel library sees it.
  * Since otel library sees it.
  */
  */
 function overwriteSdkDisabled(): void {
 function overwriteSdkDisabled(): void {
-  const instrumentationEnabled = configManager.getConfig('otel:enabled');
+  const instrumentationEnabled = configManager.getConfig('otel:enabled', ConfigSource.env);
 
 
   if (instrumentationEnabled && (
   if (instrumentationEnabled && (
     process.env.OTEL_SDK_DISABLED === 'true'
     process.env.OTEL_SDK_DISABLED === 'true'
@@ -42,9 +43,12 @@ export const startInstrumentation = async(version: string): Promise<void> => {
     return;
     return;
   }
   }
 
 
+  // load configs from env
+  await configManager.loadConfigs({ source: ConfigSource.env });
+
   overwriteSdkDisabled();
   overwriteSdkDisabled();
 
 
-  const instrumentationEnabled = configManager.getConfig('otel:enabled');
+  const instrumentationEnabled = configManager.getConfig('otel:enabled', ConfigSource.env);
   if (instrumentationEnabled) {
   if (instrumentationEnabled) {
 
 
     logger.info(`GROWI now collects anonymous telemetry.
     logger.info(`GROWI now collects anonymous telemetry.
@@ -65,7 +69,7 @@ For more information, see https://docs.growi.org/en/admin-guide/telemetry.html.
     const { NodeSDK } = await import('@opentelemetry/sdk-node');
     const { NodeSDK } = await import('@opentelemetry/sdk-node');
     const { generateNodeSDKConfiguration } = await import('./node-sdk-configuration');
     const { generateNodeSDKConfiguration } = await import('./node-sdk-configuration');
 
 
-    const serviceInstanceId = configManager.getConfig('otel:serviceInstanceId')
+    const serviceInstanceId = configManager.getConfig('otel:serviceInstanceId', ConfigSource.env)
       ?? 'generated-appSiteUrlHashed'; // TODO: generated appSiteUrlHashed
       ?? 'generated-appSiteUrlHashed'; // TODO: generated appSiteUrlHashed
 
 
     sdkInstance = new NodeSDK(generateNodeSDKConfiguration(serviceInstanceId, version));
     sdkInstance = new NodeSDK(generateNodeSDKConfiguration(serviceInstanceId, version));

+ 8 - 4
apps/app/src/server/app.ts

@@ -1,10 +1,11 @@
-import Logger from 'bunyan';
+import type Logger from 'bunyan';
 
 
+import pkg from '^/package.json';
+
+import { startInstrumentation } from '~/features/opentelemetry/server';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 import { hasProcessFlag } from '~/utils/process-utils';
 import { hasProcessFlag } from '~/utils/process-utils';
 
 
-import Crowi from './crowi';
-
 const logger: Logger = loggerFactory('growi');
 const logger: Logger = loggerFactory('growi');
 
 
 
 
@@ -21,7 +22,10 @@ process.on('unhandledRejection', (reason, p) => {
 
 
 async function main() {
 async function main() {
   try {
   try {
-    // eslint-disable-next-line @typescript-eslint/no-var-requires
+    // start OpenTelemetry
+    await startInstrumentation(pkg.version);
+
+    const Crowi = (await import('./crowi')).default;
     const growi = new Crowi();
     const growi = new Crowi();
     const server = await growi.start();
     const server = await growi.start();
 
 

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

@@ -13,7 +13,6 @@ import pkg from '^/package.json';
 import { KeycloakUserGroupSyncService } from '~/features/external-user-group/server/service/keycloak-user-group-sync';
 import { KeycloakUserGroupSyncService } from '~/features/external-user-group/server/service/keycloak-user-group-sync';
 import { LdapUserGroupSyncService } from '~/features/external-user-group/server/service/ldap-user-group-sync';
 import { LdapUserGroupSyncService } from '~/features/external-user-group/server/service/ldap-user-group-sync';
 import { startCronIfEnabled as startOpenaiCronIfEnabled } from '~/features/openai/server/services/cron';
 import { startCronIfEnabled as startOpenaiCronIfEnabled } from '~/features/openai/server/services/cron';
-import { startInstrumentation } from '~/features/opentelemetry/server';
 import QuestionnaireService from '~/features/questionnaire/server/service/questionnaire';
 import QuestionnaireService from '~/features/questionnaire/server/service/questionnaire';
 import QuestionnaireCronService from '~/features/questionnaire/server/service/questionnaire-cron';
 import QuestionnaireCronService from '~/features/questionnaire/server/service/questionnaire-cron';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
@@ -159,9 +158,6 @@ Crowi.prototype.init = async function() {
   await this.setupSessionConfig();
   await this.setupSessionConfig();
   this.setupCron();
   this.setupCron();
 
 
-  // start OpenTelemetry
-  startInstrumentation(this.version);
-
   // setup messaging services
   // setup messaging services
   await this.setupS2sMessagingService();
   await this.setupS2sMessagingService();
   await this.setupSocketIoService();
   await this.setupSocketIoService();

+ 25 - 11
apps/app/src/server/service/config-manager/config-manager.ts

@@ -11,8 +11,7 @@ import type { S2sMessageHandlable } from '../s2s-messaging/handlable';
 import type { ConfigKey, ConfigValues } from './config-definition';
 import type { ConfigKey, ConfigValues } from './config-definition';
 import { ENV_ONLY_GROUPS } from './config-definition';
 import { ENV_ONLY_GROUPS } from './config-definition';
 import { ConfigLoader } from './config-loader';
 import { ConfigLoader } from './config-loader';
-import { configManager as configManagerLegacy } from './legacy/config-manager';
-
+import type { ConfigManager as ConfigManagerLegacy } from './legacy/config-manager';
 
 
 const logger = loggerFactory('growi:service:ConfigManager');
 const logger = loggerFactory('growi:service:ConfigManager');
 
 
@@ -20,6 +19,8 @@ export type IConfigManagerForApp = IConfigManager<ConfigKey, ConfigValues>
 
 
 export class ConfigManager implements IConfigManagerForApp, S2sMessageHandlable {
 export class ConfigManager implements IConfigManagerForApp, S2sMessageHandlable {
 
 
+  private configManagerLegacy: ConfigManagerLegacy;
+
   private configLoader: ConfigLoader;
   private configLoader: ConfigLoader;
 
 
   private s2sMessagingService?: S2sMessagingService;
   private s2sMessagingService?: S2sMessagingService;
@@ -60,29 +61,42 @@ export class ConfigManager implements IConfigManagerForApp, S2sMessageHandlable
     }
     }
 
 
     // Load legacy configs
     // Load legacy configs
-    await configManagerLegacy.loadConfigs();
+    if (options == null) {
+      this.configManagerLegacy = await import('./legacy/config-manager').then(m => m.configManager);
+      await this.configManagerLegacy.loadConfigs();
+    }
 
 
     this.lastLoadedAt = new Date();
     this.lastLoadedAt = new Date();
   }
   }
 
 
   getConfig<K extends ConfigKey>(key: K, source?: ConfigSource): ConfigValues[K] {
   getConfig<K extends ConfigKey>(key: K, source?: ConfigSource): ConfigValues[K] {
-    if (!this.envConfig || !this.dbConfig) {
-      throw new Error('Config is not loaded');
-    }
-
     const value = (() => {
     const value = (() => {
       if (source === ConfigSource.env) {
       if (source === ConfigSource.env) {
+        if (!this.envConfig) {
+          throw new Error('Config is not loaded');
+        }
         return this.envConfig[key]?.value;
         return this.envConfig[key]?.value;
       }
       }
       if (source === ConfigSource.db) {
       if (source === ConfigSource.db) {
+        if (!this.dbConfig) {
+          throw new Error('Config is not loaded');
+        }
         return this.dbConfig[key]?.value;
         return this.dbConfig[key]?.value;
       }
       }
+
+      if (!this.envConfig || !this.dbConfig) {
+        throw new Error('Config is not loaded');
+      }
+
       return this.shouldUseEnvOnly(key)
       return this.shouldUseEnvOnly(key)
         ? this.envConfig[key]?.value
         ? this.envConfig[key]?.value
         : (this.dbConfig[key] ?? this.envConfig[key])?.value;
         : (this.dbConfig[key] ?? this.envConfig[key])?.value;
     })() as ConfigValues[K];
     })() as ConfigValues[K];
 
 
-    this.checkDifference(key, value);
+    // check difference between new and legacy config managers
+    if (this.configManagerLegacy != null) {
+      this.checkDifference(key, value);
+    }
 
 
     return value;
     return value;
   }
   }
@@ -90,12 +104,12 @@ export class ConfigManager implements IConfigManagerForApp, S2sMessageHandlable
   private checkDifference<K extends ConfigKey>(key: K, value: ConfigValues[K], source?: ConfigSource): void {
   private checkDifference<K extends ConfigKey>(key: K, value: ConfigValues[K], source?: ConfigSource): void {
     const valueByLegacy = (() => {
     const valueByLegacy = (() => {
       if (source === ConfigSource.env) {
       if (source === ConfigSource.env) {
-        return configManagerLegacy.getConfigFromEnvVars('crowi', key);
+        return this.configManagerLegacy.getConfigFromEnvVars('crowi', key);
       }
       }
       if (source === ConfigSource.db) {
       if (source === ConfigSource.db) {
-        return configManagerLegacy.getConfigFromDB('crowi', key);
+        return this.configManagerLegacy.getConfigFromDB('crowi', key);
       }
       }
-      return configManagerLegacy.getConfig('crowi', key);
+      return this.configManagerLegacy.getConfig('crowi', key);
     })();
     })();
 
 
     const isDifferent = (() => {
     const isDifferent = (() => {