mirror of
https://github.com/garraflavatra/rolens.git
synced 2025-01-18 13:07:58 +00:00
Add filter functionality
This commit is contained in:
parent
30b65a198f
commit
93b2d67cef
@ -2,8 +2,10 @@ import { ObjectId } from 'bson';
|
|||||||
import aggregationStages from './aggregation-stages.json';
|
import aggregationStages from './aggregation-stages.json';
|
||||||
import atomicUpdateOperators from './atomic-update-operators.json';
|
import atomicUpdateOperators from './atomic-update-operators.json';
|
||||||
import locales from './locales.json';
|
import locales from './locales.json';
|
||||||
|
import logComponents from './log-components.json';
|
||||||
|
import logLevels from './loglevels.json';
|
||||||
|
|
||||||
export { aggregationStages, atomicUpdateOperators, locales };
|
export { aggregationStages, atomicUpdateOperators, locales, logComponents, logLevels };
|
||||||
|
|
||||||
// Calculate the min and max values of (un)signed integers with n bits
|
// Calculate the min and max values of (un)signed integers with n bits
|
||||||
export const intMin = bits => Math.pow(2, bits - 1) * -1;
|
export const intMin = bits => Math.pow(2, bits - 1) * -1;
|
||||||
|
36
frontend/src/lib/mongo/log-components.json
Normal file
36
frontend/src/lib/mongo/log-components.json
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
[
|
||||||
|
"ACCESS",
|
||||||
|
"COMMAND",
|
||||||
|
"CONTROL",
|
||||||
|
"ELECTION",
|
||||||
|
"FTDC",
|
||||||
|
"GEO",
|
||||||
|
"INDEX",
|
||||||
|
"INITSYNC",
|
||||||
|
"JOURNAL",
|
||||||
|
"NETWORK",
|
||||||
|
"QUERY",
|
||||||
|
"RECOVERY",
|
||||||
|
"REPL",
|
||||||
|
"REPL_HB",
|
||||||
|
"ROLLBACK",
|
||||||
|
"SHARDING",
|
||||||
|
"STORAGE",
|
||||||
|
"TXN",
|
||||||
|
"WRITE",
|
||||||
|
"WT",
|
||||||
|
"WTBACKUP",
|
||||||
|
"WTCHKPT",
|
||||||
|
"WTCMPCT",
|
||||||
|
"WTEVICT",
|
||||||
|
"WTHS",
|
||||||
|
"WTRECOV",
|
||||||
|
"WTRTS",
|
||||||
|
"WTSLVG",
|
||||||
|
"WTTIER",
|
||||||
|
"WTTS",
|
||||||
|
"WTTXN",
|
||||||
|
"WTVRFY",
|
||||||
|
"WTWRTLOG",
|
||||||
|
"-"
|
||||||
|
]
|
7
frontend/src/lib/mongo/loglevels.json
Normal file
7
frontend/src/lib/mongo/loglevels.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"F": "Fatal",
|
||||||
|
"E": "Error",
|
||||||
|
"W": "Warning",
|
||||||
|
"I": "Info",
|
||||||
|
"D": "Debug"
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
import Icon from '$components/icon.svelte';
|
import Icon from '$components/icon.svelte';
|
||||||
import ObjectViewer from '$components/objectviewer.svelte';
|
import ObjectViewer from '$components/objectviewer.svelte';
|
||||||
import input from '$lib/actions/input';
|
import input from '$lib/actions/input';
|
||||||
|
import { logComponents, logLevels } from '$lib/mongo';
|
||||||
import { BrowserOpenURL } from '$wails/runtime/runtime';
|
import { BrowserOpenURL } from '$wails/runtime/runtime';
|
||||||
import { onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
|
|
||||||
@ -10,6 +11,8 @@
|
|||||||
|
|
||||||
const autoReloadIntervals = [ 1, 2, 5, 10, 30, 60 ];
|
const autoReloadIntervals = [ 1, 2, 5, 10, 30, 60 ];
|
||||||
let filter = 'global';
|
let filter = 'global';
|
||||||
|
let severityFilter = '';
|
||||||
|
let componentFilter = '';
|
||||||
let logs;
|
let logs;
|
||||||
let total = 0;
|
let total = 0;
|
||||||
let error = '';
|
let error = '';
|
||||||
@ -17,7 +20,7 @@
|
|||||||
let autoReloadInterval = 0;
|
let autoReloadInterval = 0;
|
||||||
let objectViewerData;
|
let objectViewerData;
|
||||||
let interval;
|
let interval;
|
||||||
$: filter && refresh();
|
$: (filter || severityFilter || componentFilter) && refresh();
|
||||||
$: busy = !logs && !error && 'Requesting logs…';
|
$: busy = !logs && !error && 'Requesting logs…';
|
||||||
|
|
||||||
$: if (autoReloadInterval) {
|
$: if (autoReloadInterval) {
|
||||||
@ -30,12 +33,19 @@
|
|||||||
async function refresh() {
|
async function refresh() {
|
||||||
let _logs = [];
|
let _logs = [];
|
||||||
({ logs: _logs, total, error } = await host.getLogs(filter));
|
({ logs: _logs, total, error } = await host.getLogs(filter));
|
||||||
|
|
||||||
logs = [];
|
logs = [];
|
||||||
|
|
||||||
for (let index = 0; index < _logs.length; index++) {
|
for (let index = 0; index < _logs.length; index++) {
|
||||||
const log = JSON.parse(_logs[index]);
|
const log = JSON.parse(_logs[index]);
|
||||||
log._index = index;
|
|
||||||
logs = [ ...logs, log ];
|
const matchesLevel = severityFilter ? log.s?.startsWith(severityFilter) : true;
|
||||||
|
const matchesComponent = componentFilter ? (componentFilter === log.c?.toUpperCase()) : true;
|
||||||
|
|
||||||
|
if (matchesLevel && matchesComponent) {
|
||||||
|
log._index = index;
|
||||||
|
log.s = logLevels[log.s] || log.s;
|
||||||
|
logs = [ ...logs, log ];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +72,46 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="stats">
|
<div class="stats">
|
||||||
|
<div class="formrow">
|
||||||
|
<label class="field">
|
||||||
|
<span class="label">Auto reload (seconds)</span>
|
||||||
|
<input type="number" class="autoreloadinput" bind:value={autoReloadInterval} list="autoreloadintervals" use:input />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="field">
|
||||||
|
<span class="label">Log type</span>
|
||||||
|
<select bind:value={filter}>
|
||||||
|
<option value="global">Global</option>
|
||||||
|
<option value="startupWarnings">Startup warnings</option>
|
||||||
|
</select>
|
||||||
|
<button class="button secondary" on:click={openFilterDocs} title="Documentation">
|
||||||
|
<Icon name="?" />
|
||||||
|
</button>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="formrow">
|
||||||
|
<label class="field">
|
||||||
|
<span class="label">Severity</span>
|
||||||
|
<select bind:value={severityFilter}>
|
||||||
|
<option value="">All</option>
|
||||||
|
{#each Object.entries(logLevels) as [ value, name ]}
|
||||||
|
<option {value}>{value} ({name})</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="field">
|
||||||
|
<span class="label">Component</span>
|
||||||
|
<select bind:value={componentFilter}>
|
||||||
|
<option value="">All</option>
|
||||||
|
{#each logComponents as value}
|
||||||
|
<option {value}>{value}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<Grid
|
<Grid
|
||||||
items={logs || []}
|
items={logs || []}
|
||||||
@ -83,33 +133,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<div>
|
<button class="button" on:click={refresh}>
|
||||||
<div class="field inline">
|
<Icon name="reload" spin={busy} /> Reload
|
||||||
<button class="button" on:click={refresh}>
|
</button>
|
||||||
<Icon name="reload" spin={busy} /> Reload
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button class="button secondary" on:click={copy} disabled={!host.status}>
|
<button class="button secondary" on:click={copy} disabled={!host.status}>
|
||||||
<Icon name={copySucceeded ? 'check' : 'clipboard'} />
|
<Icon name={copySucceeded ? 'check' : 'clipboard'} />
|
||||||
Copy JSON
|
Copy JSON
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
|
|
||||||
<label class="field inline">
|
|
||||||
<span class="label">Reload (sec)</span>
|
|
||||||
<input type="number" class="autoreloadinput" bind:value={autoReloadInterval} list="autoreloadintervals" use:input />
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label class="field inline">
|
|
||||||
<select bind:value={filter}>
|
|
||||||
<option value="global">Global</option>
|
|
||||||
<option value="startupWarnings">Startup warnings</option>
|
|
||||||
</select>
|
|
||||||
<button class="button secondary" on:click={openFilterDocs} title="Documentation">
|
|
||||||
<Icon name="?" />
|
|
||||||
</button>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if total}
|
{#if total}
|
||||||
<div class="total">
|
<div class="total">
|
||||||
@ -133,10 +164,16 @@
|
|||||||
.stats {
|
.stats {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
grid-template: 1fr auto / 1fr;
|
grid-template: auto auto 1fr auto / 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats .grid {
|
.formrow {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.5rem;
|
||||||
|
grid-template: 1fr / 1fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
@ -146,7 +183,7 @@
|
|||||||
.controls {
|
.controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.1rem;
|
gap: 0.2rem;
|
||||||
}
|
}
|
||||||
.total {
|
.total {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
Loading…
Reference in New Issue
Block a user