2026-01-12 23:41:43 +00:00
import { html , css , cssManager } from '@design.estate/dees-element' ;
2025-12-05 10:19:37 +00:00
import type { DeesChartLog } from '../dees-chart-log/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 ) = > {
2026-01-12 23:41:43 +00:00
// Get the log elements
const structuredLog = elementArg . querySelector ( '#structured-log' ) as DeesChartLog ;
const rawLog = elementArg . querySelector ( '#raw-log' ) as DeesChartLog ;
2026-04-01 05:00:21 +00:00
let structuredIntervalId : number | null ;
let rawIntervalId : number | null ;
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' ] ;
2026-01-12 23:41:43 +00:00
2025-06-16 14:59:22 +00:00
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
2026-01-12 23:41:43 +00:00
// Docker-like raw log lines with ANSI colors
const dockerLogTemplates = [
' \ x1b[90m2024-01-15T10:23:45.123Z \ x1b[0m \ x1b[36mINFO \ x1b[0m [nginx] GET /api/health 200 - 2ms',
' \ x1b[90m2024-01-15T10:23:45.456Z \ x1b[0m \ x1b[33mWARN \ x1b[0m [redis] Connection pool running low: 3/10',
' \ x1b[90m2024-01-15T10:23:45.789Z \ x1b[0m \ x1b[31mERROR \ x1b[0m [mongodb] Query timeout after 30000ms',
' \ x1b[90m2024-01-15T10:23:46.012Z \ x1b[0m \ x1b[36mINFO \ x1b[0m [app] Processing batch job #{{jobId}}',
' \ x1b[90m2024-01-15T10:23:46.345Z \ x1b[0m \ x1b[32mOK \ x1b[0m [health] All services healthy',
' \ x1b[90m2024-01-15T10:23:46.678Z \ x1b[0m \ x1b[36mINFO \ x1b[0m [kafka] Message consumed from topic: events',
' \ x1b[90m2024-01-15T10:23:47.001Z \ x1b[0m \ x1b[35mDEBUG \ x1b[0m [grpc] Request received: GetUser(id={{userId}})',
' \ x1b[90m2024-01-15T10:23:47.234Z \ x1b[0m \ x1b[31mERROR \ x1b[0m [auth] Token validation failed: expired',
' \ x1b[90m2024-01-15T10:23:47.567Z \ x1b[0m \ x1b[33mWARN \ x1b[0m [rate-limit] IP {{ip}} approaching rate limit',
' \ x1b[90m2024-01-15T10:23:47.890Z \ x1b[0m \ x1b[36mINFO \ x1b[0m [websocket] Client connected: session={{session}}',
// Multi-line log entry like stack traces
' \ x1b[31mError: Connection refused \ x1b[0m \ n at TcpConnection.connect (/app/node_modules/pg/lib/connection.js:12:15) \ n at Pool.connect (/app/node_modules/pg/lib/pool.js:45:23) \ n at async DatabaseService.query (/app/src/db/service.ts:89:12)',
];
2025-06-16 14:59:22 +00:00
const generateRandomLog = () => {
const levels: Array<'debug' | 'info' | 'warn' | 'error' | 'success'> = ['debug', 'info', 'warn', 'error', 'success'];
2026-01-12 23:41:43 +00:00
const weights = [0.2, 0.5, 0.15, 0.1, 0.05];
2025-06-16 14:59:22 +00:00
const random = Math.random();
let cumulative = 0;
let level: typeof levels[0] = 'info';
2026-01-12 23:41:43 +00:00
2025-06-16 14:59:22 +00:00
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)];
2026-01-12 23:41:43 +00:00
2025-06-16 14:59:22 +00:00
// 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
2026-01-12 23:41:43 +00:00
structuredLog.addLog(level, message, source);
};
const generateDockerLog = () => {
const template = dockerLogTemplates[Math.floor(Math.random() * dockerLogTemplates.length)];
const now = new Date().toISOString();
const logLine = template
.replace(/2024-01-15T10:23: \ d{2} \ . \ d{3}Z/g, now)
.replace('{{jobId}}', String(Math.floor(Math.random() * 10000)))
.replace('{{userId}}', String(Math.floor(Math.random() * 10000)))
.replace('{{ip}}', ` 192.168 . 1 . $ { Math . floor ( Math . random ( ) * 255 ) } ` )
.replace('{{session}}', Math.random().toString(36).substring(2, 11));
rawLog.writelnRaw(logLine);
2025-06-12 10:44:21 +00:00
};
2026-01-12 23:41:43 +00:00
const startStructuredSimulation = () => {
if (!structuredIntervalId) {
2025-06-16 14:59:22 +00:00
const scheduleNext = () => {
generateRandomLog();
const nextDelay = Math.random() * 2000 + 500;
2026-01-12 23:41:43 +00:00
structuredIntervalId = window.setTimeout(() => {
if (structuredIntervalId) {
scheduleNext();
}
}, nextDelay);
};
scheduleNext();
}
};
const stopStructuredSimulation = () => {
if (structuredIntervalId) {
window.clearTimeout(structuredIntervalId);
structuredIntervalId = null;
}
};
const startRawSimulation = () => {
if (!rawIntervalId) {
const scheduleNext = () => {
generateDockerLog();
const nextDelay = Math.random() * 1000 + 200;
rawIntervalId = window.setTimeout(() => {
if (rawIntervalId) {
2025-06-16 14:59:22 +00:00
scheduleNext();
}
}, nextDelay);
};
scheduleNext();
}
};
2025-06-12 10:44:21 +00:00
2026-01-12 23:41:43 +00:00
const stopRawSimulation = () => {
if (rawIntervalId) {
window.clearTimeout(rawIntervalId);
rawIntervalId = null;
2025-06-16 14:59:22 +00:00
}
};
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 => {
2026-04-02 19:43:16 +00:00
const text = (button as any).text?.trim();
2026-01-12 23:41:43 +00:00
switch (text) {
case 'Add Structured Log':
button.addEventListener('click', () => generateRandomLog());
break;
case 'Start Structured':
button.addEventListener('click', () => startStructuredSimulation());
break;
case 'Stop Structured':
button.addEventListener('click', () => stopStructuredSimulation());
break;
case 'Add Docker Log':
button.addEventListener('click', () => generateDockerLog());
break;
case 'Start Docker':
button.addEventListener('click', () => startRawSimulation());
break;
case 'Stop Docker':
button.addEventListener('click', () => stopRawSimulation());
break;
2025-06-16 14:59:22 +00:00
}
});
2025-06-16 14:37:09 +00:00
}}>
<style>
2026-01-12 23:41:43 +00:00
${ css `
.demoBox {
position: relative;
background: ${ cssManager . bdTheme ( 'hsl(0 0% 95%)' , 'hsl(0 0% 5%)' ) } ;
height: 100%;
width: 100%;
padding: 40px;
box-sizing: border-box;
display: flex;
flex-direction: column;
gap: 24px;
}
.section {
display: flex;
flex-direction: column;
gap: 12px;
}
.section-title {
color: ${ cssManager . bdTheme ( 'hsl(0 0% 9%)' , 'hsl(0 0% 95%)' ) } ;
font-size: 14px;
font-weight: 600;
font-family: 'Geist Sans', sans-serif;
}
.section-description {
color: ${ cssManager . bdTheme ( 'hsl(215.4 16.3% 46.9%)' , 'hsl(215 20.2% 65.1%)' ) } ;
font-size: 12px;
font-family: 'Geist Sans', sans-serif;
}
.controls {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
` }
</style>
2024-02-05 10:07:49 +01:00
<div class="demoBox">
2026-01-12 23:41:43 +00:00
<!-- Structured Logs Section -->
<div class="section">
<div class="section-title">Structured Logs (ILogEntry)</div>
<div class="section-description">
Structured log entries with level, message, and source. Supports search and keyword highlighting.
</div>
<div class="controls">
<dees-button>Add Structured Log</dees-button>
<dees-button>Start Structured</dees-button>
<dees-button>Stop Structured</dees-button>
</div>
<dees-chart-log
id="structured-log"
.label= ${ 'Production Server Logs' }
.highlightKeywords= ${ [ 'error' , 'failed' , 'timeout' ] }
.showMetrics= ${ true }
></dees-chart-log>
</div>
<!-- Raw Logs Section -->
<div class="section">
<div class="section-title">Raw Logs (Docker/Container Style)</div>
<div class="section-description">
Raw log output with ANSI escape sequences for real Docker/container logs.
</div>
<div class="controls">
<dees-button>Add Docker Log</dees-button>
<dees-button>Start Docker</dees-button>
<dees-button>Stop Docker</dees-button>
</div>
<dees-chart-log
id="raw-log"
.label= ${ 'Docker Container Logs' }
.mode= ${ 'raw' }
.showMetrics= ${ false }
></dees-chart-log>
2025-06-12 10:44:21 +00:00
</div>
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
` ;
2026-01-12 23:41:43 +00:00
} ;