start.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import type { NodeSDK } from '@opentelemetry/sdk-node';
  2. import { configManager } from '~/server/service/config-manager';
  3. import loggerFactory from '~/utils/logger';
  4. const logger = loggerFactory('growi:opentelemetry:server');
  5. let sdkInstance: NodeSDK;
  6. /**
  7. * Overwrite "OTEL_SDK_DISABLED" env var before sdk.start() is invoked if needed.
  8. * Since otel library sees it.
  9. */
  10. function overwriteSdkDisabled(): void {
  11. const instrumentationEnabled = configManager.getConfig('crowi', 'otel:enabled');
  12. if (instrumentationEnabled && (
  13. process.env.OTEL_SDK_DISABLED === 'true'
  14. || process.env.OTEL_SDK_DISABLED === '1'
  15. )) {
  16. logger.warn("OTEL_SDK_DISABLED overwritten with 'false' since GROWI's 'otel:enabled' config is true.");
  17. process.env.OTEL_SDK_DISABLED = 'false';
  18. return;
  19. }
  20. if (!instrumentationEnabled && (
  21. process.env.OTEL_SDK_DISABLED === 'false'
  22. || process.env.OTEL_SDK_DISABLED === '0'
  23. )) {
  24. logger.warn("OTEL_SDK_DISABLED is overwritten with 'true' since GROWI's 'otel:enabled' config is false.");
  25. process.env.OTEL_SDK_DISABLED = 'true';
  26. return;
  27. }
  28. }
  29. export const startInstrumentation = async(version: string): Promise<void> => {
  30. if (sdkInstance != null) {
  31. logger.warn('OpenTelemetry instrumentation already started');
  32. return;
  33. }
  34. overwriteSdkDisabled();
  35. const instrumentationEnabled = configManager.getConfig('crowi', 'otel:enabled');
  36. if (instrumentationEnabled) {
  37. logger.info(`GROWI now collects anonymous telemetry.
  38. This data is used to help improve GROWI, but you can opt-out at any time.
  39. For more information, see https://docs.growi.org/en/admin-guide/telemetry.html.
  40. `);
  41. // initialize global logger for development
  42. const isDev = process.env.NODE_ENV === 'development';
  43. if (isDev) {
  44. const { initLogger } = await import('./logger');
  45. initLogger();
  46. }
  47. // instanciate NodeSDK
  48. const { NodeSDK } = await import('@opentelemetry/sdk-node');
  49. const { generateNodeSDKConfiguration } = await import('./node-sdk-configuration');
  50. const serviceInstanceId = configManager.getConfig('crowi', 'otel:serviceInstanceId');
  51. sdkInstance = new NodeSDK(generateNodeSDKConfiguration(serviceInstanceId, version));
  52. sdkInstance.start();
  53. }
  54. };
  55. // public async shutdownInstrumentation(): Promise<void> {
  56. // await this.sdkInstance.shutdown();
  57. // // メモ: 以下の restart コードは動かない
  58. // // span/metrics ともに何も出なくなる
  59. // // そもそも、restart するような使い方が出来なさそう?
  60. // // see: https://github.com/open-telemetry/opentelemetry-specification/issues/27/
  61. // // const sdk = new NodeSDK({...});
  62. // // sdk.start();
  63. // // await sdk.shutdown().catch(console.error);
  64. // // const newSdk = new NodeSDK({...});
  65. // // newSdk.start();
  66. // }