Files
tacticalrmm-web/src/components/logs/DebugLog.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>