276 lines
6.3 KiB
Vue
276 lines
6.3 KiB
Vue
<template>
|
|
<q-card>
|
|
<q-bar v-if="modal">
|
|
<q-btn
|
|
@click="getDebugLog"
|
|
class="q-mr-sm"
|
|
dense
|
|
flat
|
|
push
|
|
icon="refresh"
|
|
/>Debug Log
|
|
<q-space />
|
|
<q-btn dense flat icon="close" v-close-popup>
|
|
<q-tooltip content-class="bg-white text-primary">Close</q-tooltip>
|
|
</q-btn>
|
|
</q-bar>
|
|
<q-table
|
|
:table-class="{
|
|
'table-bgcolor': !$q.dark.isActive,
|
|
'table-bgcolor-dark': $q.dark.isActive,
|
|
}"
|
|
class="tabs-tbl-sticky"
|
|
:style="{
|
|
'max-height': tabHeight ? tabHeight : `${$q.screen.height - 33}px`,
|
|
}"
|
|
:rows="debugLog"
|
|
:columns="columns"
|
|
:title="modal ? 'Debug Logs' : ''"
|
|
:pagination="{ sortBy: 'entry_time', descending: true, rowsPerPage: 0 }"
|
|
:loading="loading"
|
|
:filter="filter"
|
|
virtual-scroll
|
|
dense
|
|
binary-state-sort
|
|
:rows-per-page-options="[0]"
|
|
>
|
|
<template v-slot:top>
|
|
<q-btn
|
|
v-if="agent"
|
|
class="q-pr-sm"
|
|
dense
|
|
flat
|
|
push
|
|
@click="getDebugLog"
|
|
icon="refresh"
|
|
/>
|
|
<tactical-dropdown
|
|
v-if="!agent"
|
|
class="q-pr-sm"
|
|
style="width: 250px"
|
|
v-model="agentFilter"
|
|
label="Agents Filter"
|
|
:options="agentOptions"
|
|
mapOptions
|
|
outlined
|
|
clearable
|
|
filterable
|
|
/>
|
|
<tactical-dropdown
|
|
class="q-pr-sm"
|
|
style="width: 250px"
|
|
v-model="logTypeFilter"
|
|
label="Log Type Filter"
|
|
:options="logTypeOptions"
|
|
mapOptions
|
|
outlined
|
|
clearable
|
|
/>
|
|
<q-radio
|
|
v-model="logLevelFilter"
|
|
color="cyan"
|
|
val="info"
|
|
label="Info"
|
|
/>
|
|
<q-radio
|
|
v-model="logLevelFilter"
|
|
color="red"
|
|
val="critical"
|
|
label="Critical"
|
|
/>
|
|
<q-radio
|
|
v-model="logLevelFilter"
|
|
color="red"
|
|
val="error"
|
|
label="Error"
|
|
/>
|
|
<q-radio
|
|
v-model="logLevelFilter"
|
|
color="yellow"
|
|
val="warning"
|
|
label="Warning"
|
|
/>
|
|
<q-space />
|
|
<q-input
|
|
v-model="filter"
|
|
outlined
|
|
label="Search"
|
|
dense
|
|
clearable
|
|
class="q-pr-sm"
|
|
>
|
|
<template v-slot:prepend>
|
|
<q-icon name="search" color="primary" />
|
|
</template>
|
|
</q-input>
|
|
<export-table-btn :data="debugLog" :columns="columns" />
|
|
</template>
|
|
|
|
<template v-slot:top-row>
|
|
<q-tr v-if="Array.isArray(debugLog) && debugLog.length === 1000">
|
|
<q-td colspan="100%">
|
|
<q-icon name="warning" color="warning" />
|
|
Results are limited to 1000 rows.
|
|
</q-td>
|
|
</q-tr>
|
|
</template>
|
|
|
|
<template v-slot:body-cell-entry_time="props">
|
|
<q-td :props="props">
|
|
{{ formatDate(props.value) }}
|
|
</q-td>
|
|
</template>
|
|
</q-table>
|
|
</q-card>
|
|
</template>
|
|
|
|
<script>
|
|
// composition api
|
|
import { ref, toRef, watch, computed, onMounted } from "vue";
|
|
import { useStore } from "vuex";
|
|
import { useAgentDropdown } from "@/composables/agents";
|
|
import { fetchDebugLog } from "@/api/logs";
|
|
import { formatTableColumnText } from "@/utils/format";
|
|
|
|
// ui components
|
|
import TacticalDropdown from "@/components/ui/TacticalDropdown";
|
|
import ExportTableBtn from "@/components/ui/ExportTableBtn.vue";
|
|
|
|
// static data
|
|
const logTypeOptions = [
|
|
{ label: "Agent Update", value: "agent_update" },
|
|
{ label: "Agent Issues", value: "agent_issues" },
|
|
{ label: "Windows Updates", value: "windows_updates" },
|
|
{ label: "System Issues", value: "system_issues" },
|
|
{ label: "Scripting", value: "scripting" },
|
|
];
|
|
|
|
const columns = [
|
|
{
|
|
name: "entry_time",
|
|
label: "Time",
|
|
field: "entry_time",
|
|
align: "left",
|
|
sortable: true,
|
|
},
|
|
{
|
|
name: "log_level",
|
|
label: "Log Level",
|
|
field: "log_level",
|
|
align: "left",
|
|
sortable: true,
|
|
},
|
|
{
|
|
name: "agent",
|
|
label: "Agent",
|
|
field: "agent",
|
|
align: "left",
|
|
sortable: true,
|
|
},
|
|
{
|
|
name: "log_type",
|
|
label: "Log Type",
|
|
field: "log_type",
|
|
align: "left",
|
|
sortable: true,
|
|
format: (val) => formatTableColumnText(val),
|
|
},
|
|
{
|
|
name: "message",
|
|
label: "Message",
|
|
field: "message",
|
|
align: "left",
|
|
sortable: true,
|
|
},
|
|
];
|
|
|
|
export default {
|
|
name: "LogModal",
|
|
components: {
|
|
TacticalDropdown,
|
|
ExportTableBtn,
|
|
},
|
|
props: {
|
|
agent: String,
|
|
tabHeight: String,
|
|
modal: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
},
|
|
setup(props) {
|
|
// setup vuex
|
|
const store = useStore();
|
|
|
|
const formatDate = computed(() => store.getters.formatDate);
|
|
|
|
// setup dropdowns
|
|
const { agentOptions, getAgentOptions } = useAgentDropdown();
|
|
|
|
// set main debug log functionality
|
|
const debugLog = ref([]);
|
|
const agentFilter = props.agent ? toRef(props, "agent") : ref(null);
|
|
const logLevelFilter = ref("info");
|
|
const logTypeFilter = ref(null);
|
|
const loading = ref(false);
|
|
const filter = ref("");
|
|
|
|
async function getDebugLog() {
|
|
loading.value = true;
|
|
try {
|
|
const data = {
|
|
logLevelFilter: logLevelFilter.value,
|
|
};
|
|
if (agentFilter.value) data["agentFilter"] = agentFilter.value;
|
|
if (logTypeFilter.value) data["logTypeFilter"] = logTypeFilter.value;
|
|
|
|
debugLog.value = await fetchDebugLog(data);
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
loading.value = false;
|
|
}
|
|
|
|
if (props.agent) {
|
|
watch(
|
|
() => props.agent,
|
|
(newValue) => {
|
|
if (newValue) {
|
|
agentFilter.value = props.agent;
|
|
getDebugLog();
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
// watchers
|
|
watch([logLevelFilter, agentFilter, logTypeFilter], getDebugLog);
|
|
|
|
// vue component hooks
|
|
onMounted(() => {
|
|
if (!props.agent) getAgentOptions();
|
|
getDebugLog();
|
|
});
|
|
|
|
return {
|
|
// data
|
|
debugLog,
|
|
logLevelFilter,
|
|
logTypeFilter,
|
|
agentFilter,
|
|
agentOptions,
|
|
loading,
|
|
filter,
|
|
|
|
// non-reactive data
|
|
columns,
|
|
logTypeOptions,
|
|
|
|
// methods
|
|
getDebugLog,
|
|
formatDate,
|
|
};
|
|
},
|
|
};
|
|
</script>
|