Skip to content
This repository was archived by the owner on May 13, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions src/api/query.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import dayjs from 'dayjs';
import { Axios } from './axios';
import { LOG_QUERY_URL } from './constants';
import { Log, LogsQuery, LogsResponseWithHeaders } from '@/@types/parseable/api/query';
Expand All @@ -12,17 +11,19 @@ type QueryLogs = {
};

// to optimize query performace, it has been decided to round off the time at the given level
// so making the end-time inclusive
const optimizeEndTime = (endTime: Date) => {
return dayjs(endTime).add(1, 'minute').toDate();
const optimizeTime = (date: Date) => {
const tempDate = new Date(date);
tempDate.setSeconds(0);
tempDate.setMilliseconds(0);
return tempDate;
};

// ------ Default sql query

const makeDefaultQueryRequestData = (logsQuery: QueryLogs) => {
const { startTime, endTime, streamName, limit, pageOffset } = logsQuery;
const query = `SELECT * FROM ${streamName} LIMIT ${limit} OFFSET ${pageOffset}`;
return { query, startTime, endTime: optimizeEndTime(endTime) };
return { query, startTime: optimizeTime(startTime), endTime: optimizeTime(endTime) };
};

export const getQueryLogs = (logsQuery: QueryLogs) => {
Expand All @@ -41,7 +42,7 @@ export const getQueryLogsWithHeaders = (logsQuery: QueryLogs) => {

const makeCustomQueryRequestData = (logsQuery: LogsQuery, query: string) => {
const { startTime, endTime } = logsQuery;
return { query, startTime, endTime: optimizeEndTime(endTime) };
return { query, startTime: optimizeTime(startTime), endTime: optimizeTime(endTime) };
};

export const getQueryResult = (logsQuery: LogsQuery, query = '') => {
Expand Down
111 changes: 57 additions & 54 deletions src/pages/Stream/components/EventTimeLineGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,36 +82,33 @@ const getEndOfTs = (time: Date, compactType: CompactInterval): Date => {
}
};

const incrementDateByCompactType = (date: Date, type: CompactInterval): Date => {
let tempDate = new Date(date);
if (type === 'minute') {
tempDate.setMinutes(tempDate.getMinutes() + 1);
} else if (type === 'hour') {
tempDate.setHours(tempDate.getHours() + 1);
} else if (type === 'day') {
tempDate.setDate(tempDate.getDate() + 1);
} else if (type === 'quarter-hour') {
tempDate.setMinutes(tempDate.getMinutes() + 15);
} else if (type === 'half-hour') {
tempDate.setMinutes(tempDate.getMinutes() + 30);
} else if (type === 'month') {
tempDate.setMonth(tempDate.getMonth() + 1);
} else {
tempDate;
}
return new Date(tempDate);
};

const getAllIntervals = (start: Date, end: Date, compactType: CompactInterval): Date[] => {
const result = [];
const current = new Date(start);

const increment = (date: Date, type: CompactInterval) => {
switch (type) {
case 'minute':
date.setMinutes(date.getMinutes() + 1);
break;
case 'hour':
date.setHours(date.getHours() + 1);
break;
case 'day':
date.setDate(date.getDate() + 1);
break;
case 'quarter-hour':
date.setMinutes(date.getMinutes() + 15);
break;
case 'half-hour':
date.setMinutes(date.getMinutes() + 30);
break;
case 'month':
date.setMonth(date.getMonth() + 1);
break;
}
};
let currentDate = new Date(start);

while (current <= end) {
result.push(new Date(current));
increment(current, compactType);
while (currentDate <= end) {
result.push(new Date(currentDate));
currentDate = incrementDateByCompactType(currentDate, compactType);
}

return result;
Expand Down Expand Up @@ -170,6 +167,15 @@ const calcAverage = (data: LogsResponseWithHeaders | undefined) => {
return parseInt(Math.abs(total / records.length).toFixed(0));
};

type GraphTickItem = {
events: number;
minute: Date;
aboveAvgPercent: number;
compactType: CompactInterval;
startTime: dayjs.Dayjs;
endTime: dayjs.Dayjs;
};

// date_bin removes tz info
// filling data with empty values where there is no rec
const parseGraphData = (
Expand All @@ -178,7 +184,7 @@ const parseGraphData = (
startTime: Date,
endTime: Date,
interval: number,
) => {
): GraphTickItem[] => {
if (!data || !Array.isArray(data?.records)) return [];

const { fields, records } = data;
Expand All @@ -191,21 +197,28 @@ const parseGraphData = (
return new Date(`${d.date_bin_timestamp}Z`).toISOString() === ts.toISOString();
});

const startTime = dayjs(ts);
const endTimeByCompactType = incrementDateByCompactType(startTime.toDate(), compactType);
const endTime = dayjs(endTimeByCompactType);

const defaultOpts = {
events: 0,
minute: ts,
aboveAvgPercent: 0,
compactType,
startTime,
endTime,
};

if (!countData || typeof countData !== 'object') {
return {
events: 0,
minute: ts,
aboveAvgPercent: 0,
compactType,
};
return defaultOpts;
} else {
const aboveAvgCount = _.toNumber(countData.log_count) - avg;
const aboveAvgPercent = parseInt(((aboveAvgCount / avg) * 100).toFixed(2));
return {
events: countData.log_count,
minute: ts,
...defaultOpts,
events: _.toNumber(countData.log_count),
aboveAvgPercent,
compactType,
};
}
});
Expand All @@ -216,19 +229,8 @@ const parseGraphData = (
function ChartTooltip({ payload }: ChartTooltipProps) {
if (!payload || (Array.isArray(payload) && payload.length === 0)) return null;

const { minute, aboveAvgPercent, events, compactType } = payload[0]?.payload || {};
const { aboveAvgPercent, events, startTime, endTime } = payload[0]?.payload as GraphTickItem;
const isAboveAvg = aboveAvgPercent > 0;
const startTime = dayjs(minute).utc(true);
const endTime = (() => {
if (compactType === 'half-hour') {
return dayjs(minute).add(30, 'minute');
} else if (compactType === 'quarter-hour') {
return dayjs(minute).add(15, 'minute');
} else {
return dayjs(minute).add(1, compactType);
}
})();

return (
<Paper px="md" py="sm" withBorder shadow="md" radius="md">
<Text fw={600} mb={5}>
Expand Down Expand Up @@ -286,12 +288,13 @@ const EventTimeLineGraph = () => {
const activePayload = barValue?.activePayload;
if (!Array.isArray(activePayload) || activePayload.length === 0) return;

const samplePayload = activePayload[0];
if (!samplePayload || typeof samplePayload !== 'object') return;
const currentPayload = activePayload[0];
if (!currentPayload || typeof currentPayload !== 'object') return;

const graphTickItem = currentPayload.payload as GraphTickItem;
if (!graphTickItem || typeof graphTickItem !== 'object' || _.isEmpty(graphTickItem)) return;

const { minute, compactType } = samplePayload.payload || {};
const startTime = dayjs(minute);
const endTime = dayjs(minute).add(1, compactType);
const { startTime, endTime } = graphTickItem;
setLogsStore((store) => setTimeRange(store, { type: 'custom', startTime: startTime, endTime: endTime }));
}, []);

Expand Down