Skip to content

Commit

Permalink
adds monitoring metrics component and legend
Browse files Browse the repository at this point in the history
  • Loading branch information
invincibleJai authored and vikram-raj committed Jan 21, 2020
1 parent 789499a commit 5b72d57
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,22 @@ describe('<PrometheusGraphLink />', () => {
expect(wrapper.find(Link).exists()).toBe(false);
wrapper = getWrapper('test');
expect(wrapper.find(Link).exists()).toBe(true);
expect(wrapper.find(Link).props().to).toEqual('/metrics?query0=test');
expect(wrapper.find(Link).props().to).toEqual('/dev-monitoring/ns/default/metrics?query0=test');

store.dispatch(UIActions.setActivePerspective('admin'));
wrapper = getWrapper('');
expect(wrapper.find(Link).exists()).toBe(false);
wrapper = getWrapper('test');
expect(wrapper.find(Link).exists()).toBe(true);
expect(wrapper.find(Link).props().to).toEqual('/metrics?query0=test');
expect(wrapper.find(Link).props().to).toEqual('/dev-monitoring/ns/default/metrics?query0=test');

store.dispatch(setFlag(FLAGS.CAN_GET_NS, true));
store.dispatch(UIActions.setActivePerspective('dev'));
wrapper = getWrapper('');
expect(wrapper.find(Link).exists()).toBe(false);
wrapper = getWrapper('test');
expect(wrapper.find(Link).exists()).toBe(true);
expect(wrapper.find(Link).props().to).toEqual('/metrics?query0=test');
expect(wrapper.find(Link).props().to).toEqual('/dev-monitoring/ns/default/metrics?query0=test');

store.dispatch(UIActions.setActivePerspective('admin'));
wrapper = getWrapper('');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { TechPreviewBadge, ALL_NAMESPACES_KEY } from '@console/shared';
import NamespacedPage, { NamespacedPageVariants } from '../NamespacedPage';
import ProjectListPage from '../projects/ProjectListPage';
import MonitoringDashboard from './dashboard/MonitoringDashboard';
import MonitoringMetrics from './metrics/MonitoringMetrics';
import ConectedMonitoringMetrics from './metrics/MonitoringMetrics';

export const MONITORING_ALL_NS_PAGE_URI = '/dev-monitoring/all-namespaces';

Expand Down Expand Up @@ -48,7 +48,7 @@ export const MonitoringPage: React.FC<MonitoringPageProps> = ({ match }) => {
{
href: 'metrics',
name: 'Metrics',
component: MonitoringMetrics,
component: ConectedMonitoringMetrics,
},
]}
match={match}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { QueryBrowser } from '@console/internal/components/monitoring/query-brow
import { Humanize } from '@console/internal/components/utils';
import { ByteDataTypes } from '@console/shared/src/graph-helper/data-utils';
import { Area } from '@console/internal/components/graphs/area';
import { PrometheusGraphLink } from '@console/internal/components/graphs/prometheus-graph';
import './MonitoringDashboardGraph.scss';

export enum GraphTypes {
Expand Down Expand Up @@ -34,12 +35,14 @@ const MonitoringDashboardGraph: React.FC<MonitoringDashboardGraphProps> = ({
{graphType === GraphTypes.line ? (
<>
<h5 className="graph-title">{title}</h5>
<QueryBrowser
hideControls
defaultTimespan={defaultTimespan}
namespace={namespace}
queries={[query]}
/>
<PrometheusGraphLink query={query}>
<QueryBrowser
hideControls
defaultTimespan={defaultTimespan}
namespace={namespace}
queries={[query]}
/>
</PrometheusGraphLink>
</>
) : (
<Area
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { template } from 'lodash';
import {
humanizeBinaryBytes,
humanizeCpuCores,
humanizeDecimalBytesPerSec,
} from '@console/internal/components/utils';
import { ByteDataTypes } from '@console/shared/src/graph-helper/data-utils';
import { GraphTypes } from './MonitoringDashboardGraph';

export const queries = [
{
query: template(
`topk(25, sort_desc(sum(avg_over_time(pod:container_cpu_usage:sum{container="",pod!="",namespace='<%= namespace %>'}[5m])) BY (pod, namespace)))`,
),
chartType: GraphTypes.area,
title: 'Stat 1',
humanize: humanizeCpuCores,
byteDataType: ByteDataTypes.BinaryBytes,
},
{
query: template(
`topk(25, sort_desc(sum(avg_over_time(container_memory_working_set_bytes{container="",pod!="",namespace='<%= namespace %>'}[5m])) BY (pod, namespace)))`,
),
chartType: GraphTypes.area,
title: 'Stat 2',
humanize: humanizeBinaryBytes,
byteDataType: ByteDataTypes.BinaryBytes,
},
{
query: template(
`topk(25, sort_desc(sum(pod:container_fs_usage_bytes:sum{container="",pod!="",namespace='<%= namespace %>'}) BY (pod, namespace)))`,
),
chartType: GraphTypes.line,
title: 'Stat 3',
humanize: humanizeBinaryBytes,
byteDataType: ByteDataTypes.BinaryBytes,
},
{
query: template(
`topk(25, sort_desc(sum(rate(container_network_receive_bytes_total{ container="POD", pod!= "", namespace = '<%= namespace %>'}[5m]) + rate(container_network_transmit_bytes_total{ container="POD", pod!= "", namespace = '<%= namespace %>'}[5m])) BY (namespace, pod)))`,
),
chartType: GraphTypes.line,
title: 'Stat 4',
humanize: humanizeDecimalBytesPerSec,
byteDataType: ByteDataTypes.BinaryBytes,
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.odc-metrics-dropdown {
margin-bottom: 20px;
&__menu {
max-height: 50vh;
overflow: auto;
width: 100%;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import * as React from 'react';
import { connect } from 'react-redux';
import * as fuzzy from 'fuzzysearch';
import { RootState } from '@console/internal/redux';
import { Dropdown } from '@console/internal/components/utils';
import { queryBrowserRunQueries, queryBrowserPatchQuery } from '@console/internal/actions/ui';
import { getActiveNamespace } from '@console/internal/reducers/ui';
import { QueryObj } from '@console/internal/components/monitoring/query-browser';
import { metricsQuery, getTopMetricsQueries } from '../queries';
import './MetricsDropdown.scss';

const ADD_NEW_QUERY = '#ADD_NEW_QUERY#';

type StateProps = {
namespace: string;
};

type MetricsDropdownProps = {
patchQuery: (patch: QueryObj) => void;
runQueries: () => never;
namespace: string;
};

export const MetricsDropdown: React.FC<MetricsDropdownProps> = ({
patchQuery,
runQueries,
namespace,
}) => {
const items = metricsQuery;
const autocompleteFilter = (text, item) => fuzzy(text, item);
const defaultActionItem = [
{
actionTitle: `Custom Query`,
actionKey: ADD_NEW_QUERY,
},
];

const [metric, setMetric] = React.useState('');
React.useEffect(() => {
if (metric && metric !== ADD_NEW_QUERY) {
const query = getTopMetricsQueries(namespace)[metric];
patchQuery({ text: query });
runQueries();
}
}, [metric, namespace, patchQuery, runQueries]);
const onChange = (selVal: string) => {
setMetric(selVal);
};

return (
<Dropdown
autocompleteFilter={autocompleteFilter}
items={items || {}}
actionItems={defaultActionItem}
dropDownClassName="odc-metrics-dropdown dropdown--full-width"
menuClassName="odc-metrics-dropdown__menu dropdown-menu--text-wrap"
onChange={onChange}
title={'Select Query'}
/>
);
};

const mapStateToProps = (state: RootState): StateProps => ({
namespace: getActiveNamespace(state),
});

const mapDispatchToProps = (dispatch) => ({
runQueries: () => dispatch(queryBrowserRunQueries()),
patchQuery: (v: QueryObj) => dispatch(queryBrowserPatchQuery(0, v)),
});

export default connect(mapStateToProps, mapDispatchToProps)(MetricsDropdown);
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
import * as React from 'react';
import { Helmet } from 'react-helmet';
import ConnectedMetricsQueryInput from './MetricsQueryInput';
import { connect } from 'react-redux';
import { getURLSearchParams } from '@console/internal/components/utils';
import { queryBrowserRunQueries, queryBrowserPatchQuery } from '@console/internal/actions/ui';
import { QueryObj } from '@console/internal/components/monitoring/query-browser';
import ConnectedMetricsChart from './MetricsChart';

const MonitoringMetrics: React.FC = () => {
type MonitoringMetricsProps = {
patchQuery?: (patch: QueryObj) => void;
runQueries?: () => never;
};

export const MonitoringMetrics: React.FC<MonitoringMetricsProps> = ({ patchQuery, runQueries }) => {
const params = getURLSearchParams();
const query = params.query0;
React.useEffect(() => {
patchQuery({ text: query });
runQueries();
}, [query, patchQuery, runQueries]);

return (
<>
<Helmet>
Expand All @@ -25,4 +41,9 @@ const MonitoringMetrics: React.FC = () => {
);
};

export default MonitoringMetrics;
const mapDispatchToProps = (dispatch) => ({
runQueries: () => dispatch(queryBrowserRunQueries()),
patchQuery: (v: QueryObj) => dispatch(queryBrowserPatchQuery(0, v)),
});

export default connect(null, mapDispatchToProps)(MonitoringMetrics);
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import MonitoringMetrics from '../MonitoringMetrics';
import { MonitoringMetrics } from '../MonitoringMetrics';

describe('Monitoring Metrics Tab', () => {
it('should render Monitoring Metrics tab', () => {
Expand Down
7 changes: 5 additions & 2 deletions frontend/public/components/graphs/prometheus-graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Link } from 'react-router-dom';
import { FLAGS } from '@console/shared';
import { featureReducerName } from '../../reducers/features';
import { MonitoringRoutes } from '../../reducers/monitoring';
import { getActivePerspective } from '../../reducers/ui';
import { getActivePerspective, getActiveNamespace } from '../../reducers/ui';
import { RootState } from '../../redux';

export const getPrometheusExpressionBrowserURL = (urls, queries): string => {
Expand All @@ -28,13 +28,15 @@ const mapStateToProps = (state: RootState) => ({
canAccessMonitoring:
!!state[featureReducerName].get(FLAGS.CAN_GET_NS) && !!window.SERVER_FLAGS.prometheusBaseURL,
perspective: getActivePerspective(state),
namespace: getActiveNamespace(state),
});

export const PrometheusGraphLink_: React.FC<PrometheusGraphLinkProps> = ({
canAccessMonitoring,
children,
perspective,
query,
namespace,
}) => {
if (!query) {
return <>{children}</>;
Expand All @@ -46,7 +48,7 @@ export const PrometheusGraphLink_: React.FC<PrometheusGraphLinkProps> = ({
const url =
canAccessMonitoring && perspective === 'admin'
? `/monitoring/query-browser?${params.toString()}`
: `/metrics?${params.toString()}`;
: `/dev-monitoring/ns/${namespace}/metrics?${params.toString()}`;

return (
<Link to={url} style={{ color: 'inherit', textDecoration: 'none' }}>
Expand All @@ -69,6 +71,7 @@ type PrometheusGraphLinkProps = {
canAccessMonitoring: boolean;
perspective: string;
query: string;
namespace?: string;
};

type PrometheusGraphProps = {
Expand Down

0 comments on commit 5b72d57

Please sign in to comment.