Pranshu Chittora f48a884f90
fix: eslint and tsc fixes for logs (#1527)
* fix: eslint and tsc fixes for logs

* chore: remove package-lock file
2022-08-19 17:16:04 +05:30

262 lines
8.1 KiB
TypeScript

import { ActiveElement, Chart, ChartData, ChartEvent } from 'chart.js';
import Graph from 'components/Graph';
import { METRICS_PAGE_QUERY_PARAM } from 'constants/query';
import ROUTES from 'constants/routes';
import FullView from 'container/GridGraphLayout/Graph/FullView';
import convertToNanoSecondsToSecond from 'lib/convertToNanoSecondsToSecond';
import { colors } from 'lib/getRandomColor';
import history from 'lib/history';
import { convertRawQueriesToTraceSelectedTags } from 'lib/resourceAttributes';
import { escapeRegExp } from 'lodash-es';
import React, { useMemo, useRef } from 'react';
import { useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';
import { AppState } from 'store/reducers';
import { PromQLWidgets } from 'types/api/dashboard/getAll';
import MetricReducer from 'types/reducer/metrics';
import { Card, Col, GraphContainer, GraphTitle, Row } from '../styles';
import TopOperationsTable from '../TopOperationsTable';
import { Button } from './styles';
function Application({ getWidget }: DashboardProps): JSX.Element {
const { servicename } = useParams<{ servicename?: string }>();
const selectedTimeStamp = useRef(0);
const {
topOperations,
serviceOverview,
resourceAttributePromQLQuery,
resourceAttributeQueries,
topLevelOperations,
} = useSelector<AppState, MetricReducer>((state) => state.metrics);
const operationsRegex = useMemo(() => {
return encodeURIComponent(
topLevelOperations.map((e) => escapeRegExp(e)).join('|'),
);
}, [topLevelOperations]);
const selectedTraceTags: string = JSON.stringify(
convertRawQueriesToTraceSelectedTags(resourceAttributeQueries, 'array') || [],
);
const onTracePopupClick = (timestamp: number): void => {
const currentTime = timestamp;
const tPlusOne = timestamp + 1 * 60 * 1000;
const urlParams = new URLSearchParams();
urlParams.set(METRICS_PAGE_QUERY_PARAM.startTime, currentTime.toString());
urlParams.set(METRICS_PAGE_QUERY_PARAM.endTime, tPlusOne.toString());
history.replace(
`${
ROUTES.TRACE
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&&isFilterExclude={"serviceName":false}&userSelectedFilter={"status":["error","ok"],"serviceName":["${servicename}"]}&spanAggregateCurrentPage=1&spanAggregateOrder=ascend`,
);
};
const onClickHandler = async (
event: ChartEvent,
elements: ActiveElement[],
chart: Chart,
data: ChartData,
from: string,
): Promise<void> => {
if (event.native) {
const points = chart.getElementsAtEventForMode(
event.native,
'nearest',
{ intersect: true },
true,
);
const id = `${from}_button`;
const buttonElement = document.getElementById(id);
if (points.length !== 0) {
const firstPoint = points[0];
if (data.labels) {
const time = data?.labels[firstPoint.index] as Date;
if (buttonElement) {
buttonElement.style.display = 'block';
buttonElement.style.left = `${firstPoint.element.x}px`;
buttonElement.style.top = `${firstPoint.element.y}px`;
selectedTimeStamp.current = time.getTime();
}
}
} else if (buttonElement && buttonElement.style.display === 'block') {
buttonElement.style.display = 'none';
}
}
};
const onErrorTrackHandler = (timestamp: number): void => {
const currentTime = timestamp;
const tPlusOne = timestamp + 1 * 60 * 1000;
const urlParams = new URLSearchParams();
urlParams.set(METRICS_PAGE_QUERY_PARAM.startTime, currentTime.toString());
urlParams.set(METRICS_PAGE_QUERY_PARAM.endTime, tPlusOne.toString());
history.replace(
`${
ROUTES.TRACE
}?${urlParams.toString()}?selected={"serviceName":["${servicename}"],"status":["error"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&isFilterExclude={"serviceName":false,"status":false}&userSelectedFilter={"serviceName":["${servicename}"],"status":["error"]}&spanAggregateCurrentPage=1&spanAggregateOrder=ascend`,
);
};
return (
<>
<Row gutter={24}>
<Col span={12}>
<Button
type="default"
size="small"
id="Service_button"
onClick={(): void => {
onTracePopupClick(selectedTimeStamp.current);
}}
>
View Traces
</Button>
<Card>
<GraphTitle>Latency</GraphTitle>
<GraphContainer>
<Graph
onClickHandler={(ChartEvent, activeElements, chart, data): void => {
onClickHandler(ChartEvent, activeElements, chart, data, 'Service');
}}
name="service_latency"
type="line"
data={{
datasets: [
{
data: serviceOverview.map((e) =>
parseFloat(convertToNanoSecondsToSecond(e.p99)),
),
borderColor: colors[0],
label: 'p99 Latency',
showLine: true,
borderWidth: 1.5,
spanGaps: true,
pointRadius: 1.5,
},
{
data: serviceOverview.map((e) =>
parseFloat(convertToNanoSecondsToSecond(e.p95)),
),
borderColor: colors[1],
label: 'p95 Latency',
showLine: true,
borderWidth: 1.5,
spanGaps: true,
pointRadius: 1.5,
},
{
data: serviceOverview.map((e) =>
parseFloat(convertToNanoSecondsToSecond(e.p50)),
),
borderColor: colors[2],
label: 'p50 Latency',
showLine: true,
borderWidth: 1.5,
spanGaps: true,
pointRadius: 1.5,
},
],
labels: serviceOverview.map((e) => {
return new Date(
parseFloat(convertToNanoSecondsToSecond(e.timestamp)),
);
}),
}}
yAxisUnit="ms"
/>
</GraphContainer>
</Card>
</Col>
<Col span={12}>
<Button
type="default"
size="small"
id="Rate_button"
onClick={(): void => {
onTracePopupClick(selectedTimeStamp.current);
}}
>
View Traces
</Button>
<Card>
<GraphTitle>Rate (ops/s)</GraphTitle>
<GraphContainer>
<FullView
name="operations_per_sec"
fullViewOptions={false}
onClickHandler={(event, element, chart, data): void => {
onClickHandler(event, element, chart, data, 'Rate');
}}
widget={getWidget([
{
query: `sum(rate(signoz_latency_count{service_name="${servicename}", operation=~\`${operationsRegex}\`${resourceAttributePromQLQuery}}[5m]))`,
legend: 'Operations',
},
])}
yAxisUnit="ops"
/>
</GraphContainer>
</Card>
</Col>
</Row>
<Row gutter={24}>
<Col span={12}>
<Button
type="default"
size="small"
id="Error_button"
onClick={(): void => {
onErrorTrackHandler(selectedTimeStamp.current);
}}
>
View Traces
</Button>
<Card>
<GraphTitle>Error Percentage</GraphTitle>
<GraphContainer>
<FullView
name="error_percentage_%"
fullViewOptions={false}
onClickHandler={(ChartEvent, activeElements, chart, data): void => {
onClickHandler(ChartEvent, activeElements, chart, data, 'Error');
}}
widget={getWidget([
{
query: `max(sum(rate(signoz_calls_total{service_name="${servicename}", operation=~\`${operationsRegex}\`, status_code="STATUS_CODE_ERROR"${resourceAttributePromQLQuery}}[5m]) OR rate(signoz_calls_total{service_name="${servicename}", operation=~\`${operationsRegex}\`, http_status_code=~"5.."${resourceAttributePromQLQuery}}[5m]))*100/sum(rate(signoz_calls_total{service_name="${servicename}", operation=~\`${operationsRegex}\`${resourceAttributePromQLQuery}}[5m]))) < 1000 OR vector(0)`,
legend: 'Error Percentage',
},
])}
yAxisUnit="%"
/>
</GraphContainer>
</Card>
</Col>
<Col span={12}>
<Card>
<TopOperationsTable data={topOperations} />
</Card>
</Col>
</Row>
</>
);
}
interface DashboardProps {
getWidget: (query: PromQLWidgets['query']) => PromQLWidgets;
}
export default Application;