MonitorService.ts
Fixed hardcoded environment variables and simplified configuration by removing unnecessary serviceVersion parameter
MonitorService.tsv2.0.011.6 KB
MonitorService.ts(typescript)
1/**
2 * Monitor Service - Adapted from UCM pattern for application monitoring
3 *
4 * This service provides comprehensive application monitoring capabilities including
5 * performance metrics, health checks, system statistics, and resource monitoring.
6 *
7 */
8
9import { BaseService, ServiceMetadata } from "@/core/interfaces/BaseService";
10import { ILogger } from "@/core/logging/ILogger";
11
12/**
13 * Token usage information for AI API calls
14 */
15export interface TokenUsage {
16 promptTokens: number;
17 completionTokens: number;
18 totalTokens: number;
19}
20
21/**
22 * User-related events for tracking user behavior
23 */
24export enum UserEventType {
25 Registered = 'User.Registered',
26 EmailVerified = 'User.EmailVerified',
27 LoggedIn = 'User.LoggedIn',
28 LoginSuccessful = 'User.LoginSuccessful',
29 LoginFailed = 'User.LoginFailed',
30 PasswordChanged = 'User.PasswordChanged',
31 ProfileUpdated = 'User.ProfileUpdated',
32 AccountDeleted = 'User.AccountDeleted'
33}
34
35/**
36 * System-related events for tracking operational metrics
37 */
38export enum SystemEventType {
39 ServiceStarted = 'System.ServiceStarted',
40 ServiceStopped = 'System.ServiceStopped',
41 HealthCheckPassed = 'System.HealthCheckPassed',
42 HealthCheckFailed = 'System.HealthCheckFailed',
43 ConfigurationChanged = 'System.ConfigurationChanged',
44 QuotaExceeded = 'System.QuotaExceeded',
45 QuotaWarning = 'System.QuotaWarning',
46 WorkerStarted = 'System.WorkerStarted',
47 WorkerStopped = 'System.WorkerStopped',
48 JobEnqueued = 'System.JobEnqueued',
49 EmailSent = 'System.EmailSent'
50}
51
52/**
53 * Security-related events for tracking security incidents
54 */
55export enum SecurityEventType {
56 LoginAttemptFailed = 'Security.LoginAttemptFailed',
57 PasswordResetRequested = 'Security.PasswordResetRequested',
58 PasswordResetCompleted = 'Security.PasswordResetCompleted',
59 SuspiciousActivity = 'Security.SuspiciousActivity',
60 UnauthorizedAccess = 'Security.UnauthorizedAccess',
61 AccountLocked = 'Security.AccountLocked',
62 AccountUnlocked = 'Security.AccountUnlocked',
63 AdminActionPerformed = 'Security.AdminActionPerformed',
64 EmailVerificationFailed = 'Security.EmailVerificationFailed',
65 AuthenticationFailed = 'Authentication.Failed',
66 AuthenticationSuccess = 'Authentication.Success',
67 AuthorizationFailed = 'Authorization.Failed',
68 AdminAccess = 'Admin.Access',
69 AdminSessionTimeout = 'Admin.SessionTimeout',
70 RateLimitExceeded = 'RateLimit.Exceeded'
71}
72
73/**
74 * Monitor service interface for tracking events and telemetry
75 * Provides centralized monitoring and alerting capabilities
76 */
77export interface IMonitorService {
78 /**
79 * Track any custom event with arbitrary parameters
80 * @param eventName - The name of the event (use dot notation: Category.Action)
81 * @param params - Event parameters and metadata
82 */
83 onEvent(eventName: string, params: any): Promise<void>;
84
85 /**
86 * Track user-related events
87 * @param event - The user event type
88 * @param userId - The user ID associated with the event
89 * @param details - Additional event details
90 */
91 onUserEvent(event: UserEventType, userId: string, details?: any): Promise<void>;
92
93 /**
94 * Track system-related events
95 * @param event - The system event type
96 * @param details - Event details and metadata
97 */
98 onSystemEvent(event: SystemEventType, details: any): Promise<void>;
99
100 /**
101 * Track security-related events
102 * @param event - The security event type
103 * @param userId - The user ID associated with the event (if applicable)
104 * @param details - Security event details
105 */
106 onSecurityEvent(event: SecurityEventType, userId: string, details: any): Promise<void>;
107
108 /**
109 * Track AI token usage for cost monitoring
110 * @param model - The AI model used (e.g., 'gpt-4', 'gpt-3.5-turbo')
111 * @param tokens - Token usage information
112 * @param jobId - The job ID associated with the usage
113 * @param userId - The user ID who initiated the request (optional)
114 */
115 onCostEvent(model: string, tokens: TokenUsage, jobId: string, userId?: string): Promise<void>;
116
117 /**
118 * Check if the monitoring service is healthy and connected
119 * @returns True if healthy
120 */
121 isHealthy(): Promise<boolean>;
122
123 /**
124 * Initialize the monitoring service
125 * @param config - Optional configuration
126 */
127 initialize(config?: Record<string, any>): Promise<void>;
128
129 /**
130 * Gracefully shutdown the monitoring service
131 */
132 destroy(): Promise<void>;
133}
134
135/**
136 * Monitoring configuration interface
137 */
138export interface TokenTrackingConfig {
139 dailyTokenLimit: number;
140 warningThresholdPercent: number;
141}
142
143export interface MonitoringConfig {
144 enabled: boolean;
145 serviceName: string;
146 tokenTracking?: TokenTrackingConfig;
147}
148
149/**
150 * Monitor service for tracking events and telemetry
151 *
152 * Features:
153 * - Custom event tracking
154 * - Cost event usage monitoring
155 * - Security event tracking
156 * - System health monitoring
157 * - Structured logging with event correlation
158 * - Console-based implementation for simplicity
159 * - Extendable with your own telemetry client.
160 *
161 * Perfect for:
162 * - Applications requiring event monitoring
163 * - AI applications needing token usage tracking
164 * - Security-conscious systems
165 * - Multi-service architectures
166 */
167export class MonitorService extends BaseService implements IMonitorService {
168 private config: MonitoringConfig;
169 private enabled: boolean;
170 private initialized: boolean = false;
171
172 static readonly metadata: ServiceMetadata = {
173 name: 'MonitorService',
174 displayName: 'Simple Monitor',
175 description: 'Simple monitoring and event tracking service with console output',
176 contract: 'IMonitorService',
177 implementation: 'Console',
178 version: '2.0.0',
179 contractVersion: '1.0.0',
180
181 features: [
182 'Custom event tracking',
183 'Token usage monitoring',
184 'Security event tracking',
185 'System health monitoring',
186 'Structured logging'
187 ],
188
189 limitations: [
190 'Console output only',
191 'No persistent storage of metrics'
192 ],
193
194 dependencies: {
195 services: []
196 },
197
198 requirements: {
199 configuration: {
200 required: [],
201 optional: ['MONITORING_ENABLED', 'MONITORING_DAILY_TOKEN_LIMIT', 'MONITORING_WARNING_THRESHOLD']
202 }
203 },
204
205 recommendations: {
206 idealFor: [
207 'Applications requiring simple event monitoring',
208 'Development and staging environments',
209 'Security event logging'
210 ],
211 acceptableFor: [
212 'Small to medium production applications'
213 ],
214 notRecommendedFor: [
215 'High-frequency event logging requiring aggregation'
216 ]
217 },
218
219 configurationSchema: {
220 MONITORING_ENABLED: {
221 type: 'boolean',
222 default: true,
223 description: 'Enable or disable monitoring'
224 },
225 MONITORING_DAILY_TOKEN_LIMIT: {
226 type: 'number',
227 default: 500000,
228 description: 'Daily token usage limit for warnings'
229 },
230 MONITORING_WARNING_THRESHOLD: {
231 type: 'number',
232 default: 80,
233 description: 'Warning threshold percentage of daily limit'
234 }
235 }
236 };
237
238 constructor(config: MonitoringConfig, private logger: ILogger) {
239 super();
240 this.config = config;
241 this.enabled = config.enabled;
242
243 this.logger.debug('MonitorService initialized', {
244 enabled: this.enabled,
245 serviceName: config.serviceName,
246 dailyTokenLimit: config.tokenTracking?.dailyTokenLimit
247 });
248 }
249
250 /**
251 * Initialize the monitoring service
252 */
253 public async initialize(_config?: Record<string, any>): Promise<void> {
254 if (!this.enabled) {
255 this.logger.info('Monitoring is disabled, skipping initialization');
256 return;
257 }
258
259 try {
260 this.initialized = true;
261 this.logger.info('Monitor service initialized successfully');
262 } catch (error) {
263 this.logger.error('Failed to initialize Monitor service', error instanceof Error ? error : new Error(String(error)));
264 // Continue without monitoring but mark as initialized for logging
265 this.initialized = true;
266 }
267 }
268
269 /**
270 * Track any custom event
271 */
272 public async onEvent(eventName: string, params: any): Promise<void> {
273 if (!this.enabled) return;
274 if (!this.initialized) {
275 this.logger.warn('MonitorService is not initialized, skipping event tracking');
276 return;
277 }
278
279 try {
280 const eventData = {
281 eventName,
282 timestamp: new Date().toISOString(),
283 environment: process.env.NODE_ENV || 'development',
284 ...params
285 };
286
287 // Log event details
288 this.logger.info(`Event: ${eventName}`, eventData);
289 } catch (error) {
290 this.logger.error('Failed to track event', error instanceof Error ? error : new Error(String(error)), {
291 eventName,
292 error: error instanceof Error ? error.message : String(error)
293 });
294 }
295 }
296
297 /**
298 * Track user events
299 */
300 public async onUserEvent(event: UserEventType, userId: string, details?: any): Promise<void> {
301 await this.onEvent(event, {
302 userId,
303 ...details,
304 category: 'User'
305 });
306 }
307
308 /**
309 * Track system events
310 */
311 public async onSystemEvent(event: SystemEventType, details: any): Promise<void> {
312 await this.onEvent(event, {
313 ...details,
314 category: 'System'
315 });
316 }
317
318 /**
319 * Track security events
320 */
321 public async onSecurityEvent(event: SecurityEventType, userId: string, details: any): Promise<void> {
322 await this.onEvent(event, {
323 userId,
324 ...details,
325 category: 'Security',
326 severity: 'Warning' // Security events are always important
327 });
328 }
329
330 /**
331 * Track AI token usage for monitoring (without cost calculation)
332 */
333 public async onCostEvent(model: string, tokens: TokenUsage, jobId: string, userId?: string): Promise<void> {
334 // Track individual usage event
335 await this.onEvent('AI.TokensUsed', {
336 model,
337 promptTokens: tokens.promptTokens,
338 completionTokens: tokens.completionTokens,
339 totalTokens: tokens.totalTokens,
340 jobId,
341 userId,
342 category: 'TokenUsage'
343 });
344
345 // Check if approaching daily limits and warn
346 await this.checkTokenLimits(tokens.totalTokens);
347 }
348
349 /**
350 * Check token usage against daily limits and send warnings
351 */
352 private async checkTokenLimits(tokensUsed: number): Promise<void> {
353 if (!this.config.tokenTracking?.dailyTokenLimit) return;
354
355 const { dailyTokenLimit, warningThresholdPercent } = this.config.tokenTracking;
356
357 // TODO: In a real implementation, you would:
358 // 1. Get today's total token usage from database or cache
359 // 2. Calculate percentage of daily limit used
360 // 3. Send appropriate events
361
362 // For now, just log what would happen
363 this.logger.debug('Token limit check', {
364 tokensUsed,
365 dailyLimit: dailyTokenLimit,
366 warningThreshold: warningThresholdPercent
367 });
368 }
369
370 /**
371 * Check if monitoring service is healthy
372 */
373 public async isHealthy(): Promise<boolean> {
374 try {
375 if (!this.enabled) return true; // Disabled service is considered healthy
376
377 // Test that we can track a health check event
378 await this.onEvent('System.HealthCheck', {
379 service: 'MonitorService',
380 healthy: true
381 });
382
383 return true;
384 } catch (error) {
385 this.logger.error('Monitor service health check failed', error instanceof Error ? error : new Error(String(error)));
386 return false;
387 }
388 }
389
390 /**
391 * Get service metadata
392 */
393 public getMetadata(): ServiceMetadata {
394 return MonitorService.metadata;
395 }
396
397 /**
398 * Gracefully shutdown the monitoring service
399 */
400 public async destroy(): Promise<void> {
401 try {
402 this.logger.info('MonitorService destroyed successfully');
403 } catch (error) {
404 this.logger.error('Error during MonitorService destruction', error instanceof Error ? error : new Error(String(error)));
405 }
406 }
407}
Metadata
- Path
- utaba/main/services/monitoring/MonitorService.ts
- Namespace
- utaba/main/services/monitoring
- Author
- utaba
- Category
- services
- Technology
- typescript
- Contract Version
- 2.0.0
- MIME Type
- application/typescript
- Published
- 19-Jul-2025
- Last Updated
- 19-Jul-2025