Bhargav
2024-01-24 15:27:14 +05:30
committed by GitHub
parent e8fae7824e
commit 3a90f0f316
7 changed files with 294 additions and 170 deletions
@@ -90,7 +90,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
content-class="tab_content"
/>
<q-route-tab
v-if="showCloudIngestionOptions"
name="kinesisfirehose"
:to="{
name: 'kinesisfirehose',
@@ -103,7 +102,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
content-class="tab_content"
/>
<q-route-tab
v-if="showCloudIngestionOptions"
name="gcpLogs"
:to="{
name: 'gcpLogs',
@@ -274,12 +274,13 @@ const useIngestionRoutes = () => {
.find((child: any) => child.name === "custom")
.children.find((child: any) => child.name === "ingestLogs")
?.children.push(...[sysLog, sysLogNg]);
} else {
ingestionRoutes[0].children
.find((child: any) => child.name === "custom")
.children.find((child: any) => child.name === "ingestLogs")
?.children.push(...[kinesisFirehose, gcpPubSub]);
}
ingestionRoutes[0].children
.find((child: any) => child.name === "custom")
.children.find((child: any) => child.name === "ingestLogs")
?.children.push(...[kinesisFirehose, gcpPubSub]);
return ingestionRoutes;
};
+69 -35
View File
@@ -52,7 +52,8 @@ import { start } from "repl";
const defaultObject = {
organizationIdetifier: "",
runQuery: false,
loading: true,
loading: false,
loadingHistogram: false,
config: {
splitterModel: 20,
lastSplitterPosition: 0,
@@ -136,7 +137,15 @@ const defaultObject = {
queryResults: <any>[],
sortedQueryResults: <any>[],
streamResults: <any>[],
histogram: <any>{},
histogram: <any>{
xData: [],
yData: [],
chartParams: {
title: "",
unparsed_x_data: [],
timezone: "",
},
},
editorValue: <any>"",
datetime: <any>{
startTime: 0,
@@ -156,11 +165,13 @@ const defaultObject = {
tempFunctionLoading: false,
savedViews: <any>[],
customDownloadQueryObj: <any>{},
functionError: "",
},
};
const searchObj = reactive(Object.assign({}, defaultObject));
const useLogs = () => {
const searchObj = reactive(Object.assign({}, defaultObject));
const store = useStore();
const { t } = useI18n();
const $q = useQuasar();
@@ -185,7 +196,11 @@ const useLogs = () => {
searchObj.data.histogram = {
xData: [],
yData: [],
chartParams: {},
chartParams: {
title: "",
unparsed_x_data: [],
timezone: "",
},
};
searchObj.data.tempFunctionContent = "";
searchObj.data.query = "";
@@ -261,14 +276,14 @@ const useLogs = () => {
}
function resetQueryData() {
searchObj.data.queryResults = {};
// searchObj.data.queryResults = {};
searchObj.data.sortedQueryResults = [];
searchObj.data.histogram = {
xData: [],
yData: [],
chartParams: {},
};
searchObj.data.resultGrid.columns = [];
// searchObj.data.histogram = {
// xData: [],
// yData: [],
// chartParams: {},
// };
// searchObj.data.resultGrid.columns = [];
searchObj.data.resultGrid.currentPage = 1;
searchObj.runQuery = false;
searchObj.data.errorMsg = "";
@@ -487,7 +502,6 @@ const useLogs = () => {
//replace backticks with \" for sql_mode
query = query.replace(/`/g, '"');
searchObj.loading = true;
searchObj.data.queryResults.hits = [];
searchObj.data.queryResults.total = 0;
}
@@ -571,11 +585,18 @@ const useLogs = () => {
searchObj.meta.showHistogram === false
) {
delete req.aggs;
req.query.track_total_hits = true;
if (searchObj.meta.showHistogram === false) {
// delete searchObj.data.histogram;
searchObj.data.histogram = { xData: [], yData: [], chartParams: {} };
searchObj.data.histogram = {
xData: [],
yData: [],
chartParams: {
title: "",
unparsed_x_data: [],
timezone: "",
},
};
searchObj.meta.histogramDirtyFlag = true;
} else {
searchObj.meta.histogramDirtyFlag = false;
@@ -603,7 +624,7 @@ const useLogs = () => {
const getQueryData = (isPagination = false) => {
return new Promise((resolve, reject) => {
let dismiss = () => {};
const dismiss = () => {};
try {
searchObj.meta.showDetailTab = false;
@@ -638,7 +659,7 @@ const useLogs = () => {
);
}
if (isPagination) dismiss = showNotification();
// if (isPagination) dismiss = showNotification();
if (searchObj.data.datetime.type === "relative") {
if (!isPagination) initialQueryPayload.value = cloneDeep(queryReq);
@@ -682,7 +703,8 @@ const useLogs = () => {
if (
searchObj.meta.refreshInterval > 0 &&
router.currentRoute.value.name == "logs" &&
searchObj.data.queryResults.hasOwnProperty("hits")
searchObj.data.queryResults.hasOwnProperty("hits") &&
searchObj.data.queryResults.hits.length > 0
) {
searchObj.data.queryResults.from = res.data.from;
searchObj.data.queryResults.scan_size = res.data.scan_size;
@@ -691,17 +713,17 @@ const useLogs = () => {
const lastRecordTimeStamp = parseInt(
searchObj.data.queryResults.hits[0]._timestamp
);
// searchObj.data.queryResults.hits = res.data.hits;
for (let i = 0; i < res.data.hits.length; i++) {
if (
lastRecordTimeStamp <
parseInt(res.data.hits[i]._timestamp)
) {
searchObj.data.queryResults.hits.unshift(
res.data.hits[i]
);
}
}
searchObj.data.queryResults.hits = res.data.hits;
// for (let i = 0; i < res.data.hits.length; i++) {
// if (
// lastRecordTimeStamp <
// parseInt(res.data.hits[i]._timestamp)
// ) {
// searchObj.data.queryResults.hits.unshift(
// res.data.hits[i]
// );
// }
// }
// searchObj.data.queryResults.hits =
// searchObj.data.queryResults.hits.splice(0, 150);
@@ -732,9 +754,19 @@ const useLogs = () => {
// disabled histogram case, generate histogram histogram title
if (
searchObj.data.resultGrid.currentPage == 1 &&
(searchObj.meta.showHistogram === false || searchObj.meta.sqlMode)
(searchObj.meta.showHistogram === false ||
searchObj.meta.sqlMode)
) {
searchObj.data.histogram.chartParams.title = getHistogramTitle();
searchObj.data.histogram.chartParams.title =
getHistogramTitle();
}
searchObj.data.functionError = "";
if (
res.data.hasOwnProperty("function_error") &&
res.data.function_error
) {
searchObj.data.functionError = res.data.function_error;
}
searchObj.loading = false;
@@ -775,6 +807,7 @@ const useLogs = () => {
return new Promise((resolve, reject) => {
const dismiss = () => {};
try {
searchObj.loadingHistogram = true;
queryReq.query.size = 0;
queryReq.query.track_total_hits = true;
searchService
@@ -784,17 +817,18 @@ const useLogs = () => {
page_type: searchObj.data.stream.streamType,
})
.then((res) => {
dismiss();
searchObj.loading = false;
searchObj.data.errorMsg = "";
searchObj.data.queryResults.aggs = res.data.aggs;
searchObj.data.queryResults.total = res.data.total;
generateHistogramData();
// searchObj.data.histogram.chartParams.title = getHistogramTitle();
searchObj.loading = false;
searchObj.loadingHistogram = false;
dismiss();
resolve(true);
})
.catch((err) => {
searchObj.loading = false;
searchObj.loadingHistogram = false;
if (err.response != undefined) {
searchObj.data.errorMsg = err.response.data.error;
} else {
@@ -812,7 +846,7 @@ const useLogs = () => {
});
} catch (e: any) {
dismiss();
searchObj.loading = false;
searchObj.loadingHistogram = false;
showErrorNotification("Error while fetching histogram data");
reject(false);
}
@@ -1183,7 +1217,7 @@ const useLogs = () => {
) {
clearInterval(store.state.refreshIntervalID);
const refreshIntervalID = setInterval(async () => {
// searchObj.loading = true;
searchObj.loading = true;
await getQueryData(false);
generateHistogramData();
updateGridColumns();
+3 -1
View File
@@ -92,7 +92,9 @@
"initialNumber": "Initial Number",
"range": "No of Records",
"btnDownload": "Download",
"customDownloadMessage": "Enter the initial number and select the range for downloading data."
"customDownloadMessage": "Enter the initial number and select the range for downloading data.",
"noRecordFound": "No Record Found",
"functionErrorLabel": "Function not applied: (expand for more details)"
},
"menu": {
"home": "Home",
+79 -102
View File
@@ -85,110 +85,90 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</template>
<template #after>
<div
class="full-height flex justify-center items-center"
v-if="searchObj.loading == true"
v-if="
searchObj.data.errorMsg !== '' && searchObj.loading == false
"
>
<div class="q-pb-lg">
<q-spinner-hourglass
data-test="logs-search-loading-spinner"
color="primary"
size="40px"
style="margin: 0 auto; display: block"
/>
<span class="text-center">
Hold on tight, we're fetching your logs.
</span>
</div>
<h5 class="text-center">
<div
data-test="logs-search-result-not-found-text"
v-if="searchObj.data.errorCode == 0"
>
Result not found.
</div>
<div
data-test="logs-search-error-message"
v-html="searchObj.data.errorMsg"
></div>
<div
data-test="logs-search-error-20003"
v-if="parseInt(searchObj.data.errorCode) == 20003"
>
<q-btn
no-caps
unelevated
size="sm"
bg-secondary
class="no-border bg-secondary text-white"
:to="
'/streams?dialog=' +
searchObj.data.stream.selectedStream.label
"
>Click here</q-btn
>
to configure a full text search field to the stream.
</div>
<br />
<q-item-label>{{
searchObj.data.additionalErrorMsg
}}</q-item-label>
</h5>
</div>
<div
v-else-if="!areStreamsPresent && searchObj.loading == false"
v-else-if="
searchObj.data.stream.selectedStream.label == '' &&
searchObj.loading == false
"
>
<h5
data-test="logs-search-no-stream-selected-text"
class="text-center"
>
<q-icon
name="warning"
color="warning"
size="10rem"
/><br />No stream selected.
</h5>
</div>
<div
v-else-if="
searchObj.data.queryResults.hasOwnProperty('hits') &&
searchObj.data.queryResults.hits.length == 0 &&
searchObj.loading == false
"
>
<h5 data-test="logs-search-error-message" class="text-center">
<q-icon
name="warning"
color="warning"
size="10rem"
/><br />{{ searchObj.data.errorMsg }}
/><br />{{ t("search.noRecordFound") }}
</h5>
</div>
<template v-else>
<div
v-if="
searchObj.data.errorMsg !== '' &&
searchObj.loading == false
"
>
<h5 class="text-center">
<div
data-test="logs-search-result-not-found-text"
v-if="searchObj.data.errorCode == 0"
>
Result not found.
</div>
<div
data-test="logs-search-error-message"
v-html="searchObj.data.errorMsg"
></div>
<div
data-test="logs-search-error-20003"
v-if="parseInt(searchObj.data.errorCode) == 20003"
>
<q-btn
no-caps
unelevated
size="sm"
bg-secondary
class="no-border bg-secondary text-white"
:to="
'/streams?dialog=' +
searchObj.data.stream.selectedStream.label
"
>Click here</q-btn
>
to configure a full text search field to the stream.
</div>
<br />
<q-item-label>{{
searchObj.data.additionalErrorMsg
}}</q-item-label>
</h5>
</div>
<div
v-else-if="searchObj.data.stream.selectedStream.label == ''"
>
<h5
data-test="logs-search-no-stream-selected-text"
class="text-center"
>
No stream selected.
</h5>
</div>
<div
v-else-if="
searchObj.data.queryResults.hasOwnProperty('total') &&
searchObj.data.queryResults.hits.length == 0 &&
searchObj.loading == false
"
>
<h5 class="text-center">No result found.</h5>
</div>
<div
data-test="logs-search-search-result"
class="full-height"
v-show="
searchObj.data.queryResults.hasOwnProperty('total') &&
searchObj.data.queryResults.hits.length !== 0
"
>
<search-result
ref="searchResultRef"
:expandedLogs="expandedLogs"
@update:datetime="setHistogramDate"
@update:scroll="getMoreData"
@expandlog="toggleExpandLog"
/>
</div>
</template>
<div
v-else
data-test="logs-search-search-result"
class="full-height"
>
<search-result
ref="searchResultRef"
:expandedLogs="expandedLogs"
@update:datetime="setHistogramDate"
@update:scroll="getMoreData"
@expandlog="toggleExpandLog"
/>
</div>
</template>
</q-splitter>
</div>
@@ -216,6 +196,7 @@ import {
import { useQuasar } from "quasar";
import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { useI18n } from "vue-i18n";
import SearchBar from "./SearchBar.vue";
import IndexList from "./IndexList.vue";
@@ -265,14 +246,7 @@ export default defineComponent({
async getMoreData() {
if (
this.searchObj.meta.sqlMode == false &&
this.searchObj.meta.refreshInterval == 0 &&
this.searchObj.data.queryResults.total >
this.searchObj.data.queryResults.from &&
this.searchObj.data.queryResults.total >
this.searchObj.data.queryResults.size &&
this.searchObj.data.queryResults.total >
this.searchObj.data.queryResults.size +
this.searchObj.data.queryResults.from
this.searchObj.meta.refreshInterval == 0
) {
// this.searchObj.data.resultGrid.currentPage =
// ((this.searchObj.data.queryResults?.hits?.length || 0) +
@@ -281,7 +255,7 @@ export default defineComponent({
// 1;
// this.searchObj.data.resultGrid.currentPage =
// this.searchObj.data.resultGrid.currentPage + 1;
this.searchObj.loading = true;
await this.getQueryData(true);
this.refreshHistogramChart();
@@ -332,6 +306,7 @@ export default defineComponent({
},
},
setup() {
const { t } = useI18n();
const store = useStore();
const router = useRouter();
const $q = useQuasar();
@@ -416,6 +391,7 @@ export default defineComponent({
});
onBeforeMount(() => {
searchObj.loading = true;
searchObj.organizationIdetifier =
store.state.selectedOrganization.identifier;
restoreUrlQueryParams();
@@ -542,6 +518,7 @@ export default defineComponent({
};
return {
t,
store,
router,
parser,
+72 -8
View File
@@ -328,6 +328,28 @@ clickable v-close-popup>
</q-card-actions>
</q-card>
</q-dialog>
<q-dialog ref="confirmSavedViewDialog" v-model="confirmSavedViewDialogVisible">
<q-card>
<q-card-section>
{{ confirmMessageSavedView }}
</q-card-section>
<q-card-actions align="right">
<q-btn
data-test="logs-search-bar-confirm-dialog-cancel-btn"
:label="t('confirmDialog.cancel')"
color="primary"
@click="cancelConfirmDialog"
/>
<q-btn
data-test="logs-search-bar-confirm-dialog-ok-btn"
:label="t('confirmDialog.ok')"
color="positive"
@click="confirmDialogOK"
/>
</q-card-actions>
</q-card>
</q-dialog>
<q-dialog v-model="customDownloadDialog">
<q-card>
<q-card-section>
@@ -349,6 +371,7 @@ clickable v-close-popup>
filled
dense
tabindex="0"
min="0"
/>
<q-select
data-test="custom-download-range-select"
@@ -376,7 +399,7 @@ clickable v-close-popup>
v-close-popup
/>
<q-btn
unelevated
unelevated
no-caps
class="q-mr-sm text-bold"
data-test="logs-search-bar-confirm-dialog-ok-btn"
@@ -677,6 +700,15 @@ export default defineComponent({
this.customDownloadDialog = true;
},
downloadRangeData() {
if (this.downloadCustomInitialNumber < 0) {
this.$q.notify({
message: "Initial number must be positive number.",
color: "negative",
position: "top",
timeout: 2000,
});
return;
}
// const queryReq = this.buildSearch();
// console.log(this.searchObj.data.customDownloadQueryObj)
this.searchObj.data.customDownloadQueryObj.query.from = parseInt(
@@ -692,7 +724,16 @@ export default defineComponent({
})
.then((res) => {
this.customDownloadDialog = false;
this.downloadLogs(res.data.hits);
if (res.data.hits.length > 0) {
this.downloadLogs(res.data.hits);
} else {
this.$q.notify({
message: "No data found to download.",
color: "positive",
position: "top",
timeout: 2000,
});
}
})
.catch((err) => {
this.$q.notify({
@@ -742,6 +783,7 @@ export default defineComponent({
const saveFunctionLoader = ref(false);
const confirmDialogVisible: boolean = ref(false);
const confirmSavedViewDialogVisible: boolean = ref(false);
let confirmCallback;
let fnEditorobj: any = null;
let streamName = "";
@@ -1225,7 +1267,13 @@ export default defineComponent({
confirmCallback = callback;
};
const showSavedViewConfirmDialog = (callback) => {
confirmSavedViewDialogVisible.value = true;
confirmCallback = callback;
};
const cancelConfirmDialog = () => {
confirmSavedViewDialogVisible.value = false;
confirmDialogVisible.value = false;
confirmCallback = null;
};
@@ -1400,11 +1448,15 @@ export default defineComponent({
}
} else {
if (savedViewSelectedName.value.view_id) {
saveViewLoader.value = true;
updateSavedViews(
savedViewSelectedName.value.view_id,
savedViewSelectedName.value.view_name
);
saveViewLoader.value = false;
showSavedViewConfirmDialog(() => {
saveViewLoader.value = true;
updateSavedViews(
savedViewSelectedName.value.view_id,
savedViewSelectedName.value.view_name
);
});
} else {
$q.notify({
message: `Please select saved view to update.`,
@@ -1588,6 +1640,7 @@ export default defineComponent({
isSavedViewAction.value = "create";
savedViewSelectedName.value = "";
saveViewLoader.value = false;
confirmSavedViewDialogVisible.value = false;
} else {
saveViewLoader.value = false;
$q.notify({
@@ -1655,8 +1708,14 @@ export default defineComponent({
};
const resetFilters = () => {
searchObj.data.query = "";
if (searchObj.meta.sqlMode == true) {
searchObj.data.query = `SELECT * FROM "${searchObj.data.stream.selectedStream.value}"`;
} else {
searchObj.data.query = "";
}
searchObj.data.editorValue = "";
queryEditorRef.value.setValue(searchObj.data.query);
handleRunQuery();
};
const customDownloadDialog = ref(false);
@@ -1679,6 +1738,7 @@ export default defineComponent({
updateQueryValue,
updateDateTime,
showConfirmDialog,
showSavedViewConfirmDialog,
cancelConfirmDialog,
confirmDialogOK,
udpateQuery,
@@ -1722,6 +1782,7 @@ export default defineComponent({
downloadCustomRange,
downloadCustomRangeOptions,
buildSearch,
confirmSavedViewDialogVisible,
};
},
computed: {
@@ -1734,6 +1795,9 @@ export default defineComponent({
confirmMessage() {
return "Are you sure you want to update the function?";
},
confirmMessageSavedView() {
return "Are you sure you want to update the saved view?";
},
resetFunction() {
return this.searchObj.data.tempFunctionName;
},
+65 -17
View File
@@ -30,11 +30,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div class="col-6 text-right q-pr-md q-gutter-xs pagination-block">
<q-pagination
v-model="pageNumberInput"
:key="searchObj.data.queryResults.total + '-' + searchObj.data.resultGrid.currentPage"
:key="
searchObj.data.queryResults.total +
'-' +
searchObj.data.resultGrid.currentPage
"
:max="
Math.max(
1,
Math.round(
Math.ceil(
searchObj.data.queryResults.total /
searchObj.meta.resultGrid.rowsPerPage
)
@@ -68,25 +72,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</div>
</div>
<ChartRenderer
v-if="searchObj.meta.showHistogram && !searchObj.meta.sqlMode"
data-test="logs-search-result-bar-chart"
:data="plotChart"
v-show="
searchObj.meta.showHistogram &&
!searchObj.meta.sqlMode &&
searchObj.data.stream.streamType !== 'enrichment_tables'
"
style="max-height: 100px"
@updated:dataZoom="onChartUpdate"
/>
<div
class="q-pb-lg"
v-if="
searchObj.meta.showHistogram &&
!searchObj.meta.sqlMode &&
searchObj.data.stream.streamType !== 'enrichment_tables' &&
searchObj.data.histogram.xData.length === 0
"
style="top: 50px; position: absolute; left: 45%"
v-if="searchObj.loadingHistogram == true"
>
<q-spinner-hourglass
color="primary"
@@ -147,7 +142,58 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</span>
</th>
</tr>
<tr v-if="searchObj.loading == true">
<td
:colspan="searchObj.data.resultGrid.columns.length"
class="text-bold"
style="opacity: 0.7"
>
<div class="text-subtitle2 text-weight-bold">
<q-spinner-hourglass size="20px" />
{{ t("confirmDialog.loading") }}
</div>
</td>
</tr>
</thead>
<tr
data-test="log-search-result-function-error"
v-if="searchObj.data.functionError != ''"
>
<td
:colspan="searchObj.data.resultGrid.columns.length"
class="text-bold"
style="opacity: 0.6"
>
<div class="text-subtitle2 text-weight-bold bg-warning">
<q-btn
:icon="
expandedLogs['-1']
? 'expand_more'
: 'chevron_right'
"
dense
size="xs"
flat
class="q-mr-xs"
data-test="table-row-expand-menu"
@click.stop="expandLog('function_error', -1)"
></q-btn
><b>
<q-icon name="warning" size="15px"></q-icon>
{{ t("search.functionErrorLabel") }}</b
>
</div>
</td>
</tr>
<q-tr v-if="expandedLogs['-1']">
<td
:colspan="searchObj.data.resultGrid.columns.length"
class="bg-warning"
style="opacity: 0.7"
>
<pre>{{ searchObj.data.functionError }}</pre>
</td>
</q-tr>
</template>
<template v-slot="{ item: row, index }">
<q-tr
@@ -351,7 +397,8 @@ export default defineComponent({
getPageData(actionType: string) {
if (actionType == "prev") {
if (this.searchObj.data.resultGrid.currentPage > 1) {
this.searchObj.data.resultGrid.currentPage = this.searchObj.data.resultGrid.currentPage - 1;
this.searchObj.data.resultGrid.currentPage =
this.searchObj.data.resultGrid.currentPage - 1;
this.pageNumberInput = this.searchObj.data.resultGrid.currentPage;
this.$emit("update:scroll");
this.searchTableRef.scrollTo(0);
@@ -364,7 +411,8 @@ export default defineComponent({
this.searchObj.meta.resultGrid.rowsPerPage
)
) {
this.searchObj.data.resultGrid.currentPage = this.searchObj.data.resultGrid.currentPage + 1;
this.searchObj.data.resultGrid.currentPage =
this.searchObj.data.resultGrid.currentPage + 1;
this.pageNumberInput = this.searchObj.data.resultGrid.currentPage;
this.$emit("update:scroll");
this.searchTableRef.scrollTo(0);
@@ -377,7 +425,7 @@ export default defineComponent({
} else if (actionType == "pageChange") {
if (
this.pageNumberInput >
Math.round(
Math.ceil(
this.searchObj.data.queryResults.total /
this.searchObj.meta.resultGrid.rowsPerPage
)
@@ -431,7 +479,7 @@ export default defineComponent({
const noOfRecordsTitle = ref("");
const scrollPosition = ref(0);
const rowsPerPageOptions = [10, 25, 50, 100, 250, 500, 1000];
const {
searchObj,
updatedLocalLogFilterField,