Skip to content

Commit

Permalink
Merge pull request #1722 from pcbailey/add-top-consumers-dashboard-card
Browse files Browse the repository at this point in the history
Add the top consumers card to dashboard
  • Loading branch information
openshift-merge-robot committed Jul 18, 2019
2 parents 0684689 + f9a7c14 commit 3bcde7c
Show file tree
Hide file tree
Showing 17 changed files with 397 additions and 43 deletions.
18 changes: 17 additions & 1 deletion frontend/packages/console-demo-plugin/src/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
DashboardsInventoryItemGroup,
DashboardsOverviewQuery,
DashboardsOverviewUtilizationItem,
DashboardsOverviewTopConsumerItem,
} from '@console/plugin-sdk';

// TODO(vojtech): internal code needed by plugins should be moved to console-shared package
Expand All @@ -28,6 +29,7 @@ import { FLAGS } from '@console/internal/const';
import { GridPosition } from '@console/internal/components/dashboard/grid';
import { humanizeBinaryBytesWithoutB } from '@console/internal/components/utils/units';
import { OverviewQuery } from '@console/internal/components/dashboards-page/overview-dashboard/queries';
import { MetricType } from '@console/internal/components/dashboard/top-consumers-card/metric-type';

import { FooBarModel } from './models';
import { yamlTemplates } from './yaml-templates';
Expand All @@ -53,7 +55,8 @@ type ConsumedExtensions =
| DashboardsOverviewInventoryItem
| DashboardsInventoryItemGroup
| DashboardsOverviewQuery
| DashboardsOverviewUtilizationItem;
| DashboardsOverviewUtilizationItem
| DashboardsOverviewTopConsumerItem;

const plugin: Plugin<ConsumedExtensions> = [
{
Expand Down Expand Up @@ -242,6 +245,19 @@ const plugin: Plugin<ConsumedExtensions> = [
humanizeValue: humanizeBinaryBytesWithoutB,
},
},
{
type: 'Dashboards/Overview/TopConsumers/Item',
properties: {
name: 'Prometheus',
metric: 'pod_name',
queries: {
[MetricType.CPU]:
'sort(topk(5, pod_name:container_cpu_usage:sum{pod_name=~"prometheus-.*"}))',
},
mutator: (data) =>
data.map((datum) => ({ ...datum, x: (datum.x as string).replace('prometheus-', '') })),
},
},
];

export default plugin;
5 changes: 5 additions & 0 deletions frontend/packages/console-plugin-sdk/src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
isDashboardsInventoryItemGroup,
isDashboardsOverviewQuery,
isDashboardsOverviewUtilizationItem,
isDashboardsOverviewTopConsumerItem,
isOverviewResourceTab,
isOverviewCRD,
} from './typings';
Expand Down Expand Up @@ -92,6 +93,10 @@ export class ExtensionRegistry {
return this.extensions.filter(isDashboardsInventoryItemGroup);
}

public getDashboardsOverviewTopConsumerItems() {
return this.extensions.filter(isDashboardsOverviewTopConsumerItem);
}

public getOverviewResourceTabs() {
return this.extensions.filter(isOverviewResourceTab);
}
Expand Down
25 changes: 25 additions & 0 deletions frontend/packages/console-plugin-sdk/src/typings/dashboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { FirehoseResource, Humanize } from '@console/internal/components/utils';
import { K8sKind } from '@console/internal/module/k8s';
import { StatusGroupMapper } from '@console/internal/components/dashboard/inventory-card/inventory-item';
import { OverviewQuery } from '@console/internal/components/dashboards-page/overview-dashboard/queries';
import { ConsumerMutator } from '@console/internal/components/dashboards-page/overview-dashboard/top-consumers-card';
import { MetricType } from '@console/internal/components/dashboard/top-consumers-card/metric-type';

import { Extension } from './extension';
import { LazyLoader } from './types';
Expand Down Expand Up @@ -69,6 +71,20 @@ namespace ExtensionProperties {
query: string;
}

export interface DashboardsOverviewTopConsumerItem {
/** The name of the top consumer item */
name: string;

/** The name of the metric */
metric: string;

/** The queries which will be used to query prometheus */
queries: { [key in MetricType]?: string };

/** Function which can mutate results of parsed prometheus data */
mutator?: ConsumerMutator;
}

export interface DashboardsOverviewInventoryItem {
/** Resource which will be fetched and grouped by `mapper` function. */
resource: FirehoseResource;
Expand Down Expand Up @@ -183,4 +199,13 @@ export const isDashboardsInventoryItemGroup = (
e: Extension<any>,
): e is DashboardsInventoryItemGroup => e.type === 'Dashboards/Inventory/Item/Group';

export interface DashboardsOverviewTopConsumerItem
extends Extension<ExtensionProperties.DashboardsOverviewTopConsumerItem> {
type: 'Dashboards/Overview/TopConsumers/Item';
}

export const isDashboardsOverviewTopConsumerItem = (
e: Extension<any>,
): e is DashboardsOverviewTopConsumerItem => e.type === 'Dashboards/Overview/TopConsumers/Item';

export type DashboardCardSpan = 4 | 6 | 12;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';

export const ConsumersBody: React.FC<ConsumersBodyProps> = React.memo(({ children }) => (
<div className="co-consumers-card__body">
{children}
</div>
));

type ConsumersBodyProps = {
children?: React.ReactNode;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import * as React from 'react';

import { CPU_DESC, MEMORY_DESC, STORAGE_DESC, NETWORK_DESC } from './strings';
import { humanizeNumber, humanizeBinaryBytesWithoutB, humanizeDecimalBytesPerSec, Humanize } from '../../utils';
import { MetricType } from './metric-type';

export const metricTypeMap: MetricTypeMap = {
[MetricType.CPU]: {
description: CPU_DESC,
humanize: humanizeNumber,
},
[MetricType.MEMORY]: {
description: MEMORY_DESC,
humanize: humanizeBinaryBytesWithoutB,
},
[MetricType.STORAGE]: {
description: STORAGE_DESC,
humanize: humanizeNumber,
},
[MetricType.NETWORK]: {
description: NETWORK_DESC,
humanize: humanizeDecimalBytesPerSec,
},
};

export const ConsumersFilter: React.FC<ConsumersFilterProps> = ({ children }) =>
<div className="co-consumers-card__filters">{children}</div>;

type ConsumersFilterProps = {
children: React.ReactNode;
};

type MetricTypeMap = {
[key: string]: {
description: string,
humanize: Humanize,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './consumers-filter';
export * from './consumers-body';
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum MetricType {
CPU = 'By CPU',
MEMORY = 'By Memory',
STORAGE = 'By Storage',
NETWORK = 'By Network',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const CPU_DESC = 'CPU time';
export const MEMORY_DESC = 'Memory consumption';
export const STORAGE_DESC = 'Filesystem IO time';
export const NETWORK_DESC = 'Network consumption';

export const PODS = 'Pods';
export const NODES = 'Nodes';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.co-consumers-card__filters {
border-bottom: 1px solid $pf-color-black-300;
display: flex;
padding-bottom: 0.6em;
}

.co-consumers-card__body {
text-align: center;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { CapacityBody, CapacityItem } from '../../dashboard/capacity-card';
import { withDashboardResources, DashboardItemProps } from '../with-dashboard-resources';
import { humanizePercentage, humanizeDecimalBytesPerSec, humanizeBinaryBytesWithoutB } from '../../utils';
import { getInstantVectorStats, getRangeVectorStats, GetStats } from '../../graphs/utils';
import { OverviewQuery, overviewQueries } from './queries';
import { OverviewQuery, capacityQueries } from './queries';

const getLastStats = (response, getStats: GetStats): React.ReactText => {
const stats = getStats(response);
Expand All @@ -27,7 +27,7 @@ const getQueries = () => {
pluginQueries[queryKey] = pluginQuery.properties.query;
}
});
return _.defaults(pluginQueries, overviewQueries);
return _.defaults(pluginQueries, capacityQueries);
};

export const CapacityCard_: React.FC<DashboardItemProps> = ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import { CapacityCard } from './capacity-card';
import { InventoryCard } from './inventory-card';
import { EventsCard } from './events-card';
import { UtilizationCard } from './utilization-card';
import { TopConsumersCard } from './top-consumers-card';

export const OverviewDashboard: React.FC<{}> = () => {
const mainCards = [{Card: HealthCard}, {Card: CapacityCard}, {Card: UtilizationCard}];
const leftCards = [{Card: DetailsCard}, {Card: InventoryCard}];
const rightCards = [{Card: EventsCard}];
const rightCards = [{Card: EventsCard}, {Card: TopConsumersCard}];

return (
<Dashboard>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,58 @@ export enum OverviewQuery {
CPU_UTILIZATION = 'CPU_UTILIZATION',
STORAGE_UTILIZATION = 'STORAGE_UTILIZATION',
STORAGE_TOTAL = 'STORAGE_TOTAL',
PODS_BY_CPU = 'PODS_BY_CPU',
PODS_BY_MEMORY = 'PODS_BY_MEMORY',
PODS_BY_STORAGE = 'PODS_BY_STORAGE',
PODS_BY_NETWORK = 'PODS_BY_NETWORK',
NODES_BY_CPU = 'NODES_BY_CPU',
NODES_BY_MEMORY = 'NODES_BY_MEMORY',
NODES_BY_STORAGE = 'NODES_BY_STORAGE',
NODES_BY_NETWORK = 'NODES_BY_NETWORK',
}

export const overviewQueries = {
const overviewQueries = {
[OverviewQuery.MEMORY_TOTAL]: 'sum(kube_node_status_capacity_memory_bytes)',
[OverviewQuery.MEMORY_UTILIZATION]: '(sum(kube_node_status_capacity_memory_bytes) - sum(kube_node_status_allocatable_memory_bytes))[60m:5m]',
[OverviewQuery.NETWORK_TOTAL]: 'sum(avg by(instance)(node_network_speed_bytes))',
[OverviewQuery.NETWORK_UTILIZATION]: 'sum(node:node_net_utilisation:sum_irate)',
[OverviewQuery.CPU_UTILIZATION]: '((sum(node:node_cpu_utilisation:avg1m) / count(node:node_cpu_utilisation:avg1m)) * 100)[60m:5m]',
[OverviewQuery.STORAGE_UTILIZATION]: '(sum(node_filesystem_size_bytes) - sum(node_filesystem_free_bytes))[60m:5m]',
[OverviewQuery.STORAGE_TOTAL]: 'sum(node_filesystem_size_bytes)',
[OverviewQuery.PODS_BY_CPU]: 'sort(topk(5, pod_name:container_cpu_usage:sum))',
[OverviewQuery.PODS_BY_MEMORY]: 'sort(topk(5, pod_name:container_memory_usage_bytes:sum))',
[OverviewQuery.PODS_BY_STORAGE]: 'sort(topk(5, avg by (pod_name)(irate(container_fs_io_time_seconds_total{container_name="POD", pod_name!=""}[1m]))))',
[OverviewQuery.PODS_BY_NETWORK]: `sort(topk(5, sum by (pod_name)(irate(container_network_receive_bytes_total{container_name="POD", pod_name!=""}[1m]) +
irate(container_network_transmit_bytes_total{container_name="POD", pod_name!=""}[1m]))))`,
[OverviewQuery.NODES_BY_CPU]: 'sort(topk(5, node:node_cpu_utilisation:avg1m))',
[OverviewQuery.NODES_BY_MEMORY]: 'sort(topk(5, node:node_memory_bytes_total:sum - node:node_memory_bytes_available:sum))',
[OverviewQuery.NODES_BY_STORAGE]: 'sort(topk(5, node:node_disk_utilisation:avg_irate{cluster=""}))',
[OverviewQuery.NODES_BY_NETWORK]: 'sort(topk(5, node:node_net_utilisation:sum_irate{cluster=""}))',
};

export const capacityQueries = {
[OverviewQuery.MEMORY_TOTAL]: overviewQueries[OverviewQuery.MEMORY_TOTAL],
[OverviewQuery.MEMORY_UTILIZATION]: overviewQueries[OverviewQuery.MEMORY_UTILIZATION],
[OverviewQuery.NETWORK_TOTAL]: overviewQueries[OverviewQuery.NETWORK_TOTAL],
[OverviewQuery.NETWORK_UTILIZATION]: overviewQueries[OverviewQuery.NETWORK_UTILIZATION],
[OverviewQuery.CPU_UTILIZATION]: overviewQueries[OverviewQuery.CPU_UTILIZATION],
[OverviewQuery.STORAGE_UTILIZATION]: overviewQueries[OverviewQuery.STORAGE_UTILIZATION],
[OverviewQuery.STORAGE_TOTAL]: overviewQueries[OverviewQuery.STORAGE_TOTAL],
};

export const utilizationQueries = {
[OverviewQuery.CPU_UTILIZATION]: overviewQueries[OverviewQuery.CPU_UTILIZATION],
[OverviewQuery.MEMORY_UTILIZATION]: overviewQueries[OverviewQuery.MEMORY_UTILIZATION],
[OverviewQuery.STORAGE_UTILIZATION]: overviewQueries[OverviewQuery.STORAGE_UTILIZATION],
};

export const topConsumersQueries = {
[OverviewQuery.PODS_BY_CPU]: overviewQueries[OverviewQuery.PODS_BY_CPU],
[OverviewQuery.PODS_BY_MEMORY]: overviewQueries[OverviewQuery.PODS_BY_MEMORY],
[OverviewQuery.PODS_BY_STORAGE]: overviewQueries [OverviewQuery.PODS_BY_STORAGE],
[OverviewQuery.PODS_BY_NETWORK]: overviewQueries[OverviewQuery.PODS_BY_NETWORK],
[OverviewQuery.NODES_BY_CPU]: overviewQueries[OverviewQuery.NODES_BY_CPU],
[OverviewQuery.NODES_BY_MEMORY]: overviewQueries[OverviewQuery.NODES_BY_MEMORY],
[OverviewQuery.NODES_BY_STORAGE]: overviewQueries[OverviewQuery.NODES_BY_STORAGE],
[OverviewQuery.NODES_BY_NETWORK]: overviewQueries[OverviewQuery.NODES_BY_NETWORK],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.co-overview-consumers__dropdown {
width: 100%;
}

.co-overview-consumers__dropdown--left {
padding-left: 0.3em;
}

.co-overview-consumers__dropdown--right {
padding-right: 0.3em;
}

0 comments on commit 3bcde7c

Please sign in to comment.