فهرست منبع

improve custom metrics

Yuki Takei 9 ماه پیش
والد
کامیت
0fb59ca03c

+ 10 - 9
apps/app/src/features/opentelemetry/docs/improvement-task.md

@@ -7,15 +7,16 @@
 ## タスク一覧
 
 ### Phase 1: カスタムメトリクス
-- [ ] **Resource Attributes拡張**
-  - [ ] サーバーURL属性追加
-  - [ ] GROWI固有属性追加(インストールタイプ、DB種別等)
-  - [ ] 環境情報属性追加
-- [ ] **System Metrics実装**
-  - [ ] CPU使用率収集(計算ロジックの実装が必要)
-  - [ ] メモリ使用率収集(process.memoryUsage()使用)
-  - [ ] 収集間隔設定(デフォルト15秒)
-- [ ] **Application Metrics実装**
+- [x] **Resource Attributes拡張**
+  - [x] サーバーURL属性追加(環境変数から取得)
+  - [x] GROWI固有属性追加(基本情報)
+  - [x] 環境情報属性追加
+- [x] **System Metrics実装**
+  - [x] CPU使用率収集(計算ロジックの実装が必要)
+  - [x] メモリ使用率収集(process.memoryUsage()使用)
+  - [x] 収集間隔設定(デフォルト15秒)
+- [x] **Application Metrics実装**
+  - [x] ダミーメトリクス実装(将来の拡張用)
   - [ ] ユーザー数メトリクス
   - [ ] ページ数メトリクス
   - [ ] 検索回数カウンター

+ 5 - 10
apps/app/src/features/opentelemetry/server/custom-metrics/application-metrics.ts

@@ -1,17 +1,12 @@
 import { diag, metrics } from '@opentelemetry/api';
 
-const logger = diag.createComponentLogger({ namespace: 'growi:custom-metrics:application' });
+import loggerFactory from '~/utils/logger';
 
-export interface ApplicationMetricsConfig {
-  enabled: boolean;
-}
+const logger = loggerFactory('growi:opentelemetry:custom-metrics:application-metrics');
+const loggerDiag = diag.createComponentLogger({ namespace: 'growi:custom-metrics:application' });
 
-export function addApplicationMetrics(config: ApplicationMetricsConfig): void {
-  if (!config.enabled) {
-    logger.debug('Application metrics collection is disabled');
-    return;
-  }
 
+export function addApplicationMetrics(): void {
   logger.info('Starting application metrics collection');
 
   const meter = metrics.getMeter('growi-application-metrics', '1.0.0');
@@ -32,7 +27,7 @@ export function addApplicationMetrics(config: ApplicationMetricsConfig): void {
         });
       }
       catch (error) {
-        logger.error('Failed to collect application metrics', { error });
+        loggerDiag.error('Failed to collect application metrics', { error });
       }
     },
     [dummyGauge],

+ 2 - 15
apps/app/src/features/opentelemetry/server/custom-metrics/index.ts

@@ -1,15 +1,2 @@
-import { addApplicationMetrics, type ApplicationMetricsConfig } from './application-metrics';
-import { addSystemMetrics, type SystemMetricsConfig } from './system-metrics';
-
-export { addSystemMetrics, type SystemMetricsConfig } from './system-metrics';
-export { addApplicationMetrics, type ApplicationMetricsConfig } from './application-metrics';
-
-export interface CustomMetricsConfig {
-  systemMetrics: SystemMetricsConfig;
-  applicationMetrics: ApplicationMetricsConfig;
-}
-
-export function addCustomMetrics(config: CustomMetricsConfig): void {
-  addSystemMetrics(config.systemMetrics);
-  addApplicationMetrics(config.applicationMetrics);
-}
+export { addSystemMetrics } from './system-metrics';
+export { addApplicationMetrics } from './application-metrics';

+ 10 - 12
apps/app/src/features/opentelemetry/server/custom-metrics/system-metrics.ts

@@ -3,10 +3,12 @@ import * as process from 'process';
 
 import { diag, metrics } from '@opentelemetry/api';
 
-const logger = diag.createComponentLogger({ namespace: 'growi:custom-metrics:system' });
+import loggerFactory from '~/utils/logger';
+
+const logger = loggerFactory('growi:opentelemetry:custom-metrics:system-metrics');
+const loggerDiag = diag.createComponentLogger({ namespace: 'growi:custom-metrics:system' });
 
 export interface SystemMetricsConfig {
-  enabled: boolean;
   collectionInterval: number;
 }
 
@@ -18,20 +20,21 @@ function calculateCpuUsage(intervalMs: number): number | null {
 
     if (lastCpuUsage === null) {
       lastCpuUsage = currentUsage;
-      return null; // 最初の計測では使用率を計算できない
+      return null; // Cannot calculate usage rate on first measurement
     }
 
+
     const userDiff = currentUsage.user - lastCpuUsage.user;
     const systemDiff = currentUsage.system - lastCpuUsage.system;
     const totalDiff = userDiff + systemDiff;
 
-    // マイクロ秒を秒に変換し、収集間隔で割って使用率を計算
-    const intervalUs = intervalMs * 1000; // マイクロ秒に変換
+    // Convert microseconds to seconds and divide by collection interval to calculate usage rate
+    const intervalUs = intervalMs * 1000; // Convert to microseconds
     const usage = (totalDiff / intervalUs) * 100;
 
     lastCpuUsage = currentUsage;
 
-    // 0-100%の範囲でクランプ
+    // Clamp to 0-100% range
     return Math.min(Math.max(usage, 0), 100);
   }
   catch (error) {
@@ -54,11 +57,6 @@ function getMemoryInfo(): { used: number; total: number; usagePercent: number }
 }
 
 export function addSystemMetrics(config: SystemMetricsConfig): void {
-  if (!config.enabled) {
-    logger.debug('System metrics collection is disabled');
-    return;
-  }
-
   logger.info('Starting system metrics collection');
 
   const meter = metrics.getMeter('growi-system-metrics', '1.0.0');
@@ -121,7 +119,7 @@ export function addSystemMetrics(config: SystemMetricsConfig): void {
         });
       }
       catch (error) {
-        logger.error('Failed to collect system metrics', { error });
+        loggerDiag.error('Failed to collect system metrics', { error });
       }
     },
     [cpuUsageGauge, memoryUsageGauge, memoryUsagePercentGauge, processMemoryHeapGauge, processMemoryRssGauge],

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

@@ -8,6 +8,8 @@ import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, SEMRESATTRS_SERVICE_INSTANCE_I
 
 import { getGrowiVersion } from '~/utils/growi-version';
 
+import { addApplicationMetrics, addSystemMetrics } from './custom-metrics';
+
 type Configuration = Partial<NodeSDKConfiguration> & {
   resource: IResource;
 };
@@ -41,6 +43,12 @@ export const generateNodeSDKConfiguration = (serviceInstanceId?: string): Config
         },
       })],
     };
+
+    // add custom metrics
+    addApplicationMetrics();
+    addSystemMetrics({
+      collectionInterval: 15000, // 15sec
+    });
   }
 
   if (serviceInstanceId != null) {