feat(ui): add log filter based on log level (#8784)
This commit is contained in:
commit
2b65eaa2b4
1 changed files with 65 additions and 10 deletions
|
|
@ -8,6 +8,7 @@
|
|||
rafId: null,
|
||||
scrollDebounce: null,
|
||||
colorLogs: localStorage.getItem('coolify-color-logs') === 'true',
|
||||
logFilters: JSON.parse(localStorage.getItem('coolify-log-filters')) || {error: true, warning: true, debug: true, info: true},
|
||||
searchQuery: '',
|
||||
matchCount: 0,
|
||||
containerName: '{{ $container ?? "logs" }}',
|
||||
|
|
@ -70,6 +71,17 @@
|
|||
}
|
||||
}, 150);
|
||||
},
|
||||
getLogLevel(content) {
|
||||
if (/\b(error|err|failed|failure|exception|fatal|panic|critical)\b/.test(content)) return 'error';
|
||||
if (/\b(warn|warning|wrn|caution)\b/.test(content)) return 'warning';
|
||||
if (/\b(debug|dbg|trace|verbose)\b/.test(content)) return 'debug';
|
||||
return 'info';
|
||||
},
|
||||
toggleLogFilter(level) {
|
||||
this.logFilters[level] = !this.logFilters[level];
|
||||
localStorage.setItem('coolify-log-filters', JSON.stringify(this.logFilters));
|
||||
this.applySearch();
|
||||
},
|
||||
toggleColorLogs() {
|
||||
this.colorLogs = !this.colorLogs;
|
||||
localStorage.setItem('coolify-color-logs', this.colorLogs);
|
||||
|
|
@ -81,17 +93,11 @@
|
|||
const lines = logs.querySelectorAll('[data-log-line]');
|
||||
lines.forEach(line => {
|
||||
const content = (line.dataset.logContent || '').toLowerCase();
|
||||
const level = this.getLogLevel(content);
|
||||
line.dataset.logLevel = level;
|
||||
line.classList.remove('log-error', 'log-warning', 'log-debug', 'log-info');
|
||||
if (!this.colorLogs) return;
|
||||
if (/\b(error|err|failed|failure|exception|fatal|panic|critical)\b/.test(content)) {
|
||||
line.classList.add('log-error');
|
||||
} else if (/\b(warn|warning|wrn|caution)\b/.test(content)) {
|
||||
line.classList.add('log-warning');
|
||||
} else if (/\b(debug|dbg|trace|verbose)\b/.test(content)) {
|
||||
line.classList.add('log-debug');
|
||||
} else if (/\b(info|inf|notice)\b/.test(content)) {
|
||||
line.classList.add('log-info');
|
||||
}
|
||||
line.classList.add('log-' + level);
|
||||
});
|
||||
},
|
||||
hasActiveLogSelection() {
|
||||
|
|
@ -118,7 +124,10 @@
|
|||
lines.forEach(line => {
|
||||
const content = (line.dataset.logContent || '').toLowerCase();
|
||||
const textSpan = line.querySelector('[data-line-text]');
|
||||
const matches = !query || content.includes(query);
|
||||
const level = line.dataset.logLevel || this.getLogLevel(content);
|
||||
const passesFilter = this.logFilters[level] !== false;
|
||||
const matchesSearch = !query || content.includes(query);
|
||||
const matches = passesFilter && matchesSearch;
|
||||
|
||||
line.classList.toggle('hidden', !matches);
|
||||
if (matches && query) count++;
|
||||
|
|
@ -389,6 +398,52 @@ class="p-1 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-
|
|||
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" />
|
||||
</svg>
|
||||
</button>
|
||||
<div x-data="{ filterOpen: false }" class="relative">
|
||||
<button x-on:click="filterOpen = !filterOpen" title="Filter Log Levels"
|
||||
:class="Object.values(logFilters).some(v => !v) ? '!text-warning' : ''"
|
||||
class="p-1 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200">
|
||||
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
||||
stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 0 1-.659 1.591l-5.432 5.432a2.25 2.25 0 0 0-.659 1.591v2.927a2.25 2.25 0 0 1-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 0 0-.659-1.591L3.659 7.409A2.25 2.25 0 0 1 3 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0 1 12 3Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div x-show="filterOpen" x-on:click.away="filterOpen = false"
|
||||
x-transition:enter="transition ease-out duration-100"
|
||||
x-transition:enter-start="transform opacity-0 scale-95"
|
||||
x-transition:enter-end="transform opacity-100 scale-100"
|
||||
x-transition:leave="transition ease-in duration-75"
|
||||
x-transition:leave-start="transform opacity-100 scale-100"
|
||||
x-transition:leave-end="transform opacity-0 scale-95"
|
||||
class="absolute right-0 z-50 mt-2 w-max origin-top-right rounded-md bg-white dark:bg-coolgray-200 shadow-lg ring-1 ring-neutral-200 dark:ring-coolgray-300 focus:outline-none">
|
||||
<div class="py-1">
|
||||
<label class="flex items-center gap-2 px-4 py-1.5 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-coolgray-300 cursor-pointer select-none">
|
||||
<input type="checkbox" :checked="logFilters.error" x-on:change="toggleLogFilter('error')"
|
||||
class="rounded border-gray-300 dark:border-gray-600 text-warning focus:ring-warning dark:bg-coolgray-300" />
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-red-500"></span>
|
||||
Error
|
||||
</label>
|
||||
<label class="flex items-center gap-2 px-4 py-1.5 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-coolgray-300 cursor-pointer select-none">
|
||||
<input type="checkbox" :checked="logFilters.warning" x-on:change="toggleLogFilter('warning')"
|
||||
class="rounded border-gray-300 dark:border-gray-600 text-warning focus:ring-warning dark:bg-coolgray-300" />
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-yellow-500"></span>
|
||||
Warning
|
||||
</label>
|
||||
<label class="flex items-center gap-2 px-4 py-1.5 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-coolgray-300 cursor-pointer select-none">
|
||||
<input type="checkbox" :checked="logFilters.debug" x-on:change="toggleLogFilter('debug')"
|
||||
class="rounded border-gray-300 dark:border-gray-600 text-warning focus:ring-warning dark:bg-coolgray-300" />
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-purple-500"></span>
|
||||
Debug
|
||||
</label>
|
||||
<label class="flex items-center gap-2 px-4 py-1.5 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-coolgray-300 cursor-pointer select-none">
|
||||
<input type="checkbox" :checked="logFilters.info" x-on:change="toggleLogFilter('info')"
|
||||
class="rounded border-gray-300 dark:border-gray-600 text-warning focus:ring-warning dark:bg-coolgray-300" />
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-blue-500"></span>
|
||||
Info
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button title="Follow Logs" :class="alwaysScroll ? '!text-warning' : ''"
|
||||
x-on:click="toggleScroll"
|
||||
class="p-1 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200">
|
||||
|
|
|
|||
Loading…
Reference in a new issue