浏览代码

Clean up analytic code, update Simplified Chinese translations.

0xJacky 3 年之前
父节点
当前提交
42417e806d

+ 58 - 1
frontend/src/components/Chart/CPUChart.vue

@@ -8,6 +8,9 @@ import Vue from 'vue'
 
 Vue.use(VueApexCharts)
 Vue.component('apexchart', VueApexCharts)
+const fontColor = () => {
+    return window.matchMedia('(prefers-color-scheme: dark)').matches ? '#b4b4b4' : undefined
+}
 export default {
     name: 'CPUChart',
     props: {
@@ -21,6 +24,47 @@ export default {
             }
         }
     },
+    mounted() {
+        let media = window.matchMedia('(prefers-color-scheme: dark)')
+        let callback = () => {
+            this.chartOptions.xaxis = {
+                type: 'datetime',
+                labels: {
+                    datetimeUTC: false,
+                    style: {
+                        colors: fontColor()
+                    }
+                }
+            }
+            this.chartOptions.yaxis = {
+                max: 100,
+                tickAmount: 4,
+                min: 0,
+                labels: {
+                    style: {
+                        colors: fontColor()
+                    }
+                }
+            }
+            this.chartOptions.legend = {
+                labels: {
+                    colors: fontColor()
+                },
+                onItemClick: {
+                    toggleDataSeries: false
+                },
+                onItemHover: {
+                    highlightDataSeries: false
+                },
+            }
+            this.$refs.chart.updateOptions(this.chartOptions)
+        }
+        if (typeof media.addEventListener === 'function') {
+            media.addEventListener('change', callback)
+        } else if (typeof media.addListener === 'function') {
+            media.addListener(callback)
+        }
+    },
     data() {
         return {
             chartOptions: {
@@ -54,7 +98,12 @@ export default {
                 },
                 xaxis: {
                     type: 'datetime',
-                    labels: {datetimeUTC: false},
+                    labels: {
+                        datetimeUTC: false,
+                        style: {
+                            colors: fontColor()
+                        }
+                    }
                 },
                 tooltip: {
                     enabled: false
@@ -63,8 +112,16 @@ export default {
                     max: 100,
                     tickAmount: 4,
                     min: 0,
+                    labels: {
+                        style: {
+                            colors: fontColor()
+                        }
+                    }
                 },
                 legend: {
+                    labels: {
+                        colors: fontColor()
+                    },
                     onItemClick: {
                         toggleDataSeries: false
                     },

+ 58 - 1
frontend/src/components/Chart/DiskChart.vue

@@ -8,6 +8,10 @@ import Vue from 'vue'
 
 Vue.use(VueApexCharts)
 Vue.component('apexchart', VueApexCharts)
+
+const fontColor = () => {
+    return window.matchMedia('(prefers-color-scheme: dark)').matches ? '#b4b4b4' : null
+}
 export default {
     name: 'DiskChart',
     props: {
@@ -19,6 +23,46 @@ export default {
             handler() {
                 this.$refs.chart.updateSeries(this.series)
             }
+        },
+    },
+    mounted() {
+        let media = window.matchMedia('(prefers-color-scheme: dark)')
+        let callback = () => {
+            this.chartOptions.xaxis = {
+                type: 'datetime',
+                    labels: {
+                    datetimeUTC: false,
+                        style: {
+                        colors: fontColor()
+                    }
+                }
+            }
+            this.chartOptions.yaxis = {
+                tickAmount: 3,
+                    min: 0,
+                    labels: {
+                    style: {
+                        colors: fontColor()
+                    }
+                }
+            }
+            this.chartOptions.legend = {
+                labels: {
+                    colors: fontColor()
+                },
+                onItemClick: {
+                    toggleDataSeries: false
+                },
+                onItemHover: {
+                    highlightDataSeries: false
+                },
+            }
+            this.$refs.chart.updateOptions(this.chartOptions)
+        }
+        if (typeof media.addEventListener === 'function') {
+            media.addEventListener('change', callback)
+        } else if (typeof media.addListener === 'function') {
+            media.addListener(callback)
         }
     },
     data() {
@@ -54,7 +98,12 @@ export default {
                 },
                 xaxis: {
                     type: 'datetime',
-                    labels: {datetimeUTC: false},
+                    labels: {
+                        datetimeUTC: false,
+                        style: {
+                            colors: fontColor()
+                        }
+                    }
                 },
                 tooltip: {
                     enabled: false
@@ -62,8 +111,16 @@ export default {
                 yaxis: {
                     tickAmount: 3,
                     min: 0,
+                    labels: {
+                        style: {
+                            colors: fontColor()
+                        }
+                    }
                 },
                 legend: {
+                    labels: {
+                        colors: fontColor()
+                    },
                     onItemClick: {
                         toggleDataSeries: false
                     },

+ 58 - 1
frontend/src/components/Chart/NetChart.vue

@@ -8,6 +8,9 @@ import Vue from 'vue'
 
 Vue.use(VueApexCharts)
 Vue.component('apexchart', VueApexCharts)
+const fontColor = () => {
+    return window.matchMedia('(prefers-color-scheme: dark)').matches ? '#b4b4b4' : undefined
+}
 export default {
     name: 'NetChart',
     props: {
@@ -21,6 +24,49 @@ export default {
             }
         }
     },
+    mounted() {
+        let media = window.matchMedia('(prefers-color-scheme: dark)')
+        let callback = () => {
+            this.chartOptions.xaxis = {
+                type: 'datetime',
+                labels: {
+                    datetimeUTC: false,
+                    style: {
+                        colors: fontColor()
+                    }
+                }
+            }
+            this.chartOptions.yaxis = {
+                tickAmount: 3,
+                min: 0,
+                labels: {
+                    style: {
+                        colors: fontColor()
+                    },
+                    formatter: (bytes) => {
+                        return this.bytesToSize(bytes) + '/s'
+                    }
+                }
+            }
+            this.chartOptions.legend = {
+                labels: {
+                    colors: fontColor()
+                },
+                onItemClick: {
+                    toggleDataSeries: false
+                },
+                onItemHover: {
+                    highlightDataSeries: false
+                },
+            }
+            this.$refs.chart.updateOptions(this.chartOptions)
+        }
+        if (typeof media.addEventListener === 'function') {
+            media.addEventListener('change', callback)
+        } else if (typeof media.addListener === 'function') {
+            media.addListener(callback)
+        }
+    },
     data() {
         return {
             chartOptions: {
@@ -54,7 +100,12 @@ export default {
                 },
                 xaxis: {
                     type: 'datetime',
-                    labels: {datetimeUTC: false},
+                    labels: {
+                        datetimeUTC: false,
+                        style: {
+                            colors: fontColor()
+                        }
+                    }
                 },
                 tooltip: {
                     enabled: false
@@ -63,12 +114,18 @@ export default {
                     tickAmount: 3,
                     min: 0,
                     labels: {
+                        style: {
+                            colors: fontColor()
+                        },
                         formatter: (bytes) => {
                             return this.bytesToSize(bytes) + '/s'
                         }
                     }
                 },
                 legend: {
+                    labels: {
+                        colors: fontColor()
+                    },
                     onItemClick: {
                         toggleDataSeries: false
                     },

+ 10 - 4
frontend/src/components/Chart/RadialBarChart.vue

@@ -1,6 +1,7 @@
 <template>
     <div class="container">
         <p class="text">{{ centerText }}</p>
+        <p class="bottom_text">{{ bottomText }}</p>
         <apexchart type="radialBar" height="205" :options="chartOptions" :series="series" ref="chart"/>
     </div>
 </template>
@@ -18,6 +19,7 @@ export default {
         centerText: String,
         colors: String,
         name: String,
+        bottomText: String,
     },
     watch: {
         series: {
@@ -49,9 +51,7 @@ export default {
                                 offsetY: 60,
                                 fontSize: '14px',
                                 color: undefined,
-                                formatter: function (val) {
-                                    return val + "%";
-                                }
+                                formatter: () => {return ''}
                             }
                         }
                     }
@@ -87,7 +87,13 @@ export default {
         top: calc(72px);
         width: 100%;
         text-align: center;
-
+    }
+    .bottom_text {
+        position: absolute;
+        top: calc(142px);
+        font-weight: 600;
+        width: 100%;
+        text-align: center;
     }
 }
 </style>

+ 82 - 38
frontend/src/locale/en/LC_MESSAGES/app.po

@@ -10,11 +10,15 @@ msgstr ""
 "Generated-By: easygettext\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/router/index.js:100
+#: src/views/other/Install.vue:50
+msgid "<translate>Install</translate>"
+msgstr ""
+
+#: src/router/index.js:99
 msgid "404 Not Found"
 msgstr ""
 
-#: src/router/index.js:78
+#: src/router/index.js:77
 msgid "About"
 msgstr ""
 
@@ -24,7 +28,7 @@ msgid "Action"
 msgstr ""
 
 #: src/router/index.js:47 src/views/domain/DomainAdd.vue:18
-#: src/views/domain/DomainEdit.vue:45
+#: src/views/domain/DomainEdit.vue:46
 msgid "Add Site"
 msgstr ""
 
@@ -77,6 +81,14 @@ msgstr ""
 msgid "Configurations"
 msgstr ""
 
+#: src/views/dashboard/DashBoard.vue:204
+msgid "CPU Status"
+msgstr ""
+
+#: src/views/dashboard/DashBoard.vue:22
+msgid "CPU:"
+msgstr ""
+
 #: src/views/user/User.vue:23
 msgid "Created at"
 msgstr ""
@@ -85,11 +97,11 @@ msgstr ""
 msgid "Dashboard"
 msgstr ""
 
-#: src/views/other/Install.vue:105
+#: src/views/other/Install.vue:106
 msgid "Database (Optional, default: database)"
 msgstr ""
 
-#: src/router/index.js:126
+#: src/router/index.js:125
 msgid "Detected version update, this page will refresh."
 msgstr ""
 
@@ -110,19 +122,23 @@ msgstr ""
 msgid "Disabled successfully"
 msgstr ""
 
+#: src/views/dashboard/DashBoard.vue:282
+msgid "Disk IO"
+msgstr ""
+
 #: src/views/domain/DomainEdit.vue:133
 msgid "Do you want to change the template to support the TLS?"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:45
+#: src/views/domain/DomainEdit.vue:46
 msgid "Edit %{n}"
 msgstr ""
 
-#: src/router/index.js:68 src/views/config/ConfigEdit.vue:15
+#: src/router/index.js:69 src/views/config/ConfigEdit.vue:15
 msgid "Edit Configuration"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:91
+#: src/views/domain/DomainEdit.vue:92
 msgid "Edit Configuration File"
 msgstr ""
 
@@ -130,7 +146,7 @@ msgstr ""
 msgid "Edit Site"
 msgstr ""
 
-#: src/views/other/Install.vue:31
+#: src/views/other/Install.vue:32
 msgid "Email (*)"
 msgstr ""
 
@@ -195,7 +211,7 @@ msgstr ""
 msgid "Index (index)"
 msgstr ""
 
-#: src/router/index.js:88 src/views/other/Install.vue:50
+#: src/router/index.js:87 src/views/other/Install.vue:51
 msgid "Install"
 msgstr ""
 
@@ -203,7 +219,7 @@ msgstr ""
 msgid "Intermediate Certification Authorities: %{issuer}"
 msgstr ""
 
-#: src/views/other/Install.vue:46
+#: src/views/other/Install.vue:47
 msgid "Invalid E-mail!"
 msgstr ""
 
@@ -216,11 +232,11 @@ msgctxt "Project"
 msgid "License"
 msgstr ""
 
-#: src/views/dashboard/DashBoard.vue:13
+#: src/views/dashboard/DashBoard.vue:10
 msgid "Load Averages:"
 msgstr ""
 
-#: src/router/index.js:94 src/views/other/Login.vue:24
+#: src/router/index.js:93 src/views/other/Login.vue:24
 msgid "Login"
 msgstr ""
 
@@ -251,7 +267,7 @@ msgstr ""
 msgid "Manage Users"
 msgstr ""
 
-#: src/views/dashboard/DashBoard.vue:24
+#: src/views/dashboard/DashBoard.vue:100
 msgid "Memory"
 msgstr ""
 
@@ -259,7 +275,19 @@ msgstr ""
 msgid "Name"
 msgstr ""
 
-#: src/router/index.js:106
+#: src/views/dashboard/DashBoard.vue:231
+msgid "Network"
+msgstr ""
+
+#: src/views/dashboard/DashBoard.vue:165
+msgid "Network Total Receive"
+msgstr ""
+
+#: src/views/dashboard/DashBoard.vue:174
+msgid "Network Total Send"
+msgstr ""
+
+#: src/router/index.js:105
 msgid "Not Found"
 msgstr ""
 
@@ -273,27 +301,31 @@ msgid ""
 "you need to get the certificate."
 msgstr ""
 
-#: src/router/index.js:130
+#: src/router/index.js:129
 msgid "OK"
 msgstr ""
 
+#: src/views/dashboard/DashBoard.vue:16
+msgid "OS:"
+msgstr ""
+
 #: src/views/other/Login.vue:56 src/views/user/User.vue:13
 msgid "Password"
 msgstr ""
 
-#: src/views/other/Install.vue:83
+#: src/views/other/Install.vue:84
 msgid "Password (*)"
 msgstr ""
 
-#: src/views/other/Install.vue:50
+#: src/views/other/Install.vue:51
 msgid "Please input your E-mail!"
 msgstr ""
 
-#: src/views/other/Install.vue:96 src/views/other/Login.vue:69
+#: src/views/other/Install.vue:97 src/views/other/Login.vue:69
 msgid "Please input your password!"
 msgstr ""
 
-#: src/views/other/Install.vue:73 src/views/other/Login.vue:46
+#: src/views/other/Install.vue:74 src/views/other/Login.vue:46
 msgid "Please input your username!"
 msgstr ""
 
@@ -305,6 +337,14 @@ msgstr ""
 msgid "Project Team"
 msgstr ""
 
+#: src/views/dashboard/DashBoard.vue:61 src/views/dashboard/DashBoard.vue:305
+msgid "Reads"
+msgstr ""
+
+#: src/views/dashboard/DashBoard.vue:51 src/views/dashboard/DashBoard.vue:240
+msgid "Receive"
+msgstr ""
+
 #: src/views/domain/columns.js:16
 msgid "Root Directory (root)"
 msgstr ""
@@ -324,17 +364,21 @@ msgstr ""
 msgid "Saved successfully"
 msgstr ""
 
+#: src/views/dashboard/DashBoard.vue:54 src/views/dashboard/DashBoard.vue:254
+msgid "Send"
+msgstr ""
+
 #: src/views/config/ConfigEdit.vue:35 src/views/domain/DomainEdit.vue:71
 #: src/views/other/Login.vue:35
 msgid "Server error"
 msgstr ""
 
-#: src/views/domain/columns.js:10
-msgid "Server Names (server_name)"
+#: src/views/dashboard/DashBoard.vue:37
+msgid "Server Info"
 msgstr ""
 
-#: src/views/dashboard/DashBoard.vue:38
-msgid "Server Status"
+#: src/views/domain/columns.js:10
+msgid "Server Names (server_name)"
 msgstr ""
 
 #: src/router/index.js:43
@@ -345,7 +389,7 @@ msgstr ""
 msgid "Status"
 msgstr ""
 
-#: src/views/dashboard/DashBoard.vue:33
+#: src/views/dashboard/DashBoard.vue:132
 msgid "Storage"
 msgstr ""
 
@@ -353,7 +397,11 @@ msgstr ""
 msgid "Subject Name: %{name}"
 msgstr ""
 
-#: src/router/index.js:125
+#: src/views/dashboard/DashBoard.vue:116
+msgid "Swap"
+msgstr ""
+
+#: src/router/index.js:124
 msgid "System message"
 msgstr ""
 
@@ -365,7 +413,7 @@ msgid ""
 "from Let's Encrypt\" first."
 msgstr ""
 
-#: src/views/other/Install.vue:120
+#: src/views/other/Install.vue:121
 msgid "The filename cannot contain the following characters: %{c}"
 msgstr ""
 
@@ -385,22 +433,18 @@ msgstr ""
 msgid "Updated at"
 msgstr ""
 
-#: src/views/dashboard/DashBoard.vue:12
-msgid "Uptime"
-msgstr ""
-
-#: src/views/dashboard/DashBoard.vue:95
-msgid "Used: %{u}, Cached: %{c}, Free: %{f}, Physical Memory: %{p}"
-msgstr ""
-
-#: src/views/dashboard/DashBoard.vue:123
-msgid "Used: %{used} / Total: %{total}"
+#: src/views/dashboard/DashBoard.vue:6
+msgid "Uptime:"
 msgstr ""
 
 #: src/views/other/Login.vue:33 src/views/user/User.vue:5
 msgid "Username"
 msgstr ""
 
-#: src/views/other/Install.vue:60
+#: src/views/other/Install.vue:61
 msgid "Username (*)"
 msgstr ""
+
+#: src/views/dashboard/DashBoard.vue:58 src/views/dashboard/DashBoard.vue:291
+msgid "Writes"
+msgstr ""

二进制
frontend/src/locale/zh_CN/LC_MESSAGES/app.mo


+ 97 - 44
frontend/src/locale/zh_CN/LC_MESSAGES/app.po

@@ -10,13 +10,17 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: easygettext\n"
-"X-Generator: Poedit 2.2\n"
+"X-Generator: Poedit 3.0.1\n"
 
-#: src/router/index.js:100
+#: src/views/other/Install.vue:50
+msgid "<translate>Install</translate>"
+msgstr ""
+
+#: src/router/index.js:99
 msgid "404 Not Found"
 msgstr "404 未找到页面"
 
-#: src/router/index.js:78
+#: src/router/index.js:77
 msgid "About"
 msgstr "关于"
 
@@ -26,7 +30,7 @@ msgid "Action"
 msgstr "操作"
 
 #: src/router/index.js:47 src/views/domain/DomainAdd.vue:18
-#: src/views/domain/DomainEdit.vue:45
+#: src/views/domain/DomainEdit.vue:46
 msgid "Add Site"
 msgstr "添加站点"
 
@@ -79,6 +83,14 @@ msgstr "配置名称"
 msgid "Configurations"
 msgstr "配置"
 
+#: src/views/dashboard/DashBoard.vue:204
+msgid "CPU Status"
+msgstr "CPU 状态"
+
+#: src/views/dashboard/DashBoard.vue:22
+msgid "CPU:"
+msgstr ""
+
 #: src/views/user/User.vue:23
 msgid "Created at"
 msgstr "创建时间"
@@ -87,11 +99,11 @@ msgstr "创建时间"
 msgid "Dashboard"
 msgstr "仪表盘"
 
-#: src/views/other/Install.vue:105
+#: src/views/other/Install.vue:106
 msgid "Database (Optional, default: database)"
 msgstr "数据库 (可选,默认: database)"
 
-#: src/router/index.js:126
+#: src/router/index.js:125
 msgid "Detected version update, this page will refresh."
 msgstr "检测到版本更新,页面将会刷新。"
 
@@ -112,19 +124,23 @@ msgstr "禁用"
 msgid "Disabled successfully"
 msgstr "禁用成功"
 
+#: src/views/dashboard/DashBoard.vue:282
+msgid "Disk IO"
+msgstr "磁盘 IO"
+
 #: src/views/domain/DomainEdit.vue:133
 msgid "Do you want to change the template to support the TLS?"
 msgstr "你想要改变模板以支持 TLS 吗?"
 
-#: src/views/domain/DomainEdit.vue:45
+#: src/views/domain/DomainEdit.vue:46
 msgid "Edit %{n}"
 msgstr "编辑 %{n}"
 
-#: src/router/index.js:68 src/views/config/ConfigEdit.vue:15
+#: src/router/index.js:69 src/views/config/ConfigEdit.vue:15
 msgid "Edit Configuration"
 msgstr "编辑配置"
 
-#: src/views/domain/DomainEdit.vue:91
+#: src/views/domain/DomainEdit.vue:92
 msgid "Edit Configuration File"
 msgstr "编辑配置文件"
 
@@ -132,7 +148,7 @@ msgstr "编辑配置文件"
 msgid "Edit Site"
 msgstr "编辑站点"
 
-#: src/views/other/Install.vue:31
+#: src/views/other/Install.vue:32
 msgid "Email (*)"
 msgstr "邮箱 (*)"
 
@@ -197,7 +213,7 @@ msgstr "HTTPS 监听端口"
 msgid "Index (index)"
 msgstr "网站首页 (index)"
 
-#: src/router/index.js:88 src/views/other/Install.vue:50
+#: src/router/index.js:87 src/views/other/Install.vue:51
 msgid "Install"
 msgstr "安装"
 
@@ -205,7 +221,7 @@ msgstr "安装"
 msgid "Intermediate Certification Authorities: %{issuer}"
 msgstr "中级证书颁发机构: %{issuer}"
 
-#: src/views/other/Install.vue:46
+#: src/views/other/Install.vue:47
 msgid "Invalid E-mail!"
 msgstr "无效的邮箱!"
 
@@ -218,11 +234,11 @@ msgctxt "Project"
 msgid "License"
 msgstr "开源许可"
 
-#: src/views/dashboard/DashBoard.vue:13
+#: src/views/dashboard/DashBoard.vue:10
 msgid "Load Averages:"
 msgstr "系统负载:"
 
-#: src/router/index.js:94 src/views/other/Login.vue:24
+#: src/router/index.js:93 src/views/other/Login.vue:24
 msgid "Login"
 msgstr "登录"
 
@@ -240,8 +256,8 @@ msgid ""
 "directory to <code>HTTPChallengePort</code> (default: 9180) before getting "
 "the certificate."
 msgstr ""
-"在获取签发证书前,请确保配置文件中已将 <code>.well-known</code> 目录反向代"
-"到<code>HTTPChallengePort</code> (默认: 9180)"
+"在获取签发证书前,请确保配置文件中已将 <code>.well-known</code> 目录反向代"
+"到<code>HTTPChallengePort</code> (默认: 9180)"
 
 #: src/router/index.js:60
 msgid "Manage Configs"
@@ -255,7 +271,7 @@ msgstr "网站管理"
 msgid "Manage Users"
 msgstr "用户管理"
 
-#: src/views/dashboard/DashBoard.vue:24
+#: src/views/dashboard/DashBoard.vue:100
 msgid "Memory"
 msgstr "内存"
 
@@ -263,7 +279,19 @@ msgstr "内存"
 msgid "Name"
 msgstr "名称"
 
-#: src/router/index.js:106
+#: src/views/dashboard/DashBoard.vue:231
+msgid "Network"
+msgstr ""
+
+#: src/views/dashboard/DashBoard.vue:165
+msgid "Network Total Receive"
+msgstr "下载流量"
+
+#: src/views/dashboard/DashBoard.vue:174
+msgid "Network Total Send"
+msgstr "上传流量"
+
+#: src/router/index.js:105
 msgid "Not Found"
 msgstr "找不到页面"
 
@@ -277,27 +305,31 @@ msgid ""
 "you need to get the certificate."
 msgstr "注意:当前配置中的 server_name 必须为需要申请证书的域名。"
 
-#: src/router/index.js:130
+#: src/router/index.js:129
 msgid "OK"
 msgstr "确定"
 
+#: src/views/dashboard/DashBoard.vue:16
+msgid "OS:"
+msgstr ""
+
 #: src/views/other/Login.vue:56 src/views/user/User.vue:13
 msgid "Password"
 msgstr "密码"
 
-#: src/views/other/Install.vue:83
+#: src/views/other/Install.vue:84
 msgid "Password (*)"
 msgstr "密码 (*)"
 
-#: src/views/other/Install.vue:50
+#: src/views/other/Install.vue:51
 msgid "Please input your E-mail!"
 msgstr "请输入您的邮箱!"
 
-#: src/views/other/Install.vue:96 src/views/other/Login.vue:69
+#: src/views/other/Install.vue:97 src/views/other/Login.vue:69
 msgid "Please input your password!"
 msgstr "请输入您的密码!"
 
-#: src/views/other/Install.vue:73 src/views/other/Login.vue:46
+#: src/views/other/Install.vue:74 src/views/other/Login.vue:46
 msgid "Please input your username!"
 msgstr "请输入您的用户名!"
 
@@ -309,6 +341,14 @@ msgstr "私钥路径 (ssl_certificate_key)"
 msgid "Project Team"
 msgstr "项目团队"
 
+#: src/views/dashboard/DashBoard.vue:61 src/views/dashboard/DashBoard.vue:305
+msgid "Reads"
+msgstr "读"
+
+#: src/views/dashboard/DashBoard.vue:51 src/views/dashboard/DashBoard.vue:240
+msgid "Receive"
+msgstr "下载"
+
 #: src/views/domain/columns.js:16
 msgid "Root Directory (root)"
 msgstr "网站根目录 (root)"
@@ -328,19 +368,23 @@ msgstr "保存错误 %{msg}"
 msgid "Saved successfully"
 msgstr "保存成功"
 
+#: src/views/dashboard/DashBoard.vue:54 src/views/dashboard/DashBoard.vue:254
+msgid "Send"
+msgstr "上传"
+
 #: src/views/config/ConfigEdit.vue:35 src/views/domain/DomainEdit.vue:71
 #: src/views/other/Login.vue:35
 msgid "Server error"
 msgstr "服务器错误"
 
+#: src/views/dashboard/DashBoard.vue:37
+msgid "Server Info"
+msgstr "服务器信息"
+
 #: src/views/domain/columns.js:10
 msgid "Server Names (server_name)"
 msgstr "网站域名 (server_name)"
 
-#: src/views/dashboard/DashBoard.vue:38
-msgid "Server Status"
-msgstr "服务器状态"
-
 #: src/router/index.js:43
 msgid "Sites List"
 msgstr "站点列表"
@@ -349,7 +393,7 @@ msgstr "站点列表"
 msgid "Status"
 msgstr "状态"
 
-#: src/views/dashboard/DashBoard.vue:33
+#: src/views/dashboard/DashBoard.vue:132
 msgid "Storage"
 msgstr "存储"
 
@@ -357,7 +401,11 @@ msgstr "存储"
 msgid "Subject Name: %{name}"
 msgstr "主体名称: %{name}"
 
-#: src/router/index.js:125
+#: src/views/dashboard/DashBoard.vue:116
+msgid "Swap"
+msgstr ""
+
+#: src/router/index.js:124
 msgid "System message"
 msgstr "系统消息"
 
@@ -371,7 +419,7 @@ msgstr ""
 "系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。"
 "<br/>如果您之前没有证书,请先点击 \"从 Let's Encrypt 获取证书\"。"
 
-#: src/views/other/Install.vue:120
+#: src/views/other/Install.vue:121
 msgid "The filename cannot contain the following characters: %{c}"
 msgstr "文件名不能包含以下字符: %{c}"
 
@@ -381,8 +429,8 @@ msgid ""
 "fields in your configuration file. The configuration filename cannot be "
 "changed after it has been created."
 msgstr ""
-"只有在您的配置文件中有相应字段时,下列的配置才能生效。配置文件名称创建后不"
-"修改。"
+"只有在您的配置文件中有相应字段时,下列的配置才能生效。配置文件名称创建后不"
+"修改。"
 
 #: src/views/domain/DomainEdit.vue:134
 msgid "This operation will lose the custom configuration."
@@ -393,25 +441,30 @@ msgstr "该操作将会丢失自定义配置。"
 msgid "Updated at"
 msgstr "修改时间"
 
-#: src/views/dashboard/DashBoard.vue:12
-msgid "Uptime"
-msgstr "运行时间"
-
-#: src/views/dashboard/DashBoard.vue:95
-msgid "Used: %{u}, Cached: %{c}, Free: %{f}, Physical Memory: %{p}"
-msgstr "已使用: %{u}, 缓存: %{c}, 空闲: %{f}, 物理内存: %{p}"
-
-#: src/views/dashboard/DashBoard.vue:123
-msgid "Used: %{used} / Total: %{total}"
-msgstr "已使用: %{used} / 总共: %{total}"
+#: src/views/dashboard/DashBoard.vue:6
+msgid "Uptime:"
+msgstr "运行时间:"
 
 #: src/views/other/Login.vue:33 src/views/user/User.vue:5
 msgid "Username"
 msgstr "用户名"
 
-#: src/views/other/Install.vue:60
+#: src/views/other/Install.vue:61
 msgid "Username (*)"
 msgstr "用户名 (*)"
 
+#: src/views/dashboard/DashBoard.vue:58 src/views/dashboard/DashBoard.vue:291
+msgid "Writes"
+msgstr "写"
+
+#~ msgid "Server Status"
+#~ msgstr "服务器状态"
+
+#~ msgid "Used: %{u}, Cached: %{c}, Free: %{f}, Physical Memory: %{p}"
+#~ msgstr "已使用: %{u}, 缓存: %{c}, 空闲: %{f}, 物理内存: %{p}"
+
+#~ msgid "Used: %{used} / Total: %{total}"
+#~ msgstr "已使用: %{used} / 总共: %{total}"
+
 #~ msgid "CPU"
 #~ msgstr "CPU"

+ 94 - 38
frontend/src/locale/zh_TW/LC_MESSAGES/app.po

@@ -13,11 +13,15 @@ msgstr ""
 "Generated-By: easygettext\n"
 "X-Generator: Poedit 2.2\n"
 
-#: src/router/index.js:100
+#: src/views/other/Install.vue:50
+msgid "<translate>Install</translate>"
+msgstr ""
+
+#: src/router/index.js:99
 msgid "404 Not Found"
 msgstr "404 未找到頁面"
 
-#: src/router/index.js:78
+#: src/router/index.js:77
 msgid "About"
 msgstr "關於"
 
@@ -27,7 +31,7 @@ msgid "Action"
 msgstr "操作"
 
 #: src/router/index.js:47 src/views/domain/DomainAdd.vue:18
-#: src/views/domain/DomainEdit.vue:45
+#: src/views/domain/DomainEdit.vue:46
 msgid "Add Site"
 msgstr "新增站點"
 
@@ -80,6 +84,15 @@ msgstr "配置名稱"
 msgid "Configurations"
 msgstr "配置"
 
+#: src/views/dashboard/DashBoard.vue:204
+#, fuzzy
+msgid "CPU Status"
+msgstr "狀態"
+
+#: src/views/dashboard/DashBoard.vue:22
+msgid "CPU:"
+msgstr ""
+
 #: src/views/user/User.vue:23
 msgid "Created at"
 msgstr "建立時間"
@@ -88,11 +101,11 @@ msgstr "建立時間"
 msgid "Dashboard"
 msgstr "儀表盤"
 
-#: src/views/other/Install.vue:105
+#: src/views/other/Install.vue:106
 msgid "Database (Optional, default: database)"
 msgstr "資料庫 (可選,預設: database)"
 
-#: src/router/index.js:126
+#: src/router/index.js:125
 msgid "Detected version update, this page will refresh."
 msgstr "檢測到版本更新,頁面將會重新整理。"
 
@@ -113,19 +126,23 @@ msgstr "禁用"
 msgid "Disabled successfully"
 msgstr "禁用成功"
 
+#: src/views/dashboard/DashBoard.vue:282
+msgid "Disk IO"
+msgstr ""
+
 #: src/views/domain/DomainEdit.vue:133
 msgid "Do you want to change the template to support the TLS?"
 msgstr "你想要改變模板以支援 TLS 嗎?"
 
-#: src/views/domain/DomainEdit.vue:45
+#: src/views/domain/DomainEdit.vue:46
 msgid "Edit %{n}"
 msgstr "編輯 %{n}"
 
-#: src/router/index.js:68 src/views/config/ConfigEdit.vue:15
+#: src/router/index.js:69 src/views/config/ConfigEdit.vue:15
 msgid "Edit Configuration"
 msgstr "編輯配置"
 
-#: src/views/domain/DomainEdit.vue:91
+#: src/views/domain/DomainEdit.vue:92
 msgid "Edit Configuration File"
 msgstr "編輯配置檔案"
 
@@ -133,7 +150,7 @@ msgstr "編輯配置檔案"
 msgid "Edit Site"
 msgstr "編輯站點"
 
-#: src/views/other/Install.vue:31
+#: src/views/other/Install.vue:32
 msgid "Email (*)"
 msgstr "郵箱 (*)"
 
@@ -198,7 +215,7 @@ msgstr "HTTPS 監聽埠"
 msgid "Index (index)"
 msgstr "網站首頁 (index)"
 
-#: src/router/index.js:88 src/views/other/Install.vue:50
+#: src/router/index.js:87 src/views/other/Install.vue:51
 msgid "Install"
 msgstr "安裝"
 
@@ -206,7 +223,7 @@ msgstr "安裝"
 msgid "Intermediate Certification Authorities: %{issuer}"
 msgstr "中級證書頒發機構: %{issuer}"
 
-#: src/views/other/Install.vue:46
+#: src/views/other/Install.vue:47
 msgid "Invalid E-mail!"
 msgstr "無效的郵箱!"
 
@@ -219,11 +236,11 @@ msgctxt "Project"
 msgid "License"
 msgstr "開源許可"
 
-#: src/views/dashboard/DashBoard.vue:13
+#: src/views/dashboard/DashBoard.vue:10
 msgid "Load Averages:"
 msgstr "系統負載:"
 
-#: src/router/index.js:94 src/views/other/Login.vue:24
+#: src/router/index.js:93 src/views/other/Login.vue:24
 msgid "Login"
 msgstr "登入"
 
@@ -256,7 +273,7 @@ msgstr "網站管理"
 msgid "Manage Users"
 msgstr "使用者管理"
 
-#: src/views/dashboard/DashBoard.vue:24
+#: src/views/dashboard/DashBoard.vue:100
 msgid "Memory"
 msgstr "記憶體"
 
@@ -264,7 +281,19 @@ msgstr "記憶體"
 msgid "Name"
 msgstr "名稱"
 
-#: src/router/index.js:106
+#: src/views/dashboard/DashBoard.vue:231
+msgid "Network"
+msgstr ""
+
+#: src/views/dashboard/DashBoard.vue:165
+msgid "Network Total Receive"
+msgstr ""
+
+#: src/views/dashboard/DashBoard.vue:174
+msgid "Network Total Send"
+msgstr ""
+
+#: src/router/index.js:105
 msgid "Not Found"
 msgstr "找不到頁面"
 
@@ -278,27 +307,31 @@ msgid ""
 "you need to get the certificate."
 msgstr "注意:當前配置中的 server_name 必須為需要申請證書的域名。"
 
-#: src/router/index.js:130
+#: src/router/index.js:129
 msgid "OK"
 msgstr "確定"
 
+#: src/views/dashboard/DashBoard.vue:16
+msgid "OS:"
+msgstr ""
+
 #: src/views/other/Login.vue:56 src/views/user/User.vue:13
 msgid "Password"
 msgstr "密碼"
 
-#: src/views/other/Install.vue:83
+#: src/views/other/Install.vue:84
 msgid "Password (*)"
 msgstr "密碼 (*)"
 
-#: src/views/other/Install.vue:50
+#: src/views/other/Install.vue:51
 msgid "Please input your E-mail!"
 msgstr "請輸入您的郵箱!"
 
-#: src/views/other/Install.vue:96 src/views/other/Login.vue:69
+#: src/views/other/Install.vue:97 src/views/other/Login.vue:69
 msgid "Please input your password!"
 msgstr "請輸入您的密碼!"
 
-#: src/views/other/Install.vue:73 src/views/other/Login.vue:46
+#: src/views/other/Install.vue:74 src/views/other/Login.vue:46
 msgid "Please input your username!"
 msgstr "請輸入您的使用者名稱!"
 
@@ -310,6 +343,14 @@ msgstr "私鑰路徑 (ssl_certificate_key)"
 msgid "Project Team"
 msgstr "專案團隊"
 
+#: src/views/dashboard/DashBoard.vue:61 src/views/dashboard/DashBoard.vue:305
+msgid "Reads"
+msgstr ""
+
+#: src/views/dashboard/DashBoard.vue:51 src/views/dashboard/DashBoard.vue:240
+msgid "Receive"
+msgstr ""
+
 #: src/views/domain/columns.js:16
 msgid "Root Directory (root)"
 msgstr "網站根目錄 (root)"
@@ -329,19 +370,24 @@ msgstr "儲存錯誤 %{msg}"
 msgid "Saved successfully"
 msgstr "儲存成功"
 
+#: src/views/dashboard/DashBoard.vue:54 src/views/dashboard/DashBoard.vue:254
+msgid "Send"
+msgstr ""
+
 #: src/views/config/ConfigEdit.vue:35 src/views/domain/DomainEdit.vue:71
 #: src/views/other/Login.vue:35
 msgid "Server error"
 msgstr "伺服器錯誤"
 
+#: src/views/dashboard/DashBoard.vue:37
+#, fuzzy
+msgid "Server Info"
+msgstr "伺服器錯誤"
+
 #: src/views/domain/columns.js:10
 msgid "Server Names (server_name)"
 msgstr "網站域名 (server_name)"
 
-#: src/views/dashboard/DashBoard.vue:38
-msgid "Server Status"
-msgstr "伺服器狀態"
-
 #: src/router/index.js:43
 msgid "Sites List"
 msgstr "站點列表"
@@ -350,7 +396,7 @@ msgstr "站點列表"
 msgid "Status"
 msgstr "狀態"
 
-#: src/views/dashboard/DashBoard.vue:33
+#: src/views/dashboard/DashBoard.vue:132
 msgid "Storage"
 msgstr "儲存"
 
@@ -358,7 +404,11 @@ msgstr "儲存"
 msgid "Subject Name: %{name}"
 msgstr "主體名稱: %{name}"
 
-#: src/router/index.js:125
+#: src/views/dashboard/DashBoard.vue:116
+msgid "Swap"
+msgstr ""
+
+#: src/router/index.js:124
 msgid "System message"
 msgstr "系統訊息"
 
@@ -372,7 +422,7 @@ msgstr ""
 "系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。"
 "<br/>如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。"
 
-#: src/views/other/Install.vue:120
+#: src/views/other/Install.vue:121
 msgid "The filename cannot contain the following characters: %{c}"
 msgstr "檔名不能包含以下字元: %{c}"
 
@@ -394,25 +444,31 @@ msgstr "該操作將會丟失自定義配置。"
 msgid "Updated at"
 msgstr "修改時間"
 
-#: src/views/dashboard/DashBoard.vue:12
-msgid "Uptime"
+#: src/views/dashboard/DashBoard.vue:6
+#, fuzzy
+msgid "Uptime:"
 msgstr "執行時間"
 
-#: src/views/dashboard/DashBoard.vue:95
-msgid "Used: %{u}, Cached: %{c}, Free: %{f}, Physical Memory: %{p}"
-msgstr "已使用: %{u}, 快取: %{c}, 空閒: %{f}, 物理記憶體: %{p}"
-
-#: src/views/dashboard/DashBoard.vue:123
-msgid "Used: %{used} / Total: %{total}"
-msgstr "已使用: %{used} / 總共: %{total}"
-
 #: src/views/other/Login.vue:33 src/views/user/User.vue:5
 msgid "Username"
 msgstr "使用者名稱"
 
-#: src/views/other/Install.vue:60
+#: src/views/other/Install.vue:61
 msgid "Username (*)"
 msgstr "使用者名稱 (*)"
 
+#: src/views/dashboard/DashBoard.vue:58 src/views/dashboard/DashBoard.vue:291
+msgid "Writes"
+msgstr ""
+
+#~ msgid "Server Status"
+#~ msgstr "伺服器狀態"
+
+#~ msgid "Used: %{u}, Cached: %{c}, Free: %{f}, Physical Memory: %{p}"
+#~ msgstr "已使用: %{u}, 快取: %{c}, 空閒: %{f}, 物理記憶體: %{p}"
+
+#~ msgid "Used: %{used} / Total: %{total}"
+#~ msgstr "已使用: %{used} / 總共: %{total}"
+
 #~ msgid "CPU"
 #~ msgstr "CPU"

文件差异内容过多而无法显示
+ 0 - 0
frontend/src/translations.json


+ 14 - 21
frontend/src/views/dashboard/DashBoard.vue

@@ -1,7 +1,7 @@
 <template>
     <div>
         <a-row :gutter="[16,16]" class="first-row">
-            <a-col :lg="7" :md="24">
+            <a-col :xl="6" :lg="24" :md="24">
                 <a-card :title="$gettext('Server Info')">
                     <p>
                         <translate>Uptime:</translate>
@@ -23,37 +23,28 @@
                         <translate>CPU:</translate>
                         {{ cpu_info[0]?.modelName }} * {{ cpu_info.length }}
                     </p>
-<!--                    <p><translate>Memory</translate>: {{-->
-<!--                            $gettextInterpolate(-->
-<!--                                $gettext('Used: %{u}, Cached: %{c}, Free: %{f}, Physical Memory: %{p}'),-->
-<!--                                {u: memory_used, c: memory_cached, f: memory_free, p: memory_total})-->
-<!--                        }}</p>-->
-<!--                    <p><translate>Storage</translate>: {{-->
-<!--                            $gettextInterpolate($gettext('Used: %{used} / Total: %{total}'),-->
-<!--                                {used: disk_used, total: disk_total})-->
-<!--                        }}-->
-<!--                    </p>-->
                 </a-card>
             </a-col>
-            <a-col :lg="12" :md="24" class="chart_dashboard">
+            <a-col :xl="12" :lg="18" :md="24" class="chart_dashboard">
                 <a-card>
                     <a-row>
                         <a-col :xs="24" :sm="24" :md="8">
                             <radial-bar-chart :name="$gettext('Memory')" :series="[memory_pressure]"
-                                              :centerText="memory_used" colors="#36a3eb"/>
+                                              :centerText="memory_used" :bottom-text="memory_total" colors="#36a3eb"/>
                         </a-col>
                         <a-col :xs="24" :sm="12" :md="8">
                             <radial-bar-chart :name="$gettext('Swap')" :series="[memory_swap_percent]"
-                                              :centerText="memory_swap_used" colors="#ff6385"/>
+                                              :centerText="memory_swap_used"
+                                              :bottom-text="memory_swap_total" colors="#ff6385"/>
                         </a-col>
                         <a-col :xs="24" :sm="12" :md="8">
                             <radial-bar-chart :name="$gettext('Storage')" :series="[disk_percentage]"
-                                              :centerText="disk_used" colors="#87d068"/>
+                                              :centerText="disk_used" :bottom-text="disk_total" colors="#87d068"/>
                         </a-col>
                     </a-row>
                 </a-card>
             </a-col>
-            <a-col :lg="5" :sm="24" class="chart_dashboard">
+            <a-col :xl="6" :lg="6" :sm="24" class="chart_dashboard">
                 <a-card>
                     <a-row :gutter="16">
                         <a-col :span="24">
@@ -62,14 +53,14 @@
                         </a-col>
                         <a-col :span="24">
                             <a-statistic :value="bytesToSize(net.last_sent)"
-                                         :title="$gettext('Network Total Send')" />
+                                         :title="$gettext('Network Total Send')"/>
                         </a-col>
                     </a-row>
                 </a-card>
             </a-col>
         </a-row>
         <a-row class="row-two" :gutter="[16,32]">
-            <a-col :lg="8" :md="24" :sm="24">
+            <a-col :xl="7" :lg="24" :md="24" :sm="24">
                 <a-card :title="$gettext('CPU Status')">
                     <a-statistic :value="cpu" title="CPU">
                         <template v-slot:suffix>
@@ -79,7 +70,7 @@
                     <c-p-u-chart :series="cpu_analytic_series"/>
                 </a-card>
             </a-col>
-            <a-col :lg="8" :md="24" :sm="24">
+            <a-col :xl="10" :lg="12" :md="24" :sm="24">
                 <a-card :title="$gettext('Network')">
                     <a-row :gutter="16">
                         <a-col :span="12">
@@ -101,7 +92,7 @@
                     <net-chart :series="net_analytic"/>
                 </a-card>
             </a-col>
-            <a-col :lg="8" :md="24" :sm="24">
+            <a-col :xl="7" :lg="12" :md="24" :sm="24">
                 <a-card :title="$gettext('Disk IO')">
                     <a-row :gutter="16">
                         <a-col :span="12">
@@ -163,6 +154,7 @@ export default {
             }],
             cpu: 0,
             memory_swap_used: '',
+            memory_swap_total: '',
             memory_swap_percent: 0,
             disk_percentage: 0,
             disk_total: '',
@@ -253,6 +245,7 @@ export default {
             this.memory_total = r.memory_total
             this.memory_swap_percent = r.memory_swap_percent
             this.memory_swap_used = r.memory_swap_used
+            this.memory_swap_total = r.memory_swap_total
 
             // disk
             this.disk_percentage = r.disk_percentage
@@ -277,8 +270,8 @@ export default {
             this.net_analytic[1].data.push([time, this.net.sent])
 
             if (this.net_analytic[0].data.length > 100) {
-                this.net_analytic[1].data.shift()
                 this.net_analytic[0].data.shift()
+                this.net_analytic[1].data.shift()
             }
 
             // diskIO

+ 1 - 1
frontend/src/views/other/About.vue

@@ -15,7 +15,7 @@
         <p>Vue</p>
         <p>Websocket</p>
         <h3 v-translate translate-context="Project">License</h3>
-        <p>GNU General Public License v2.0</p>
+        <p>GNU General Public License v3.0</p>
         <p>Copyright © 2020 - {{ this_year }} Nginx UI </p>
     </a-card>
 </template>

+ 2 - 1
main.go

@@ -3,6 +3,7 @@ package main
 import (
 	"context"
 	"flag"
+	"github.com/0xJacky/Nginx-UI/server/analytic"
 	"github.com/0xJacky/Nginx-UI/server/model"
 	"github.com/0xJacky/Nginx-UI/server/router"
 	"github.com/0xJacky/Nginx-UI/server/settings"
@@ -36,7 +37,7 @@ func main() {
 	if "" != settings.ServerSettings.JwtSecret {
 		model.Init()
 		go tool.AutoCert()
-		go tool.RecordServerAnalytic()
+		go analytic.RecordServerAnalytic()
 	}
 
 	srv := &http.Server{

+ 58 - 0
server/analytic/analytic.go

@@ -0,0 +1,58 @@
+package analytic
+
+import (
+	"github.com/shirou/gopsutil/v3/net"
+	"log"
+	"time"
+)
+
+type usage struct {
+	Time  time.Time   `json:"x"`
+	Usage interface{} `json:"y"`
+}
+
+var (
+	CpuUserRecord   []usage
+	CpuTotalRecord  []usage
+	NetRecvRecord   []usage
+	NetSentRecord   []usage
+	DiskWriteRecord []usage
+	DiskReadRecord  []usage
+	LastDiskWrites  uint64
+	LastDiskReads   uint64
+	LastNetSent     uint64
+	LastNetRecv     uint64
+)
+
+func init() {
+	network, _ := net.IOCounters(false)
+
+	if len(network) > 0 {
+		LastNetRecv = network[0].BytesRecv
+		LastNetSent = network[0].BytesSent
+	}
+
+	LastDiskReads, LastDiskWrites = getTotalDiskIO()
+
+	now := time.Now()
+	// init record slices
+	for i := 100; i > 0; i-- {
+		u := usage{Time: now.Add(time.Duration(-i) * time.Second), Usage: 0}
+		CpuUserRecord = append(CpuUserRecord, u)
+		CpuTotalRecord = append(CpuTotalRecord, u)
+		NetRecvRecord = append(NetRecvRecord, u)
+		NetSentRecord = append(NetSentRecord, u)
+		DiskWriteRecord = append(DiskWriteRecord, u)
+		DiskReadRecord = append(DiskReadRecord, u)
+	}
+}
+
+func RecordServerAnalytic() {
+	log.Println("[Nginx UI] RecordServerAnalytic Started")
+	for {
+		now := time.Now()
+		recordCpu(now) // this func will spend more than 1 second.
+		recordNetwork(now)
+		recordDiskIO(now)
+	}
+}

+ 96 - 0
server/analytic/record.go

@@ -0,0 +1,96 @@
+package analytic
+
+import (
+	"github.com/shirou/gopsutil/v3/cpu"
+	"github.com/shirou/gopsutil/v3/disk"
+	"github.com/shirou/gopsutil/v3/net"
+	"runtime"
+	"time"
+)
+
+func getTotalDiskIO() (read, write uint64) {
+	diskIOCounters, _ := disk.IOCounters()
+	for _, v := range diskIOCounters {
+		write += v.WriteCount
+		read += v.ReadCount
+	}
+	return
+}
+
+func recordCpu(now time.Time) {
+	cpuTimesBefore, _ := cpu.Times(false)
+	time.Sleep(1000 * time.Millisecond)
+	cpuTimesAfter, _ := cpu.Times(false)
+	threadNum := runtime.GOMAXPROCS(0)
+
+	cpuUserUsage := (cpuTimesAfter[0].User - cpuTimesBefore[0].User) / (float64(1000*threadNum) / 1000)
+	cpuUserUsage *= 100
+	cpuSystemUsage := (cpuTimesAfter[0].System - cpuTimesBefore[0].System) / (float64(1000*threadNum) / 1000)
+	cpuSystemUsage *= 100
+
+	u := usage{
+		Time:  now,
+		Usage: cpuUserUsage,
+	}
+
+	CpuUserRecord = append(CpuUserRecord, u)
+
+	s := usage{
+		Time:  now,
+		Usage: cpuUserUsage + cpuSystemUsage,
+	}
+
+	CpuTotalRecord = append(CpuTotalRecord, s)
+
+	if len(CpuUserRecord) > 100 {
+		CpuUserRecord = CpuUserRecord[1:]
+	}
+
+	if len(CpuTotalRecord) > 100 {
+		CpuTotalRecord = CpuTotalRecord[1:]
+	}
+}
+
+func recordNetwork(now time.Time) {
+	network, _ := net.IOCounters(false)
+	if len(network) == 0 {
+		return
+	}
+	NetRecvRecord = append(NetRecvRecord, usage{
+		Time:  now,
+		Usage: network[0].BytesRecv - LastNetRecv,
+	})
+	NetSentRecord = append(NetSentRecord, usage{
+		Time:  now,
+		Usage: network[0].BytesSent - LastNetSent,
+	})
+	LastNetRecv = network[0].BytesRecv
+	LastNetSent = network[0].BytesSent
+	if len(NetRecvRecord) > 100 {
+		NetRecvRecord = NetRecvRecord[1:]
+	}
+	if len(NetSentRecord) > 100 {
+		NetSentRecord = NetSentRecord[1:]
+	}
+}
+
+func recordDiskIO(now time.Time) {
+	readCount, writeCount := getTotalDiskIO()
+
+	DiskReadRecord = append(DiskReadRecord, usage{
+		Time:  now,
+		Usage: readCount - LastDiskReads,
+	})
+	DiskWriteRecord = append(DiskWriteRecord, usage{
+		Time:  now,
+		Usage: writeCount - LastDiskWrites,
+	})
+	if len(DiskReadRecord) > 100 {
+		DiskReadRecord = DiskReadRecord[1:]
+	}
+	if len(DiskWriteRecord) > 100 {
+		DiskWriteRecord = DiskWriteRecord[1:]
+	}
+	LastDiskWrites = writeCount
+	LastDiskReads = readCount
+}

+ 9 - 9
server/api/analytic.go

@@ -3,7 +3,7 @@ package api
 import (
 	"encoding/json"
 	"fmt"
-	"github.com/0xJacky/Nginx-UI/server/tool"
+	"github.com/0xJacky/Nginx-UI/server/analytic"
 	"github.com/shirou/gopsutil/v3/cpu"
 	"github.com/shirou/gopsutil/v3/disk"
 	"github.com/shirou/gopsutil/v3/host"
@@ -89,8 +89,8 @@ func Analytic(c *gin.Context) {
 			response["disk_percentage"], _ = strconv.ParseFloat(fmt.Sprintf("%.2f", diskUsage.UsedPercent), 64)
 
 			response["diskIO"] = gin.H{
-				"writes": tool.DiskWriteBuffer[len(tool.DiskWriteBuffer)-1],
-				"reads":  tool.DiskReadBuffer[len(tool.DiskReadBuffer)-1],
+				"writes": analytic.DiskWriteRecord[len(analytic.DiskWriteRecord)-1],
+				"reads":  analytic.DiskReadRecord[len(analytic.DiskReadRecord)-1],
 			}
 
 			network, _ := net.IOCounters(false)
@@ -125,17 +125,17 @@ func GetAnalyticInit(c *gin.Context) {
 		"host": hostInfo,
 		"cpu": gin.H{
 			"info":  cpuInfo,
-			"user":  tool.CpuUserBuffer,
-			"total": tool.CpuTotalBuffer,
+			"user":  analytic.CpuUserRecord,
+			"total": analytic.CpuTotalRecord,
 		},
 		"network": gin.H{
 			"init":      _net,
-			"bytesRecv": tool.NetRecvBuffer,
-			"bytesSent": tool.NetSentBuffer,
+			"bytesRecv": analytic.NetRecvRecord,
+			"bytesSent": analytic.NetSentRecord,
 		},
 		"diskIO": gin.H{
-			"writes": tool.DiskWriteBuffer,
-			"reads":  tool.DiskReadBuffer,
+			"writes": analytic.DiskWriteRecord,
+			"reads":  analytic.DiskReadRecord,
 		},
 	})
 }

+ 0 - 2
server/settings/settings.go

@@ -15,7 +15,6 @@ type Server struct {
 	HTTPChallengePort string
 	Email             string
 	Database          string
-	DiskName          string
 }
 
 var ServerSettings = &Server{
@@ -23,7 +22,6 @@ var ServerSettings = &Server{
 	RunMode:           "debug",
 	HTTPChallengePort: "9180",
 	Database:          "database",
-	DiskName:          "vda",
 }
 
 var ConfPath string

+ 0 - 124
server/tool/analytic.go

@@ -1,124 +0,0 @@
-package tool
-
-import (
-	"github.com/0xJacky/Nginx-UI/server/settings"
-	"github.com/shirou/gopsutil/v3/cpu"
-	"github.com/shirou/gopsutil/v3/disk"
-	"github.com/shirou/gopsutil/v3/net"
-	"runtime"
-	"time"
-)
-
-type usage struct {
-	Time  time.Time `json:"x"`
-	Usage float64   `json:"y"`
-}
-
-var CpuUserBuffer []usage
-var CpuTotalBuffer []usage
-var NetRecvBuffer []usage
-var NetSentBuffer []usage
-var DiskWriteBuffer []usage
-var DiskReadBuffer []usage
-
-var LastDiskWrites uint64
-var LastDiskReads uint64
-
-var LastNetRecv uint64
-var LastNetSent uint64
-
-func RecordServerAnalytic() {
-	network, _ := net.IOCounters(false)
-	diskIOCounters, _ := disk.IOCounters(settings.ServerSettings.DiskName)
-	diskIO, ok := diskIOCounters[settings.ServerSettings.DiskName]
-
-	if ok {
-		LastDiskWrites = diskIO.WriteCount
-		LastDiskReads = diskIO.ReadCount
-	}
-
-	if len(network) > 0 {
-		LastNetRecv = network[0].BytesRecv
-		LastNetSent = network[0].BytesSent
-	}
-
-	now := time.Now()
-	// 初始化记录数组
-	for i := 100; i > 0; i-- {
-		u := usage{Time: now.Add(time.Duration(-i) * time.Second)}
-		CpuUserBuffer = append(CpuUserBuffer, u)
-		CpuTotalBuffer = append(CpuTotalBuffer, u)
-		NetRecvBuffer = append(NetRecvBuffer, u)
-		NetSentBuffer = append(NetSentBuffer, u)
-		DiskWriteBuffer = append(DiskWriteBuffer, u)
-		DiskReadBuffer = append(DiskReadBuffer, u)
-	}
-	for {
-		cpuTimesBefore, _ := cpu.Times(false)
-		time.Sleep(1000 * time.Millisecond)
-		cpuTimesAfter, _ := cpu.Times(false)
-		threadNum := runtime.GOMAXPROCS(0)
-
-		cpuUserUsage := (cpuTimesAfter[0].User - cpuTimesBefore[0].User) / (float64(1000*threadNum) / 1000)
-		cpuUserUsage *= 100
-		cpuSystemUsage := (cpuTimesAfter[0].System - cpuTimesBefore[0].System) / (float64(1000*threadNum) / 1000)
-		cpuSystemUsage *= 100
-		now := time.Now()
-		u := usage{
-			Time:  now,
-			Usage: cpuUserUsage,
-		}
-		CpuUserBuffer = append(CpuUserBuffer, u)
-		s := usage{
-			Time:  now,
-			Usage: cpuUserUsage + cpuSystemUsage,
-		}
-		CpuTotalBuffer = append(CpuTotalBuffer, s)
-		if len(CpuUserBuffer) > 100 {
-			CpuUserBuffer = CpuUserBuffer[1:]
-		}
-		if len(CpuTotalBuffer) > 100 {
-			CpuTotalBuffer = CpuTotalBuffer[1:]
-		}
-		network, _ = net.IOCounters(false)
-		if len(network) == 0 {
-			continue
-		}
-		NetRecvBuffer = append(NetRecvBuffer, usage{
-			Time:  now,
-			Usage: float64(network[0].BytesRecv - LastNetRecv),
-		})
-		NetSentBuffer = append(NetRecvBuffer, usage{
-			Time:  now,
-			Usage: float64(network[0].BytesSent - LastNetSent),
-		})
-		LastNetRecv = network[0].BytesRecv
-		LastNetSent = network[0].BytesSent
-		if len(NetRecvBuffer) > 100 {
-			NetRecvBuffer = NetRecvBuffer[1:]
-		}
-		if len(NetSentBuffer) > 100 {
-			NetSentBuffer = NetSentBuffer[1:]
-		}
-		diskIOCounters, _ = disk.IOCounters(settings.ServerSettings.DiskName)
-		diskIO, ok = diskIOCounters[settings.ServerSettings.DiskName]
-		if ok {
-			DiskReadBuffer = append(DiskReadBuffer, usage{
-				Time:  now,
-				Usage: float64(diskIO.ReadCount - LastDiskReads),
-			})
-			DiskWriteBuffer = append(DiskWriteBuffer, usage{
-				Time:  now,
-				Usage: float64(diskIO.WriteCount - LastDiskWrites),
-			})
-			if len(DiskReadBuffer) > 100 {
-				DiskReadBuffer = DiskReadBuffer[1:]
-			}
-			if len(DiskWriteBuffer) > 100 {
-				DiskWriteBuffer = DiskWriteBuffer[1:]
-			}
-			LastDiskWrites = diskIO.WriteCount
-			LastDiskReads = diskIO.ReadCount
-		}
-	}
-}

部分文件因为文件数量过多而无法显示