I/O metrics (#224)

* feat: Proxy Node IO stats to the FE

* chore: Sync up FE

* feat: Charts for cache sizes

* feat: All graphs are in

* chore: Remove browserlist
This commit is contained in:
Maciej Hirsz
2020-01-30 15:03:19 +01:00
committed by GitHub
parent 668065c1a8
commit 19f57d71be
14 changed files with 211 additions and 21 deletions
+4
View File
@@ -34,6 +34,10 @@ export default class App extends React.Component<{}, State> {
mem: true,
upload: false,
download: false,
stateCacheSize: false,
dbCacheSize: false,
diskRead: false,
diskWrite: false,
blocknumber: true,
blockhash: true,
blocktime: true,
+2 -2
View File
@@ -166,9 +166,9 @@ export class Connection {
}
case Actions.AddedNode: {
const [id, nodeDetails, nodeStats, nodeHardware, blockDetails, location, connectedAt] = message.payload;
const [id, nodeDetails, nodeStats, nodeIO, nodeHardware, blockDetails, location, connectedAt] = message.payload;
const pinned = this.pins.has(nodeDetails[0]);
const node = new Node(pinned, id, nodeDetails, nodeStats, nodeHardware, blockDetails, location, connectedAt);
const node = new Node(pinned, id, nodeDetails, nodeStats, nodeIO, nodeHardware, blockDetails, location, connectedAt);
nodes.add(node);
@@ -31,6 +31,10 @@ import cpuIcon from '../../icons/microchip-solid.svg';
import memoryIcon from '../../icons/memory-solid.svg';
import uploadIcon from '../../icons/cloud-upload.svg';
import downloadIcon from '../../icons/cloud-download.svg';
import readIcon from '../../icons/arrow-up.svg';
import writeIcon from '../../icons/arrow-down.svg';
import databaseIcon from '../../icons/database.svg';
import stateIcon from '../../icons/git-branch.svg';
import networkIcon from '../../icons/network.svg';
import uptimeIcon from '../../icons/pulse.svg';
import externalLinkIcon from '../../icons/link-external.svg';
@@ -210,6 +214,74 @@ export namespace Column {
}
};
export const STATE_CACHE: Column = {
label: 'State Cache Size',
icon: stateIcon,
width: 40,
setting: 'stateCacheSize',
sortBy: ({ stateCacheSize }) => stateCacheSize.length < 3 ? 0 : stateCacheSize[stateCacheSize.length - 1],
render: ({ stateCacheSize, chartstamps }) => {
if (stateCacheSize.length < 3) {
return '-';
}
return (
<Sparkline width={44} height={16} stroke={1} format={formatBytes} values={stateCacheSize} stamps={chartstamps} minScale={MEMORY_SCALE} />
);
}
};
export const DB_CACHE: Column = {
label: 'Database Cache Size',
icon: databaseIcon,
width: 40,
setting: 'dbCacheSize',
sortBy: ({ dbCacheSize }) => dbCacheSize.length < 3 ? 0 : dbCacheSize[dbCacheSize.length - 1],
render: ({ dbCacheSize, chartstamps }) => {
if (dbCacheSize.length < 3) {
return '-';
}
return (
<Sparkline width={44} height={16} stroke={1} format={formatBytes} values={dbCacheSize} stamps={chartstamps} minScale={MEMORY_SCALE} />
);
}
};
export const DISK_READ: Column = {
label: 'Disk Read',
icon: readIcon,
width: 40,
setting: 'diskRead',
sortBy: ({ diskRead }) => diskRead.length < 3 ? 0 : diskRead[diskRead.length - 1],
render: ({ diskRead, chartstamps }) => {
if (diskRead.length < 3) {
return '-';
}
return (
<Sparkline width={44} height={16} stroke={1} format={formatBandwidth} values={diskRead} stamps={chartstamps} minScale={MEMORY_SCALE} />
);
}
};
export const DISK_WRITE: Column = {
label: 'Disk Write',
icon: writeIcon,
width: 40,
setting: 'diskWrite',
sortBy: ({ diskWrite }) => diskWrite.length < 3 ? 0 : diskWrite[diskWrite.length - 1],
render: ({ diskWrite, chartstamps }) => {
if (diskWrite.length < 3) {
return '-';
}
return (
<Sparkline width={44} height={16} stroke={1} format={formatBandwidth} values={diskWrite} stamps={chartstamps} minScale={MEMORY_SCALE} />
);
}
};
export const BLOCK_NUMBER: Column = {
label: 'Block',
icon: blockIcon,
@@ -330,6 +402,18 @@ function formatMemory(kbs: number, stamp: Maybe<Types.Timestamp>): string {
}
}
function formatBytes(bytes: number, stamp: Maybe<Types.Timestamp>): string {
const ago = stamp ? ` (${formatStamp(stamp)})` : '';
if (bytes >= 1024 * 1024) {
return `${(bytes / (1024 * 1024)).toFixed(1)} MB${ago}`;
} else if (bytes >= 1000) {
return `${(bytes / 1024).toFixed(1)} kB${ago}`;
} else {
return `${bytes} B${ago}`;
}
}
function formatBandwidth(bps: number, stamp: Maybe<Types.Timestamp>): string {
const ago = stamp ? ` (${formatStamp(stamp)})` : '';
@@ -36,6 +36,10 @@ export class Row extends React.Component<Row.Props, Row.State> {
Column.MEM,
Column.UPLOAD,
Column.DOWNLOAD,
Column.STATE_CACHE,
Column.DB_CACHE,
Column.DISK_READ,
Column.DISK_WRITE,
Column.BLOCK_NUMBER,
Column.BLOCK_HASH,
Column.FINALIZED,
+21
View File
@@ -43,6 +43,10 @@ export class Node {
public cpu: Types.CPUUse[];
public upload: Types.BytesPerSecond[];
public download: Types.BytesPerSecond[];
public stateCacheSize: Types.Bytes[];
public dbCacheSize: Types.Bytes[];
public diskRead: Types.BytesPerSecond[];
public diskWrite: Types.BytesPerSecond[];
public chartstamps: Types.Timestamp[];
public height: Types.BlockNumber;
@@ -66,6 +70,7 @@ export class Node {
id: Types.NodeId,
nodeDetails: Types.NodeDetails,
nodeStats: Types.NodeStats,
nodeIO: Types.NodeIO,
nodeHardware: Types.NodeHardware,
blockDetails: Types.BlockDetails,
location: Maybe<Types.NodeLocation>,
@@ -89,6 +94,7 @@ export class Node {
this.sortableVersion = (major * 1000 + minor * 100 + patch) | 0;
this.updateStats(nodeStats);
this.updateIO(nodeIO);
this.updateHardware(nodeHardware);
this.updateBlock(blockDetails);
@@ -106,6 +112,17 @@ export class Node {
this.trigger();
}
public updateIO(io: Types.NodeIO) {
const [stateCacheSize, dbCacheSize, diskRead, diskWrite] = io;
this.stateCacheSize = stateCacheSize;
this.dbCacheSize = dbCacheSize;
this.diskRead = diskRead;
this.diskWrite = diskWrite;
this.trigger();
}
public updateHardware(hardware: Types.NodeHardware) {
const [mem, cpu, upload, download, chartstamps] = hardware;
@@ -202,6 +219,10 @@ export namespace State {
mem: boolean;
upload: boolean;
download: boolean;
stateCacheSize: boolean;
dbCacheSize: boolean;
diskRead: boolean;
diskWrite: boolean;
blocknumber: boolean;
blockhash: boolean;
finalized: boolean;