slakwik commited on
Commit
fa6ecb7
·
verified ·
1 Parent(s): b9bd739

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +719 -19
index.html CHANGED
@@ -1,19 +1,719 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Zabbix Event Analyzer with Ollama</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ :root {
11
+ --primary: #3b82f6;
12
+ --primary-dark: #1d4ed8;
13
+ --secondary: #10b981;
14
+ --background: #f8fafc;
15
+ --card: #ffffff;
16
+ --text: #1e293b;
17
+ --text-light: #64748b;
18
+ --border: #e2e8f0;
19
+ --danger: #ef4444;
20
+ --warning: #f59e0b;
21
+ --info: #06b6d4;
22
+ }
23
+
24
+ body {
25
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
26
+ background-color: var(--background);
27
+ color: var(--text);
28
+ }
29
+
30
+ .gradient-bg {
31
+ background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
32
+ }
33
+
34
+ .card {
35
+ background: var(--card);
36
+ border-radius: 12px;
37
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
38
+ border: 1px solid var(--border);
39
+ }
40
+
41
+ .severity-badge {
42
+ padding: 4px 12px;
43
+ border-radius: 20px;
44
+ font-size: 0.875rem;
45
+ font-weight: 600;
46
+ display: inline-flex;
47
+ align-items: center;
48
+ gap: 6px;
49
+ }
50
+
51
+ .severity-disaster {
52
+ background-color: #fef2f2;
53
+ color: #991b1b;
54
+ }
55
+
56
+ .severity-high {
57
+ background-color: #fee2e2;
58
+ color: #b91c1c;
59
+ }
60
+
61
+ .severity-average {
62
+ background-color: #fef3c7;
63
+ color: #b45309;
64
+ }
65
+
66
+ .severity-warning {
67
+ background-color: #fef9c3;
68
+ color: #a16207;
69
+ }
70
+
71
+ .severity-info {
72
+ background-color: #dbeafe;
73
+ color: #1e40af;
74
+ }
75
+
76
+ .severity-not-classified {
77
+ background-color: #f3f4f6;
78
+ color: #6b7280;
79
+ }
80
+
81
+ .event-timeline {
82
+ position: relative;
83
+ padding-left: 20px;
84
+ }
85
+
86
+ .event-timeline::before {
87
+ content: '';
88
+ position: absolute;
89
+ left: 0;
90
+ top: 0;
91
+ bottom: 0;
92
+ width: 2px;
93
+ background: linear-gradient(to bottom, var(--primary), var(--secondary));
94
+ border-radius: 2px;
95
+ }
96
+
97
+ .event-item {
98
+ position: relative;
99
+ margin-bottom: 24px;
100
+ }
101
+
102
+ .event-item::before {
103
+ content: '';
104
+ position: absolute;
105
+ left: -26px;
106
+ top: 0;
107
+ width: 12px;
108
+ height: 12px;
109
+ border-radius: 50%;
110
+ background: var(--card);
111
+ border: 2px solid var(--primary);
112
+ }
113
+
114
+ .analysis-result {
115
+ animation: fadeIn 0.5s ease-in-out;
116
+ }
117
+
118
+ @keyframes fadeIn {
119
+ from { opacity: 0; transform: translateY(10px); }
120
+ to { opacity: 1; transform: translateY(0); }
121
+ }
122
+
123
+ .loading-spinner {
124
+ width: 40px;
125
+ height: 40px;
126
+ border: 4px solid rgba(255, 255, 255, 0.3);
127
+ border-radius: 50%;
128
+ border-top-color: white;
129
+ animation: spin 1s ease-in-out infinite;
130
+ }
131
+
132
+ @keyframes spin {
133
+ to { transform: rotate(360deg); }
134
+ }
135
+
136
+ .sidebar {
137
+ transition: transform 0.3s ease-in-out;
138
+ }
139
+
140
+ @media (max-width: 768px) {
141
+ .sidebar {
142
+ transform: translateX(-100%);
143
+ }
144
+
145
+ .sidebar.open {
146
+ transform: translateX(0);
147
+ }
148
+ }
149
+ </style>
150
+ </head>
151
+ <body class="min-h-screen">
152
+ <!-- Header -->
153
+ <header class="bg-white shadow-sm border-b">
154
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
155
+ <div class="flex justify-between items-center h-16">
156
+ <div class="flex items-center">
157
+ <button id="menu-btn" class="md:hidden p-2 rounded-md text-gray-500 hover:text-gray-700 hover:bg-gray-100">
158
+ <i class="fas fa-bars text-xl"></i>
159
+ </button>
160
+ <div class="flex items-center space-x-3">
161
+ <div class="w-8 h-8 bg-gradient-to-r from-blue-500 to-green-500 rounded-md flex items-center justify-center">
162
+ <i class="fas fa-chart-line text-white text-sm"></i>
163
+ </div>
164
+ <span class="text-xl font-bold text-gray-800">Zabbix Event Analyzer</span>
165
+ </div>
166
+ </div>
167
+
168
+ <div class="flex items-center space-x-4">
169
+ <div class="hidden md:flex items-center space-x-2 text-sm text-gray-600">
170
+ <i class="fas fa-robot text-blue-500"></i>
171
+ <span>Powered by Ollama</span>
172
+ </div>
173
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="text-sm text-gray-500 hover:text-gray-700 flex items-center space-x-1">
174
+ <i class="fas fa-code"></i>
175
+ <span>Built with anycoder</span>
176
+ </a>
177
+ </div>
178
+ </div>
179
+ </div>
180
+ </header>
181
+
182
+ <div class="flex">
183
+ <!-- Sidebar -->
184
+ <aside id="sidebar" class="sidebar w-64 bg-white border-r flex-shrink-0 md:block">
185
+ <div class="p-4 border-b">
186
+ <h3 class="font-semibold text-gray-800">Filters</h3>
187
+ </div>
188
+
189
+ <div class="p-4 space-y-6">
190
+ <div>
191
+ <label class="block text-sm font-medium text-gray-700 mb-2">Severity</label>
192
+ <div class="space-y-2">
193
+ <label class="flex items-center">
194
+ <input type="checkbox" class="rounded border-gray-300 text-blue-600 focus:ring-blue-500" checked>
195
+ <span class="ml-2 text-sm text-gray-600">Disaster</span>
196
+ </label>
197
+ <label class="flex items-center">
198
+ <input type="checkbox" class="rounded border-gray-300 text-blue-600 focus:ring-blue-500" checked>
199
+ <span class="ml-2 text-sm text-gray-600">High</span>
200
+ </label>
201
+ <label class="flex items-center">
202
+ <input type="checkbox" class="rounded border-gray-300 text-blue-600 focus:ring-blue-500" checked>
203
+ <span class="ml-2 text-sm text-gray-600">Average</span>
204
+ </label>
205
+ <label class="flex items-center">
206
+ <input type="checkbox" class="rounded border-gray-300 text-blue-600 focus:ring-blue-500" checked>
207
+ <span class="ml-2 text-sm text-gray-600">Warning</span>
208
+ </label>
209
+ <label class="flex items-center">
210
+ <input type="checkbox" class="rounded border-gray-300 text-blue-600 focus:ring-blue-500" checked>
211
+ <span class="ml-2 text-sm text-gray-600">Information</span>
212
+ </label>
213
+ <label class="flex items-center">
214
+ <input type="checkbox" class="rounded border-gray-300 text-blue-600 focus:ring-blue-500" checked>
215
+ <span class="ml-2 text-sm text-gray-600">Not classified</span>
216
+ </label>
217
+ </div>
218
+ </div>
219
+
220
+ <div>
221
+ <label for="time-range" class="block text-sm font-medium text-gray-700 mb-2">Time Range</label>
222
+ <select id="time-range" class="w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500">
223
+ <option value="1h">Last 1 hour</option>
224
+ <option value="6h" selected>Last 6 hours</option>
225
+ <option value="12h">Last 12 hours</option>
226
+ <option value="24h">Last 24 hours</option>
227
+ <option value="7d">Last 7 days</option>
228
+ <option value="30d">Last 30 days</option>
229
+ </select>
230
+ </div>
231
+
232
+ <div>
233
+ <label for="host-filter" class="block text-sm font-medium text-gray-700 mb-2">Host</label>
234
+ <input type="text" id="host-filter" placeholder="Filter by host..." class="w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500">
235
+ </div>
236
+
237
+ <div>
238
+ <label for="event-filter" class="block text-sm font-medium text-gray-700 mb-2">Event Name</label>
239
+ <input type="text" id="event-filter" placeholder="Filter by event name..." class="w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500">
240
+ </div>
241
+
242
+ <button id="apply-filters" class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition-colors">
243
+ Apply Filters
244
+ </button>
245
+ </div>
246
+ </aside>
247
+
248
+ <!-- Main Content -->
249
+ <main class="flex-1 overflow-y-auto">
250
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
251
+ <!-- Stats Cards -->
252
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
253
+ <div class="card p-6">
254
+ <div class="flex items-center justify-between">
255
+ <div>
256
+ <p class="text-sm font-medium text-gray-500">Total Events</p>
257
+ <p class="text-3xl font-bold text-gray-800 mt-1">1,248</p>
258
+ </div>
259
+ <div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center">
260
+ <i class="fas fa-bell text-blue-600 text-xl"></i>
261
+ </div>
262
+ </div>
263
+ <p class="text-sm text-green-600 mt-2 flex items-center">
264
+ <i class="fas fa-arrow-up mr-1"></i>
265
+ 12% from yesterday
266
+ </p>
267
+ </div>
268
+
269
+ <div class="card p-6">
270
+ <div class="flex items-center justify-between">
271
+ <div>
272
+ <p class="text-sm font-medium text-gray-500">Critical Events</p>
273
+ <p class="text-3xl font-bold text-gray-800 mt-1">42</p>
274
+ </div>
275
+ <div class="w-12 h-12 bg-red-100 rounded-full flex items-center justify-center">
276
+ <i class="fas fa-exclamation-triangle text-red-600 text-xl"></i>
277
+ </div>
278
+ </div>
279
+ <p class="text-sm text-red-600 mt-2 flex items-center">
280
+ <i class="fas fa-arrow-down mr-1"></i>
281
+ 5% from yesterday
282
+ </p>
283
+ </div>
284
+
285
+ <div class="card p-6">
286
+ <div class="flex items-center justify-between">
287
+ <div>
288
+ <p class="text-sm font-medium text-gray-500">Analyzed Events</p>
289
+ <p class="text-3xl font-bold text-gray-800 mt-1">876</p>
290
+ </div>
291
+ <div class="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center">
292
+ <i class="fas fa-brain text-green-600 text-xl"></i>
293
+ </div>
294
+ </div>
295
+ <p class="text-sm text-green-600 mt-2 flex items-center">
296
+ <i class="fas fa-arrow-up mr-1"></i>
297
+ 22% from yesterday
298
+ </p>
299
+ </div>
300
+
301
+ <div class="card p-6">
302
+ <div class="flex items-center justify-between">
303
+ <div>
304
+ <p class="text-sm font-medium text-gray-500">Active Triggers</p>
305
+ <p class="text-3xl font-bold text-gray-800 mt-1">18</p>
306
+ </div>
307
+ <div class="w-12 h-12 bg-purple-100 rounded-full flex items-center justify-center">
308
+ <i class="fas fa-bolt text-purple-600 text-xl"></i>
309
+ </div>
310
+ </div>
311
+ <p class="text-sm text-purple-600 mt-2 flex items-center">
312
+ <i class="fas fa-arrow-up mr-1"></i>
313
+ 8% from yesterday
314
+ </p>
315
+ </div>
316
+ </div>
317
+
318
+ <!-- Main Content Area -->
319
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
320
+ <!-- Events Timeline -->
321
+ <div class="lg:col-span-2">
322
+ <div class="card">
323
+ <div class="p-6 border-b">
324
+ <div class="flex items-center justify-between">
325
+ <h2 class="text-lg font-semibold text-gray-800">Recent Events</h2>
326
+ <button id="refresh-events" class="text-blue-600 hover:text-blue-800 flex items-center space-x-1">
327
+ <i class="fas fa-sync-alt"></i>
328
+ <span>Refresh</span>
329
+ </button>
330
+ </div>
331
+ </div>
332
+
333
+ <div class="p-6">
334
+ <div class="event-timeline">
335
+ <!-- Event items will be populated by JavaScript -->
336
+ <div id="events-container" class="space-y-6">
337
+ <!-- Sample event item (will be generated by JS) -->
338
+ <div class="event-item">
339
+ <div class="bg-gray-50 rounded-lg p-4">
340
+ <div class="flex items-start justify-between">
341
+ <div class="flex-1">
342
+ <div class="flex items-center space-x-3">
343
+ <span class="severity-badge severity-high">
344
+ <i class="fas fa-exclamation-circle"></i>
345
+ <span>High</span>
346
+ </span>
347
+ <span class="text-sm text-gray-500">2023-11-15 14:32:17</span>
348
+ </div>
349
+ <h3 class="font-semibold text-gray-800 mt-2">High CPU load on web-server-01</h3>
350
+ <p class="text-sm text-gray-600 mt-1">CPU load has been over 90% for the last 5 minutes</p>
351
+ <div class="mt-3 flex flex-wrap gap-2">
352
+ <span class="px-2 py-1 bg-gray-100 text-xs rounded-full">web-server-01</span>
353
+ <span class="px-2 py-1 bg-gray-100 text-xs rounded-full">CPU</span>
354
+ <span class="px-2 py-1 bg-gray-100 text-xs rounded-full">Performance</span>
355
+ </div>
356
+ </div>
357
+ <button class="analyze-btn text-blue-600 hover:text-blue-800 px-3 py-1 rounded-md text-sm font-medium" data-event-id="1">
358
+ <i class="fas fa-brain mr-1"></i> Analyze
359
+ </button>
360
+ </div>
361
+ </div>
362
+ </div>
363
+ </div>
364
+ </div>
365
+
366
+ <div class="mt-8 flex justify-center">
367
+ <button id="load-more" class="bg-gray-100 hover:bg-gray-200 text-gray-700 px-4 py-2 rounded-md">
368
+ Load More Events
369
+ </button>
370
+ </div>
371
+ </div>
372
+ </div>
373
+ </div>
374
+
375
+ <!-- Analysis Panel -->
376
+ <div class="lg:col-span-1">
377
+ <div class="card h-full">
378
+ <div class="p-6 border-b">
379
+ <h2 class="text-lg font-semibold text-gray-800">AI Analysis</h2>
380
+ <p class="text-sm text-gray-500">Powered by Ollama</p>
381
+ </div>
382
+
383
+ <div class="p-6">
384
+ <div id="analysis-placeholder" class="text-center py-12">
385
+ <div class="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-4">
386
+ <i class="fas fa-brain text-blue-600 text-2xl"></i>
387
+ </div>
388
+ <h3 class="text-gray-800 font-medium">Select an event to analyze</h3>
389
+ <p class="text-gray-500 text-sm mt-1">Click the "Analyze" button on any event to get AI-powered insights</p>
390
+ </div>
391
+
392
+ <div id="analysis-result" class="hidden">
393
+ <div class="flex items-center justify-between mb-4">
394
+ <h3 class="font-semibold text-gray-800">Analysis Results</h3>
395
+ <span class="text-sm text-gray-500" id="analysis-time">Just now</span>
396
+ </div>
397
+
398
+ <div class="space-y-4">
399
+ <div>
400
+ <p class="text-sm font-medium text-gray-500 mb-1">Root Cause</p>
401
+ <p class="text-gray-800" id="analysis-root-cause">The high CPU load is likely caused by a sudden spike in web traffic combined with inefficient database queries in the application.</p>
402
+ </div>
403
+
404
+ <div>
405
+ <p class="text-sm font-medium text-gray-500 mb-1">Recommended Actions</p>
406
+ <ul class="space-y-2 text-gray-800" id="analysis-actions">
407
+ <li class="flex items-start">
408
+ <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
409
+ <span>Check web server access logs for traffic patterns</span>
410
+ </li>
411
+ <li class="flex items-start">
412
+ <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
413
+ <span>Optimize slow database queries</span>
414
+ </li>
415
+ <li class="flex items-start">
416
+ <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
417
+ <span>Consider adding more web server instances</span>
418
+ </li>
419
+ </ul>
420
+ </div>
421
+
422
+ <div>
423
+ <p class="text-sm font-medium text-gray-500 mb-1">Confidence Level</p>
424
+ <div class="flex items-center space-x-2">
425
+ <div class="w-full bg-gray-200 rounded-full h-2">
426
+ <div class="bg-blue-600 h-2 rounded-full" style="width: 85%"></div>
427
+ </div>
428
+ <span class="text-sm font-medium text-gray-800">85%</span>
429
+ </div>
430
+ </div>
431
+
432
+ <div class="pt-4 border-t">
433
+ <p class="text-sm font-medium text-gray-500 mb-2">Additional Context</p>
434
+ <div class="space-y-2 text-sm text-gray-600" id="analysis-context">
435
+ <p>Similar events occurred 3 times in the last week during peak hours.</p>
436
+ <p>The database server shows correlated high load during these events.</p>
437
+ <p>No recent deployment changes that would explain this behavior.</p>
438
+ </div>
439
+ </div>
440
+ </div>
441
+ </div>
442
+ </div>
443
+ </div>
444
+ </div>
445
+ </div>
446
+ </div>
447
+ </main>
448
+ </div>
449
+
450
+ <!-- Loading Overlay -->
451
+ <div id="loading-overlay" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
452
+ <div class="bg-white rounded-lg p-6 w-80 text-center">
453
+ <div class="flex justify-center mb-4">
454
+ <div class="loading-spinner"></div>
455
+ </div>
456
+ <h3 class="text-lg font-semibold text-gray-800 mb-2">Analyzing Event</h3>
457
+ <p class="text-gray-600">Ollama is processing the event data and generating insights...</p>
458
+ <p class="text-sm text-gray-500 mt-2">This may take a few seconds</p>
459
+ </div>
460
+ </div>
461
+
462
+ <script>
463
+ // Mock data for events
464
+ const mockEvents = [
465
+ {
466
+ id: 1,
467
+ timestamp: "2023-11-15 14:32:17",
468
+ severity: "high",
469
+ name: "High CPU load on web-server-01",
470
+ description: "CPU load has been over 90% for the last 5 minutes",
471
+ host: "web-server-01",
472
+ tags: ["web-server-01", "CPU", "Performance"],
473
+ analyzed: false
474
+ },
475
+ {
476
+ id: 2,
477
+ timestamp: "2023-11-15 13:45:22",
478
+ severity: "disaster",
479
+ name: "Database connection failed",
480
+ description: "Primary database server is not responding to connection requests",
481
+ host: "db-primary-01",
482
+ tags: ["db-primary-01", "Database", "Connection"],
483
+ analyzed: false
484
+ },
485
+ {
486
+ id: 3,
487
+ timestamp: "2023-11-15 12:10:08",
488
+ severity: "average",
489
+ name: "Disk space warning on backup server",
490
+ description: "Backup storage is at 85% capacity",
491
+ host: "backup-server-01",
492
+ tags: ["backup-server-01", "Storage", "Disk"],
493
+ analyzed: false
494
+ },
495
+ {
496
+ id: 4,
497
+ timestamp: "2023-11-15 11:22:45",
498
+ severity: "warning",
499
+ name: "High memory usage on API server",
500
+ description: "Memory usage exceeds 90% threshold",
501
+ host: "api-server-02",
502
+ tags: ["api-server-02", "Memory", "Performance"],
503
+ analyzed: false
504
+ },
505
+ {
506
+ id: 5,
507
+ timestamp: "2023-11-15 10:15:33",
508
+ severity: "info",
509
+ name: "Scheduled maintenance completed",
510
+ description: "Nightly maintenance tasks finished successfully",
511
+ host: "monitoring-server",
512
+ tags: ["monitoring-server", "Maintenance", "Scheduled"],
513
+ analyzed: false
514
+ },
515
+ {
516
+ id: 6,
517
+ timestamp: "2023-11-15 09:05:12",
518
+ severity: "high",
519
+ name: "Network latency detected",
520
+ description: "Increased latency between data centers",
521
+ host: "network-core-01",
522
+ tags: ["network-core-01", "Network", "Latency"],
523
+ analyzed: false
524
+ }
525
+ ];
526
+
527
+ // Mock analysis data
528
+ const mockAnalysis = {
529
+ rootCause: "The high CPU load is likely caused by a sudden spike in web traffic combined with inefficient database queries in the application.",
530
+ actions: [
531
+ "Check web server access logs for traffic patterns",
532
+ "Optimize slow database queries",
533
+ "Consider adding more web server instances"
534
+ ],
535
+ confidence: 85,
536
+ context: [
537
+ "Similar events occurred 3 times in the last week during peak hours.",
538
+ "The database server shows correlated high load during these events.",
539
+ "No recent deployment changes that would explain this behavior."
540
+ ]
541
+ };
542
+
543
+ // DOM Elements
544
+ const eventsContainer = document.getElementById('events-container');
545
+ const analysisPlaceholder = document.getElementById('analysis-placeholder');
546
+ const analysisResult = document.getElementById('analysis-result');
547
+ const loadingOverlay = document.getElementById('loading-overlay');
548
+ const menuBtn = document.getElementById('menu-btn');
549
+ const sidebar = document.getElementById('sidebar');
550
+ const refreshBtn = document.getElementById('refresh-events');
551
+ const loadMoreBtn = document.getElementById('load-more');
552
+
553
+ // Initialize the app
554
+ function init() {
555
+ renderEvents();
556
+ setupEventListeners();
557
+ }
558
+
559
+ // Render events to the timeline
560
+ function renderEvents() {
561
+ eventsContainer.innerHTML = '';
562
+
563
+ // For demo purposes, we'll show all events
564
+ mockEvents.forEach(event => {
565
+ const eventElement = createEventElement(event);
566
+ eventsContainer.appendChild(eventElement);
567
+ });
568
+ }
569
+
570
+ // Create an event element
571
+ function createEventElement(event) {
572
+ const eventDiv = document.createElement('div');
573
+ eventDiv.className = 'event-item';
574
+ eventDiv.innerHTML = `
575
+ <div class="bg-gray-50 rounded-lg p-4">
576
+ <div class="flex items-start justify-between">
577
+ <div class="flex-1">
578
+ <div class="flex items-center space-x-3">
579
+ <span class="severity-badge severity-${event.severity}">
580
+ <i class="fas fa-exclamation-circle"></i>
581
+ <span>${capitalizeFirstLetter(event.severity)}</span>
582
+ </span>
583
+ <span class="text-sm text-gray-500">${event.timestamp}</span>
584
+ </div>
585
+ <h3 class="font-semibold text-gray-800 mt-2">${event.name}</h3>
586
+ <p class="text-sm text-gray-600 mt-1">${event.description}</p>
587
+ <div class="mt-3 flex flex-wrap gap-2">
588
+ ${event.tags.map(tag => `
589
+ <span class="px-2 py-1 bg-gray-100 text-xs rounded-full">${tag}</span>
590
+ `).join('')}
591
+ </div>
592
+ </div>
593
+ <button class="analyze-btn text-blue-600 hover:text-blue-800 px-3 py-1 rounded-md text-sm font-medium" data-event-id="${event.id}">
594
+ <i class="fas fa-brain mr-1"></i> Analyze
595
+ </button>
596
+ </div>
597
+ </div>
598
+ `;
599
+ return eventDiv;
600
+ }
601
+
602
+ // Setup event listeners
603
+ function setupEventListeners() {
604
+ // Mobile menu toggle
605
+ menuBtn.addEventListener('click', () => {
606
+ sidebar.classList.toggle('open');
607
+ });
608
+
609
+ // Close sidebar when clicking outside on mobile
610
+ document.addEventListener('click', (e) => {
611
+ if (window.innerWidth < 768 && !sidebar.contains(e.target) && !menuBtn.contains(e.target)) {
612
+ sidebar.classList.remove('open');
613
+ }
614
+ });
615
+
616
+ // Analyze button click handler (event delegation)
617
+ eventsContainer.addEventListener('click', (e) => {
618
+ if (e.target.closest('.analyze-btn')) {
619
+ const eventId = parseInt(e.target.closest('.analyze-btn').dataset.eventId);
620
+ analyzeEvent(eventId);
621
+ }
622
+ });
623
+
624
+ // Refresh events button
625
+ refreshBtn.addEventListener('click', () => {
626
+ // In a real app, this would fetch new data
627
+ showNotification("Events refreshed", "success");
628
+ });
629
+
630
+ // Load more events button
631
+ loadMoreBtn.addEventListener('click', () => {
632
+ // In a real app, this would load more events
633
+ showNotification("No more events to load", "info");
634
+ });
635
+
636
+ // Apply filters button
637
+ document.getElementById('apply-filters').addEventListener('click', () => {
638
+ // In a real app, this would apply the filters
639
+ showNotification("Filters applied", "success");
640
+ });
641
+ }
642
+
643
+ // Simulate analyzing an event with Ollama
644
+ function analyzeEvent(eventId) {
645
+ // Show loading overlay
646
+ loadingOverlay.classList.remove('hidden');
647
+
648
+ // Hide placeholder and show analysis after a delay (simulating API call)
649
+ setTimeout(() => {
650
+ // Find the event
651
+ const event = mockEvents.find(e => e.id === eventId);
652
+
653
+ // Update the analysis result with mock data
654
+ document.getElementById('analysis-root-cause').textContent = mockAnalysis.rootCause;
655
+
656
+ const actionsList = document.getElementById('analysis-actions');
657
+ actionsList.innerHTML = mockAnalysis.actions.map(action => `
658
+ <li class="flex items-start">
659
+ <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
660
+ <span>${action}</span>
661
+ </li>
662
+ `).join('');
663
+
664
+ document.getElementById('analysis-time').textContent = "Just now";
665
+ document.getElementById('analysis-context').innerHTML = mockAnalysis.context.map(item => `
666
+ <p>${item}</p>
667
+ `).join('');
668
+
669
+ // Update confidence level
670
+ const confidenceBar = analysisResult.querySelector('.bg-blue-600');
671
+ confidenceBar.style.width = `${mockAnalysis.confidence}%`;
672
+ confidenceBar.nextElementSibling.textContent = `${mockAnalysis.confidence}%`;
673
+
674
+ // Show analysis result
675
+ analysisPlaceholder.classList.add('hidden');
676
+ analysisResult.classList.remove('hidden');
677
+
678
+ // Hide loading overlay
679
+ loadingOverlay.classList.add('hidden');
680
+
681
+ // Mark event as analyzed
682
+ event.analyzed = true;
683
+ const analyzeBtn = document.querySelector(`.analyze-btn[data-event-id="${eventId}"]`);
684
+ analyzeBtn.innerHTML = '<i class="fas fa-check-circle mr-1"></i> Analyzed';
685
+ analyzeBtn.classList.remove('text-blue-600', 'hover:text-blue-800');
686
+ analyzeBtn.classList.add('text-green-600', 'cursor-default');
687
+ analyzeBtn.removeAttribute('data-event-id');
688
+
689
+ showNotification("Event analyzed successfully", "success");
690
+ }, 1500);
691
+ }
692
+
693
+ // Helper function to capitalize first letter
694
+ function capitalizeFirstLetter(string) {
695
+ return string.charAt(0).toUpperCase() + string.slice(1);
696
+ }
697
+
698
+ // Show notification
699
+ function showNotification(message, type) {
700
+ // In a real app, you might use a proper notification system
701
+ const notification = document.createElement('div');
702
+ notification.className = `fixed bottom-4 right-4 px-4 py-2 rounded-md shadow-lg text-white ${
703
+ type === 'success' ? 'bg-green-600' :
704
+ type === 'error' ? 'bg-red-600' :
705
+ type === 'warning' ? 'bg-yellow-600' : 'bg-blue-600'
706
+ }`;
707
+ notification.textContent = message;
708
+ document.body.appendChild(notification);
709
+
710
+ setTimeout(() => {
711
+ notification.remove();
712
+ }, 3000);
713
+ }
714
+
715
+ // Initialize the app when DOM is loaded
716
+ document.addEventListener('DOMContentLoaded', init);
717
+ </script>
718
+ </body>
719
+ </html>