Skip to content

Commit

Permalink
Merge pull request openshift-pipelines#28 from vikram-raj/odc-7443
Browse files Browse the repository at this point in the history
ODC-7443: Integrate metrics tab for Pipeline and Repository with Summary API
  • Loading branch information
openshift-merge-bot[bot] authored Dec 14, 2023
2 parents 617d463 + 09a6e7c commit 325b942
Show file tree
Hide file tree
Showing 11 changed files with 226 additions and 87 deletions.
18 changes: 18 additions & 0 deletions console-extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,24 @@
"required": ["PIPELINE_TEKTON_RESULT_INSTALLED"]
}
},
{
"type": "console.tab/horizontalNav",
"properties": {
"model": {
"group": "pipelinesascode.tekton.dev",
"version": "v1alpha1",
"kind": "Repository"
},
"page": {
"name": "%Metrics%",
"href": "metrics"
},
"component": { "$codeRef": "metricsComponent.PipelinesMetricsPage" }
},
"flags": {
"required": ["PIPELINE_TEKTON_RESULT_INSTALLED"]
}
},
{
"type": "console.flag/hookProvider",
"properties": {
Expand Down
2 changes: 0 additions & 2 deletions locales/en/plugin__pipeline-console-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"3 days": "3 days",
"3 weeks": "3 weeks",
"4 weeks": "4 weeks",
"Administrators can try this quick start to configure their metrics level to pipelinerun and taskrun. The pipelinerun and taskrun metrics level collects large volume of metrics over time in unbounded cardinality which may lead to metrics unreliability.": "Administrators can try this quick start to configure their metrics level to pipelinerun and taskrun. The pipelinerun and taskrun metrics level collects large volume of metrics over time in unbounded cardinality which may lead to metrics unreliability.",
"All": "All",
"Average duration": "Average duration",
"Average Duration": "Average Duration",
Expand All @@ -32,7 +31,6 @@
"Per Pipeline": "Per Pipeline",
"Per Repository": "Per Repository",
"Pipeline": "Pipeline",
"Pipeline metrics configuration defaults to pipelines and task level": "Pipeline metrics configuration defaults to pipelines and task level",
"PipelineRun status": "PipelineRun status",
"Pipelines": "Pipelines",
"Project": "Project",
Expand Down
62 changes: 58 additions & 4 deletions src/components/pipelines-metrics/PipelinesAverageDuration.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import * as _ from 'lodash';
import _ from 'lodash';
import * as classNames from 'classnames';
import { useTranslation } from 'react-i18next';
import { DomainPropType, DomainTuple } from 'victory-core';
Expand All @@ -15,23 +15,38 @@ import {
import { Card, CardBody, CardTitle } from '@patternfly/react-core';
import {
formatDate,
getDropDownDate,
getXaxisValues,
parsePrometheusDuration,
timeToMinutes,
} from '../pipelines-overview/dateTime';
import { ALL_NAMESPACES_KEY } from '../../consts';
import { DataType } from '../utils/tekton-results';
import { SummaryResponse, getResultsSummary } from '../utils/summary-api';
import { getFilter, useInterval } from '../pipelines-overview/utils';

interface PipelinesAverageDurationProps {
timespan?: number;
domain?: DomainPropType;
bordered?: boolean;
interval?: number;
parentName?: string;
kind?: string;
namespace?: string;
}
type DomainType = { x?: DomainTuple; y?: DomainTuple };

const PipelinesAverageDuration: React.FC<PipelinesAverageDurationProps> = ({
timespan,
domain,
bordered,
interval,
parentName,
namespace,
kind,
}) => {
const { t } = useTranslation('plugin__pipeline-console-plugin');
const [data, setData] = React.useState<SummaryResponse>();
const startTimespan = timespan - parsePrometheusDuration('1d');
const endDate = new Date(Date.now()).setHours(0, 0, 0, 0);
const startDate = new Date(Date.now() - startTimespan).setHours(0, 0, 0, 0);
Expand All @@ -40,10 +55,45 @@ const PipelinesAverageDuration: React.FC<PipelinesAverageDurationProps> = ({
x: domainX || [startDate, endDate],
y: domainY || undefined,
};

if (namespace == ALL_NAMESPACES_KEY) {
namespace = '-';
}

const tickValues = getXaxisValues(timespan);

const date = getDropDownDate(timespan).toISOString();

const getSummaryData = () => {
const summaryOpt = {
summary: 'avg_duration',
data_type: DataType.PipelineRun,
filter: getFilter(date, parentName, kind),
groupBy: 'day',
};

getResultsSummary(namespace, summaryOpt)
.then((d) => {
setData(d);
})
.catch((e) => {
throw e;
});
};

useInterval(getSummaryData, interval, namespace, date);

const chartData = tickValues.map((value) => {
return { x: value, y: 100 };
const s = data?.summary.find((d) => {
return (
new Date(d.group_value * 1000).toDateString() ===
new Date(value).toDateString()
);
});
return {
x: value,
y: timeToMinutes(s?.avg_duration) || 0,
};
});

if (!domainY) {
Expand Down Expand Up @@ -94,7 +144,7 @@ const PipelinesAverageDuration: React.FC<PipelinesAverageDurationProps> = ({
<Chart
containerComponent={
<ChartVoronoiContainer
labels={({ datum }) => `${datum.y}`}
labels={({ datum }) => `${datum.y}m`}
constrainToVisibleArea
/>
}
Expand All @@ -115,7 +165,11 @@ const PipelinesAverageDuration: React.FC<PipelinesAverageDurationProps> = ({
style={xAxisStyle}
tickFormat={xTickFormat}
/>
<ChartAxis dependentAxis style={yAxisStyle} />
<ChartAxis
dependentAxis
style={yAxisStyle}
tickFormat={(v) => `${v}m`}
/>
<ChartGroup>
<ChartBar data={chartData} barWidth={18} />
</ChartGroup>
Expand Down
5 changes: 3 additions & 2 deletions src/components/pipelines-metrics/PipelinesMetrics.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.pipeline-metrics__alert {
margin: var(--pf-global--spacer--md);
.pipelines-metrix-dropdown {
margin-top: var(--pf-global--spacer--md);
margin-left: var(--pf-global--spacer--md);
}

.pipelines-metrics__background {
Expand Down
38 changes: 18 additions & 20 deletions src/components/pipelines-metrics/PipelinesMetricsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import * as React from 'react';
import { useParams } from 'react-router-dom-v5-compat';
import { useTranslation } from 'react-i18next';
import PipelineRunsStatusCard from '../pipelines-overview/PipelineRunsStatusCard';
import { Alert, Flex, FlexItem } from '@patternfly/react-core';
import { Flex, FlexItem } from '@patternfly/react-core';
import PipelinesRunsDurationCard from '../pipelines-overview/PipelineRunsDurationCard';
import PipelinesRunsNumbersChart from '../pipelines-overview/PipelineRunsNumbersChart';
import { parsePrometheusDuration } from '../pipelines-overview/dateTime';
import TimeRangeDropdown from '../pipelines-overview/TimeRangeDropdown';
import RefreshDropdown from '../pipelines-overview/RefreshDropdown';
import PipelinesAverageDuration from './PipelinesAverageDuration';
import { K8sResourceKind } from '@openshift-console/dynamic-plugin-sdk';
import './PipelinesMetrics.scss';

const PipelinesMetricsPage: React.FC = () => {
const { t } = useTranslation('plugin__pipeline-console-plugin');
type PipelinesMetricsPageProps = {
obj: K8sResourceKind;
};

const PipelinesMetricsPage: React.FC<PipelinesMetricsPageProps> = ({ obj }) => {
const params = useParams();
const { ns: namespace, name: parentName } = params;
const [timespan, setTimespan] = React.useState(parsePrometheusDuration('1w'));
Expand All @@ -22,21 +25,7 @@ const PipelinesMetricsPage: React.FC = () => {

return (
<>
<Alert
className="pipeline-metrics__alert"
isInline
variant="info"
title={t(
'Pipeline metrics configuration defaults to pipelines and task level',
)}
>
<p>
{t(
'Administrators can try this quick start to configure their metrics level to pipelinerun and taskrun. The pipelinerun and taskrun metrics level collects large volume of metrics over time in unbounded cardinality which may lead to metrics unreliability.',
)}
</p>
</Alert>
<Flex className="project-dropdown-label__flex">
<Flex className="pipelines-metrix-dropdown">
<FlexItem>
<TimeRangeDropdown timespan={timespan} setTimespan={setTimespan} />
</FlexItem>
Expand All @@ -51,6 +40,8 @@ const PipelinesMetricsPage: React.FC = () => {
domain={{ y: [0, 100] }}
bordered={false}
namespace={namespace}
parentName={parentName}
kind={obj.kind}
interval={interval}
/>

Expand All @@ -63,6 +54,8 @@ const PipelinesMetricsPage: React.FC = () => {
namespace={namespace}
parentName={parentName}
timespan={timespan}
interval={interval}
kind={obj.kind}
domain={{ y: [0, 500] }}
/>
</FlexItem>
Expand All @@ -72,7 +65,11 @@ const PipelinesMetricsPage: React.FC = () => {
>
<PipelinesAverageDuration
timespan={timespan}
domain={{ y: [0, 500] }}
domain={{ y: [0, 5] }}
namespace={namespace}
parentName={parentName}
interval={interval}
kind={obj.kind}
/>
</FlexItem>
<FlexItem
Expand All @@ -84,6 +81,7 @@ const PipelinesMetricsPage: React.FC = () => {
parentName={parentName}
timespan={timespan}
interval={interval}
kind={obj.kind}
/>
</FlexItem>
</Flex>
Expand Down
10 changes: 4 additions & 6 deletions src/components/pipelines-overview/PipelineRunsDurationCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
Grid,
GridItem,
} from '@patternfly/react-core';
import { SummaryProps, useInterval } from './utils';
import { SummaryProps, getFilter, useInterval } from './utils';
import { getResultsSummary } from '../utils/summary-api';
import { DataType } from '../utils/tekton-results';
import { ALL_NAMESPACES_KEY } from '../../consts';
Expand All @@ -30,6 +30,7 @@ interface PipelinesRunsDurationProps {
parentName?: string;
summaryData?: SummaryProps;
bordered?: boolean;
kind?: string;
}

const PipelinesRunsDurationCard: React.FC<PipelinesRunsDurationProps> = ({
Expand All @@ -38,6 +39,7 @@ const PipelinesRunsDurationCard: React.FC<PipelinesRunsDurationProps> = ({
parentName,
interval,
bordered,
kind,
}) => {
const { t } = useTranslation('plugin__pipeline-console-plugin');
const [summaryData, setSummaryData] = React.useState<SummaryProps>({});
Expand All @@ -51,16 +53,12 @@ const PipelinesRunsDurationCard: React.FC<PipelinesRunsDurationProps> = ({
}, [namespace, timespan]);

const date = getDropDownDate(timespan).toISOString();
let filter = '';
parentName
? (filter = `data.status.startTime>timestamp("${date}")&&data.metadata.labels['tekton.dev/pipeline']=="${parentName}"`)
: (filter = `data.status.startTime>timestamp("${date}")`);

const getSummaryData = () => {
getResultsSummary(namespace, {
summary: 'total_duration,avg_duration,max_duration',
data_type: DataType.PipelineRun,
filter,
filter: getFilter(date, parentName, kind),
})
.then((response) => {
setLoaded(true);
Expand Down
12 changes: 5 additions & 7 deletions src/components/pipelines-overview/PipelineRunsNumbersChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
import { DataType } from '../utils/tekton-results';
import { SummaryResponse, getResultsSummary } from '../utils/summary-api';
import { ALL_NAMESPACES_KEY } from '../../consts';
import { useInterval } from './utils';
import { getFilter, useInterval } from './utils';
import { LoadingInline } from '../Loading';

interface PipelinesRunsNumbersChartProps {
Expand All @@ -32,6 +32,7 @@ interface PipelinesRunsNumbersChartProps {
domain?: DomainPropType;
parentName?: string;
bordered?: boolean;
kind?: string;
}
type DomainType = { x?: DomainTuple; y?: DomainTuple };

Expand All @@ -42,6 +43,7 @@ const PipelinesRunsNumbersChart: React.FC<PipelinesRunsNumbersChartProps> = ({
domain,
parentName,
bordered,
kind,
}) => {
const { t } = useTranslation('plugin__pipeline-console-plugin');
const startTimespan = timespan - parsePrometheusDuration('1d');
Expand All @@ -59,20 +61,16 @@ const PipelinesRunsNumbersChart: React.FC<PipelinesRunsNumbersChartProps> = ({
if (namespace == ALL_NAMESPACES_KEY) {
namespace = '-';
}

const tickValues = getXaxisValues(timespan);

const date = getDropDownDate(timespan).toISOString();

let filter = '';
parentName
? (filter = `data.status.startTime>timestamp("${date}")&&data.metadata.labels['tekton.dev/pipeline']=="${parentName}"`)
: (filter = `data.status.startTime>timestamp("${date}")`);

const getSummaryData = () => {
const summaryOpt = {
summary: 'total',
data_type: DataType.PipelineRun,
filter,
filter: getFilter(date, parentName, kind),
groupBy: 'day',
};

Expand Down
10 changes: 7 additions & 3 deletions src/components/pipelines-overview/PipelineRunsStatusCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
getXaxisValues,
parsePrometheusDuration,
} from './dateTime';
import { useInterval } from './utils';
import { getFilter, useInterval } from './utils';
import { SummaryResponse, getResultsSummary } from '../utils/summary-api';
import { DataType } from '../utils/tekton-results';
import './PipelinesOverview.scss';
Expand All @@ -48,6 +48,8 @@ interface PipelinesRunsStatusCardProps {
bordered?: boolean;
namespace: string;
interval: number;
kind?: string;
parentName?: string;
}

type DomainType = { x?: DomainTuple; y?: DomainTuple };
Expand All @@ -58,6 +60,8 @@ const PipelinesRunsStatusCard: React.FC<PipelinesRunsStatusCardProps> = ({
bordered,
namespace,
interval,
parentName,
kind,
}) => {
const { t } = useTranslation('plugin__pipeline-console-plugin');
const [data, setData] = React.useState<SummaryResponse>();
Expand All @@ -80,7 +84,7 @@ const PipelinesRunsStatusCard: React.FC<PipelinesRunsStatusCardProps> = ({
const getSummaryData = (summary, setData, groupBy?) => {
const summaryOpt = {
summary,
filter: `data.status.startTime>timestamp("${date}")`,
filter: getFilter(date, parentName, kind),
data_type: DataType.PipelineRun,
};
groupBy && (summaryOpt['groupBy'] = groupBy);
Expand Down Expand Up @@ -300,7 +304,7 @@ const PipelinesRunsStatusCard: React.FC<PipelinesRunsStatusCardProps> = ({
}
scale={{ x: 'time', y: 'linear' }}
domain={domainValue}
domainPadding={{ x: [30, 25], y: [30, 25] }}
domainPadding={{ x: [30, 25] }}
height={200}
padding={{
top: 20,
Expand Down
Loading

0 comments on commit 325b942

Please sign in to comment.