Skip to content

Commit

Permalink
fix: add probe success rate to context (#269)
Browse files Browse the repository at this point in the history
  • Loading branch information
rdubrock committed May 10, 2021
1 parent 0a3861f commit 46b501c
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 29 deletions.
110 changes: 82 additions & 28 deletions src/components/SuccessRateContextProvider.tsx
@@ -1,11 +1,12 @@
import React, { PropsWithChildren, useContext, useEffect, useState } from 'react';
import { Check } from 'types';
import { Check, Probe } from 'types';
import { queryMetric } from 'utils';
import { InstanceContext } from 'contexts/InstanceContext';
import { SuccessRates, SuccessRateContext, SuccessRateTypes, SuccessRate } from 'contexts/SuccessRateContext';

interface Props {
checks: Check[];
checks?: Check[];
probes?: Probe[];
}

const values: SuccessRates = {
Expand All @@ -16,6 +17,7 @@ const values: SuccessRates = {
type SeedRequestMetric = {
instance: string;
job: string;
probe: string;
};

type SeedRequestValue = [number, string];
Expand All @@ -27,7 +29,63 @@ type SeedRequestItem = {

type SeedRequestResponse = SeedRequestItem[];

export function SuccessRateContextProvider({ checks, children }: PropsWithChildren<Props>) {
const parseCheckResults = (checks: Check[] | undefined, data: any) => {
if (!checks) {
return;
}

const response = data as SeedRequestResponse;
const resultsPerCheck = checks.reduce<SuccessRate>((acc, check) => {
if (!check.id) {
return acc;
}
acc[check.id] = undefined;
return acc;
}, {});

response.forEach((item) => {
const check = checks?.find((check) => check.job === item.metric.job && check.target === item.metric.instance);
if (check && check.id) {
const returnedValue = item.value?.[1];
if (returnedValue !== undefined) {
const float = parseFloat(returnedValue);
resultsPerCheck[check.id] = float;
}
}
});

return resultsPerCheck;
};

const parseProbeResults = (probes: Probe[] | undefined, data: any) => {
if (!probes) {
return {};
}

const response = data as SeedRequestResponse;
const resultsPerCheck = probes.reduce<SuccessRate>((acc, probe) => {
if (!probe.id) {
return acc;
}
acc[probe.id] = undefined;
return acc;
}, {});

response.forEach((item) => {
const check = probes?.find((probe) => probe.name === item.metric.probe);
if (check && check.id) {
const returnedValue = item.value?.[1];
if (returnedValue !== undefined) {
const float = parseFloat(returnedValue);
resultsPerCheck[check.id] = float;
}
}
});

return resultsPerCheck;
};

export function SuccessRateContextProvider({ checks, probes, children }: PropsWithChildren<Props>) {
const { instance } = useContext(InstanceContext);
const [successRateValues, setSuccessRate] = useState<SuccessRates>(values);
const [loading, setLoading] = useState(true);
Expand All @@ -49,11 +107,25 @@ export function SuccessRateContextProvider({ checks, children }: PropsWithChildr
useEffect(() => {
const getSuccessRates = async () => {
setLoading(true);
const uptimeQuery = `sum(rate(probe_all_success_sum[3h])) by (job, instance) / sum(rate(probe_all_success_count[3h])) by (job, instance)`;
const checkUptimeQuery =
'sum(rate(probe_all_success_sum[3h])) by (job, instance) / sum(rate(probe_all_success_count[3h])) by (job, instance)';
const probeUptimeQuery =
'sum(rate(probe_all_success_sum[3h])) by (probe) / sum(rate(probe_all_success_count[3h])) by (probe)';

const successRateType = checks ? SuccessRateTypes.Checks : SuccessRateTypes.Probes;

const uptimeQuery = successRateType === SuccessRateTypes.Checks ? checkUptimeQuery : probeUptimeQuery;

const url = instance?.api?.getMetricsDS()?.url;
if (!url || !checks.length) {

if (
!url ||
(successRateType === SuccessRateTypes.Checks && !checks?.length) ||
(successRateType === SuccessRateTypes.Probes && !probes?.length)
) {
return;
}

const now = Math.floor(Date.now() / 1000);
const start = now - 60 * 60 * 3;
const options = {
Expand All @@ -63,35 +135,17 @@ export function SuccessRateContextProvider({ checks, children }: PropsWithChildr
};
const { error, data } = await queryMetric(url, uptimeQuery, options);

const resultsByType =
successRateType === SuccessRateTypes.Checks ? parseCheckResults(checks, data) : parseProbeResults(probes, data);

if (error || !data) {
setLoading(false);
return;
}

const resultsPerCheck = checks.reduce<SuccessRate>((acc, check) => {
if (!check.id) {
return acc;
}
acc[check.id] = undefined;
return acc;
}, {});

const response = data as SeedRequestResponse;

response.forEach((item) => {
const check = checks?.find((check) => check.job === item.metric.job && check.target === item.metric.instance);
if (check && check.id) {
const returnedValue = item.value?.[1];
if (returnedValue !== undefined) {
const float = parseFloat(returnedValue);
resultsPerCheck[check.id] = float;
}
}
});

setSuccessRate((state) => ({
...state,
[SuccessRateTypes.Checks]: resultsPerCheck,
[successRateType]: resultsByType,
}));
setLoading(false);
};
Expand All @@ -104,7 +158,7 @@ export function SuccessRateContextProvider({ checks, children }: PropsWithChildr
}, 60 * 1000);

return () => clearInterval(interval);
}, [checks, instance.api]);
}, [checks, instance.api, probes]);

return (
<SuccessRateContext.Provider value={{ values: successRateValues, loading, updateSuccessRate }}>
Expand Down
7 changes: 6 additions & 1 deletion src/page/ProbesPage.tsx
Expand Up @@ -7,6 +7,7 @@ import { getLocationSrv } from '@grafana/runtime';
import ProbeEditor from 'components/ProbeEditor';
import { InstanceContext } from 'contexts/InstanceContext';
import { ProbeList } from 'components/ProbeList';
import { SuccessRateContextProvider } from 'components/SuccessRateContextProvider';

interface Props {
id?: string;
Expand Down Expand Up @@ -76,5 +77,9 @@ export const ProbesPage = ({ id }: Props) => {
} as Probe;
return <ProbeEditor probe={template} onReturn={onGoBack} />;
}
return <ProbeList probes={probes} onAddNew={() => setAddingNew(true)} onSelectProbe={onSelectProbe} />;
return (
<SuccessRateContextProvider probes={probes}>
<ProbeList probes={probes} onAddNew={() => setAddingNew(true)} onSelectProbe={onSelectProbe} />
</SuccessRateContextProvider>
);
};

0 comments on commit 46b501c

Please sign in to comment.