Merge pull request #251 from influxdata/feature/host-apps

Feature/host apps
pull/255/head
Will Piers 2016-10-17 10:46:04 -07:00 committed by GitHub
commit bc0f5919a1
3 changed files with 60 additions and 9 deletions

View File

@ -1,4 +1,5 @@
import {proxy} from 'utils/queryUrlGenerator'; import {proxy} from 'utils/queryUrlGenerator';
import AJAX from 'utils/ajax';
import _ from 'lodash'; import _ from 'lodash';
export function getCpuAndLoadForHosts(proxyLink) { export function getCpuAndLoadForHosts(proxyLink) {
@ -9,7 +10,9 @@ export function getCpuAndLoadForHosts(proxyLink) {
}).then((resp) => { }).then((resp) => {
const hosts = {}; const hosts = {};
const precision = 100; const precision = 100;
resp.data.results[0].series.forEach((s) => { const cpuSeries = _.get(resp, ['data', 'results', '0', 'series'], []);
const loadSeries = _.get(resp, ['data', 'results', '1', 'series'], []);
cpuSeries.forEach((s) => {
const meanIndex = s.columns.findIndex((col) => col === 'mean'); const meanIndex = s.columns.findIndex((col) => col === 'mean');
hosts[s.tags.host] = { hosts[s.tags.host] = {
name: s.tags.host, name: s.tags.host,
@ -17,11 +20,48 @@ export function getCpuAndLoadForHosts(proxyLink) {
}; };
}); });
resp.data.results[1].series.forEach((s) => { loadSeries.forEach((s) => {
const meanIndex = s.columns.findIndex((col) => col === 'mean'); const meanIndex = s.columns.findIndex((col) => col === 'mean');
hosts[s.tags.host].load = (Math.round(s.values[0][meanIndex] * precision) / precision); hosts[s.tags.host].load = (Math.round(s.values[0][meanIndex] * precision) / precision);
}); });
return _.values(hosts); return hosts;
});
}
export function getMappings() {
return AJAX({
method: 'GET',
url: `/chronograf/v1/mappings`,
});
}
export function getAppsForHosts(proxyLink, hosts, supportedApps) {
const measurements = supportedApps.map((m) => `${m}$`).join('|');
return proxy({
source: proxyLink,
query: `show series from /${measurements}/`,
db: 'telegraf',
}).then((resp) => {
const newHosts = Object.assign({}, hosts);
const allSeries = _.get(resp, ['data', 'results', '0', 'series', '0', 'values'], []);
allSeries.forEach(([series]) => {
const matches = series.match(/(\w*),.*,host=([^,]*)/);
if (!matches || matches.length !== 3) { // eslint-disable-line no-magic-numbers
return;
}
const app = matches[1];
const host = matches[2];
if (!newHosts[host]) {
return;
}
if (!newHosts[host].apps) {
newHosts[host].apps = [];
}
newHosts[host].apps = _.uniq(newHosts[host].apps.concat(app));
});
return newHosts;
}); });
} }

View File

@ -7,6 +7,7 @@ const HostsTable = React.createClass({
name: PropTypes.string, name: PropTypes.string,
cpu: PropTypes.number, cpu: PropTypes.number,
load: PropTypes.number, load: PropTypes.number,
apps: PropTypes.arrayOf(PropTypes.string.isRequired),
})), })),
source: PropTypes.shape({ source: PropTypes.shape({
id: PropTypes.string.isRequired, id: PropTypes.string.isRequired,
@ -86,14 +87,14 @@ const HostsTable = React.createClass({
</thead> </thead>
<tbody> <tbody>
{ {
hosts.map(({name, cpu, load}) => { hosts.map(({name, cpu, load, apps = []}) => {
return ( return (
<tr key={name}> <tr key={name}>
<td className="monotype"><a href={`/sources/${source.id}/hosts/${name}`}>{name}</a></td> <td className="monotype"><a href={`/sources/${source.id}/hosts/${name}`}>{name}</a></td>
<td className="text-center"><div className="table-dot dot-success"></div></td> <td className="text-center"><div className="table-dot dot-success"></div></td>
<td className="monotype">{`${cpu.toFixed(2)}%`}</td> <td className="monotype">{`${cpu.toFixed(2)}%`}</td>
<td className="monotype">{`${load.toFixed(2)}`}</td> <td className="monotype">{`${load.toFixed(2)}`}</td>
<td className="monotype">influxdb, ntp, system</td> <td className="monotype">{`${apps.join(', ')}`}</td>
</tr> </tr>
); );
}) })

View File

@ -1,7 +1,8 @@
import React, {PropTypes} from 'react'; import React, {PropTypes} from 'react';
import _ from 'lodash';
import FlashMessages from 'shared/components/FlashMessages'; import FlashMessages from 'shared/components/FlashMessages';
import HostsTable from '../components/HostsTable'; import HostsTable from '../components/HostsTable';
import {getCpuAndLoadForHosts} from '../apis'; import {getCpuAndLoadForHosts, getMappings, getAppsForHosts} from '../apis';
export const HostsPage = React.createClass({ export const HostsPage = React.createClass({
propTypes: { propTypes: {
@ -18,13 +19,22 @@ export const HostsPage = React.createClass({
getInitialState() { getInitialState() {
return { return {
hosts: [], hosts: {},
}; };
}, },
componentDidMount() { componentDidMount() {
getCpuAndLoadForHosts(this.props.source.links.proxy).then((hosts) => { const {source} = this.props;
Promise.all([
getCpuAndLoadForHosts(source.links.proxy),
getMappings(),
]).then(([hosts, {data: {mappings}}]) => {
this.setState({hosts}); this.setState({hosts});
const apps = mappings.concat([{name: 'docker'}, {name: 'influxdb'}]).map((m) => m.name);
// concatting docker and influxdb for now
getAppsForHosts(source.links.proxy, hosts, apps).then((newHosts) => {
this.setState({hosts: newHosts});
});
}).catch(() => { }).catch(() => {
this.props.addFlashMessage({ this.props.addFlashMessage({
type: 'error', type: 'error',
@ -49,7 +59,7 @@ export const HostsPage = React.createClass({
<div className="container-fluid"> <div className="container-fluid">
<div className="row"> <div className="row">
<div className="col-md-12"> <div className="col-md-12">
<HostsTable source={this.props.source} hosts={this.state.hosts} /> <HostsTable source={this.props.source} hosts={_.values(this.state.hosts)} />
</div> </div>
</div> </div>
</div> </div>