Legion commander! Consul Caesar.js has entrusted you with the most important task in your entire Roman career - creating a complete performance optimization system for a large army of Roman forts. This will be a real test of all the skills you've acquired while studying Performance & Optimization!
Your army consists of 50+ Roman forts operating in different provinces, serving thousands of users simultaneously. The system must be:
1// legion-optimization.module.ts
2import { Module } from '@nestjs/common';
3import { ConfigModule } from '@nestjs/config';
4import { RedisModule } from '@nestjs-modules/ioredis';
5import { BullModule } from '@nestjs/bull';
6import { PrometheusModule } from '@willsoto/nestjs-prometheus';
7
8@Module({
9 imports: [
10 // Environment configuration
11 ConfigModule.forRoot({
12 isGlobal: true,
13 envFilePath: ['.env.local', '.env'],
14 }),
15
16 // Redis for cache, sessions, queues
17 RedisModule.forRootAsync({
18 useFactory: (configService: ConfigService) => ({
19 type: 'single',
20 url: configService.get('REDIS_URL'),
21 options: {
22 retryDelayOnFailover: 100,
23 enableReadyCheck: false,
24 maxRetriesPerRequest: null,
25 },
26 }),
27 inject: [ConfigService],
28 }),
29
30 // Background job processing
31 BullModule.forRootAsync({
32 useFactory: (configService: ConfigService) => ({
33 redis: {
34 host: configService.get('REDIS_HOST'),
35 port: configService.get('REDIS_PORT'),
36 password: configService.get('REDIS_PASSWORD'),
37 },
38 defaultJobOptions: {
39 removeOnComplete: 100,
40 removeOnFail: 50,
41 attempts: 3,
42 backoff: {
43 type: 'exponential',
44 delay: 2000,
45 },
46 },
47 }),
48 inject: [ConfigService],
49 }),
50
51 // Metrics and monitoring
52 PrometheusModule.register({
53 path: '/metrics',
54 defaultMetrics: {
55 enabled: true,
56 config: {
57 prefix: 'legionaries_legion_',
58 },
59 },
60 }),
61
62 // Main modules
63 PerformanceModule,
64 CacheModule,
65 LoadBalancingModule,
66 AutoScalingModule,
67 MonitoringModule,
68 OptimizationModule,
69 ],
70})
71export class LegionOptimizationModule {}1// performance-monitoring.service.ts
2import { Injectable, Logger } from '@nestjs/common';
3import { Cron } from '@nestjs/schedule';
4import { InjectMetric } from '@willsoto/nestjs-prometheus';
5import { Counter, Histogram, Gauge } from 'prom-client';
6import * as os from 'os';
7import * as process from 'process';
8
9@Injectable()
10export class PerformanceMonitoringService {
11 private readonly logger = new Logger(PerformanceMonitoringService.name);
12
13 constructor(
14 @InjectMetric('http_requests_total') private requestCounter: Counter<string>,
15 @InjectMetric('http_request_duration_seconds') private requestDuration: Histogram<string>,
16 @InjectMetric('system_cpu_usage') private cpuGauge: Gauge<string>,
17 @InjectMetric('system_memory_usage') private memoryGauge: Gauge<string>,
18 @InjectMetric('active_connections') private connectionsGauge: Gauge<string>,
19 @InjectMetric('cache_hit_ratio') private cacheHitRatio: Gauge<string>,
20 ) {}
21
22 // HTTP request monitoring
23 recordHttpRequest(method: string, route: string, statusCode: number, duration: number) {
24 this.requestCounter.labels(method, route, statusCode.toString()).inc();
25 this.requestDuration.labels(method, route).observe(duration / 1000);
26 }
27
28 // System resource monitoring
29 @Cron('*/30 * * * * *') // Every 30 seconds
30 async collectSystemMetrics() {
31 try {
32 // CPU usage
33 const cpuUsage = await this.getCpuUsage();
34 this.cpuGauge.set(cpuUsage);
35
36 // Memory usage
37 const memInfo = process.memoryUsage();
38 const totalMemory = os.totalmem();
39 const usedMemory = memInfo.heapUsed + memInfo.external;
40 const memoryUsagePercent = (usedMemory / totalMemory) * 100;
41 this.memoryGauge.set(memoryUsagePercent);
42
43 // Active connections (symulowane)
44 const activeConnections = await this.getActiveConnections();
45 this.connectionsGauge.set(activeConnections);
46
47 // Cache performance
48 const cacheStats = await this.getCacheStats();
49 this.cacheHitRatio.set(cacheStats.hitRatio);
50
51 } catch (error) {
52 this.logger.error('Error collecting system metrics:', error);
53 }
54 }
55
56 // Detailed performance analysis
57 async getPerformanceReport(): Promise<PerformanceReport> {
58 const systemLoad = await this.getSystemLoad();
59 const applicationMetrics = await this.getApplicationMetrics();
60 const databaseMetrics = await this.getDatabaseMetrics();
61 const cacheMetrics = await this.getCacheMetrics();
62
63 return {
64 timestamp: new Date(),
65 system: systemLoad,
66 application: applicationMetrics,
67 database: databaseMetrics,
68 cache: cacheMetrics,
69 recommendations: this.generateRecommendations(systemLoad, applicationMetrics),
70 healthScore: this.calculateHealthScore(systemLoad, applicationMetrics, databaseMetrics),
71 };
72 }
73
74 private async getCpuUsage(): Promise<number> {
75 return new Promise((resolve) => {
76 const startUsage = process.cpuUsage();
77 const startTime = process.hrtime();
78
79 setTimeout(() => {
80 const endUsage = process.cpuUsage(startUsage);
81 const endTime = process.hrtime(startTime);
82
83 const userUsage = endUsage.user / 1000000; // Convert to seconds
84 const systemUsage = endUsage.system / 1000000;
85 const totalTime = endTime[0] + endTime[1] / 1000000000;
86
87 const cpuPercent = ((userUsage + systemUsage) / totalTime) * 100;
88 resolve(Math.min(100, cpuPercent));
89 }, 100);
90 });
91 }
92
93 private async getActiveConnections(): Promise<number> {
94 // In a real application you would get this from the load balancer or reverse proxy
95 return Math.floor(Math.random() * 1000) + 100;
96 }
97
98 private async getCacheStats(): Promise<{ hitRatio: number }> {
99 // Simulation - in reality you would get this from Redis
100 const hits = Math.floor(Math.random() * 1000) + 800;
101 const misses = Math.floor(Math.random() * 200) + 50;
102 const hitRatio = hits / (hits + misses);
103 return { hitRatio };
104 }
105
106 private async getSystemLoad(): Promise<SystemLoad> {
107 const loadAvg = os.loadavg();
108 const totalMem = os.totalmem();
109 const freeMem = os.freemem();
110 const usedMem = totalMem - freeMem;
111
112 return {
113 cpu: await this.getCpuUsage(),
114 memory: {
115 total: Math.round(totalMem / 1024 / 1024), // MB
116 used: Math.round(usedMem / 1024 / 1024),
117 free: Math.round(freeMem / 1024 / 1024),
118 usagePercent: Math.round((usedMem / totalMem) * 100),
119 },
120 load: {
121 oneMinute: loadAvg[0],
122 fiveMinutes: loadAvg[1],
123 fifteenMinutes: loadAvg[2],
124 },
125 uptime: process.uptime(),
126 };
127 }
128
129 private async getApplicationMetrics(): Promise<ApplicationMetrics> {
130 // Simulated application metrics
131 return {
132 requestsPerSecond: Math.floor(Math.random() * 500) + 100,
133 averageResponseTime: Math.random() * 100 + 50,
134 p95ResponseTime: Math.random() * 200 + 100,
135 p99ResponseTime: Math.random() * 500 + 200,
136 errorRate: Math.random() * 0.05, // 0-5%
137 activeUsers: Math.floor(Math.random() * 5000) + 1000,
138 throughput: Math.floor(Math.random() * 10000) + 5000,
139 };
140 }
141
142 private async getDatabaseMetrics(): Promise<DatabaseMetrics> {
143 return {
144 connectionPoolSize: 20,
145 activeConnections: Math.floor(Math.random() * 15) + 5,
146 queryTime: {
147 avg: Math.random() * 50 + 10,
148 p95: Math.random() * 100 + 50,
149 p99: Math.random() * 200 + 100,
150 },
151 slowQueries: Math.floor(Math.random() * 5),
152 deadlocks: Math.floor(Math.random() * 2),
153 };
154 }
155
156 private async getCacheMetrics(): Promise<CacheMetrics> {
157 const hits = Math.floor(Math.random() * 10000) + 8000;
158 const misses = Math.floor(Math.random() * 2000) + 500;
159
160 return {
161 hitRatio: hits / (hits + misses),
162 hits,
163 misses,
164 evictions: Math.floor(Math.random() * 100),
165 memoryUsage: Math.floor(Math.random() * 512) + 256, // MB
166 keyCount: Math.floor(Math.random() * 100000) + 50000,
167 };
168 }
169
170 private generateRecommendations(
171 systemLoad: SystemLoad,
172 appMetrics: ApplicationMetrics
173 ): string[] {
174 const recommendations = [];
175
176 if (systemLoad.cpu > 80) {
177 recommendations.push('CPU usage is high - consider horizontal scaling');
178 }
179
180 if (systemLoad.memory.usagePercent > 85) {
181 recommendations.push('Memory usage is critical - optimize memory allocation');
182 }
183
184 if (appMetrics.averageResponseTime > 200) {
185 recommendations.push('Response times are slow - optimize database queries and add caching');
186 }
187
188 if (appMetrics.errorRate > 0.02) {
189 recommendations.push('Error rate is above threshold - investigate application errors');
190 }
191
192 if (systemLoad.load.oneMinute > os.cpus().length) {
193 recommendations.push('System load is high - consider load balancing');
194 }
195
196 return recommendations;
197 }
198
199 private calculateHealthScore(
200 systemLoad: SystemLoad,
201 appMetrics: ApplicationMetrics,
202 dbMetrics: DatabaseMetrics
203 ): number {
204 let score = 100;
205
206 // CPU penalty
207 if (systemLoad.cpu > 90) score -= 30;
208 else if (systemLoad.cpu > 70) score -= 15;
209 else if (systemLoad.cpu > 50) score -= 5;
210
211 // Memory penalty
212 if (systemLoad.memory.usagePercent > 90) score -= 25;
213 else if (systemLoad.memory.usagePercent > 75) score -= 10;
214
215 // Response time penalty
216 if (appMetrics.averageResponseTime > 500) score -= 20;
217 else if (appMetrics.averageResponseTime > 200) score -= 10;
218
219 // Error rate penalty
220 if (appMetrics.errorRate > 0.05) score -= 30;
221 else if (appMetrics.errorRate > 0.02) score -= 15;
222
223 // Database penalty
224 if (dbMetrics.queryTime.avg > 100) score -= 10;
225
226 return Math.max(0, score);
227 }
228}
229
230interface SystemLoad {
231 cpu: number;
232 memory: {
233 total: number;
234 used: number;
235 free: number;
236 usagePercent: number;
237 };
238 load: {
239 oneMinute: number;
240 fiveMinutes: number;
241 fifteenMinutes: number;
242 };
243 uptime: number;
244}
245
246interface ApplicationMetrics {
247 requestsPerSecond: number;
248 averageResponseTime: number;
249 p95ResponseTime: number;
250 p99ResponseTime: number;
251 errorRate: number;
252 activeUsers: number;
253 throughput: number;
254}
255
256interface DatabaseMetrics {
257 connectionPoolSize: number;
258 activeConnections: number;
259 queryTime: {
260 avg: number;
261 p95: number;
262 p99: number;
263 };
264 slowQueries: number;
265 deadlocks: number;
266}
267
268interface CacheMetrics {
269 hitRatio: number;
270 hits: number;
271 misses: number;
272 evictions: number;
273 memoryUsage: number;
274 keyCount: number;
275}
276
277interface PerformanceReport {
278 timestamp: Date;
279 system: SystemLoad;
280 application: ApplicationMetrics;
281 database: DatabaseMetrics;
282 cache: CacheMetrics;
283 recommendations: string[];
284 healthScore: number;
285}1// auto-scaling.service.ts
2import { Injectable, Logger } from '@nestjs/common';
3import { Cron } from '@nestjs/schedule';
4import { ConfigService } from '@nestjs/config';
5
6@Injectable()
7export class AutoScalingService {
8 private readonly logger = new Logger(AutoScalingService.name);
9 private scalingInProgress = false;
10 private lastScalingAction = 0;
11 private readonly minCooldown = 300000; // 5 minutes between actions
12
13 constructor(
14 private configService: ConfigService,
15 private performanceMonitoring: PerformanceMonitoringService,
16 private loadBalancer: LoadBalancerService,
17 ) {}
18
19 @Cron('*/60 * * * * *') // Every minute
20 async evaluateScaling() {
21 if (this.scalingInProgress) return;
22
23 const now = Date.now();
24 if (now - this.lastScalingAction < this.minCooldown) return;
25
26 try {
27 const metrics = await this.performanceMonitoring.getPerformanceReport();
28 const decision = this.makeScalingDecision(metrics);
29
30 if (decision.action !== 'none') {
31 this.scalingInProgress = true;
32 await this.executeScalingAction(decision);
33 this.lastScalingAction = now;
34 }
35 } catch (error) {
36 this.logger.error('Error during scaling evaluation:', error);
37 } finally {
38 this.scalingInProgress = false;
39 }
40 }
41
42 private makeScalingDecision(metrics: PerformanceReport): ScalingDecision {
43 const thresholds = {
44 scaleOut: {
45 cpu: 70,
46 memory: 80,
47 responseTime: 300,
48 errorRate: 0.02,
49 },
50 scaleIn: {
51 cpu: 30,
52 memory: 40,
53 responseTime: 100,
54 errorRate: 0.005,
55 },
56 };
57
58 const currentInstances = this.loadBalancer.getActiveInstances().length;
59 const maxInstances = this.configService.get<number>('MAX_INSTANCES', 10);
60 const minInstances = this.configService.get<number>('MIN_INSTANCES', 2);
61
62 // Scale out conditions
63 if (currentInstances < maxInstances) {
64 if (
65 metrics.system.cpu > thresholds.scaleOut.cpu ||
66 metrics.system.memory.usagePercent > thresholds.scaleOut.memory ||
67 metrics.application.averageResponseTime > thresholds.scaleOut.responseTime ||
68 metrics.application.errorRate > thresholds.scaleOut.errorRate
69 ) {
70 const targetInstances = Math.min(
71 maxInstances,
72 currentInstances + this.calculateScaleOutAmount(metrics)
73 );
74
75 return {
76 action: 'scale-out',
77 currentInstances,
78 targetInstances,
79 reason: this.getScaleOutReason(metrics, thresholds.scaleOut),
80 };
81 }
82 }
83
84 // Scale in conditions
85 if (currentInstances > minInstances) {
86 if (
87 metrics.system.cpu < thresholds.scaleIn.cpu &&
88 metrics.system.memory.usagePercent < thresholds.scaleIn.memory &&
89 metrics.application.averageResponseTime < thresholds.scaleIn.responseTime &&
90 metrics.application.errorRate < thresholds.scaleIn.errorRate
91 ) {
92 const targetInstances = Math.max(
93 minInstances,
94 currentInstances - 1 // Conservative scale-in
95 );
96
97 return {
98 action: 'scale-in',
99 currentInstances,
100 targetInstances,
101 reason: 'System resources are underutilized',
102 };
103 }
104 }
105
106 return {
107 action: 'none',
108 currentInstances,
109 targetInstances: currentInstances,
110 reason: 'No scaling action required',
111 };
112 }
113
114 private calculateScaleOutAmount(metrics: PerformanceReport): number {
115 // More aggressive scaling under high load
116 if (metrics.system.cpu > 90 || metrics.application.errorRate > 0.05) {
117 return 3; // Add 3 instances
118 }
119 if (metrics.system.cpu > 80 || metrics.application.averageResponseTime > 500) {
120 return 2; // Add 2 instances
121 }
122 return 1; // Add 1 instance
123 }
124
125 private getScaleOutReason(metrics: PerformanceReport, thresholds: any): string {
126 const reasons = [];
127
128 if (metrics.system.cpu > thresholds.cpu) {
129 reasons.push(`CPU usage: ${metrics.system.cpu.toFixed(1)}%`);
130 }
131 if (metrics.system.memory.usagePercent > thresholds.memory) {
132 reasons.push(`Memory usage: ${metrics.system.memory.usagePercent}%`);
133 }
134 if (metrics.application.averageResponseTime > thresholds.responseTime) {
135 reasons.push(`Response time: ${metrics.application.averageResponseTime.toFixed(1)}ms`);
136 }
137 if (metrics.application.errorRate > thresholds.errorRate) {
138 reasons.push(`Error rate: ${(metrics.application.errorRate * 100).toFixed(2)}%`);
139 }
140
141 return reasons.join(', ');
142 }
143
144 private async executeScalingAction(decision: ScalingDecision): Promise<void> {
145 this.logger.log(`Executing ${decision.action}: ${decision.currentInstances} -> ${decision.targetInstances}`);
146 this.logger.log(`Reason: ${decision.reason}`);
147
148 try {
149 if (decision.action === 'scale-out') {
150 await this.scaleOut(decision.targetInstances - decision.currentInstances);
151 } else if (decision.action === 'scale-in') {
152 await this.scaleIn(decision.currentInstances - decision.targetInstances);
153 }
154 } catch (error) {
155 this.logger.error(`Failed to execute ${decision.action}:`, error);
156 throw error;
157 }
158 }
159
160 private async scaleOut(instanceCount: number): Promise<void> {
161 for (let i = 0; i < instanceCount; i++) {
162 try {
163 const instance = await this.createNewInstance();
164 await this.loadBalancer.addInstance(instance);
165 this.logger.log(`✅ Added new instance: ${instance.id}`);
166
167 // Delay between creating instances
168 if (i < instanceCount - 1) {
169 await this.delay(5000);
170 }
171 } catch (error) {
172 this.logger.error(`Failed to create instance ${i + 1}:`, error);
173 }
174 }
175 }
176
177 private async scaleIn(instanceCount: number): Promise<void> {
178 const instances = this.loadBalancer.getActiveInstances();
179 const instancesToRemove = instances
180 .sort((a, b) => a.currentLoad - b.currentLoad) // Remove least loaded
181 .slice(0, instanceCount);
182
183 for (const instance of instancesToRemove) {
184 try {
185 await this.loadBalancer.drainInstance(instance.id);
186 await this.terminateInstance(instance.id);
187 this.logger.log(`✅ Removed instance: ${instance.id}`);
188 } catch (error) {
189 this.logger.error(`Failed to remove instance ${instance.id}:`, error);
190 }
191 }
192 }
193
194 private async createNewInstance(): Promise<ServerInstance> {
195 // Simulating creation of a new instance (in reality this would be AWS/GCP/Azure API)
196 const instanceId = `legionaries-cohort-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
197
198 return {
199 id: instanceId,
200 host: `${instanceId}.legion.local`,
201 port: 3000,
202 region: 'Hispania-central',
203 status: 'starting',
204 createdAt: new Date(),
205 currentLoad: 0,
206 maxCapacity: 1000,
207 };
208 }
209
210 private async terminateInstance(instanceId: string): Promise<void> {
211 // Simulating instance removal
212 this.logger.log(`Terminating instance: ${instanceId}`);
213 await this.delay(2000);
214 }
215
216 private delay(ms: number): Promise<void> {
217 return new Promise(resolve => setTimeout(resolve, ms));
218 }
219
220 async getScalingHistory(): Promise<ScalingEvent[]> {
221 // In a real application this would be fetched from the database
222 return [
223 {
224 timestamp: new Date(Date.now() - 3600000),
225 action: 'scale-out',
226 fromInstances: 2,
227 toInstances: 4,
228 reason: 'CPU usage: 85%, Response time: 450ms',
229 success: true,
230 },
231 {
232 timestamp: new Date(Date.now() - 7200000),
233 action: 'scale-in',
234 fromInstances: 5,
235 toInstances: 3,
236 reason: 'System resources underutilized',
237 success: true,
238 },
239 ];
240 }
241}
242
243interface ScalingDecision {
244 action: 'scale-out' | 'scale-in' | 'none';
245 currentInstances: number;
246 targetInstances: number;
247 reason: string;
248}
249
250interface ScalingEvent {
251 timestamp: Date;
252 action: string;
253 fromInstances: number;
254 toInstances: number;
255 reason: string;
256 success: boolean;
257}
258
259interface ServerInstance {
260 id: string;
261 host: string;
262 port: number;
263 region: string;
264 status: string;
265 createdAt: Date;
266 currentLoad: number;
267 maxCapacity: number;
268}1// optimization-engine.service.ts
2import { Injectable, Logger } from '@nestjs/common';
3import { Cron } from '@nestjs/schedule';
4
5@Injectable()
6export class OptimizationEngineService {
7 private readonly logger = new Logger(OptimizationEngineService.name);
8 private learningData: PerformanceDataPoint[] = [];
9 private optimizationHistory: OptimizationAction[] = [];
10
11 constructor(
12 private performanceMonitoring: PerformanceMonitoringService,
13 private cacheManager: IntelligentCacheService,
14 private databaseOptimizer: DatabaseOptimizerService,
15 private autoScaling: AutoScalingService,
16 ) {}
17
18 @Cron('*/300 * * * * *') // Every 5 minutes
19 async runOptimizationCycle() {
20 try {
21 this.logger.log('Starting optimization cycle');
22
23 // Collect performance data
24 const currentMetrics = await this.performanceMonitoring.getPerformanceReport();
25 this.addDataPoint(currentMetrics);
26
27 // Analyze trends
28 const trends = this.analyzeTrends();
29
30 // Predict future load
31 const predictions = this.predictFutureLoad();
32
33 // Generate optimization recommendations
34 const recommendations = await this.generateOptimizationRecommendations(
35 currentMetrics,
36 trends,
37 predictions
38 );
39
40 // Execute automatic optimizations
41 await this.executeAutomaticOptimizations(recommendations);
42
43 this.logger.log(`✅ Optimization cycle completed. Applied ${recommendations.filter(r => r.autoApply).length} optimizations`);
44
45 } catch (error) {
46 this.logger.error('Error during optimization cycle:', error);
47 }
48 }
49
50 private addDataPoint(metrics: PerformanceReport) {
51 this.learningData.push({
52 timestamp: new Date(),
53 metrics,
54 context: this.getCurrentContext(),
55 });
56
57 // Keep only the last 1000 data points
58 if (this.learningData.length > 1000) {
59 this.learningData = this.learningData.slice(-1000);
60 }
61 }
62
63 private analyzeTrends(): TrendAnalysis {
64 if (this.learningData.length < 10) {
65 return {
66 cpuTrend: 'stable',
67 memoryTrend: 'stable',
68 responseTimeTrend: 'stable',
69 errorRateTrend: 'stable',
70 confidenceLevel: 0.1,
71 };
72 }
73
74 const recent = this.learningData.slice(-60); // Last hour (every 5 min)
75 const older = this.learningData.slice(-120, -60); // Previous hour
76
77 return {
78 cpuTrend: this.calculateTrend(
79 older.map(d => d.metrics.system.cpu),
80 recent.map(d => d.metrics.system.cpu)
81 ),
82 memoryTrend: this.calculateTrend(
83 older.map(d => d.metrics.system.memory.usagePercent),
84 recent.map(d => d.metrics.system.memory.usagePercent)
85 ),
86 responseTimeTrend: this.calculateTrend(
87 older.map(d => d.metrics.application.averageResponseTime),
88 recent.map(d => d.metrics.application.averageResponseTime)
89 ),
90 errorRateTrend: this.calculateTrend(
91 older.map(d => d.metrics.application.errorRate),
92 recent.map(d => d.metrics.application.errorRate)
93 ),
94 confidenceLevel: Math.min(recent.length / 60, 1),
95 };
96 }
97
98 private calculateTrend(oldValues: number[], newValues: number[]): 'increasing' | 'decreasing' | 'stable' {
99 if (oldValues.length === 0 || newValues.length === 0) return 'stable';
100
101 const oldAvg = oldValues.reduce((a, b) => a + b, 0) / oldValues.length;
102 const newAvg = newValues.reduce((a, b) => a + b, 0) / newValues.length;
103
104 const changePercent = ((newAvg - oldAvg) / oldAvg) * 100;
105
106 if (changePercent > 10) return 'increasing';
107 if (changePercent < -10) return 'decreasing';
108 return 'stable';
109 }
110
111 private predictFutureLoad(): LoadPrediction {
112 // Simplified ML-like prediction based on historical patterns
113 const hourOfDay = new Date().getHours();
114 const dayOfWeek = new Date().getDay();
115
116 // Simulating load patterns
117 const hourlyPattern = this.getHourlyLoadPattern();
118 const weeklyPattern = this.getWeeklyLoadPattern();
119
120 const predictedCpuIncrease = hourlyPattern[hourOfDay] * weeklyPattern[dayOfWeek];
121 const predictedMemoryIncrease = predictedCpuIncrease * 0.8; // Memory usually follows CPU
122
123 return {
124 nextHourLoad: {
125 cpu: Math.min(100, predictedCpuIncrease),
126 memory: Math.min(100, predictedMemoryIncrease),
127 requests: Math.floor(predictedCpuIncrease * 10),
128 },
129 confidence: 0.75,
130 factors: ['hourly_pattern', 'weekly_pattern', 'historical_data'],
131 };
132 }
133
134 private getHourlyLoadPattern(): number[] {
135 // Example load pattern throughout the day
136 return [
137 20, 15, 10, 8, 6, 8, // 00-05: Noc
138 15, 25, 40, 60, 80, 90, // 06-11: Morning/before noon
139 95, 85, 75, 80, 85, 90, // 12-17: Noon/afternoon
140 70, 60, 50, 40, 30, 25 // 18-23: Evening
141 ];
142 }
143
144 private getWeeklyLoadPattern(): number[] {
145 // Weekly pattern (0 = Sunday)
146 return [0.7, 1.0, 1.0, 1.0, 1.0, 1.0, 0.8]; // Less on weekends
147 }
148
149 private async generateOptimizationRecommendations(
150 metrics: PerformanceReport,
151 trends: TrendAnalysis,
152 predictions: LoadPrediction
153 ): Promise<OptimizationRecommendation[]> {
154 const recommendations: OptimizationRecommendation[] = [];
155
156 // Cache optimization
157 if (metrics.cache.hitRatio < 0.8) {
158 recommendations.push({
159 type: 'cache',
160 priority: 'high',
161 action: 'optimize_cache_strategy',
162 description: `Cache hit ratio is ${(metrics.cache.hitRatio * 100).toFixed(1)}% - optimize caching strategy`,
163 autoApply: true,
164 estimatedImpact: 'Improve response time by 20-30%',
165 implementation: async () => {
166 await this.cacheManager.optimizeCacheStrategy();
167 },
168 });
169 }
170
171 // Database optimization
172 if (metrics.database.queryTime.avg > 100) {
173 recommendations.push({
174 type: 'database',
175 priority: 'high',
176 action: 'optimize_slow_queries',
177 description: `Average query time is ${metrics.database.queryTime.avg.toFixed(1)}ms - optimize database queries`,
178 autoApply: false, // Requires manual review
179 estimatedImpact: 'Reduce query time by 40-60%',
180 implementation: async () => {
181 await this.databaseOptimizer.optimizeSlowQueries();
182 },
183 });
184 }
185
186 // Predictive scaling
187 if (predictions.nextHourLoad.cpu > 80 && trends.cpuTrend === 'increasing') {
188 recommendations.push({
189 type: 'scaling',
190 priority: 'medium',
191 action: 'predictive_scale_out',
192 description: 'Predicted high load in next hour - scale out preemptively',
193 autoApply: true,
194 estimatedImpact: 'Prevent performance degradation',
195 implementation: async () => {
196 // Auto-scaling already exists, but we can be more proactive
197 this.logger.log('Triggering predictive scaling based on load prediction');
198 },
199 });
200 }
201
202 // Memory optimization
203 if (metrics.system.memory.usagePercent > 85) {
204 recommendations.push({
205 type: 'memory',
206 priority: 'high',
207 action: 'optimize_memory_usage',
208 description: `Memory usage is ${metrics.system.memory.usagePercent}% - optimize memory allocation`,
209 autoApply: true,
210 estimatedImpact: 'Reduce memory usage by 15-25%',
211 implementation: async () => {
212 await this.optimizeMemoryUsage();
213 },
214 });
215 }
216
217 return recommendations;
218 }
219
220 private async executeAutomaticOptimizations(
221 recommendations: OptimizationRecommendation[]
222 ): Promise<void> {
223 const autoRecommendations = recommendations.filter(r => r.autoApply);
224
225 for (const recommendation of autoRecommendations) {
226 try {
227 this.logger.log(` Applying optimization: ${recommendation.action}`);
228 await recommendation.implementation();
229
230 this.optimizationHistory.push({
231 timestamp: new Date(),
232 type: recommendation.type,
233 action: recommendation.action,
234 success: true,
235 impact: recommendation.estimatedImpact,
236 });
237
238 } catch (error) {
239 this.logger.error(`Failed to apply optimization ${recommendation.action}:`, error);
240
241 this.optimizationHistory.push({
242 timestamp: new Date(),
243 type: recommendation.type,
244 action: recommendation.action,
245 success: false,
246 error: error.message,
247 });
248 }
249 }
250 }
251
252 private async optimizeMemoryUsage(): Promise<void> {
253 // Clear caches
254 await this.cacheManager.clearOldEntries();
255
256 // Run garbage collection
257 if (global.gc) {
258 global.gc();
259 }
260
261 // Optimize memory allocation
262 await this.optimizeMemoryAllocation();
263 }
264
265 private async optimizeMemoryAllocation(): Promise<void> {
266 // Simulating memory allocation optimization
267 this.logger.log('🧠 Optimizing memory allocation patterns');
268 }
269
270 private getCurrentContext(): PerformanceContext {
271 const now = new Date();
272 return {
273 hour: now.getHours(),
274 dayOfWeek: now.getDay(),
275 isWeekend: now.getDay() === 0 || now.getDay() === 6,
276 isBusinessHours: now.getHours() >= 9 && now.getHours() <= 17,
277 activeInstances: this.autoScaling.getActiveInstances?.()?.length || 0,
278 };
279 }
280
281 async getOptimizationReport(): Promise<OptimizationReport> {
282 const recentOptimizations = this.optimizationHistory.slice(-20);
283 const successRate = recentOptimizations.length > 0
284 ? recentOptimizations.filter(o => o.success).length / recentOptimizations.length
285 : 0;
286
287 return {
288 timestamp: new Date(),
289 totalOptimizations: this.optimizationHistory.length,
290 recentOptimizations,
291 successRate,
292 learningDataPoints: this.learningData.length,
293 trends: this.analyzeTrends(),
294 predictions: this.predictFutureLoad(),
295 };
296 }
297}
298
299interface PerformanceDataPoint {
300 timestamp: Date;
301 metrics: PerformanceReport;
302 context: PerformanceContext;
303}
304
305interface PerformanceContext {
306 hour: number;
307 dayOfWeek: number;
308 isWeekend: boolean;
309 isBusinessHours: boolean;
310 activeInstances: number;
311}
312
313interface TrendAnalysis {
314 cpuTrend: 'increasing' | 'decreasing' | 'stable';
315 memoryTrend: 'increasing' | 'decreasing' | 'stable';
316 responseTimeTrend: 'increasing' | 'decreasing' | 'stable';
317 errorRateTrend: 'increasing' | 'decreasing' | 'stable';
318 confidenceLevel: number;
319}
320
321interface LoadPrediction {
322 nextHourLoad: {
323 cpu: number;
324 memory: number;
325 requests: number;
326 };
327 confidence: number;
328 factors: string[];
329}
330
331interface OptimizationRecommendation {
332 type: 'cache' | 'database' | 'scaling' | 'memory' | 'network';
333 priority: 'low' | 'medium' | 'high' | 'critical';
334 action: string;
335 description: string;
336 autoApply: boolean;
337 estimatedImpact: string;
338 implementation: () => Promise<void>;
339}
340
341interface OptimizationAction {
342 timestamp: Date;
343 type: string;
344 action: string;
345 success: boolean;
346 impact?: string;
347 error?: string;
348}
349
350interface OptimizationReport {
351 timestamp: Date;
352 totalOptimizations: number;
353 recentOptimizations: OptimizationAction[];
354 successRate: number;
355 learningDataPoints: number;
356 trends: TrendAnalysis;
357 predictions: LoadPrediction;
358}1// legion-dashboard.controller.ts
2import { Controller, Get, Post, Body, Query, UseGuards } from '@nestjs/common';
3import { ApiTags, ApiOperation } from '@nestjs/swagger';
4
5@ApiTags('Legion Management')
6@Controller('admin/legion')
7@UseGuards(AdminGuard)
8export class LegionDashboardController {
9 constructor(
10 private performanceMonitoring: PerformanceMonitoringService,
11 private autoScaling: AutoScalingService,
12 private optimizationEngine: OptimizationEngineService,
13 private loadBalancer: LoadBalancerService,
14 private cacheManager: IntelligentCacheService,
15 ) {}
16
17 @Get('dashboard')
18 @ApiOperation({ summary: 'Get complete legion dashboard' })
19 async getLegionDashboard() {
20 const [
21 performanceReport,
22 scalingHistory,
23 optimizationReport,
24 loadBalancerStatus,
25 cacheStats
26 ] = await Promise.all([
27 this.performanceMonitoring.getPerformanceReport(),
28 this.autoScaling.getScalingHistory(),
29 this.optimizationEngine.getOptimizationReport(),
30 this.loadBalancer.getStatus(),
31 this.cacheManager.getStats()
32 ]);
33
34 return {
35 timestamp: new Date(),
36 legionOverview: {
37 activeLegions: loadBalancerStatus.activeInstances,
38 totalCapacity: loadBalancerStatus.totalCapacity,
39 currentLoad: loadBalancerStatus.currentLoad,
40 healthScore: performanceReport.healthScore,
41 status: this.calculateLegionStatus(performanceReport.healthScore),
42 },
43 performance: performanceReport,
44 autoScaling: {
45 history: scalingHistory,
46 nextEvaluation: new Date(Date.now() + 60000), // Next minute
47 },
48 optimization: optimizationReport,
49 loadBalancing: loadBalancerStatus,
50 cache: cacheStats,
51 alerts: this.generateAlerts(performanceReport),
52 };
53 }
54
55 @Get('recommendations')
56 @ApiOperation({ summary: 'Get optimization recommendations' })
57 async getRecommendations() {
58 const performanceReport = await this.performanceMonitoring.getPerformanceReport();
59 const trends = this.optimizationEngine.analyzeTrends();
60 const predictions = this.optimizationEngine.predictFutureLoad();
61
62 return this.optimizationEngine.generateOptimizationRecommendations(
63 performanceReport,
64 trends,
65 predictions
66 );
67 }
68
69 @Post('optimize')
70 @ApiOperation({ summary: 'Trigger manual optimization' })
71 async triggerOptimization(@Body() options: { type?: string; force?: boolean }) {
72 await this.optimizationEngine.runOptimizationCycle();
73 return { message: 'Optimization cycle triggered successfully' };
74 }
75
76 @Get('metrics/export')
77 @ApiOperation({ summary: 'Export performance metrics' })
78 async exportMetrics(@Query('format') format: string = 'json', @Query('hours') hours: string = '24') {
79 const hoursNum = parseInt(hours);
80 const metrics = await this.performanceMonitoring.getHistoricalMetrics(hoursNum);
81
82 if (format === 'csv') {
83 return this.convertToCSV(metrics);
84 }
85
86 return metrics;
87 }
88
89 @Post('scaling/manual')
90 @ApiOperation({ summary: 'Manual scaling action' })
91 async manualScaling(@Body() action: { type: 'scale-out' | 'scale-in'; instances: number }) {
92 if (action.type === 'scale-out') {
93 await this.autoScaling.scaleOut(action.instances);
94 } else {
95 await this.autoScaling.scaleIn(action.instances);
96 }
97
98 return { message: `Manual ${action.type} of ${action.instances} instances initiated` };
99 }
100
101 @Get('health-check')
102 @ApiOperation({ summary: 'Comprehensive legion health check' })
103 async healthCheck() {
104 const checks = await Promise.allSettled([
105 this.checkDatabaseHealth(),
106 this.checkRedisHealth(),
107 this.checkLoadBalancerHealth(),
108 this.checkInstancesHealth(),
109 ]);
110
111 const results = checks.map((check, index) => ({
112 service: ['database', 'redis', 'load-balancer', 'instances'][index],
113 status: check.status === 'fulfilled' ? 'healthy' : 'unhealthy',
114 details: check.status === 'fulfilled' ? check.value : check.reason.message,
115 }));
116
117 const overallHealth = results.every(r => r.status === 'healthy') ? 'healthy' : 'degraded';
118
119 return {
120 timestamp: new Date(),
121 overallHealth,
122 services: results,
123 };
124 }
125
126 private calculateLegionStatus(healthScore: number): 'optimal' | 'good' | 'warning' | 'critical' {
127 if (healthScore >= 90) return 'optimal';
128 if (healthScore >= 75) return 'good';
129 if (healthScore >= 50) return 'warning';
130 return 'critical';
131 }
132
133 private generateAlerts(performanceReport: PerformanceReport): Alert[] {
134 const alerts: Alert[] = [];
135
136 if (performanceReport.system.cpu > 90) {
137 alerts.push({
138 level: 'critical',
139 message: `Critical CPU usage: ${performanceReport.system.cpu.toFixed(1)}%`,
140 category: 'performance',
141 timestamp: new Date(),
142 });
143 }
144
145 if (performanceReport.application.errorRate > 0.05) {
146 alerts.push({
147 level: 'critical',
148 message: `High error rate: ${(performanceReport.application.errorRate * 100).toFixed(2)}%`,
149 category: 'reliability',
150 timestamp: new Date(),
151 });
152 }
153
154 if (performanceReport.application.averageResponseTime > 500) {
155 alerts.push({
156 level: 'warning',
157 message: `Slow response times: ${performanceReport.application.averageResponseTime.toFixed(1)}ms`,
158 category: 'performance',
159 timestamp: new Date(),
160 });
161 }
162
163 return alerts;
164 }
165
166 private async checkDatabaseHealth(): Promise<string> {
167 // Simulate database health check
168 return 'Database connections: 15/20, Query time: 45ms avg';
169 }
170
171 private async checkRedisHealth(): Promise<string> {
172 // Simulate Redis health check
173 return 'Redis connected, Memory: 256MB, Hit ratio: 94%';
174 }
175
176 private async checkLoadBalancerHealth(): Promise<string> {
177 const status = await this.loadBalancer.getStatus();
178 return `Active instances: ${status.activeInstances}, Load: ${status.currentLoad}%`;
179 }
180
181 private async checkInstancesHealth(): Promise<string> {
182 const instances = this.loadBalancer.getActiveInstances();
183 const healthyInstances = instances.filter(i => i.status === 'healthy').length;
184 return `Healthy instances: ${healthyInstances}/${instances.length}`;
185 }
186
187 private convertToCSV(data: any[]): string {
188 // Simplified CSV conversion
189 if (data.length === 0) return '';
190
191 const headers = Object.keys(data[0]).join(',');
192 const rows = data.map(row => Object.values(row).join(','));
193
194 return [headers, ...rows].join('
195');
196 }
197}
198
199interface Alert {
200 level: 'info' | 'warning' | 'critical';
201 message: string;
202 category: 'performance' | 'reliability' | 'security' | 'capacity';
203 timestamp: Date;
204}Your project will be evaluated for:
✓ Scalability - whether the system handles growing load ✓ Performance - response times, throughput, resource efficiency ✓ Reliability - uptime, error handling, graceful degradation ✓ Observability - monitoring, logging, metrics, tracing ✓ Automation - self-healing, auto-scaling, optimization ✓ Code quality - architecture, testing, documentation
Good luck, legion commander! Your mission is to create the most efficient and intelligent army of Roman forts that has ever guarded the digital provinces!