Unverified Commit d6884cac authored by DIO's avatar DIO Committed by GitHub
Browse files

Merge branch 'main' into issues-106

parents 057fba11 bb155d23
develop 'issue141' 1244-edit-alert 1725-expection 24-may-2022-testing 414-uri add-cypress add-github--actions add-packages-back add-testing-framework alertmanager-discovery alerts ankit01-oss-patch-1 anweshknayak-patch-1 bug/synk-security-fixes bump-json-iterator bump-prometheus ch-connection-exit ch-index-changes change-installation change-p90 change-sample-alert check-antd-css chore-telemetry chore/analytics chore/change-validation-message chore/improve-metrics-perf chore/improve-perf-remote-read chore/install-script-update chore/migration-0.8.0 chore/migration-file-path chore/moving-to-clickhouse-v2 chore/remove-query-service-codeowners chore/update-otelcollector-0.43.0 clickhouse-helm clickhouse-persistence configurable-storage-class crud-dashboards custom_metrics dashboarad-vars dashboard-bug-fix debug-dep debug-dep-migrate docker-swarm effgo enable-alerts enable-gzip-frontend error-grpc feat-doc-contribute feat-statsd-receiver feat/addHasErrorColumn feat/amol-ee feat/clickhouse-db-optimizations feat/custom-func-getSubTreeSpans feat/dynamic-tooltip feat/ee feat/exclude-filter-support feat/featureFlagging feat/fields-compression feat/gRPC-code-method feat/getFilteredSpans feat/getSpanFilters feat/gh-bot feat/newTraceFilter feat/searchTraceId feat/support-custom-events feat/support-error-tab-page feat/support-events feat/tagValueSuggestion feat/trace-detail feat/trace-resource-attributes feat/udf-function-getSubTreeSpans feat/usage feat/usage-reporting filter-set fix-ami-linux-docker fix-api-call-twice fix-cors-put fix-double-client fix-endpoints-css fix-eslint fix-filtered-spans fix-gant-chart-timeline fix-husky fix-scroll-gantt-chart fix-service-map-zoom fix-tabs-issue fix-user fix/414-error-trace-filter-APIs fix/aggregate fix/error-exception-page-typo fix/error-exception-sql-issue fix/errorDetailURL fix/exceptionPageOptimization fix/exclude-operation fix/null-values fix/serviceMapDependencies fix/setTTLapis fix/telemetry-bug gzip hostmetrics infra-metrics issue-1228 issue-1252 issue-1293 issue-1294 issue-1442 issue-1485-develop issue-1511 issue-1583 issue-618 issue-pod-687 issues-106 labels_object main makeavish-patch-1 makeavish-patch-2 metric-suggest-apis-chv2 metrics-builder-all metrics-table new-metrics new-metrics-enums palashgdev-patch-1 palashgdev-patch-2 perf/trace-detail-page playwright pranay01-patch-1 pranshuchittora/feat/dynamic-step-size prashant/add-codeowners prashant/add-deploy-docs prashant/ci-k3s-enchancements prashant/contributing-docs prashant/docker-data-path prashant/e2e-k3s-changes prashant/frontend-docker prashant/hotrod-log-options prashant/hotrod-template prashant/hotrod-yaml prashant/install-script-changes prashant/integrate-behaviorbot prashant/migrate-helm-charts prashant/minor-k3s-changes prashant/nginx-cache-improvement prashant/remove-ports prashant/rename-config prashant/single-hotrod-manifest prashant/two-compose-yaml prashant/version-ping-mini-css-extract-plugin prashant/versioning prod-feedback query_refactor reduce-bundle-size reduce-bundle-size-1 refactor-gant-chart refactor-metrics-reducer refactor-redux refactor-selected-span refactoring release/v0.10 release/v0.10.0 release/v0.10.1 release/v0.10.2 release/v0.11 release/v0.11.0 release/v0.11.1 release/v0.11.2 release/v0.11.3 release/v0.6 release/v0.6.0 release/v0.6.1 release/v0.6.2 release/v0.7 release/v0.7.0 release/v0.7.1 release/v0.7.2 release/v0.7.3 release/v0.7.4 release/v0.7.5 release/v0.8 release/v0.8.0 release/v0.8.1 release/v0.8.2 release/v0.9 release/v0.9.0 release/v0.9.1 release/v0.9.2 remove-bundle-analyzer remove-gzip revert-310-snyk-fix-d368e29b07323337ebe6ba0e289d85e7 revert-382-fix-eslint-error revert-386-remove-package revert-456-storybook revert-628-chore/migration-file-path revert-770-trace-styles revert-814-release/v0.7.0 revert-835-pc/feat/shared-styles-for-styled-components snyk-fix-0c242a73fc20c472e37f0b59a7c93a5a snyk-fix-194ab2b3455dd9e2099068fc3ac5f20f snyk-fix-3d7b28e56a36018c4b5cf8438365ff27 snyk-fix-4ef12a6988dec7696867e0b2accb8289 snyk-fix-634b756aa5179844cafb3a54d707b934 snyk-fix-7ee2560cd9d67a9821899135c05c1175 snyk-fix-8f3a2f55a70c214b57d1a3b3bce7d0cf snyk-fix-a7789225303bf723cc0665d987e0bf24 snyk-fix-badf8cd7fc1f284699352ace871e5075 snyk-fix-d1c97e9d4144298a9396308ed03ebd9e snyk-fix-d368e29b07323337ebe6ba0e289d85e7 snyk-fix-d5e919722918d14db890a368b9964203 span-metrics spanAggregatesAPI test test-dropdown-fix trace-gantt-chart trace-search troubleshoot ttl-get-int ttl-plus update-zoom-px uuid-server wip-release-0.11.1 0.3.5 0.2.2 v0.11.3 v0.11.3-rc.1 v0.11.2 v0.11.2-rc.3 v0.11.2-rc.2 v0.11.2-rc.1 v0.11.1 v0.11.1-rc.1 v0.11.0 v0.11.0-rc.1 v0.11 v0.10.2 v0.10.1 v0.10.1-rc.1 v0.10.0 v0.10.0-rc2 v0.10.0-rc1 v0.10 v0.9.2 v0.9.2-rc1 v0.9.1 v0.9.0 v0.9.0-rc2 v0.9.0-rc1 v0.9 v0.8.2 v0.8.1 v0.8.1-rc5 v0.8.1-rc4 v0.8.1-rc3 v0.8.1-rc2 v0.8.1-rc1 v0.8.0 v0.8.0-rc6 v0.8.0-rc5 v0.8.0-rc4 v0.8.0-rc3 v0.8.0-rc2 v0.8.0-rc1 v0.8 v0.7.5 v0.7.5-rc2 v0.7.5-rc1 v0.7.4 v0.7.4-rc2 v0.7.4-rc1 v0.7.3 v0.7.2 v0.7.2-rc1 v0.7.1 v0.7.0 v0.7 v0.6.2 v0.6.1 v0.6.0 v0.6 v0.5.4 v0.5.3 v0.5.2 v0.5.1 v0.5.0 v0.4.5 v0.4.4 v0.4.3 v0.4.2 v0.4.1 v0.4.0 v0.3.6 v0.3.5 v0.3.4 v0.3.3 v0.3.2 v0.3.1 v0.2.2
No related merge requests found
Showing with 184 additions and 92 deletions
+184 -92
export enum LOCAL_STORAGE {
METRICS_TIME_IN_DURATION = "metricsTimeDuration",
METRICS_TIME_IN_DURATION = "metricsTimeDurations",
}
import React, { Suspense } from "react";
import { Layout, Spin } from "antd";
import { Spin } from "antd";
import { useThemeSwitcher } from "react-css-theme-switcher";
import ROUTES from "Src/constants/routes";
import { IS_LOGGED_IN } from "Src/constants/auth";
import {
BrowserRouter as Router,
Route,
Switch,
Redirect,
} from "react-router-dom";
import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom";
import SideNav from "./Nav/SideNav";
import TopNav from "./Nav/TopNav";
import BaseLayout from "./BaseLayout";
import {
ServiceMetrics,
ServiceMap,
......@@ -24,8 +18,6 @@ import {
IntstrumentationPage,
} from "Src/pages";
const { Content, Footer } = Layout;
const App = () => {
const { status } = useThemeSwitcher();
......@@ -34,47 +26,44 @@ const App = () => {
}
return (
<Router basename="/">
<Layout style={{ minHeight: "100vh" }}>
<SideNav />
<Layout className="site-layout">
<Content style={{ margin: "0 16px" }}>
<TopNav />
<Suspense fallback={<Spin size="large" />}>
<Switch>
<Route path={ROUTES.SIGN_UP} component={Signup} />
<Route path={ROUTES.SERVICE_METRICS} component={ServiceMetrics} />
<Route path={ROUTES.SERVICE_MAP} component={ServiceMap} />
<Route path={ROUTES.TRACES} exact component={TraceDetail} />
<Route path={ROUTES.TRACE_GRAPH} component={TraceGraph} />
<Route path={ROUTES.SETTINGS} exact component={SettingsPage} />
<Route
path={ROUTES.INSTRUMENTATION}
exact
component={IntstrumentationPage}
/>
<Route path={ROUTES.USAGE_EXPLORER} component={UsageExplorer} />
<Route path={ROUTES.APPLICATION} exact component={ServicesTable} />
<Route
path="/"
exact
render={() => {
return localStorage.getItem(IS_LOGGED_IN) === "yes" ? (
<Redirect to={ROUTES.APPLICATION} />
) : (
<Redirect to={ROUTES.SIGN_UP} />
);
}}
/>
</Switch>
</Suspense>
</Content>
<Footer style={{ textAlign: "center", fontSize: 10 }}>
SigNoz Inc. ©2020{" "}
</Footer>
</Layout>
</Layout>
</Router>
<BrowserRouter>
<Suspense fallback={<Spin size="large" />}>
<Route path={"/"}>
<Switch>
<BaseLayout>
<Route path={ROUTES.SIGN_UP} exact component={Signup} />
<Route path={ROUTES.APPLICATION} exact component={ServicesTable} />
<Route path={ROUTES.SERVICE_METRICS} exact component={ServiceMetrics} />
<Route path={ROUTES.SERVICE_MAP} exact component={ServiceMap} />
<Route path={ROUTES.TRACES} exact component={TraceDetail} />
<Route path={ROUTES.TRACE_GRAPH} exact component={TraceGraph} />
<Route path={ROUTES.SETTINGS} exact component={SettingsPage} />
<Route
path={ROUTES.INSTRUMENTATION}
exact
component={IntstrumentationPage}
/>
<Route
path={ROUTES.USAGE_EXPLORER}
exactexact
component={UsageExplorer}
/>
<Route
path="/"
exact
render={() => {
return localStorage.getItem(IS_LOGGED_IN) === "yes" ? (
<Redirect to={ROUTES.APPLICATION} />
) : (
<Redirect to={ROUTES.SIGN_UP} />
);
}}
/>
</BaseLayout>
</Switch>
</Route>
</Suspense>
</BrowserRouter>
);
};
......
import React, { ReactNode } from "react";
import { Layout } from "antd";
import SideNav from "./Nav/SideNav";
import TopNav from "./Nav/TopNav";
const { Content, Footer } = Layout;
interface BaseLayoutProps {
children: ReactNode;
}
const BaseLayout: React.FC<BaseLayoutProps> = ({ children }) => {
return (
<Layout style={{ minHeight: "100vh" }}>
<SideNav />
<Layout className="site-layout">
<Content style={{ margin: "0 16px" }}>
<TopNav />
{children}
</Content>
<Footer style={{ textAlign: "center", fontSize: 10 }}>
SigNoz Inc. ©2020{" "}
</Footer>
</Layout>
</Layout>
);
};
export default BaseLayout;
import React, { useEffect, useState } from "react";
import { cloneDeep } from "lodash";
import { Select as DefaultSelect, Button, Space, Form } from "antd";
import styled from "styled-components";
import { withRouter } from "react-router";
import { getLocalStorageRouteKey } from "./utils";
import { RouteComponentProps, useLocation } from "react-router-dom";
import { connect } from "react-redux";
import ROUTES from "Src/constants/routes";
import { findIndex } from "lodash";
import CustomDateTimeModal from "./CustomDateTimeModal";
import { GlobalTime, updateTimeInterval } from "../../../store/actions";
import { StoreState } from "../../../store/reducers";
......@@ -25,9 +26,7 @@ const DateTimeWrapper = styled.div`
margin-top: 20px;
justify-content: flex-end !important;
`;
const Select = styled(DefaultSelect)`
width: 150px;
`;
const Select = styled(DefaultSelect)``;
interface DateTimeSelectorProps extends RouteComponentProps<any> {
currentpath?: string;
updateTimeInterval: Function;
......@@ -39,14 +38,23 @@ This components is mounted all the time. Use event listener to track changes.
*/
const _DateTimeSelector = (props: DateTimeSelectorProps) => {
const location = useLocation();
const LocalStorageRouteKey: string = getLocalStorageRouteKey(
location.pathname,
);
const timeDurationInLocalStorage =
JSON.parse(localStorage.getItem(LOCAL_STORAGE.METRICS_TIME_IN_DURATION)) ||
{};
const options =
location.pathname === ROUTES.SERVICE_MAP ? ServiceMapOptions : Options;
const defaultTime =
location.pathname === ROUTES.SERVICE_MAP ||
location.pathname === ROUTES.APPLICATION
? DefaultOptionsBasedOnRoute[location.pathname]
: DefaultOptionsBasedOnRoute.default;
let defaultTime = DefaultOptionsBasedOnRoute[LocalStorageRouteKey]
? DefaultOptionsBasedOnRoute[LocalStorageRouteKey]
: DefaultOptionsBasedOnRoute.default;
if (timeDurationInLocalStorage[LocalStorageRouteKey]) {
defaultTime = timeDurationInLocalStorage[LocalStorageRouteKey];
}
const [currentLocalStorageRouteKey, setCurrentLocalStorageRouteKey] = useState(
LocalStorageRouteKey,
);
const [customDTPickerVisible, setCustomDTPickerVisible] = useState(false);
const [timeInterval, setTimeInterval] = useState(defaultTime);
const [startTime, setStartTime] = useState<moment.Moment | null>(null);
......@@ -57,9 +65,6 @@ const _DateTimeSelector = (props: DateTimeSelectorProps) => {
const [form_dtselector] = Form.useForm();
const updateTimeOnQueryParamChange = () => {
const timeDurationInLocalStorage = localStorage.getItem(
LOCAL_STORAGE.METRICS_TIME_IN_DURATION,
);
const urlParams = new URLSearchParams(location.search);
const intervalInQueryParam = urlParams.get(METRICS_PAGE_QUERY_PARAM.interval);
const startTimeString = urlParams.get(METRICS_PAGE_QUERY_PARAM.startTime);
......@@ -75,25 +80,38 @@ const _DateTimeSelector = (props: DateTimeSelectorProps) => {
const startTime = moment(Number(startTimeString));
const endTime = moment(Number(endTimeString));
setCustomTime(startTime, endTime, true);
} else if (currentLocalStorageRouteKey !== LocalStorageRouteKey) {
setMetricsTimeInterval(defaultTime);
setCurrentLocalStorageRouteKey(LocalStorageRouteKey);
}
// first pref: handle intervalInQueryParam
else if (intervalInQueryParam) {
window.localStorage.setItem(
LOCAL_STORAGE.METRICS_TIME_IN_DURATION,
intervalInQueryParam,
);
setMetricsTimeInterval(intervalInQueryParam);
} else if (timeDurationInLocalStorage) {
setMetricsTimeInterval(timeDurationInLocalStorage);
}
};
const setToLocalStorage = (val: string) => {
let timeDurationInLocalStorageObj = cloneDeep(timeDurationInLocalStorage);
if (timeDurationInLocalStorageObj) {
timeDurationInLocalStorageObj[LocalStorageRouteKey] = val;
} else {
timeDurationInLocalStorageObj = {
[LocalStorageRouteKey]: val,
};
}
window.localStorage.setItem(
LOCAL_STORAGE.METRICS_TIME_IN_DURATION,
JSON.stringify(timeDurationInLocalStorageObj),
);
};
useEffect(() => {
setMetricsTimeInterval(defaultTime);
}, []);
// On URL Change
useEffect(() => {
updateTimeOnQueryParamChange();
if (findIndex(options, (option) => option.value === timeInterval) === -1) {
setTimeInterval(defaultTime);
}
}, [location]);
const setMetricsTimeInterval = (value: string) => {
......@@ -101,8 +119,7 @@ const _DateTimeSelector = (props: DateTimeSelectorProps) => {
setTimeInterval(value);
setEndTime(null);
setStartTime(null);
window.localStorage.setItem(LOCAL_STORAGE.METRICS_TIME_IN_DURATION, value);
setToLocalStorage(value);
};
const setCustomTime = (
startTime: moment.Moment,
......@@ -259,8 +276,10 @@ const mapStateToProps = (state: StoreState): { globalTime: GlobalTime } => {
return { globalTime: state.globalTime };
};
export const DateTimeSelector = connect(mapStateToProps, {
updateTimeInterval: updateTimeInterval,
})(_DateTimeSelector);
export const DateTimeSelector = withRouter(
connect(mapStateToProps, {
updateTimeInterval: updateTimeInterval,
})(_DateTimeSelector),
);
export default withRouter(DateTimeSelector);
export default DateTimeSelector;
......@@ -19,5 +19,6 @@ export const ServiceMapOptions = [
export const DefaultOptionsBasedOnRoute = {
[ROUTES.SERVICE_MAP]: ServiceMapOptions[0].value,
[ROUTES.APPLICATION]: Options[0].value,
[ROUTES.SERVICE_METRICS]: Options[2].value,
default: Options[2].value,
};
import ROUTES from "Src/constants/routes";
export const getLocalStorageRouteKey = (pathName: string) => {
let localStorageKey = "";
const pathNameSplit = pathName.split("/");
if (!pathNameSplit[2]) {
localStorageKey = pathName;
} else {
Object.keys(ROUTES).forEach((key) => {
if (ROUTES[key].indexOf(":") > -1) {
if (ROUTES[key].indexOf(pathNameSplit[1]) > -1) {
localStorageKey = ROUTES[key];
}
}
});
}
return localStorageKey;
};
......@@ -4,6 +4,7 @@ import { InfoCircleOutlined } from "@ant-design/icons";
import { Select } from "antd";
import styled from "styled-components";
const { Option } = Select;
import { cloneDeep } from "lodash";
const Container = styled.div`
margin-top: 12px;
......@@ -25,14 +26,25 @@ const Container = styled.div`
interface SelectServiceProps {
services: servicesItem[];
zoomToService: (arg0: string) => void;
zoomToDefault: () => void;
}
const defaultOption = {
serviceName: "Default"
};
const SelectService = (props: SelectServiceProps) => {
const [selectedVal, setSelectedVal] = useState<string>();
const { services, zoomToService } = props;
const [selectedVal, setSelectedVal] = useState<string>(defaultOption.serviceName);
const { zoomToService, zoomToDefault } = props;
const services = cloneDeep(props.services);
services.unshift(defaultOption)
const handleSelect = (value: string) => {
if(value === defaultOption.serviceName){
zoomToDefault()
} else {
zoomToService(value);
}
setSelectedVal(value);
zoomToService(value);
};
return (
<Container>
......
......@@ -10,7 +10,8 @@ import {
import { Spin } from "antd";
import styled from "styled-components";
import { StoreState } from "../../store/reducers";
import { getGraphData, getTooltip, transformLabel } from "./utils";
import { getZoomPx, getGraphData, getTooltip, transformLabel } from "./utils";
import SelectService from "./SelectService";
import { ForceGraph2D } from "react-force-graph";
......@@ -72,7 +73,11 @@ const ServiceMap = (props: ServiceMapProps) => {
}
const zoomToService = (value: string) => {
fgRef && fgRef.current.zoomToFit(700, 380, (e) => e.id === value);
fgRef && fgRef.current.zoomToFit(700, getZoomPx(), (e) => e.id === value);
};
const zoomToDefault = () => {
fgRef && fgRef.current.zoomToFit(100, 120);
};
const { nodes, links } = getGraphData(serviceMap);
......@@ -82,13 +87,11 @@ const ServiceMap = (props: ServiceMapProps) => {
<SelectService
services={serviceMap.services}
zoomToService={zoomToService}
zoomToDefault={zoomToDefault}
/>
<ForceGraph2D
ref={fgRef}
cooldownTicks={100}
onEngineStop={() => {
fgRef.current.zoomToFit(100, 120);
}}
graphData={graphData}
nodeLabel={getTooltip}
linkAutoColorBy={(d) => d.target}
......@@ -106,7 +109,7 @@ const ServiceMap = (props: ServiceMapProps) => {
ctx.fill();
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = "#333333";
ctx.fillStyle = "#646464";
ctx.fillText(label, node.x, node.y);
}}
onNodeClick={(node) => {
......
......@@ -74,6 +74,17 @@ export const getGraphData = (serviceMap: serviceMapStore): graphDataType => {
};
};
export const getZoomPx = (): number => {
const width = window.screen.width;
if (width < 1400) {
return 190;
} else if (width > 1400 && width < 1700) {
return 380;
} else if (width > 1700) {
return 470;
}
};
export const getTooltip = (node: {
p99: number;
errorRate: number;
......
......@@ -38,6 +38,11 @@ export interface servicesAction {
export const getServiceMapItems = (globalTime: GlobalTime) => {
return async (dispatch: Dispatch) => {
dispatch<serviceMapItemAction>({
type: ActionTypes.getServiceMapItems,
payload: [],
});
let request_string =
"/serviceMapDependencies?start=" +
globalTime.minTime +
......@@ -45,7 +50,7 @@ export const getServiceMapItems = (globalTime: GlobalTime) => {
globalTime.maxTime;
const response = await api.get<servicesMapItem[]>(apiV1 + request_string);
dispatch<serviceMapItemAction>({
type: ActionTypes.getServiceMapItems,
payload: response.data,
......@@ -55,11 +60,16 @@ export const getServiceMapItems = (globalTime: GlobalTime) => {
export const getDetailedServiceMapItems = (globalTime: GlobalTime) => {
return async (dispatch: Dispatch) => {
dispatch<servicesAction>({
type: ActionTypes.getServices,
payload: [],
});
let request_string =
"/services?start=" + globalTime.minTime + "&end=" + globalTime.maxTime;
const response = await api.get<servicesItem[]>(apiV1 + request_string);
dispatch<servicesAction>({
type: ActionTypes.getServices,
payload: response.data,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment