mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-09-25 00:13:12 +08:00
View traces fix for past 15 min interval
This commit is contained in:
parent
4c629721bd
commit
7f495181a7
@ -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 =
|
||||||
|
@ -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);
|
||||||
}}
|
}}
|
||||||
|
@ -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>
|
||||||
|
@ -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">
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
export enum METRICS_PAGE_QUERY_PARAM {
|
export enum METRICS_PAGE_QUERY_PARAM {
|
||||||
time = "time",
|
interval = "interval",
|
||||||
|
startTime = "startTime",
|
||||||
|
endTime = "endTime"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
) => {
|
) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user