View traces fix for past 15 min interval

This commit is contained in:
“himanshu” 2021-01-21 00:27:54 +05:30
parent 4c629721bd
commit 7f495181a7
6 changed files with 106 additions and 42 deletions

View File

@ -10,16 +10,16 @@ import { getUsageDataAction } from "./usage";
import { updateTimeIntervalAction } from "./global"; import { updateTimeIntervalAction } from "./global";
export enum ActionTypes { export enum ActionTypes {
updateTraceFilters, updateTraceFilters= "UPDATE_TRACES_FILTER",
updateInput, updateInput = "UPDATE_INPUT",
fetchTraces, fetchTraces = "FETCH_TRACES",
fetchTraceItem, fetchTraceItem = "FETCH_TRACE_ITEM",
getServicesList, getServicesList = "GET_SERVICE_LIST",
getServiceMetrics, getServiceMetrics = "GET_SERVICE_METRICS",
getTopEndpoints, getTopEndpoints = "GET_TOP_ENDPOINTS",
getUsageData, getUsageData = "GET_USAGE_DATE",
updateTimeInterval, updateTimeInterval = "UPDATE_TIME_INTERVAL",
getFilteredTraceMetrics, getFilteredTraceMetrics = "GET_FILTERED_TRACE_METRICS",
} }
export type Action = export type Action =

View File

@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import { Select, Button, Space, Form } from "antd"; import { Select, Button, Space, Form } from "antd";
import styled from "styled-components"; import styled from "styled-components";
import { withRouter } from "react-router"; import { withRouter } from "react-router";
import { RouteComponentProps } from "react-router-dom"; import { RouteComponentProps, useLocation } from "react-router-dom";
import { connect } from "react-redux"; import { connect } from "react-redux";
import CustomDateTimeModal from "./CustomDateTimeModal"; import CustomDateTimeModal from "./CustomDateTimeModal";
@ -13,6 +13,7 @@ import FormItem from "antd/lib/form/FormItem";
import { DateTimeRangeType } from "../actions"; import { DateTimeRangeType } from "../actions";
import { METRICS_PAGE_QUERY_PARAM } from "../constants/query"; import { METRICS_PAGE_QUERY_PARAM } from "../constants/query";
import { LOCAL_STORAGE } from "../constants/localStorage"; import { LOCAL_STORAGE } from "../constants/localStorage";
import moment from "moment";
const { Option } = Select; const { Option } = Select;
const DateTimeWrapper = styled.div` const DateTimeWrapper = styled.div`
@ -25,45 +26,99 @@ interface DateTimeSelectorProps extends RouteComponentProps<any> {
globalTime: GlobalTime; globalTime: GlobalTime;
} }
/*
This components is mounted all the time. Use event listener to track changes.
*/
const _DateTimeSelector = (props: DateTimeSelectorProps) => { const _DateTimeSelector = (props: DateTimeSelectorProps) => {
const defaultTime = "15min"; const defaultTime = "30min";
const [customDTPickerVisible, setCustomDTPickerVisible] = useState(false); const [customDTPickerVisible, setCustomDTPickerVisible] = useState(false);
const [timeInterval, setTimeInterval] = useState(defaultTime); const [timeInterval, setTimeInterval] = useState(defaultTime);
const [startTime, setStartTime] = useState<moment.Moment | null>(null);
const [endTime, setEndTime] = useState<moment.Moment | null>(null);
const [refreshButtonHidden, setRefreshButtonHidden] = useState(false); const [refreshButtonHidden, setRefreshButtonHidden] = useState(false);
const [form_dtselector] = Form.useForm(); const [form_dtselector] = Form.useForm();
const location = useLocation();
useEffect(() => { const updateTimeOnQueryParamChange = ()=>{
const timeDurationInLocalStorage = localStorage.getItem( const timeDurationInLocalStorage = localStorage.getItem(
LOCAL_STORAGE.METRICS_TIME_IN_DURATION, LOCAL_STORAGE.METRICS_TIME_IN_DURATION,
); );
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
const timeInQueryParam = urlParams.get(METRICS_PAGE_QUERY_PARAM.time); const intervalInQueryParam = urlParams.get(METRICS_PAGE_QUERY_PARAM.interval);
if (timeInQueryParam) { const startTimeString = urlParams.get(METRICS_PAGE_QUERY_PARAM.startTime);
setMetricsTime(timeInQueryParam); const endTimeString = urlParams.get(METRICS_PAGE_QUERY_PARAM.endTime);
} else if (timeDurationInLocalStorage) {
setMetricsTime(timeDurationInLocalStorage); // first pref: handle both startTime and endTime
if(startTimeString && startTimeString.length>0 && endTimeString && endTimeString.length>0){
const startTime = moment(Number(startTimeString));
const endTime = moment(Number(endTimeString));
setCustomTime(startTime,endTime,true)
} }
// first pref: handle intervalInQueryParam
else if (intervalInQueryParam) {
window.localStorage.setItem(
LOCAL_STORAGE.METRICS_TIME_IN_DURATION,
intervalInQueryParam,
);
setMetricsTimeInterval(intervalInQueryParam);
} else if (timeDurationInLocalStorage) {
setMetricsTimeInterval(timeDurationInLocalStorage);
}
}
// On URL Change
useEffect(() => {
updateTimeOnQueryParamChange();
}, [location]);
//On mount
useEffect(() => {
updateTimeOnQueryParamChange();
}, []); }, []);
const setMetricsTime = (value: string) => { const setMetricsTimeInterval= (value: string) => {
props.history.push({
search: `?${METRICS_PAGE_QUERY_PARAM.time}=${value}`,
}); //pass time in URL query param for all choices except custom in datetime picker
props.updateTimeInterval(value); props.updateTimeInterval(value);
setTimeInterval(value); setTimeInterval(value);
setEndTime(null);
setStartTime(null);
window.localStorage.setItem(
LOCAL_STORAGE.METRICS_TIME_IN_DURATION,
value,
);
}; };
const setCustomTime= (startTime: moment.Moment, endTime: moment.Moment, triggeredByURLChange = false) => {
props.updateTimeInterval("custom", [
startTime.valueOf(),
endTime.valueOf(),
]);
setEndTime(endTime);
setStartTime(startTime);
};
const updateUrlForTimeInterval = (value: string) => {
props.history.push({
search: `?${METRICS_PAGE_QUERY_PARAM.interval}=${value}`,
}); //pass time in URL query param for all choices except custom in datetime picker
};
const updateUrlForCustomTime= (startTime: moment.Moment, endTime: moment.Moment, triggeredByURLChange = false) => {
props.history.push(`?${METRICS_PAGE_QUERY_PARAM.startTime}=${startTime.valueOf()}&${METRICS_PAGE_QUERY_PARAM.endTime}=${endTime.valueOf()}`);
}
const handleOnSelect = (value: string) => { const handleOnSelect = (value: string) => {
if (value === "custom") { if (value === "custom") {
setCustomDTPickerVisible(true); setCustomDTPickerVisible(true);
} else { } else {
setTimeInterval(value); updateUrlForTimeInterval(value);
setRefreshButtonHidden(false); // for normal intervals, show refresh button setRefreshButtonHidden(false); // for normal intervals, show refresh button
} }
}; };
//function called on clicking apply in customDateTimeModal //function called on clicking apply in customDateTimeModal
const handleOk = (dateTimeRange: DateTimeRangeType) => { const handleCustomDate = (dateTimeRange: DateTimeRangeType) => {
// pass values in ms [minTime, maxTime] // pass values in ms [minTime, maxTime]
if ( if (
dateTimeRange !== null && dateTimeRange !== null &&
@ -71,10 +126,10 @@ const _DateTimeSelector = (props: DateTimeSelectorProps) => {
dateTimeRange[0] !== null && dateTimeRange[0] !== null &&
dateTimeRange[1] !== null dateTimeRange[1] !== null
) { ) {
props.updateTimeInterval("custom", [ const startTime = dateTimeRange[0].valueOf();
dateTimeRange[0].valueOf(), const endTime = dateTimeRange[1].valueOf();
dateTimeRange[1].valueOf(),
]); updateUrlForCustomTime(moment(startTime),moment(endTime))
//setting globaltime //setting globaltime
setRefreshButtonHidden(true); setRefreshButtonHidden(true);
form_dtselector.setFieldsValue({ form_dtselector.setFieldsValue({
@ -104,11 +159,7 @@ const _DateTimeSelector = (props: DateTimeSelectorProps) => {
}; };
const handleRefresh = () => { const handleRefresh = () => {
window.localStorage.setItem( setMetricsTimeInterval(timeInterval);
LOCAL_STORAGE.METRICS_TIME_IN_DURATION,
timeInterval,
);
setMetricsTime(timeInterval);
}; };
const options = [ const options = [
@ -123,6 +174,8 @@ const _DateTimeSelector = (props: DateTimeSelectorProps) => {
if (props.location.pathname.startsWith("/usage-explorer")) { if (props.location.pathname.startsWith("/usage-explorer")) {
return null; return null;
} else { } else {
const inputLabeLToShow = startTime && endTime? (`${startTime.format("YYYY/MM/DD HH:mm")} - ${endTime.format("YYYY/MM/DD HH:mm")}`):timeInterval
return ( return (
<DateTimeWrapper> <DateTimeWrapper>
<Space> <Space>
@ -133,7 +186,7 @@ const _DateTimeSelector = (props: DateTimeSelectorProps) => {
style={{ marginTop: 10, marginBottom: 10 }} style={{ marginTop: 10, marginBottom: 10 }}
> >
<FormItem></FormItem> <FormItem></FormItem>
<Select onSelect={handleOnSelect} value={timeInterval}> <Select onSelect={handleOnSelect} value={inputLabeLToShow}>
{options.map(({ value, label }) => ( {options.map(({ value, label }) => (
<Option value={value}>{label}</Option> <Option value={value}>{label}</Option>
))} ))}
@ -148,7 +201,7 @@ const _DateTimeSelector = (props: DateTimeSelectorProps) => {
</Form> </Form>
<CustomDateTimeModal <CustomDateTimeModal
visible={customDTPickerVisible} visible={customDTPickerVisible}
onCreate={handleOk} onCreate={handleCustomDate}
onCancel={() => { onCancel={() => {
setCustomDTPickerVisible(false); setCustomDTPickerVisible(false);
}} }}

View File

@ -186,7 +186,9 @@ class LatencyLineChart extends React.Component<LatencyLineChartProps> {
ycoordinate={this.state.ycoordinate} ycoordinate={this.state.ycoordinate}
> >
<PopUpElements <PopUpElements
onClick={() => this.props.popupClickHandler(this.state.firstpoint_ts)} onClick={() => {
this.props.popupClickHandler(this.state.firstpoint_ts)
}}
> >
View Traces View Traces
</PopUpElements> </PopUpElements>

View File

@ -17,6 +17,7 @@ import LatencyLineChart from "./LatencyLineChart";
import RequestRateChart from "./RequestRateChart"; import RequestRateChart from "./RequestRateChart";
import ErrorRateChart from "./ErrorRateChart"; import ErrorRateChart from "./ErrorRateChart";
import TopEndpointsTable from "./TopEndpointsTable"; import TopEndpointsTable from "./TopEndpointsTable";
import { METRICS_PAGE_QUERY_PARAM } from "../../constants/query";
const { TabPane } = Tabs; const { TabPane } = Tabs;
@ -38,11 +39,16 @@ const _ServiceMetrics = (props: ServicesMetricsProps) => {
}, [props.globalTime, params.servicename]); }, [props.globalTime, params.servicename]);
const onTracePopupClick = (timestamp: number) => { const onTracePopupClick = (timestamp: number) => {
const tMinus5Min = timestamp / 1000000 - 5 * 60 * 1000;
const currentTime = timestamp / 1000000;
props.updateTimeInterval("custom", [ props.updateTimeInterval("custom", [
timestamp / 1000000 - 5 * 60 * 1000, tMinus5Min,
timestamp / 1000000, currentTime,
]); // updateTimeInterval takes second range in ms -- give -5 min to selected time, ]); // updateTimeInterval takes second range in ms -- give -5 min to selected time,
props.history.push("/traces");
props.history.push(`/traces?${METRICS_PAGE_QUERY_PARAM.startTime}=${tMinus5Min}&${METRICS_PAGE_QUERY_PARAM.endTime}=${currentTime}`);
}; };
return ( return (
<Tabs defaultActiveKey="1"> <Tabs defaultActiveKey="1">

View File

@ -1,3 +1,6 @@
export enum METRICS_PAGE_QUERY_PARAM { export enum METRICS_PAGE_QUERY_PARAM {
time = "time", interval = "interval",
startTime = "startTime",
endTime = "endTime"
} }

View File

@ -3,7 +3,7 @@ import { ActionTypes, Action, GlobalTime } from "../actions";
export const updateGlobalTimeReducer = ( export const updateGlobalTimeReducer = (
state: GlobalTime = { state: GlobalTime = {
maxTime: Date.now() * 1000000, maxTime: Date.now() * 1000000,
minTime: (Date.now() - 15 * 60 * 1000) * 1000000, minTime: (Date.now() - 15 * 60 * 1000) * 1000000
}, },
action: Action, action: Action,
) => { ) => {