mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-18 21:38:57 +08:00
parent
9242bf6482
commit
9a73095a8f
16 changed files with 404 additions and 113 deletions
|
|
@ -15,6 +15,15 @@ type MonitorData struct {
|
|||
Value []interface{} `json:"value"`
|
||||
}
|
||||
|
||||
type Process struct {
|
||||
Name string `json:"name"`
|
||||
Pid int32 `json:"pid"`
|
||||
Percent float64 `json:"percent"`
|
||||
Memory uint64 `json:"memory"`
|
||||
Cmd string `json:"cmd"`
|
||||
User string `json:"user"`
|
||||
}
|
||||
|
||||
type MonitorSetting struct {
|
||||
MonitorStatus string `json:"monitorStatus"`
|
||||
MonitorStoreDays string `json:"monitorStoreDays"`
|
||||
|
|
|
|||
|
|
@ -3,13 +3,17 @@ package model
|
|||
type MonitorBase struct {
|
||||
BaseModel
|
||||
Cpu float64 `json:"cpu"`
|
||||
TopCPU string `json:"topCPU"`
|
||||
TopCPUItems interface{} `gorm:"-" json:"topCPUItems"`
|
||||
|
||||
Memory float64 `json:"memory"`
|
||||
TopMem string `json:"topMem"`
|
||||
TopMemItems interface{} `gorm:"-" json:"topMemItems"`
|
||||
|
||||
LoadUsage float64 `json:"loadUsage"`
|
||||
CpuLoad1 float64 `json:"cpuLoad1"`
|
||||
CpuLoad5 float64 `json:"cpuLoad5"`
|
||||
CpuLoad15 float64 `json:"cpuLoad15"`
|
||||
|
||||
Memory float64 `json:"memory"`
|
||||
}
|
||||
|
||||
type MonitorIO struct {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
|
|
@ -21,6 +22,7 @@ import (
|
|||
"github.com/shirou/gopsutil/v4/load"
|
||||
"github.com/shirou/gopsutil/v4/mem"
|
||||
"github.com/shirou/gopsutil/v4/net"
|
||||
"github.com/shirou/gopsutil/v4/process"
|
||||
)
|
||||
|
||||
type MonitorService struct {
|
||||
|
|
@ -64,6 +66,18 @@ func (m *MonitorService) LoadMonitorData(req dto.MonitorSearch) ([]dto.MonitorDa
|
|||
itemData.Param = "base"
|
||||
for _, base := range bases {
|
||||
itemData.Date = append(itemData.Date, base.CreatedAt)
|
||||
if req.Param == "all" || req.Param == "cpu" {
|
||||
var processes []dto.Process
|
||||
_ = json.Unmarshal([]byte(base.TopCPU), &processes)
|
||||
base.TopCPUItems = processes
|
||||
base.TopCPU = ""
|
||||
}
|
||||
if req.Param == "all" || req.Param == "mem" {
|
||||
var processes []dto.Process
|
||||
_ = json.Unmarshal([]byte(base.TopMem), &processes)
|
||||
base.TopMemItems = processes
|
||||
base.TopMem = ""
|
||||
}
|
||||
itemData.Value = append(itemData.Value, base)
|
||||
}
|
||||
data = append(data, itemData)
|
||||
|
|
@ -169,8 +183,14 @@ func (m *MonitorService) Run() {
|
|||
if len(totalPercent) == 1 {
|
||||
itemModel.Cpu = totalPercent[0]
|
||||
}
|
||||
topCPU := m.loadTopCPU()
|
||||
if len(topCPU) != 0 {
|
||||
topItemCPU, err := json.Marshal(topCPU)
|
||||
if err == nil {
|
||||
itemModel.TopCPU = string(topItemCPU)
|
||||
}
|
||||
}
|
||||
cpuCount, _ := cpu.Counts(false)
|
||||
|
||||
loadInfo, _ := load.Avg()
|
||||
itemModel.CpuLoad1 = loadInfo.Load1
|
||||
itemModel.CpuLoad5 = loadInfo.Load5
|
||||
|
|
@ -179,6 +199,13 @@ func (m *MonitorService) Run() {
|
|||
|
||||
memoryInfo, _ := mem.VirtualMemory()
|
||||
itemModel.Memory = memoryInfo.UsedPercent
|
||||
topMem := m.loadTopMem()
|
||||
if len(topMem) != 0 {
|
||||
topMemItem, err := json.Marshal(topMem)
|
||||
if err == nil {
|
||||
itemModel.TopMem = string(topMemItem)
|
||||
}
|
||||
}
|
||||
|
||||
if err := settingRepo.CreateMonitorBase(itemModel); err != nil {
|
||||
global.LOG.Errorf("Insert basic monitoring data failed, err: %v", err)
|
||||
|
|
@ -323,6 +350,108 @@ func (m *MonitorService) saveNetDataToDB(ctx context.Context, interval float64)
|
|||
}
|
||||
}
|
||||
|
||||
func (m *MonitorService) loadTopCPU() []dto.Process {
|
||||
processes, err := process.Processes()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
top5 := make([]dto.Process, 0, 5)
|
||||
for _, p := range processes {
|
||||
percent, err := p.CPUPercent()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
minIndex := 0
|
||||
if len(top5) >= 5 {
|
||||
minCPU := top5[0].Percent
|
||||
for i := 1; i < len(top5); i++ {
|
||||
if top5[i].Percent < minCPU {
|
||||
minCPU = top5[i].Percent
|
||||
minIndex = i
|
||||
}
|
||||
}
|
||||
if percent < minCPU {
|
||||
continue
|
||||
}
|
||||
}
|
||||
name, err := p.Name()
|
||||
if err != nil {
|
||||
name = "undifine"
|
||||
}
|
||||
cmd, err := p.Cmdline()
|
||||
if err != nil {
|
||||
cmd = "undifine"
|
||||
}
|
||||
user, err := p.Username()
|
||||
if err != nil {
|
||||
user = "undifine"
|
||||
}
|
||||
if len(top5) == 5 {
|
||||
top5[minIndex] = dto.Process{Percent: percent, Pid: p.Pid, User: user, Name: name, Cmd: cmd}
|
||||
} else {
|
||||
top5 = append(top5, dto.Process{Percent: percent, Pid: p.Pid, User: user, Name: name, Cmd: cmd})
|
||||
}
|
||||
}
|
||||
sort.Slice(top5, func(i, j int) bool {
|
||||
return top5[i].Percent > top5[j].Percent
|
||||
})
|
||||
|
||||
return top5
|
||||
}
|
||||
|
||||
func (m *MonitorService) loadTopMem() []dto.Process {
|
||||
processes, err := process.Processes()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
top5 := make([]dto.Process, 0, 5)
|
||||
for _, p := range processes {
|
||||
stat, err := p.MemoryInfo()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
memItem := stat.RSS
|
||||
minIndex := 0
|
||||
if len(top5) >= 5 {
|
||||
min := top5[0].Memory
|
||||
for i := 1; i < len(top5); i++ {
|
||||
if top5[i].Memory < min {
|
||||
min = top5[i].Memory
|
||||
minIndex = i
|
||||
}
|
||||
}
|
||||
if memItem < min {
|
||||
continue
|
||||
}
|
||||
}
|
||||
name, err := p.Name()
|
||||
if err != nil {
|
||||
name = "undifine"
|
||||
}
|
||||
cmd, err := p.Cmdline()
|
||||
if err != nil {
|
||||
cmd = "undifine"
|
||||
}
|
||||
user, err := p.Username()
|
||||
if err != nil {
|
||||
user = "undifine"
|
||||
}
|
||||
percent, _ := p.MemoryPercent()
|
||||
if len(top5) == 5 {
|
||||
top5[minIndex] = dto.Process{Percent: float64(percent), Pid: p.Pid, User: user, Name: name, Cmd: cmd, Memory: memItem}
|
||||
} else {
|
||||
top5 = append(top5, dto.Process{Percent: float64(percent), Pid: p.Pid, User: user, Name: name, Cmd: cmd, Memory: memItem})
|
||||
}
|
||||
}
|
||||
|
||||
sort.Slice(top5, func(i, j int) bool {
|
||||
return top5[i].Memory > top5[j].Memory
|
||||
})
|
||||
return top5
|
||||
}
|
||||
|
||||
func StartMonitor(removeBefore bool, interval string) error {
|
||||
if removeBefore {
|
||||
monitorCancel()
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ func InitAgentDB() {
|
|||
migrations.UpdateWebsiteSSLAddColumn,
|
||||
migrations.AddTensorRTLLMModel,
|
||||
migrations.UpdateMonitorInterval,
|
||||
migrations.AddMonitorProcess,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
|
|
|||
|
|
@ -659,3 +659,10 @@ var UpdateMonitorInterval = &gormigrate.Migration{
|
|||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var AddMonitorProcess = &gormigrate.Migration{
|
||||
ID: "20251030-add-monitor-process",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return global.MonitorDB.AutoMigrate(&model.MonitorBase{})
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ const message = {
|
|||
timeRange: 'To',
|
||||
dateStart: 'Date start',
|
||||
dateEnd: 'Date end',
|
||||
date: 'Date',
|
||||
},
|
||||
table: {
|
||||
all: 'All',
|
||||
|
|
@ -1193,10 +1194,11 @@ const message = {
|
|||
readWriteTime: 'I/O latency',
|
||||
today: 'Today',
|
||||
yesterday: 'Yesterday',
|
||||
lastNDay: 'Last {0} day(s)',
|
||||
lastNDay: 'Last {0} days',
|
||||
lastNMonth: 'Last {0} months',
|
||||
lastHalfYear: 'Last half year',
|
||||
memory: 'Memory',
|
||||
percent: 'Percentage',
|
||||
cache: 'Cache',
|
||||
disk: 'Disk',
|
||||
network: 'Network',
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ const message = {
|
|||
timeRange: 'Hasta',
|
||||
dateStart: 'Fecha de inicio',
|
||||
dateEnd: 'Fecha de fin',
|
||||
date: 'Fecha',
|
||||
},
|
||||
table: {
|
||||
all: 'Todo',
|
||||
|
|
@ -1200,8 +1201,9 @@ const message = {
|
|||
yesterday: 'Ayer',
|
||||
lastNDay: 'Últimos {0} días',
|
||||
lastNMonth: 'Últimos {0} meses',
|
||||
lastHalfYear: 'Últimos seis meses',
|
||||
lastHalfYear: 'Último semestre',
|
||||
memory: 'Memoria',
|
||||
percent: 'Porcentaje',
|
||||
cache: 'Caché',
|
||||
disk: 'Disco',
|
||||
network: 'Red',
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ const message = {
|
|||
timeRange: 'に',
|
||||
dateStart: '日付開始',
|
||||
dateEnd: '日付の終わり',
|
||||
date: '日付',
|
||||
},
|
||||
table: {
|
||||
all: '全て',
|
||||
|
|
@ -1157,8 +1158,11 @@ const message = {
|
|||
readWriteTime: 'I/Oレイテンシ',
|
||||
today: '今日',
|
||||
yesterday: '昨日',
|
||||
lastNDay: '最後の{0}日',
|
||||
lastNDay: '過去 {0} 日間',
|
||||
lastNMonth: '過去 {0} ヶ月間',
|
||||
lastHalfYear: '過去半年間',
|
||||
memory: 'メモリ',
|
||||
percent: '割合',
|
||||
cache: 'キャッシュ',
|
||||
disk: 'ディスク',
|
||||
network: 'ネットワーク',
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ const message = {
|
|||
timeRange: '부터',
|
||||
dateStart: '시작 날짜',
|
||||
dateEnd: '종료 날짜',
|
||||
date: '날짜',
|
||||
},
|
||||
table: {
|
||||
all: '전체',
|
||||
|
|
@ -1150,7 +1151,10 @@ const message = {
|
|||
today: '오늘',
|
||||
yesterday: '어제',
|
||||
lastNDay: '최근 {0}일',
|
||||
lastNMonth: '최근 {0}개월',
|
||||
lastHalfYear: '최근 반년',
|
||||
memory: '메모리',
|
||||
percent: '비율',
|
||||
cache: '캐시',
|
||||
disk: '디스크',
|
||||
network: '네트워크',
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ const message = {
|
|||
timeRange: 'Hingga',
|
||||
dateStart: 'Tarikh mula',
|
||||
dateEnd: 'Tarikh tamat',
|
||||
date: 'Tarikh',
|
||||
},
|
||||
table: {
|
||||
all: 'Semua',
|
||||
|
|
@ -1190,7 +1191,10 @@ const message = {
|
|||
today: 'Hari ini',
|
||||
yesterday: 'Semalam',
|
||||
lastNDay: '{0} hari terakhir',
|
||||
lastNMonth: '{0} bulan terakhir',
|
||||
lastHalfYear: 'Setengah tahun terakhir',
|
||||
memory: 'Memori',
|
||||
percent: 'Peratusan',
|
||||
cache: 'Cache',
|
||||
disk: 'Cakera',
|
||||
network: 'Rangkaian',
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ const message = {
|
|||
timeRange: 'Até',
|
||||
dateStart: 'Data inicial',
|
||||
dateEnd: 'Data final',
|
||||
date: 'Data',
|
||||
},
|
||||
table: {
|
||||
all: 'Todos',
|
||||
|
|
@ -1181,8 +1182,11 @@ const message = {
|
|||
readWriteTime: 'Latência de I/O',
|
||||
today: 'Hoje',
|
||||
yesterday: 'Ontem',
|
||||
lastNDay: 'Últimos {0} dia(s)',
|
||||
lastNDay: 'Últimos {0} dias',
|
||||
lastNMonth: 'Últimos {0} meses',
|
||||
lastHalfYear: 'Último semestre',
|
||||
memory: 'Memória',
|
||||
percent: 'Percentual',
|
||||
cache: 'Cache',
|
||||
disk: 'Disco',
|
||||
network: 'Rede',
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ const message = {
|
|||
timeRange: 'До',
|
||||
dateStart: 'Дата начала',
|
||||
dateEnd: 'Дата окончания',
|
||||
date: 'Дата',
|
||||
},
|
||||
table: {
|
||||
all: 'Все',
|
||||
|
|
@ -1186,7 +1187,10 @@ const message = {
|
|||
today: 'Сегодня',
|
||||
yesterday: 'Вчера',
|
||||
lastNDay: 'Последние {0} дней',
|
||||
lastNMonth: 'Последние {0} месяцев',
|
||||
lastHalfYear: 'Последние полгода',
|
||||
memory: 'Память',
|
||||
percent: 'Процент',
|
||||
cache: 'Кэш',
|
||||
disk: 'Диск',
|
||||
network: 'Сеть',
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ const message = {
|
|||
timeRange: 'İle',
|
||||
dateStart: 'Başlangıç tarihi',
|
||||
dateEnd: 'Bitiş tarihi',
|
||||
date: 'Tarih',
|
||||
},
|
||||
table: {
|
||||
all: 'Tümü',
|
||||
|
|
@ -1209,8 +1210,9 @@ const message = {
|
|||
yesterday: 'Dün',
|
||||
lastNDay: 'Son {0} gün',
|
||||
lastNMonth: 'Son {0} ay',
|
||||
lastHalfYear: 'Son yarı yıl',
|
||||
lastHalfYear: 'Son yarım yıl',
|
||||
memory: 'Bellek',
|
||||
percent: 'Yüzde',
|
||||
cache: 'Önbellek',
|
||||
disk: 'Disk',
|
||||
network: 'Ağ',
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ const message = {
|
|||
timeRange: '至',
|
||||
dateStart: '開始日期',
|
||||
dateEnd: '結束日期',
|
||||
date: '日期',
|
||||
},
|
||||
table: {
|
||||
all: '所有',
|
||||
|
|
@ -1134,6 +1135,7 @@ const message = {
|
|||
lastNMonth: '近 {0} 月',
|
||||
lastHalfYear: '近半年',
|
||||
memory: '記憶體',
|
||||
percent: '佔比',
|
||||
cache: '快取',
|
||||
disk: '磁碟',
|
||||
network: '網路',
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ const message = {
|
|||
timeRange: '至',
|
||||
dateStart: '开始日期',
|
||||
dateEnd: '结束日期',
|
||||
date: '日期',
|
||||
},
|
||||
table: {
|
||||
all: '所有',
|
||||
|
|
@ -1136,6 +1137,7 @@ const message = {
|
|||
lastNMonth: '近 {0} 月',
|
||||
lastHalfYear: '近半年',
|
||||
memory: '内存',
|
||||
percent: '占比',
|
||||
cache: '缓存',
|
||||
disk: '磁盘',
|
||||
network: '网络',
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { loadMonitor, getNetworkOptions, getIOOptions } from '@/api/modules/host';
|
||||
import { computeSizeFromKBs, dateFormatWithoutYear } from '@/utils/util';
|
||||
import { computeSize, computeSizeFromKBs, dateFormat } from '@/utils/util';
|
||||
import i18n from '@/lang';
|
||||
import MonitorRouter from '@/views/host/monitor/index.vue';
|
||||
import { GlobalStore } from '@/store';
|
||||
|
|
@ -233,7 +233,6 @@ const mobile = computed(() => {
|
|||
return globalStore.isMobile();
|
||||
});
|
||||
|
||||
const zoomStart = ref();
|
||||
const monitorBase = ref();
|
||||
const timeRangeGlobal = ref<[Date, Date]>([new Date(new Date().setHours(0, 0, 0, 0)), new Date()]);
|
||||
const timeRangeLoad = ref<[Date, Date]>([new Date(new Date().setHours(0, 0, 0, 0)), new Date()]);
|
||||
|
|
@ -304,41 +303,13 @@ const search = async (param: string) => {
|
|||
case 'base':
|
||||
let baseDate = item.date.length === 0 ? loadEmptyDate(timeRangeCpu.value) : item.date;
|
||||
baseDate = baseDate.map(function (item: any) {
|
||||
return dateFormatWithoutYear(item);
|
||||
return dateFormat(null, null, item);
|
||||
});
|
||||
if (param === 'cpu' || param === 'all') {
|
||||
let cpuData = item.value.map(function (item: any) {
|
||||
return item.cpu.toFixed(2);
|
||||
});
|
||||
cpuData = cpuData.length === 0 ? loadEmptyData() : cpuData;
|
||||
chartsOption.value['loadCPUChart'] = {
|
||||
xData: baseDate,
|
||||
yData: [
|
||||
{
|
||||
name: 'CPU',
|
||||
data: cpuData,
|
||||
},
|
||||
],
|
||||
|
||||
formatStr: '%',
|
||||
};
|
||||
initCPUCharts(baseDate, item);
|
||||
}
|
||||
if (param === 'memory' || param === 'all') {
|
||||
let memoryData = item.value.map(function (item: any) {
|
||||
return item.memory.toFixed(2);
|
||||
});
|
||||
memoryData = memoryData.length === 0 ? loadEmptyData() : memoryData;
|
||||
chartsOption.value['loadMemoryChart'] = {
|
||||
xData: baseDate,
|
||||
yData: [
|
||||
{
|
||||
name: i18n.global.t('monitor.memory'),
|
||||
data: memoryData,
|
||||
},
|
||||
],
|
||||
|
||||
formatStr: '%',
|
||||
};
|
||||
initMemCharts(baseDate, item);
|
||||
}
|
||||
if (param === 'load' || param === 'all') {
|
||||
initLoadCharts(item);
|
||||
|
|
@ -348,38 +319,8 @@ const search = async (param: string) => {
|
|||
initIOCharts(item);
|
||||
break;
|
||||
case 'network':
|
||||
let networkDate = item.date.length === 0 ? loadEmptyDate(timeRangeNetwork.value) : item.date;
|
||||
networkDate = networkDate.map(function (item: any) {
|
||||
return dateFormatWithoutYear(item);
|
||||
});
|
||||
let networkUp = item.value.map(function (item: any) {
|
||||
return item.up.toFixed(2);
|
||||
});
|
||||
networkUp = networkUp.length === 0 ? loadEmptyData() : networkUp;
|
||||
let networkOut = item.value.map(function (item: any) {
|
||||
return item.down.toFixed(2);
|
||||
});
|
||||
networkOut = networkOut.length === 0 ? loadEmptyData() : networkOut;
|
||||
|
||||
chartsOption.value['loadNetworkChart'] = {
|
||||
xData: networkDate,
|
||||
yData: [
|
||||
{
|
||||
name: i18n.global.t('monitor.up'),
|
||||
data: networkUp,
|
||||
},
|
||||
{
|
||||
name: i18n.global.t('monitor.down'),
|
||||
data: networkOut,
|
||||
},
|
||||
],
|
||||
grid: {
|
||||
left: getSideWidth(true),
|
||||
right: getSideWidth(true),
|
||||
bottom: '20%',
|
||||
},
|
||||
formatStr: 'KB/s',
|
||||
};
|
||||
initNetCharts(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -413,7 +354,7 @@ const loadIOOptions = async () => {
|
|||
function initLoadCharts(item: Host.MonitorData) {
|
||||
let itemLoadDate = item.date.length === 0 ? loadEmptyDate(timeRangeLoad.value) : item.date;
|
||||
let loadDate = itemLoadDate.map(function (item: any) {
|
||||
return dateFormatWithoutYear(item);
|
||||
return dateFormat(null, null, item);
|
||||
});
|
||||
let load1Data = item.value.map(function (item: any) {
|
||||
return item.cpuLoad1.toFixed(2);
|
||||
|
|
@ -428,9 +369,9 @@ function initLoadCharts(item: Host.MonitorData) {
|
|||
});
|
||||
load15Data = load15Data.length === 0 ? loadEmptyData() : load15Data;
|
||||
let loadUsage = item.value.map(function (item: any) {
|
||||
return item.loadUsage.toFixed(2);
|
||||
return { value: item.loadUsage.toFixed(2), top: item.topCPUItems, unit: '%' };
|
||||
});
|
||||
loadUsage = loadUsage.length === 0 ? loadEmptyData() : loadUsage;
|
||||
loadUsage = loadUsage.length === 0 ? loadTopEmptyData() : loadUsage;
|
||||
chartsOption.value['loadLoadChart'] = {
|
||||
xData: loadDate,
|
||||
yData: [
|
||||
|
|
@ -465,26 +406,109 @@ function initLoadCharts(item: Host.MonitorData) {
|
|||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function (datas: any) {
|
||||
let res = datas[0].name + '<br/>';
|
||||
return withCPUProcess(datas);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function initCPUCharts(baseDate: any, items: Host.MonitorData) {
|
||||
let data = items.value.map(function (item: any) {
|
||||
return { value: item.cpu.toFixed(2), top: item.topCPUItems, unit: '%' };
|
||||
});
|
||||
data = data.length === 0 ? loadTopEmptyData() : data;
|
||||
chartsOption.value['loadCPUChart'] = {
|
||||
xData: baseDate,
|
||||
yData: [
|
||||
{
|
||||
name: 'CPU',
|
||||
data: data,
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function (datas: any) {
|
||||
return withCPUProcess(datas);
|
||||
},
|
||||
},
|
||||
|
||||
formatStr: '%',
|
||||
};
|
||||
}
|
||||
|
||||
function initMemCharts(baseDate: any, items: Host.MonitorData) {
|
||||
let data = items.value.map(function (item: any) {
|
||||
return { value: item.memory.toFixed(2), top: item.topMemItems };
|
||||
});
|
||||
data = data.length === 0 ? loadTopEmptyData() : data;
|
||||
chartsOption.value['loadMemoryChart'] = {
|
||||
xData: baseDate,
|
||||
yData: [
|
||||
{
|
||||
name: i18n.global.t('monitor.memory'),
|
||||
data: data,
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function (datas: any) {
|
||||
return withMemProcess(datas);
|
||||
},
|
||||
},
|
||||
|
||||
formatStr: '%',
|
||||
};
|
||||
}
|
||||
|
||||
function initNetCharts(item: Host.MonitorData) {
|
||||
let networkDate = item.date.length === 0 ? loadEmptyDate(timeRangeNetwork.value) : item.date;
|
||||
let date = networkDate.map(function (item: any) {
|
||||
return dateFormat(null, null, item);
|
||||
});
|
||||
let networkUp = item.value.map(function (item: any) {
|
||||
return item.up.toFixed(2);
|
||||
});
|
||||
networkUp = networkUp.length === 0 ? loadEmptyData() : networkUp;
|
||||
let networkOut = item.value.map(function (item: any) {
|
||||
return item.down.toFixed(2);
|
||||
});
|
||||
networkOut = networkOut.length === 0 ? loadEmptyData() : networkOut;
|
||||
|
||||
chartsOption.value['loadNetworkChart'] = {
|
||||
xData: date,
|
||||
yData: [
|
||||
{
|
||||
name: i18n.global.t('monitor.up'),
|
||||
data: networkUp,
|
||||
},
|
||||
{
|
||||
name: i18n.global.t('monitor.down'),
|
||||
data: networkOut,
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function (datas: any) {
|
||||
let res = loadDate(datas[0].name);
|
||||
for (const item of datas) {
|
||||
if (item.seriesName === i18n.global.t('monitor.resourceUsage')) {
|
||||
res +=
|
||||
item.marker + ' ' + item.seriesName + i18n.global.t('commons.colon') + item.data + '%<br/>';
|
||||
} else {
|
||||
res +=
|
||||
item.marker + ' ' + item.seriesName + i18n.global.t('commons.colon') + item.data + '<br/>';
|
||||
}
|
||||
res += loadSeries(item, computeSizeFromKBs(item.data), '');
|
||||
}
|
||||
return res;
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
left: getSideWidth(true),
|
||||
right: getSideWidth(true),
|
||||
bottom: '20%',
|
||||
},
|
||||
formatStr: 'KB/s',
|
||||
};
|
||||
}
|
||||
|
||||
function initIOCharts(item: Host.MonitorData) {
|
||||
let itemIODate = item.date?.length === 0 ? loadEmptyDate(timeRangeIO.value) : item.date;
|
||||
let ioDate = itemIODate.map(function (item: any) {
|
||||
return dateFormatWithoutYear(item);
|
||||
return dateFormat(null, null, item);
|
||||
});
|
||||
let ioRead = item.value.map(function (item: any) {
|
||||
return Number((item.read / 1024).toFixed(2));
|
||||
|
|
@ -527,41 +551,19 @@ function initIOCharts(item: Host.MonitorData) {
|
|||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function (datas: any) {
|
||||
let res = datas[0].name + '<br/>';
|
||||
let res = loadDate(datas[0].name);
|
||||
for (const item of datas) {
|
||||
if (
|
||||
item.seriesName === i18n.global.t('monitor.read') ||
|
||||
item.seriesName === i18n.global.t('monitor.write')
|
||||
) {
|
||||
res +=
|
||||
item.marker +
|
||||
' ' +
|
||||
item.seriesName +
|
||||
i18n.global.t('commons.colon') +
|
||||
computeSizeFromKBs(item.data) +
|
||||
'<br/>';
|
||||
res += loadSeries(item, computeSizeFromKBs(item.data), '');
|
||||
}
|
||||
if (item.seriesName === i18n.global.t('monitor.readWriteCount')) {
|
||||
res +=
|
||||
item.marker +
|
||||
' ' +
|
||||
item.seriesName +
|
||||
i18n.global.t('commons.colon') +
|
||||
item.data +
|
||||
' ' +
|
||||
i18n.global.t('commons.units.time') +
|
||||
'/s' +
|
||||
'<br/>';
|
||||
res += loadSeries(item, item.data, i18n.global.t('commons.units.time') + '/s');
|
||||
}
|
||||
if (item.seriesName === i18n.global.t('monitor.readWriteTime')) {
|
||||
res +=
|
||||
item.marker +
|
||||
' ' +
|
||||
item.seriesName +
|
||||
i18n.global.t('commons.colon') +
|
||||
item.data +
|
||||
' ms' +
|
||||
'<br/>';
|
||||
res += loadSeries(item, item.data, ' ms');
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
|
@ -593,13 +595,122 @@ function loadEmptyDate(timeRange: any) {
|
|||
function loadEmptyData() {
|
||||
return [0, 0];
|
||||
}
|
||||
function loadTopEmptyData() {
|
||||
return [{ value: 0, top: 0, unit: '' }];
|
||||
}
|
||||
|
||||
function withCPUProcess(datas: any) {
|
||||
let tops;
|
||||
let res = loadDate(datas[0].name);
|
||||
for (const item of datas) {
|
||||
if (item.data?.top) {
|
||||
tops = item.data?.top;
|
||||
}
|
||||
res += loadSeries(item, item.data.value ? item.data.value : item.data, item.data.unit || '');
|
||||
}
|
||||
if (!tops) {
|
||||
return '';
|
||||
}
|
||||
res += `
|
||||
<div style="margin-top: 10px; border-bottom: 1px dashed black;"></div>
|
||||
<table style="border-collapse: collapse; margin-top: 20px; font-size: 12px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="padding: 6px 8px;">PID</th>
|
||||
<th style="padding: 6px 8px;">${i18n.global.t('commons.table.user')}</th>
|
||||
<th style="padding: 6px 8px;">${i18n.global.t('menu.process')}</th>
|
||||
<th style="padding: 6px 8px;">${i18n.global.t('monitor.percent')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
for (const row of tops) {
|
||||
res += `
|
||||
<tr>
|
||||
<td style="padding: 6px 8px; text-align: center;">
|
||||
${row.pid}
|
||||
</td>
|
||||
<td style="padding: 6px 8px; text-align: center;">
|
||||
${row.user}
|
||||
</td>
|
||||
<td style="padding: 6px 8px; text-align: center;">
|
||||
${row.name}
|
||||
</td>
|
||||
<td style="padding: 6px 8px; text-align: center;">
|
||||
${row.percent.toFixed(2)}%
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function withMemProcess(datas: any) {
|
||||
let res = loadDate(datas[0].name);
|
||||
for (const item of datas) {
|
||||
res += loadSeries(item, item.data.value ? item.data.value : item.data, ' %');
|
||||
}
|
||||
if (!datas[0].data.top) {
|
||||
return res;
|
||||
}
|
||||
res += `
|
||||
<div style="margin-top: 10px; border-bottom: 1px dashed black;"></div>
|
||||
<table style="border-collapse: collapse; margin-top: 20px; font-size: 12px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="padding: 6px 8px;">PID</th>
|
||||
<th style="padding: 6px 8px;">${i18n.global.t('commons.table.user')}</th>
|
||||
<th style="padding: 6px 8px;">${i18n.global.t('menu.process')}</th>
|
||||
<th style="padding: 6px 8px;">${i18n.global.t('monitor.memory')}</th>
|
||||
<th style="padding: 6px 8px;">${i18n.global.t('monitor.percent')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
for (const item of datas) {
|
||||
for (const row of item.data.top) {
|
||||
res += `
|
||||
<tr>
|
||||
<td style="padding: 6px 8px; text-align: center;">
|
||||
<span style="display: inline-block;"></span>
|
||||
${row.pid}
|
||||
</td>
|
||||
<td style="padding: 6px 8px; text-align: center;">
|
||||
${row.user}
|
||||
</td>
|
||||
<td style="padding: 6px 8px; text-align: center;">
|
||||
${row.name}
|
||||
</td>
|
||||
<td style="padding: 6px 8px; text-align: center;">
|
||||
${computeSize(row.memory)}
|
||||
</td>
|
||||
<td style="padding: 6px 8px; text-align: center;">
|
||||
${row.percent.toFixed(2)}%
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function loadDate(name: any) {
|
||||
return ` <div style="display: inline-block; width: 100%; padding-bottom: 10px;">
|
||||
${i18n.global.t('commons.search.date')}: ${name}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function loadSeries(item: any, data: any, unit: any) {
|
||||
return `<div style="width: 100%;">
|
||||
${item.marker} ${item.seriesName}: ${data} ${unit}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function getSideWidth(b: boolean) {
|
||||
return !b || document.body.clientWidth > 1600 ? '7%' : '10%';
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
zoomStart.value = dateFormatWithoutYear(new Date(new Date().setHours(0, 0, 0, 0)));
|
||||
loadNetworkOptions();
|
||||
loadIOOptions();
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue