diff --git a/README.md b/README.md
index 12b76d5..d7e0f15 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-![Project Logo](https://cdn.jsdelivr.net/gh/yoobool/flask-state@1.0.6/src/flask_state/static/flask_state.png)
+![Project Logo](https://cdn.jsdelivr.net/gh/yoobool/flask-state@1.0.7/src/flask_state/static/flask_state.png)
[![Contributor Badge](https://img.shields.io/badge/Contributions-Welcome-0059b3)](https://github.com/yoobool/flask-state/tree/master/.github/ISSUE_TEMPLATE)
[![Gitter Badge](https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter)](https://gitter.im/flaskstate/community)
@@ -11,7 +11,7 @@ English | [简体中文](https://github.com/yoobool/flask-state/blob/master/READ
Flask-State is a lightweight chart plugin for displaying machine state data in your web application.
-* **Monitored Metric:** CPU, memory, disk usage, LoadAVG and boot time.
+* **Monitored Metric:** CPU, memory, disk usage, disk IO, Network IO, LoadAVG and boot time.
* **Extensible:** Offers rich customization options, including redis monitoring, user authentication,
custom logging, i18n and etc.
* **Stable:** Solves multiprocessing concurrency problems (if you use [gunicorn](https://gunicorn.org/))
@@ -20,7 +20,7 @@ built on top of lightweight dependencies.
This project is in active development and thoroughly tested to ensure that Flask-State
stays up-to-date with its project roadmap.
-![Screenshot](https://cdn.jsdelivr.net/gh/yoobool/flask-state@1.0.6/examples/static/flask_state.png)
+![Screenshot](https://cdn.jsdelivr.net/gh/yoobool/flask-state@1.0.7/examples/static/flask_state.png)
## Documentation
@@ -39,8 +39,8 @@ Alternatively, install Flask-State via NPM or include this script tag to the hea
section of your HTML document:
```html
-
-
+
+
```
```bash
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 0c1d3e4..a2be850 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -1,6 +1,6 @@
[English](https://github.com/yoobool/flask-state/blob/master/README.md) | 简体中文
-![Project Logo](https://cdn.jsdelivr.net/gh/yoobool/flask-state@1.0.6/src/flask_state/static/flask_state.png)
+![Project Logo](https://cdn.jsdelivr.net/gh/yoobool/flask-state@1.0.7/src/flask_state/static/flask_state.png)
[![Contributor Badge](https://img.shields.io/badge/Contributions-Welcome-0059b3)](https://github.com/yoobool/flask-state/tree/master/.github/ISSUE_TEMPLATE)
[![Gitter Badge](https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter)](https://gitter.im/flaskstate/community)
@@ -12,7 +12,7 @@
Flask-State是一款在您浏览器上使用的轻便、图表化插件。
-* **监控状态**:CPU,内存,磁盘,LoadAvg,启动时长。
+* **监控状态**:CPU,内存,磁盘,磁盘IO, 网络IO, LoadAvg,启动时长。
* **可扩展**:除记录本机状态外,还包括丰富的扩展功能选择。其中有Redis监控、用户验证、自定义logging和i18n等。
* **稳定**:轻量级的依赖关系,同时解决了多进程并发问题。
@@ -20,7 +20,7 @@ Flask-State是一个活跃的项目,经过了充分的测试以及有一系列
###
-![Screenshot](https://cdn.jsdelivr.net/gh/yoobool/flask-state@1.0.6/examples/static/flask_state.png)
+![Screenshot](https://cdn.jsdelivr.net/gh/yoobool/flask-state@1.0.7/examples/static/flask_state.png)
## Documentation
@@ -31,6 +31,21 @@ Flask-State是一个活跃的项目,经过了充分的测试以及有一系列
从这里 [PyPI](https://pip.pypa.io/en/stable/quickstart/) 下载:
+```bash
+pip install Flask-State
+```
+
+通过NPM安装Flask-State或将此脚本标签放在HTML文件的开头部分:
+
+```html
+
+
+```
+
+```bash
+npm install flask-state --save
+```
+
## Usage
Flask-State插件安装后,还需要引入JavaScript文件和CSS文件,然后初始化组件运行方式。在某些配置上,你也可以选择修改。
diff --git a/examples/static/flask_state.png b/examples/static/flask_state.png
old mode 100644
new mode 100755
index 625c437..820490c
Binary files a/examples/static/flask_state.png and b/examples/static/flask_state.png differ
diff --git a/examples/static/initial.js b/examples/static/initial.js
index 60b872b..3d87e42 100644
--- a/examples/static/initial.js
+++ b/examples/static/initial.js
@@ -43,9 +43,9 @@ class MachineStatus {
/* Insert window element */
initFlaskStateContainer() {
- let _chart = this.mobile ? `
`
- : ``;
- let _content = `Host Status
Memory
CPU
Disk Usage
Load Avg
Uptime
Redis Status
Used Mem
Mem Fragmentation Ratio
Cache Hits Ratio
24h Hits Ratio
Uptime
Connections
` + _chart + `
`;
+ let _chart = this.mobile ? `
`
+ : ``;
+ let _content = `Host Status
Memory
CPU
Disk Usage
Load Avg
Disk IO
Network IO
Uptime
Redis Status
Used Mem
Mem Fragmentation Ratio
Cache Hits Ratio
24h Hits Ratio
Uptime
Connections
` + _chart + `
`;
document.getElementsByTagName('body')[0].insertAdjacentHTML('beforeend', _content);
}
@@ -94,7 +94,7 @@ class MachineStatus {
const elemDict = {
0: 'fs-info-tab-memory',
1: 'fs-info-tab-cpu',
- 2: 'fs-info-tab-disk-usage',
+ 2: 'fs-info-network-io',
3: 'fs-info-tab-loadavg'
};
for (let item of liArr) {
@@ -123,6 +123,8 @@ class MachineStatus {
document.getElementById('fs-memory').innerHTML = this.language.memory;
document.getElementById('fs-disk-usage').innerHTML = this.language.disk_usage;
document.getElementById('fs-load-avg').innerHTML = this.language.load_avg;
+ document.getElementById('fs-disk-io').innerHTML = this.language.disk_io;
+ document.getElementById('fs-network-io').innerHTML = this.language.network_io;
document.getElementById('fs-boot-seconds').innerHTML = this.language.boot_seconds;
document.getElementById('fs-used-memory').innerHTML = this.language.used_memory;
document.getElementById('fs-used-memory-rss').innerHTML = this.language.used_memory_rss;
@@ -140,10 +142,10 @@ class MachineStatus {
this.consoleCpuChart = echarts.init(document.getElementById('fs-info-cpu-chart'), null, {renderer: 'svg'});
this.consoleMemoryChart = echarts.init(document.getElementById('fs-info-memory-chart'), null, {renderer: 'svg'});
this.consoleLoadavgChart = echarts.init(document.getElementById('fs-info-loadavg-chart'), null, {renderer: 'svg'});
- this.consoleDiskUsageChart = echarts.init(document.getElementById('fs-info-diskusage-chart'), null, {renderer: 'svg'});
+ this.consoleDiskUsageChart = echarts.init(document.getElementById('fs-info-networkio-chart'), null, {renderer: 'svg'});
this.cpuOption = MachineStatus.generateChatOption(this.mobile, this.language.cpu || 'CPU', '', this.language.today || 'Today');
this.memoryOption = MachineStatus.generateChatOption(this.mobile, this.language.memory || 'Memory', '', this.language.today || 'Today');
- this.diskUsageOption = MachineStatus.generateChatOption(this.mobile, this.language.disk_usage || 'Disk Usage', '', this.language.today || 'Today');
+ this.networkIOOption = MachineStatus.generateChatOption(this.mobile, this.language.network_io || 'Network IO', 'networkIO', this.language.today || 'Today');
this.loadavgOption = MachineStatus.generateChatOption(this.mobile, 'Load Avg', 'loadavg', this.language.minutes || 'min');
}
@@ -170,17 +172,8 @@ class MachineStatus {
return;
}
- const fields = ["ts", "cpu", "memory", "load_avg", "disk_usage"];
const data = response.data;
- data.items = data.items.map(item => {
- let element = {};
- fields.forEach((field, index) => {
- if (field === "ts") return element[field] = SECONDS_TO_MILLISECONDS * item[index];
- element[field] = item[index];
- });
- return element;
- });
let currentStatistic = data.currentStatistic;
if (Object.keys(currentStatistic).length) {
let hostInfoSpan = document.getElementById('fs-host-status').getElementsByClassName('fs-badge-content');
@@ -188,8 +181,10 @@ class MachineStatus {
hostInfoSpan[1].innerHTML = currentStatistic.cpu + '%';
hostInfoSpan[2].innerHTML = currentStatistic.disk_usage + '%';
hostInfoSpan[3].innerHTML = currentStatistic.load_avg[0] + "," + currentStatistic.load_avg[1] + "," + currentStatistic.load_avg[2];
+ hostInfoSpan[4].innerHTML = "R " + MachineStatus.getFormatBit(currentStatistic.disk_read) + " | " + "W " + MachineStatus.getFormatBit(currentStatistic.disk_write) + "";
+ hostInfoSpan[5].innerHTML = "⬇ " + MachineStatus.getFormatBit(currentStatistic.net_recv) + " | " + "⬆ " + MachineStatus.getFormatBit(currentStatistic.net_sent) + "";
- hostInfoSpan[4].innerHTML = MachineStatus.getFormatSeconds(currentStatistic.boot_seconds || 0, this.language.days, this.language.hours, this.language.minutes, this.language.seconds);
+ hostInfoSpan[6].innerHTML = MachineStatus.getFormatSeconds(currentStatistic.boot_seconds || 0, this.language.days, this.language.hours, this.language.minutes, this.language.seconds);
const machineIndex = ['memory', 'cpu', 'disk_usage', 'load_avg'];
machineIndex.forEach(function (item, index) {
@@ -252,8 +247,19 @@ class MachineStatus {
}
}
+ const fields = ["ts", "cpu", "memory", "load_avg"];
+ data.items = data.items.map(item => {
+ let element = {};
+ fields.forEach((field, index) => {
+ if (field === "ts") return element[field] = SECONDS_TO_MILLISECONDS * item[index];
+ element[field] = item[index];
+ });
+ return element;
+ });
data.items.reverse();
+ data.io.reverse();
let dataMap = MachineStatus.getChartsData(data.items);
+ let ioMap = MachineStatus.getIOChartsData(data.io);
let tsList = dataMap.ts_list;
let cpuList = dataMap.cpu_list;
@@ -261,16 +267,18 @@ class MachineStatus {
let loadavgList = dataMap.load_avg_list[0];
let loadavg5MinList = dataMap.load_avg_list[1];
let loadavg15MinList = dataMap.load_avg_list[2];
- let diskUsageList = dataMap.disk_usage_list;
+
+ this.networkIOOption.xAxis.data = ioMap.ts_list;
+ this.networkIOOption.series[0].data = ioMap.net_recv;
+ this.networkIOOption.series[1].data = ioMap.net_sent;
+ this.consoleDiskUsageChart.setOption(this.networkIOOption);
this.memoryOption.xAxis.data = tsList;
this.cpuOption.xAxis.data = tsList;
this.loadavgOption.xAxis.data = tsList;
- this.diskUsageOption.xAxis.data = tsList;
this.memoryOption.series[0].data = memoryList;
this.cpuOption.series[0].data = cpuList;
- this.diskUsageOption.series[0].data = diskUsageList;
this.loadavgOption.series[0].data = loadavgList;
this.loadavgOption.series[1].data = loadavg5MinList;
this.loadavgOption.series[2].data = loadavg15MinList;
@@ -278,7 +286,6 @@ class MachineStatus {
this.consoleMemoryChart.setOption(this.memoryOption);
this.consoleCpuChart.setOption(this.cpuOption);
this.consoleLoadavgChart.setOption(this.loadavgOption);
- this.consoleDiskUsageChart.setOption(this.diskUsageOption);
MachineStatus.resizeChart([this.consoleMemoryChart, this.consoleCpuChart, this.consoleLoadavgChart, this.consoleDiskUsageChart]);
}).then(() => {
this.consoleMemoryChart.hideLoading();
@@ -332,7 +339,7 @@ class MachineStatus {
/* Initialize echart */
static generateChatOption(isMobile, titleText, tableName = '', lineName = '') {
let baseData = {
- color: tableName === 'loadavg' ? ['#ffa726', '#42a5f5', '#66bb6a'] : ['#42a5f5'],
+ color: tableName === 'loadavg' ? ['#ffa726', '#42a5f5', '#66bb6a'] : tableName === 'networkIO' ? ['#ffa726', '#42a5f5'] : ['#42a5f5'],
title: {
show: !isMobile,
text: titleText
@@ -341,6 +348,12 @@ class MachineStatus {
trigger: 'axis',
formatter: (params) => {
let value = echarts.format.formatTime('yyyy-MM-dd hh:mm:ss', new Date(parseInt(params[0].axisValue)), false) + '
';
+ if (tableName === 'networkIO') {
+ for (let i = 0; i < params.length; i++) {
+ value += (params[i].marker + params[i].seriesName + ': ' + MachineStatus.getFormatBit(params[i].value) + '
')
+ }
+ return value;
+ }
for (let i = 0; i < params.length; i++) {
value += (params[i].marker + params[i].seriesName + ': ' + params[i].value +
(tableName === 'loadavg' ? '' : '%') + '
')
@@ -353,7 +366,7 @@ class MachineStatus {
textStyle: {
fontSize: 14
},
- show: titleText === 'Load Avg',
+ show: titleText === 'Load Avg' || tableName === "networkIO",
},
grid: {
left: '3%',
@@ -382,7 +395,13 @@ class MachineStatus {
yAxis: {
type: 'value',
axisLabel: {
- formatter: (value) => value + (titleText === 'Load Avg' ? '' : '%'),
+ formatter: (value) => {
+ if (tableName === 'networkIO') {
+ let result = MachineStatus.getFormatBit(value, 0);
+ return result.substring(0, result.length - 2);
+ }
+ return value + (titleText === 'Load Avg' ? '' : '%')
+ },
},
},
series: [
@@ -406,13 +425,24 @@ class MachineStatus {
});
});
}
+ if (tableName === 'networkIO') {
+ baseData.legend.data = ['recv', 'sent'];
+ baseData.series = [];
+ baseData.legend.data.forEach((name) => {
+ baseData.series.push({
+ name: name,
+ type: 'line',
+ symbol: 'none',
+ hoverAnimation: false
+ });
+ });
+ }
return baseData;
}
/* Get Echarts data */
static getChartsData(rawData) {
let cpuList = [];
- let diskUsageList = [];
let loadAvgList = [];
let loadAvg5minList = [];
let loadAvg15minList = [];
@@ -421,7 +451,6 @@ class MachineStatus {
for (let i = 0; i < rawData.length; i++) {
let item = rawData[i];
cpuList.push(item.cpu);
- diskUsageList.push(item.disk_usage);
loadAvgList.push(item.load_avg[0]);
loadAvg5minList.push(item.load_avg[1]);
loadAvg15minList.push(item.load_avg[2]);
@@ -429,12 +458,50 @@ class MachineStatus {
tsList.push(item.ts);
}
return {
- 'cpu_list': cpuList, 'disk_usage_list': diskUsageList,
- 'load_avg_list': [loadAvgList, loadAvg5minList, loadAvg15minList],
+ 'cpu_list': cpuList, 'load_avg_list': [loadAvgList, loadAvg5minList, loadAvg15minList],
'memory_list': memoryList, 'ts_list': tsList
};
};
+ /* Get Echarts data */
+ static getIOChartsData(rawData) {
+ let netRecvList = [];
+ let netSentList = [];
+ let tsList = [];
+ for (let i = 0; i < rawData.length; i++) {
+ let item = rawData[i];
+ tsList.push(item[0] * SECONDS_TO_MILLISECONDS);
+ netRecvList.push(item[1]);
+ netSentList.push(item[2]);
+ }
+ return {
+ 'net_recv': netRecvList, 'net_sent': netSentList, 'ts_list': tsList
+ };
+ };
+
+ /* Get format Bit */
+ static getFormatBit(value, fixed = 2) {
+ let suffix;
+ let b_value = value / 8;
+ if (b_value >= 10e11) {
+ b_value = (b_value / 10e11).toFixed(fixed);
+ suffix = "TB/s";
+ } else if (b_value >= 10e8) {
+ b_value = (b_value / 10e8).toFixed(fixed);
+ suffix = "GB/s";
+ } else if (b_value >= 10e5) {
+ b_value = (b_value / 10e5).toFixed(fixed);
+ suffix = "MB/s";
+ } else if (b_value >= 10e2) {
+ b_value = (b_value / 10e2).toFixed(fixed);
+ suffix = "KB/s";
+ } else {
+ suffix = "B/s";
+ b_value = b_value.toFixed(2);
+ }
+ return b_value + ' ' + suffix;
+ };
+
/* Get format time */
static getFormatSeconds(value, days = 'days', hours = 'hours', minutes = 'min', seconds = 'seconds') {
let secondTime = parseInt(value);
diff --git a/examples/templates/index.html b/examples/templates/index.html
index 2b28895..3a608be 100644
--- a/examples/templates/index.html
+++ b/examples/templates/index.html
@@ -5,16 +5,17 @@
index
-
-
+
+
+
-