2024-02-05 10:07:49 +01:00
|
|
|
import { html } from '@design.estate/dees-element';
|
2025-06-16 14:37:09 +00:00
|
|
|
import type { DeesChartLog } from './dees-chart-log.js';
|
2025-06-16 15:11:52 +00:00
|
|
|
import '@design.estate/dees-wcctools/demotools';
|
2024-02-05 10:07:49 +01:00
|
|
|
|
|
|
|
export const demoFunc = () => {
|
2025-06-16 14:59:22 +00:00
|
|
|
return html`
|
|
|
|
<dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
|
|
|
|
// Get the log element
|
|
|
|
const logElement = elementArg.querySelector('dees-chart-log') as DeesChartLog;
|
|
|
|
let intervalId: number;
|
2025-06-12 10:44:21 +00:00
|
|
|
|
2025-06-16 14:59:22 +00:00
|
|
|
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',
|
|
|
|
],
|
|
|
|
};
|
2025-06-12 10:44:21 +00:00
|
|
|
|
2025-06-16 14:59:22 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2025-06-12 10:44:21 +00:00
|
|
|
|
2025-06-16 14:59:22 +00:00
|
|
|
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));
|
2025-06-12 10:44:21 +00:00
|
|
|
|
2025-06-16 14:59:22 +00:00
|
|
|
logElement.addLog(level, message, source);
|
2025-06-12 10:44:21 +00:00
|
|
|
};
|
|
|
|
|
2025-06-16 14:59:22 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
};
|
2025-06-12 10:44:21 +00:00
|
|
|
|
2025-06-16 14:59:22 +00:00
|
|
|
const stopSimulation = () => {
|
|
|
|
if (intervalId) {
|
|
|
|
window.clearTimeout(intervalId);
|
|
|
|
intervalId = null;
|
|
|
|
}
|
|
|
|
};
|
2025-06-12 10:44:21 +00:00
|
|
|
|
2025-06-16 14:59:22 +00:00
|
|
|
// 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());
|
|
|
|
}
|
|
|
|
});
|
2025-06-16 14:37:09 +00:00
|
|
|
}}>
|
|
|
|
<style>
|
2024-02-05 10:07:49 +01:00
|
|
|
.demoBox {
|
|
|
|
position: relative;
|
|
|
|
background: #000000;
|
|
|
|
height: 100%;
|
|
|
|
width: 100%;
|
|
|
|
padding: 40px;
|
2025-06-12 10:44:21 +00:00
|
|
|
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;
|
2024-02-05 10:07:49 +01:00
|
|
|
}
|
|
|
|
</style>
|
|
|
|
<div class="demoBox">
|
2025-06-12 10:44:21 +00:00
|
|
|
<div class="controls">
|
2025-06-16 14:59:22 +00:00
|
|
|
<dees-button>Add Single Log</dees-button>
|
|
|
|
<dees-button>Start Simulation</dees-button>
|
|
|
|
<dees-button>Stop Simulation</dees-button>
|
2025-06-12 10:44:21 +00:00
|
|
|
</div>
|
|
|
|
<div class="info">Simulating realistic server logs with various levels and sources</div>
|
2024-02-05 10:07:49 +01:00
|
|
|
<dees-chart-log
|
2025-06-12 10:44:21 +00:00
|
|
|
.label=${'Production Server Logs'}
|
2024-02-05 10:07:49 +01:00
|
|
|
></dees-chart-log>
|
2025-06-16 14:59:22 +00:00
|
|
|
</div>
|
2025-06-16 14:37:09 +00:00
|
|
|
</dees-demowrapper>
|
2024-02-05 10:07:49 +01:00
|
|
|
`;
|
2025-06-16 14:59:22 +00:00
|
|
|
};
|