|
6 | 6 | fullscreen: false, |
7 | 7 | alwaysScroll: false, |
8 | 8 | intervalId: null, |
| 9 | + colorLogs: localStorage.getItem('coolify-color-logs') === 'true', |
9 | 10 | searchQuery: '', |
10 | 11 | renderTrigger: 0, |
11 | 12 | containerName: '{{ $container ?? "logs" }}', |
|
44 | 45 | this.intervalId = null; |
45 | 46 | } |
46 | 47 | }, |
| 48 | + toggleColorLogs() { |
| 49 | + this.colorLogs = !this.colorLogs; |
| 50 | + localStorage.setItem('coolify-color-logs', this.colorLogs); |
| 51 | + }, |
| 52 | + getLogLevel(text) { |
| 53 | + const lowerText = text.toLowerCase(); |
| 54 | + // Error detection (highest priority) |
| 55 | + if (/\b(error|err|failed|failure|exception|fatal|panic|critical)\b/.test(lowerText)) { |
| 56 | + return 'error'; |
| 57 | + } |
| 58 | + // Warning detection |
| 59 | + if (/\b(warn|warning|wrn|caution)\b/.test(lowerText)) { |
| 60 | + return 'warning'; |
| 61 | + } |
| 62 | + // Debug detection |
| 63 | + if (/\b(debug|dbg|trace|verbose)\b/.test(lowerText)) { |
| 64 | + return 'debug'; |
| 65 | + } |
| 66 | + // Info detection |
| 67 | + if (/\b(info|inf|notice)\b/.test(lowerText)) { |
| 68 | + return 'info'; |
| 69 | + } |
| 70 | + return null; |
| 71 | + }, |
47 | 72 | matchesSearch(line) { |
48 | 73 | if (!this.searchQuery.trim()) return true; |
49 | 74 | return line.toLowerCase().includes(this.searchQuery.toLowerCase()); |
@@ -174,7 +199,7 @@ class="flex items-center justify-between gap-2 px-4 py-2 border-b dark:border-co |
174 | 199 | class="absolute left-2 top-1/2 -translate-y-1/2 text-xs text-gray-400 pointer-events-none">Lines:</span> |
175 | 200 | <input type="number" wire:model="numberOfLines" placeholder="100" min="1" |
176 | 201 | title="Number of Lines" {{ $streamLogs ? 'readonly' : '' }} |
177 | | - class="input input-sm w-24 pl-11 text-center dark:bg-coolgray-300" /> |
| 202 | + class="input input-sm w-32 pl-11 text-center dark:bg-coolgray-300" /> |
178 | 203 | </form> |
179 | 204 | <span x-show="searchQuery.trim()" x-text="getMatchCount() + ' matches'" |
180 | 205 | class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap"></span> |
@@ -221,6 +246,15 @@ class="p-1 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text- |
221 | 246 | d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" /> |
222 | 247 | </svg> |
223 | 248 | </button> |
| 249 | + <button title="Toggle Log Colors" x-on:click="toggleColorLogs" |
| 250 | + :class="colorLogs ? '!text-warning' : ''" |
| 251 | + class="p-1 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"> |
| 252 | + <svg class="w-4 h-4" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none" |
| 253 | + stroke="currentColor" stroke-width="1.5"> |
| 254 | + <path stroke-linecap="round" stroke-linejoin="round" |
| 255 | + d="M9.53 16.122a3 3 0 0 0-5.78 1.128 2.25 2.25 0 0 1-2.4 2.245 4.5 4.5 0 0 0 8.4-2.245c0-.399-.078-.78-.22-1.128Zm0 0a15.998 15.998 0 0 0 3.388-1.62m-5.043-.025a15.994 15.994 0 0 1 1.622-3.395m3.42 3.42a15.995 15.995 0 0 0 4.764-4.648l3.876-5.814a1.151 1.151 0 0 0-1.597-1.597L14.146 6.32a15.996 15.996 0 0 0-4.649 4.763m3.42 3.42a6.776 6.776 0 0 0-3.42-3.42" /> |
| 256 | + </svg> |
| 257 | + </button> |
224 | 258 | <button wire:click="toggleStreamLogs" |
225 | 259 | title="{{ $streamLogs ? 'Stop Streaming' : 'Stream Logs' }}" |
226 | 260 | class="p-1 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 {{ $streamLogs ? '!text-warning' : '' }}"> |
@@ -303,8 +337,14 @@ class="text-gray-500 dark:text-gray-400 py-2"> |
303 | 337 |
|
304 | 338 | @endphp |
305 | 339 | <div data-log-line data-log-content="{{ $line }}" |
306 | | - x-bind:class="{ 'hidden': !matchesSearch($el.dataset.logContent) }" |
307 | | - class="flex gap-2 hover:bg-gray-100 dark:hover:bg-coolgray-500"> |
| 340 | + x-bind:class="{ |
| 341 | + 'hidden': !matchesSearch($el.dataset.logContent), |
| 342 | + 'bg-red-500/10 dark:bg-red-500/15': colorLogs && getLogLevel($el.dataset.logContent) === 'error', |
| 343 | + 'bg-yellow-500/10 dark:bg-yellow-500/15': colorLogs && getLogLevel($el.dataset.logContent) === 'warning', |
| 344 | + 'bg-purple-500/10 dark:bg-purple-500/15': colorLogs && getLogLevel($el.dataset.logContent) === 'debug', |
| 345 | + 'bg-blue-500/10 dark:bg-blue-500/15': colorLogs && getLogLevel($el.dataset.logContent) === 'info', |
| 346 | + }" |
| 347 | + class="flex gap-2"> |
308 | 348 | @if ($timestamp && $showTimeStamps) |
309 | 349 | <span class="shrink-0 text-gray-500">{{ $timestamp }}</span> |
310 | 350 | @endif |
|
0 commit comments