mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 04:29:04 +08:00
Merge branch 'main' into query_refactor
This commit is contained in:
commit
e524ce5743
30
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
30
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bug description
|
||||||
|
|
||||||
|
*Please describe.*
|
||||||
|
*If this affects the front-end, screenshots would be of great help.*
|
||||||
|
|
||||||
|
## Expected behavior
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## How to reproduce
|
||||||
|
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Additional context
|
||||||
|
|
||||||
|
|
||||||
|
#### *Thank you* for your bug report – we love squashing them!
|
29
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
29
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Is your feature request related to a problem?
|
||||||
|
|
||||||
|
*Please describe.*
|
||||||
|
|
||||||
|
## Describe the solution you'd like
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Describe alternatives you've considered
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Additional context
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### *Thank you* for your feature request – we love each and every one!
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
33
.github/ISSUE_TEMPLATE/performance-issue-report.md
vendored
Normal file
33
.github/ISSUE_TEMPLATE/performance-issue-report.md
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
name: Performance issue report
|
||||||
|
about: Long response times, high resource usage? Ensuring that SigNoz is scalable
|
||||||
|
is our top priority
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## In what situation are you experiencing subpar performance?
|
||||||
|
|
||||||
|
*Please describe.*
|
||||||
|
|
||||||
|
## How to reproduce
|
||||||
|
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
|
||||||
|
## Your Environment
|
||||||
|
|
||||||
|
- [ ] Linux
|
||||||
|
- [ ] Mac
|
||||||
|
- [ ] Windows
|
||||||
|
|
||||||
|
Please provide details of OS version etc.
|
||||||
|
|
||||||
|
## Additional context
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### *Thank you* for your performance issue report – we want SigNoz to be blazing fast!
|
@ -8,7 +8,7 @@
|
|||||||
<img alt="License" src="https://img.shields.io/badge/license-MIT-brightgreen"> </a>
|
<img alt="License" src="https://img.shields.io/badge/license-MIT-brightgreen"> </a>
|
||||||
<img alt="Downloads" src="https://img.shields.io/docker/pulls/signoz/frontend?label=Downloads"> </a>
|
<img alt="Downloads" src="https://img.shields.io/docker/pulls/signoz/frontend?label=Downloads"> </a>
|
||||||
<img alt="GitHub issues" src="https://img.shields.io/github/issues/signoz/signoz"> </a>
|
<img alt="GitHub issues" src="https://img.shields.io/github/issues/signoz/signoz"> </a>
|
||||||
<a href="https://twitter.com/intent/tweet?text=Monitor%20your%20applications%20and%20troubleshoot%20problems%20with%20SigNoz,%20an%20open-source%20alternative%20to%20DataDog,%20NewRelic.&url=https://signoz.io/&via=SigNoz_io&hashtags=opensource,signoz,observability">
|
<a href="https://twitter.com/intent/tweet?text=Monitor%20your%20applications%20and%20troubleshoot%20problems%20with%20SigNoz,%20an%20open-source%20alternative%20to%20DataDog,%20NewRelic.&url=https://signoz.io/&via=SigNozHQ&hashtags=opensource,signoz,observability">
|
||||||
<img alt="tweet" src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a>
|
<img alt="tweet" src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import {
|
|||||||
SettingsPage,
|
SettingsPage,
|
||||||
IntstrumentationPage,
|
IntstrumentationPage,
|
||||||
} from "Src/pages";
|
} from "Src/pages";
|
||||||
|
import { RouteProvider } from "./RouteProvider";
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const { status } = useThemeSwitcher();
|
const { status } = useThemeSwitcher();
|
||||||
@ -30,6 +31,7 @@ const App = () => {
|
|||||||
<Suspense fallback={<Spin size="large" />}>
|
<Suspense fallback={<Spin size="large" />}>
|
||||||
<Route path={"/"}>
|
<Route path={"/"}>
|
||||||
<Switch>
|
<Switch>
|
||||||
|
<RouteProvider>
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
<Route path={ROUTES.SIGN_UP} exact component={Signup} />
|
<Route path={ROUTES.SIGN_UP} exact component={Signup} />
|
||||||
<Route path={ROUTES.APPLICATION} exact component={ServicesTable} />
|
<Route path={ROUTES.APPLICATION} exact component={ServicesTable} />
|
||||||
@ -60,6 +62,7 @@ const App = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
</RouteProvider>
|
||||||
</Switch>
|
</Switch>
|
||||||
</Route>
|
</Route>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
import React, { ReactNode } from "react";
|
import React, { ReactNode, useEffect } from "react";
|
||||||
|
|
||||||
import { Layout } from "antd";
|
import { Layout } from "antd";
|
||||||
import SideNav from "./Nav/SideNav";
|
import SideNav from "./Nav/SideNav";
|
||||||
import TopNav from "./Nav/TopNav";
|
import TopNav from "./Nav/TopNav";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
import ROUTES from "Src/constants/routes";
|
||||||
|
import { useRoute } from "./RouteProvider";
|
||||||
|
|
||||||
const { Content, Footer } = Layout;
|
const { Content, Footer } = Layout;
|
||||||
|
|
||||||
interface BaseLayoutProps {
|
interface BaseLayoutProps {
|
||||||
@ -10,6 +14,13 @@ interface BaseLayoutProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const BaseLayout: React.FC<BaseLayoutProps> = ({ children }) => {
|
const BaseLayout: React.FC<BaseLayoutProps> = ({ children }) => {
|
||||||
|
const location = useLocation();
|
||||||
|
const { dispatch } = useRoute();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
dispatch({ type: "UPDATE_IS_LOADED", payload: location.pathname });
|
||||||
|
}, [location]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout style={{ minHeight: "100vh" }}>
|
<Layout style={{ minHeight: "100vh" }}>
|
||||||
<SideNav />
|
<SideNav />
|
||||||
|
12
frontend/src/modules/Metrics/TopEndpointsTable.css
Normal file
12
frontend/src/modules/Metrics/TopEndpointsTable.css
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
@media only screen and (min-width: 768px) {
|
||||||
|
.topEndpointsButton {
|
||||||
|
white-space: nowrap;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topEndpointsButton span {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
max-width: 120px;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Table, Button } from "antd";
|
import { Table, Button, Tooltip } from "antd";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { useHistory, useParams } from "react-router-dom";
|
import { useHistory, useParams } from "react-router-dom";
|
||||||
@ -7,12 +7,16 @@ import { topEndpointListItem } from "../../store/actions/metrics";
|
|||||||
import { METRICS_PAGE_QUERY_PARAM } from "Src/constants/query";
|
import { METRICS_PAGE_QUERY_PARAM } from "Src/constants/query";
|
||||||
import { GlobalTime } from "Src/store/actions";
|
import { GlobalTime } from "Src/store/actions";
|
||||||
import { StoreState } from "Src/store/reducers";
|
import { StoreState } from "Src/store/reducers";
|
||||||
|
import "./TopEndpointsTable.css";
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
const Wrapper = styled.div`
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
padding-left: 20px;
|
padding-left: 8px;
|
||||||
padding-right: 20px;
|
padding-right: 8px;
|
||||||
|
@media only screen and (max-width: 767px) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
.ant-table table {
|
.ant-table table {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
@ -22,6 +26,9 @@ const Wrapper = styled.div`
|
|||||||
.ant-table-thead > tr > th {
|
.ant-table-thead > tr > th {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
.ant-table-column-sorters {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
interface TopEndpointsTableProps {
|
interface TopEndpointsTableProps {
|
||||||
@ -58,9 +65,15 @@ const _TopEndpointsTable = (props: TopEndpointsTableProps) => {
|
|||||||
key: "name",
|
key: "name",
|
||||||
|
|
||||||
render: (text: string) => (
|
render: (text: string) => (
|
||||||
<Button type="link" onClick={() => handleOnClick(text)}>
|
<Tooltip placement="topLeft" title={text}>
|
||||||
|
<Button
|
||||||
|
className="topEndpointsButton"
|
||||||
|
type="link"
|
||||||
|
onClick={() => handleOnClick(text)}
|
||||||
|
>
|
||||||
{text}
|
{text}
|
||||||
</Button>
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
83
frontend/src/modules/RouteProvider.tsx
Normal file
83
frontend/src/modules/RouteProvider.tsx
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import React, { useContext, createContext, ReactNode, Dispatch } from "react";
|
||||||
|
import ROUTES from "Src/constants/routes";
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
[key: string]: {
|
||||||
|
route: string;
|
||||||
|
isLoaded: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ActionTypes {
|
||||||
|
UPDATE_IS_LOADED = "UPDATE_IS_LOADED",
|
||||||
|
}
|
||||||
|
|
||||||
|
type Action = {
|
||||||
|
type: ActionTypes;
|
||||||
|
payload: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface ContextType {
|
||||||
|
state: State;
|
||||||
|
dispatch: Dispatch<Action>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RouteContext = createContext<ContextType | null>(null);
|
||||||
|
|
||||||
|
interface RouteProviderProps {
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
interface RouteObj {
|
||||||
|
[key: string]: {
|
||||||
|
route: string;
|
||||||
|
isLoaded: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateLocation = (state: State, action: Action): State => {
|
||||||
|
if (action.type === ActionTypes.UPDATE_IS_LOADED) {
|
||||||
|
/*
|
||||||
|
Update the isLoaded property in routes obj
|
||||||
|
if the route matches the current pathname
|
||||||
|
|
||||||
|
Why: Checkout this issue https://github.com/SigNoz/signoz/issues/110
|
||||||
|
To avoid calling the api's twice for Date picker,
|
||||||
|
We will only call once the route is changed
|
||||||
|
*/
|
||||||
|
Object.keys(ROUTES).map((items) => {
|
||||||
|
state[items].isLoaded = state[items].route === action.payload;
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getInitialState = () => {
|
||||||
|
const routes: RouteObj = {};
|
||||||
|
Object.keys(ROUTES).map((items) => {
|
||||||
|
routes[items] = {
|
||||||
|
route: `${ROUTES[items]}`,
|
||||||
|
isLoaded: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return routes;
|
||||||
|
};
|
||||||
|
|
||||||
|
const RouteProvider: React.FC<RouteProviderProps> = ({ children }) => {
|
||||||
|
const [state, dispatch] = React.useReducer(updateLocation, getInitialState());
|
||||||
|
const value = { state, dispatch };
|
||||||
|
return <RouteContext.Provider value={value}>{children}</RouteContext.Provider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useRoute = (): ContextType => {
|
||||||
|
const context = useContext(RouteContext);
|
||||||
|
if (context === undefined) {
|
||||||
|
throw new Error("useRoute must be used within a RouteProvider");
|
||||||
|
}
|
||||||
|
return context as ContextType;
|
||||||
|
};
|
||||||
|
export { RouteProvider, useRoute };
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useContext, useEffect, useRef } from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { RouteComponentProps } from "react-router-dom";
|
import { RouteComponentProps } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
@ -14,6 +14,7 @@ import { StoreState } from "../../store/reducers";
|
|||||||
import { getZoomPx, getGraphData, getTooltip, transformLabel } from "./utils";
|
import { getZoomPx, getGraphData, getTooltip, transformLabel } from "./utils";
|
||||||
import SelectService from "./SelectService";
|
import SelectService from "./SelectService";
|
||||||
import { ForceGraph2D } from "react-force-graph";
|
import { ForceGraph2D } from "react-force-graph";
|
||||||
|
import { useRoute } from "../RouteProvider";
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
.force-graph-container .graph-tooltip {
|
.force-graph-container .graph-tooltip {
|
||||||
@ -53,6 +54,8 @@ export interface graphDataType {
|
|||||||
|
|
||||||
const ServiceMap = (props: ServiceMapProps) => {
|
const ServiceMap = (props: ServiceMapProps) => {
|
||||||
const fgRef = useRef();
|
const fgRef = useRef();
|
||||||
|
const { state } = useRoute();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getDetailedServiceMapItems,
|
getDetailedServiceMapItems,
|
||||||
getServiceMapItems,
|
getServiceMapItems,
|
||||||
@ -61,8 +64,14 @@ const ServiceMap = (props: ServiceMapProps) => {
|
|||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
/*
|
||||||
|
Call the apis only when the route is loaded.
|
||||||
|
Check this issue: https://github.com/SigNoz/signoz/issues/110
|
||||||
|
*/
|
||||||
|
if (state.SERVICE_MAP.isLoaded) {
|
||||||
getServiceMapItems(globalTime);
|
getServiceMapItems(globalTime);
|
||||||
getDetailedServiceMapItems(globalTime);
|
getDetailedServiceMapItems(globalTime);
|
||||||
|
}
|
||||||
}, [globalTime]);
|
}, [globalTime]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
GlobalTime,
|
GlobalTime,
|
||||||
TraceFilters,
|
TraceFilters,
|
||||||
} from "../../store/actions";
|
} from "../../store/actions";
|
||||||
|
import { useRoute } from "../RouteProvider";
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
@ -81,6 +82,8 @@ const _TraceCustomVisualizations = (props: TraceCustomVisualizationsProps) => {
|
|||||||
const [selectedEntity, setSelectedEntity] = useState("calls");
|
const [selectedEntity, setSelectedEntity] = useState("calls");
|
||||||
const [selectedAggOption, setSelectedAggOption] = useState("count");
|
const [selectedAggOption, setSelectedAggOption] = useState("count");
|
||||||
const [selectedStep, setSelectedStep] = useState("60");
|
const [selectedStep, setSelectedStep] = useState("60");
|
||||||
|
const { state } = useRoute();
|
||||||
|
|
||||||
// Step should be multiples of 60, 60 -> 1 min
|
// Step should be multiples of 60, 60 -> 1 min
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -109,7 +112,14 @@ const _TraceCustomVisualizations = (props: TraceCustomVisualizationsProps) => {
|
|||||||
minTime: props.globalTime.minTime - 15 * 60 * 1000000000,
|
minTime: props.globalTime.minTime - 15 * 60 * 1000000000,
|
||||||
maxTime: props.globalTime.maxTime + 15 * 60 * 1000000000,
|
maxTime: props.globalTime.maxTime + 15 * 60 * 1000000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Call the apis only when the route is loaded.
|
||||||
|
Check this issue: https://github.com/SigNoz/signoz/issues/110
|
||||||
|
*/
|
||||||
|
if (state.TRACES.isLoaded) {
|
||||||
props.getFilteredTraceMetrics(request_string, plusMinus15);
|
props.getFilteredTraceMetrics(request_string, plusMinus15);
|
||||||
|
}
|
||||||
}, [selectedEntity, selectedAggOption, props.traceFilters, props.globalTime]);
|
}, [selectedEntity, selectedAggOption, props.traceFilters, props.globalTime]);
|
||||||
|
|
||||||
//Custom metrics API called if time, tracefilters, selected entity or agg option changes
|
//Custom metrics API called if time, tracefilters, selected entity or agg option changes
|
||||||
|
@ -18,6 +18,7 @@ import FormItem from "antd/lib/form/FormItem";
|
|||||||
import api, { apiV1 } from "../../api";
|
import api, { apiV1 } from "../../api";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import { METRICS_PAGE_QUERY_PARAM } from "Src/constants/query";
|
import { METRICS_PAGE_QUERY_PARAM } from "Src/constants/query";
|
||||||
|
import { useRoute } from "../RouteProvider";
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
@ -45,6 +46,7 @@ const _TraceFilter = (props: TraceFilterProps) => {
|
|||||||
const [tagKeyOptions, setTagKeyOptions] = useState<TagKeyOptionItem[]>([]);
|
const [tagKeyOptions, setTagKeyOptions] = useState<TagKeyOptionItem[]>([]);
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const urlParams = new URLSearchParams(location.search.split("?")[1]);
|
const urlParams = new URLSearchParams(location.search.split("?")[1]);
|
||||||
|
const { state } = useRoute();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
handleApplyFilterForm({
|
handleApplyFilterForm({
|
||||||
@ -122,7 +124,13 @@ const _TraceFilter = (props: TraceFilterProps) => {
|
|||||||
"&tags=" +
|
"&tags=" +
|
||||||
encodeURIComponent(JSON.stringify(props.traceFilters.tags));
|
encodeURIComponent(JSON.stringify(props.traceFilters.tags));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Call the apis only when the route is loaded.
|
||||||
|
Check this issue: https://github.com/SigNoz/signoz/issues/110
|
||||||
|
*/
|
||||||
|
if (state.TRACES.isLoaded) {
|
||||||
props.fetchTraces(props.globalTime, request_string);
|
props.fetchTraces(props.globalTime, request_string);
|
||||||
|
}
|
||||||
}, [props.traceFilters, props.globalTime]);
|
}, [props.traceFilters, props.globalTime]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -13,6 +13,7 @@ import {
|
|||||||
import { StoreState } from "../../store/reducers";
|
import { StoreState } from "../../store/reducers";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { isOnboardingSkipped } from "../../utils/app";
|
import { isOnboardingSkipped } from "../../utils/app";
|
||||||
|
import { useRoute } from "../RouteProvider";
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
interface UsageExplorerProps {
|
interface UsageExplorerProps {
|
||||||
@ -56,6 +57,8 @@ const _UsageExplorer = (props: UsageExplorerProps) => {
|
|||||||
const [selectedInterval, setSelectedInterval] = useState(interval[2]);
|
const [selectedInterval, setSelectedInterval] = useState(interval[2]);
|
||||||
const [selectedService, setSelectedService] = useState<string>("");
|
const [selectedService, setSelectedService] = useState<string>("");
|
||||||
|
|
||||||
|
const { state } = useRoute();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedTime && selectedInterval) {
|
if (selectedTime && selectedInterval) {
|
||||||
const maxTime = new Date().getTime() * 1000000;
|
const maxTime = new Date().getTime() * 1000000;
|
||||||
@ -71,7 +74,13 @@ const _UsageExplorer = (props: UsageExplorerProps) => {
|
|||||||
}, [selectedTime, selectedInterval, selectedService]);
|
}, [selectedTime, selectedInterval, selectedService]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
/*
|
||||||
|
Call the apis only when the route is loaded.
|
||||||
|
Check this issue: https://github.com/SigNoz/signoz/issues/110
|
||||||
|
*/
|
||||||
|
if (state.USAGE_EXPLORER.isLoaded) {
|
||||||
props.getServicesList(props.globalTime);
|
props.getServicesList(props.globalTime);
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user