170 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { html } from '@design.estate/dees-element';
 | |
| import type { DeesChartLog } from './dees-chart-log.js';
 | |
| import '@design.estate/dees-wcctools/demotools';
 | |
| 
 | |
| export const demoFunc = () => {
 | |
|   return html`
 | |
|     <dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
 | |
|       // Get the log element
 | |
|       const logElement = elementArg.querySelector('dees-chart-log') as DeesChartLog;
 | |
|       let intervalId: number;
 | |
| 
 | |
|       const serverSources = ['Server', 'Database', 'API', 'Auth', 'Cache', 'Queue', 'WebSocket', 'Scheduler'];
 | |
|       
 | |
|       const logTemplates = {
 | |
|         debug: [
 | |
|           'Loading module: {{module}}',
 | |
|           'Cache hit for key: {{key}}',
 | |
|           'SQL query executed in {{time}}ms',
 | |
|           'Request headers: {{headers}}',
 | |
|           'Environment variable loaded: {{var}}',
 | |
|         ],
 | |
|         info: [
 | |
|           'Request received: {{method}} {{path}}',
 | |
|           'User {{userId}} authenticated successfully',
 | |
|           'Processing job {{jobId}} from queue',
 | |
|           'Scheduled task "{{task}}" started',
 | |
|           'WebSocket connection established from {{ip}}',
 | |
|         ],
 | |
|         warn: [
 | |
|           'Slow query detected: {{query}} ({{time}}ms)',
 | |
|           'Memory usage at {{percent}}%',
 | |
|           'Rate limit approaching for IP {{ip}}',
 | |
|           'Deprecated API endpoint called: {{endpoint}}',
 | |
|           'Certificate expires in {{days}} days',
 | |
|         ],
 | |
|         error: [
 | |
|           'Database connection lost: {{error}}',
 | |
|           'Failed to process request: {{error}}',
 | |
|           'Authentication failed for user {{user}}',
 | |
|           'File not found: {{path}}',
 | |
|           'Service unavailable: {{service}}',
 | |
|         ],
 | |
|         success: [
 | |
|           'Server started successfully on port {{port}}',
 | |
|           'Database migration completed',
 | |
|           'Backup completed: {{size}} MB',
 | |
|           'SSL certificate renewed',
 | |
|           'Health check passed: all systems operational',
 | |
|         ],
 | |
|       };
 | |
| 
 | |
|       const generateRandomLog = () => {
 | |
|         const levels: Array<'debug' | 'info' | 'warn' | 'error' | 'success'> = ['debug', 'info', 'warn', 'error', 'success'];
 | |
|         const weights = [0.2, 0.5, 0.15, 0.1, 0.05]; // Weighted probability
 | |
|         
 | |
|         const random = Math.random();
 | |
|         let cumulative = 0;
 | |
|         let level: typeof levels[0] = 'info';
 | |
|         
 | |
|         for (let i = 0; i < weights.length; i++) {
 | |
|           cumulative += weights[i];
 | |
|           if (random < cumulative) {
 | |
|             level = levels[i];
 | |
|             break;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         const source = serverSources[Math.floor(Math.random() * serverSources.length)];
 | |
|         const templates = logTemplates[level];
 | |
|         const template = templates[Math.floor(Math.random() * templates.length)];
 | |
|         
 | |
|         // Replace placeholders with random values
 | |
|         const message = template
 | |
|           .replace('{{module}}', ['express', 'mongoose', 'redis', 'socket.io'][Math.floor(Math.random() * 4)])
 | |
|           .replace('{{key}}', 'user:' + Math.floor(Math.random() * 1000))
 | |
|           .replace('{{time}}', String(Math.floor(Math.random() * 500) + 50))
 | |
|           .replace('{{headers}}', 'Content-Type: application/json, Authorization: Bearer ...')
 | |
|           .replace('{{var}}', ['NODE_ENV', 'DATABASE_URL', 'API_KEY', 'PORT'][Math.floor(Math.random() * 4)])
 | |
|           .replace('{{method}}', ['GET', 'POST', 'PUT', 'DELETE'][Math.floor(Math.random() * 4)])
 | |
|           .replace('{{path}}', ['/api/users', '/api/auth/login', '/api/products', '/health'][Math.floor(Math.random() * 4)])
 | |
|           .replace('{{userId}}', String(Math.floor(Math.random() * 10000)))
 | |
|           .replace('{{jobId}}', 'job_' + Math.random().toString(36).substring(2, 11))
 | |
|           .replace('{{task}}', ['cleanup', 'backup', 'report-generation', 'cache-refresh'][Math.floor(Math.random() * 4)])
 | |
|           .replace('{{ip}}', `192.168.1.${Math.floor(Math.random() * 255)}`)
 | |
|           .replace('{{query}}', 'SELECT * FROM users WHERE ...')
 | |
|           .replace('{{percent}}', String(Math.floor(Math.random() * 30) + 70))
 | |
|           .replace('{{endpoint}}', '/api/v1/legacy')
 | |
|           .replace('{{days}}', String(Math.floor(Math.random() * 30) + 1))
 | |
|           .replace('{{error}}', ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'][Math.floor(Math.random() * 3)])
 | |
|           .replace('{{user}}', 'user_' + Math.floor(Math.random() * 1000))
 | |
|           .replace('{{service}}', ['Redis', 'MongoDB', 'ElasticSearch'][Math.floor(Math.random() * 3)])
 | |
|           .replace('{{port}}', String(3000 + Math.floor(Math.random() * 10)))
 | |
|           .replace('{{size}}', String(Math.floor(Math.random() * 500) + 100));
 | |
| 
 | |
|         logElement.addLog(level, message, source);
 | |
|       };
 | |
| 
 | |
|       const startSimulation = () => {
 | |
|         if (!intervalId) {
 | |
|           // Generate logs at random intervals between 500ms and 2500ms
 | |
|           const scheduleNext = () => {
 | |
|             generateRandomLog();
 | |
|             const nextDelay = Math.random() * 2000 + 500;
 | |
|             intervalId = window.setTimeout(() => {
 | |
|               if (intervalId) {
 | |
|                 scheduleNext();
 | |
|               }
 | |
|             }, nextDelay);
 | |
|           };
 | |
|           scheduleNext();
 | |
|         }
 | |
|       };
 | |
| 
 | |
|       const stopSimulation = () => {
 | |
|         if (intervalId) {
 | |
|           window.clearTimeout(intervalId);
 | |
|           intervalId = null;
 | |
|         }
 | |
|       };
 | |
| 
 | |
|       // Wire up button click handlers
 | |
|       const buttons = elementArg.querySelectorAll('dees-button');
 | |
|       buttons.forEach(button => {
 | |
|         const text = button.textContent?.trim();
 | |
|         if (text === 'Add Single Log') {
 | |
|           button.addEventListener('click', () => generateRandomLog());
 | |
|         } else if (text === 'Start Simulation') {
 | |
|           button.addEventListener('click', () => startSimulation());
 | |
|         } else if (text === 'Stop Simulation') {
 | |
|           button.addEventListener('click', () => stopSimulation());
 | |
|         }
 | |
|       });
 | |
|     }}>
 | |
|       <style>
 | |
|       .demoBox {
 | |
|         position: relative;
 | |
|         background: #000000;
 | |
|         height: 100%;
 | |
|         width: 100%;
 | |
|         padding: 40px;
 | |
|         box-sizing: border-box;
 | |
|         display: flex;
 | |
|         flex-direction: column;
 | |
|         gap: 20px;
 | |
|       }
 | |
|       .controls {
 | |
|         display: flex;
 | |
|         gap: 10px;
 | |
|         flex-wrap: wrap;
 | |
|       }
 | |
|       .info {
 | |
|         color: #888;
 | |
|         font-size: 12px;
 | |
|         font-family: 'Geist Sans', sans-serif;
 | |
|       }
 | |
|     </style>
 | |
|     <div class="demoBox">
 | |
|       <div class="controls">
 | |
|         <dees-button>Add Single Log</dees-button>
 | |
|         <dees-button>Start Simulation</dees-button>
 | |
|         <dees-button>Stop Simulation</dees-button>
 | |
|       </div>
 | |
|       <div class="info">Simulating realistic server logs with various levels and sources</div>
 | |
|       <dees-chart-log
 | |
|         .label=${'Production Server Logs'}
 | |
|       ></dees-chart-log>
 | |
|     </div>
 | |
|     </dees-demowrapper>
 | |
|   `;
 | |
| }; |