Save locked metric in the url.

- introduces "metric type" so we can flick across topos and keep the
  "type" of metric selected. Cheating and using label as the type atm.
This commit is contained in:
Simon Howe
2016-03-23 12:47:53 +01:00
parent f64908acf2
commit 1710db6262
5 changed files with 63 additions and 31 deletions

View File

@@ -28,21 +28,26 @@ export function lockNextMetric(delta) {
AppDispatcher.dispatch({
type: ActionTypes.LOCK_METRIC,
metricId: nextMetric
metricId: nextMetric,
metricType: AppStore.getAvailableCanvasMetricsTypes()[nextMetric]
});
updateRoute();
}
export function lockMetric(metricId) {
AppDispatcher.dispatch({
type: ActionTypes.LOCK_METRIC,
metricId
metricId,
metricType: AppStore.getAvailableCanvasMetricsTypes()[metricId]
});
updateRoute();
}
export function unlockMetric() {
AppDispatcher.dispatch({
type: ActionTypes.UNLOCK_METRIC,
});
updateRoute();
}
export function changeTopologyOption(option, value, topologyId) {

View File

@@ -139,11 +139,11 @@ export default class App extends React.Component {
topologyId={this.state.currentTopologyId} />
<Sidebar>
<MetricSelector
{this.state.availableCanvasMetrics.length > 0 && <MetricSelector
availableCanvasMetrics={this.state.availableCanvasMetrics}
lockedMetric={this.state.lockedMetric}
selectedMetric={this.state.selectedMetric}
/>
/>}
<Status errorUrl={this.state.errorUrl} topology={this.state.currentTopology}
topologiesLoaded={this.state.topologiesLoaded}
websocketClosed={this.state.websocketClosed} />

View File

@@ -1,7 +1,6 @@
import React from 'react';
import classNames from 'classnames';
import { selectMetric, lockMetric, unlockMetric } from '../actions/app-actions';
import { label } from '../utils/data-utils';
export class MetricSelectorItem extends React.Component {
@@ -45,7 +44,7 @@ export class MetricSelectorItem extends React.Component {
className={className}
onMouseOver={this.onMouseOver}
onClick={this.onMouseClick}>
{label(metric)}
{metric.label}
{isLocked && <span className="sidebar-item-actions">
<span className="sidebar-item-action fa fa-thumb-tack"></span>
</span>}

View File

@@ -62,6 +62,7 @@ let websocketClosed = true;
let selectedMetric = null;
let lockedMetric = selectedMetric;
let lockedMetricType = null;
let availableCanvasMetrics = [];
@@ -144,6 +145,7 @@ export class AppStore extends Store {
controlPipe: this.getControlPipe(),
nodeDetails: this.getNodeDetailsState(),
selectedNodeId,
lockedMetricType,
topologyId: currentTopologyId,
topologyOptions: topologyOptions.toJS() // all options
};
@@ -182,6 +184,10 @@ export class AppStore extends Store {
return availableCanvasMetrics;
}
getAvailableCanvasMetricsTypes() {
return _.fromPairs(this.getAvailableCanvasMetrics().map(m => [m.id, m.label]));
}
getControlStatus() {
return controlStatus.toJS();
}
@@ -428,12 +434,14 @@ export class AppStore extends Store {
}
case ActionTypes.LOCK_METRIC: {
lockedMetric = payload.metricId;
lockedMetricType = payload.metricType;
selectedMetric = payload.metricId;
this.__emitChange();
break;
}
case ActionTypes.UNLOCK_METRIC: {
lockedMetric = null;
lockedMetricType = null;
this.__emitChange();
break;
}
@@ -607,7 +615,13 @@ export class AppStore extends Store {
.toSet()
.sortBy(n => METRIC_LABELS[n])
.toJS()
.map(v => ({id: v, label: v}));
.map(v => ({id: v, label: METRIC_LABELS[v]}));
const similarTypeMetric = availableCanvasMetrics.find(m => m.label === lockedMetricType);
lockedMetric = similarTypeMetric && similarTypeMetric.id;
if (!availableCanvasMetrics.map(m => m.id).includes(selectedMetric)) {
selectedMetric = lockedMetric;
}
if (emitChange) {
this.__emitChange();
@@ -654,6 +668,7 @@ export class AppStore extends Store {
setTopology(payload.state.topologyId);
setDefaultTopologyOptions(topologies);
selectedNodeId = payload.state.selectedNodeId;
lockedMetricType = payload.state.lockedMetricType;
if (payload.state.controlPipe) {
controlPipes = makeOrderedMap({
[payload.state.controlPipe.id]:

View File

@@ -42,16 +42,16 @@ function getNextValue(keyValues, maxValue) {
}
export const METRIC_LABELS = {
docker_cpu_total_usage: 'Container CPU',
docker_memory_usage: 'Container Memory',
host_cpu_usage_percent: 'Host CPU',
host_mem_usage_bytes: 'Host Memory',
load1: 'Host Load 1',
load15: 'Host Load 15',
load5: 'Host Load 5',
open_files_count: 'Process Open files',
process_cpu_usage_percent: 'Process CPU',
process_memory_usage_bytes: 'Process Memory'
docker_cpu_total_usage: 'CPU',
docker_memory_usage: 'Memory',
host_cpu_usage_percent: 'CPU',
host_mem_usage_bytes: 'Memory',
load1: 'Load 1',
load15: 'Load 15',
load5: 'Load 5',
open_files_count: 'Open files',
process_cpu_usage_percent: 'CPU',
process_memory_usage_bytes: 'Memory'
};
@@ -84,7 +84,7 @@ const cpuMetric = (node, name, max = 100) => ({
max
});
const fileMetric = (node, name, max = 10000) => ({
const fileMetric = (node, name, max = 1000) => ({
samples: [{value: getNextValue([node.id, name], max)}],
max
});
@@ -94,23 +94,36 @@ const loadMetric = (node, name, max = 10) => ({
max
});
const metrics = {
// process
square: {
process_cpu_usage_percent: cpuMetric,
process_memory_usage_bytes: memoryMetric,
open_files_count: fileMetric
},
// container
hexagon: {
docker_cpu_total_usage: cpuMetric,
docker_memory_usage: memoryMetric
},
// host
circle: {
load5: loadMetric,
host_cpu_usage_percent: cpuMetric,
host_mem_usage_bytes: memoryMetric
}
};
function mergeMetrics(node) {
if (node.pseudo) {
if (node.pseudo || node.stack) {
return node;
}
return Object.assign({}, node, {
metrics: {
process_cpu_usage_percent: cpuMetric(node, 'process_cpu_usage_percent'),
process_memory_usage_bytes: memoryMetric(node, 'process_memory_usage_bytes'),
open_files_count: fileMetric(node, 'open_files_count'),
load1: loadMetric(node, 'load1'),
load5: loadMetric(node, 'load5'),
load15: loadMetric(node, 'load15'),
docker_cpu_total_usage: cpuMetric(node, 'docker_cpu_total_usage'),
docker_memory_usage: memoryMetric(node, 'docker_memory_usage'),
host_cpu_usage_percent: cpuMetric(node, 'host_cpu_usage_percent'),
host_mem_usage_bytes: memoryMetric(node, 'host_mem_usage_bytes')
}
metrics: _(metrics[node.shape])
.map((fn, name) => [name, fn(node)])
.fromPairs()
.value()
});
}