diff --git a/agent/app/dto/monitor.go b/agent/app/dto/monitor.go index fa9baf56d..de6ca6ce3 100644 --- a/agent/app/dto/monitor.go +++ b/agent/app/dto/monitor.go @@ -20,9 +20,10 @@ type MonitorSetting struct { MonitorStoreDays string `json:"monitorStoreDays"` MonitorInterval string `json:"monitorInterval"` DefaultNetwork string `json:"defaultNetwork"` + DefaultIO string `json:"defaultIO"` } type MonitorSettingUpdate struct { - Key string `json:"key" validate:"required,oneof=MonitorStatus MonitorStoreDays MonitorInterval DefaultNetwork"` + Key string `json:"key" validate:"required,oneof=MonitorStatus MonitorStoreDays MonitorInterval DefaultNetwork DefaultIO"` Value string `json:"value"` } diff --git a/agent/app/dto/setting.go b/agent/app/dto/setting.go index e19b38f2f..17ccdd917 100644 --- a/agent/app/dto/setting.go +++ b/agent/app/dto/setting.go @@ -10,6 +10,7 @@ type SettingInfo struct { NtpSite string `json:"ntpSite"` DefaultNetwork string `json:"defaultNetwork"` + DefaultIO string `json:"defaultIO"` LastCleanTime string `json:"lastCleanTime"` LastCleanSize string `json:"lastCleanSize"` LastCleanData string `json:"lastCleanData"` diff --git a/agent/app/service/monitor.go b/agent/app/service/monitor.go index 532ebc2bf..2a93ed27e 100644 --- a/agent/app/service/monitor.go +++ b/agent/app/service/monitor.go @@ -69,7 +69,7 @@ func (m *MonitorService) LoadMonitorData(req dto.MonitorSearch) ([]dto.MonitorDa data = append(data, itemData) } if req.Param == "all" || req.Param == "io" { - bases, err := monitorRepo.GetIO(repo.WithByCreatedAt(req.StartTime, req.EndTime)) + bases, err := monitorRepo.GetIO(repo.WithByName(req.Info), repo.WithByCreatedAt(req.StartTime, req.EndTime)) if err != nil { return nil, err } @@ -201,9 +201,18 @@ func (m *MonitorService) Run() { func (m *MonitorService) loadDiskIO() { ioStat, _ := disk.IOCounters() var diskIOList []disk.IOCountersStat + var ioStatAll disk.IOCountersStat for _, io := range ioStat { + ioStatAll.Name = "all" + ioStatAll.ReadBytes += io.ReadBytes + ioStatAll.WriteBytes += io.WriteBytes + ioStatAll.ReadTime += io.ReadTime + ioStatAll.WriteTime += io.WriteTime + ioStatAll.WriteCount += io.WriteCount + ioStatAll.ReadCount += io.ReadCount diskIOList = append(diskIOList, io) } + diskIOList = append(diskIOList, ioStatAll) m.DiskIO <- diskIOList } @@ -234,29 +243,29 @@ func (m *MonitorService) saveIODataToDB(ctx context.Context, interval float64) { var itemIO model.MonitorIO itemIO.Name = io1.Name if io2.ReadBytes != 0 && io1.ReadBytes != 0 && io2.ReadBytes > io1.ReadBytes { - itemIO.Read = uint64(float64(io2.ReadBytes-io1.ReadBytes) / interval / 60) + itemIO.Read = uint64(float64(io2.ReadBytes-io1.ReadBytes) / interval) } if io2.WriteBytes != 0 && io1.WriteBytes != 0 && io2.WriteBytes > io1.WriteBytes { - itemIO.Write = uint64(float64(io2.WriteBytes-io1.WriteBytes) / interval / 60) + itemIO.Write = uint64(float64(io2.WriteBytes-io1.WriteBytes) / interval) } if io2.ReadCount != 0 && io1.ReadCount != 0 && io2.ReadCount > io1.ReadCount { - itemIO.Count = uint64(float64(io2.ReadCount-io1.ReadCount) / interval / 60) + itemIO.Count = uint64(float64(io2.ReadCount-io1.ReadCount) / interval) } writeCount := uint64(0) if io2.WriteCount != 0 && io1.WriteCount != 0 && io2.WriteCount > io1.WriteCount { - writeCount = uint64(float64(io2.WriteCount-io1.WriteCount) / interval * 60) + writeCount = uint64(float64(io2.WriteCount-io1.WriteCount) / interval) } if writeCount > itemIO.Count { itemIO.Count = writeCount } if io2.ReadTime != 0 && io1.ReadTime != 0 && io2.ReadTime > io1.ReadTime { - itemIO.Time = uint64(float64(io2.ReadTime-io1.ReadTime) / interval / 60) + itemIO.Time = uint64(float64(io2.ReadTime-io1.ReadTime) / interval) } writeTime := uint64(0) if io2.WriteTime != 0 && io1.WriteTime != 0 && io2.WriteTime > io1.WriteTime { - writeTime = uint64(float64(io2.WriteTime-io1.WriteTime) / interval / 60) + writeTime = uint64(float64(io2.WriteTime-io1.WriteTime) / interval) } if writeTime > itemIO.Time { itemIO.Time = writeTime @@ -294,10 +303,10 @@ func (m *MonitorService) saveNetDataToDB(ctx context.Context, interval float64) itemNet.Name = net1.Name if net2.BytesSent != 0 && net1.BytesSent != 0 && net2.BytesSent > net1.BytesSent { - itemNet.Up = float64(net2.BytesSent-net1.BytesSent) / 1024 / interval / 60 + itemNet.Up = float64(net2.BytesSent-net1.BytesSent) / 1024 / interval } if net2.BytesRecv != 0 && net1.BytesRecv != 0 && net2.BytesRecv > net1.BytesRecv { - itemNet.Down = float64(net2.BytesRecv-net1.BytesRecv) / 1024 / interval / 60 + itemNet.Down = float64(net2.BytesRecv-net1.BytesRecv) / 1024 / interval } netList = append(netList, itemNet) break @@ -330,7 +339,7 @@ func StartMonitor(removeBefore bool, interval string) error { now := time.Now() nextMinute := now.Truncate(time.Minute).Add(time.Minute) time.AfterFunc(time.Until(nextMinute), func() { - monitorID, err := global.Cron.AddJob(fmt.Sprintf("@every %sm", interval), service) + monitorID, err := global.Cron.AddJob(fmt.Sprintf("@every %ss", interval), service) if err != nil { return } diff --git a/agent/init/migration/migrate.go b/agent/init/migration/migrate.go index 74bdd743a..a4a3ed2e2 100644 --- a/agent/init/migration/migrate.go +++ b/agent/init/migration/migrate.go @@ -47,6 +47,7 @@ func InitAgentDB() { migrations.UpdateCronjobSpec, migrations.UpdateWebsiteSSLAddColumn, migrations.AddTensorRTLLMModel, + migrations.UpdateMonitorInterval, }) if err := m.Migrate(); err != nil { global.LOG.Error(err) diff --git a/agent/init/migration/migrations/init.go b/agent/init/migration/migrations/init.go index 7c8461790..3d178f77a 100644 --- a/agent/init/migration/migrations/init.go +++ b/agent/init/migration/migrations/init.go @@ -6,6 +6,7 @@ import ( "os" "os/user" "path" + "strconv" "strings" "time" @@ -634,3 +635,27 @@ var AddTensorRTLLMModel = &gormigrate.Migration{ return tx.AutoMigrate(&model.TensorRTLLM{}) }, } + +var UpdateMonitorInterval = &gormigrate.Migration{ + ID: "20251026-update-monitor-interval", + Migrate: func(tx *gorm.DB) error { + var monitorInterval model.Setting + if err := tx.Where("key = ?", "MonitorInterval").First(&monitorInterval).Error; err != nil { + return err + } + interval, _ := strconv.Atoi(monitorInterval.Value) + if interval == 0 { + interval = 300 + } + if err := tx.Model(&model.Setting{}). + Where("key = ?", "MonitorInterval"). + Updates(map[string]interface{}{"value": fmt.Sprintf("%v", interval*60)}). + Error; err != nil { + return err + } + if err := tx.Create(&model.Setting{Key: "DefaultIO", Value: "all"}).Error; err != nil { + return err + } + return nil + }, +} diff --git a/frontend/src/api/interface/host.ts b/frontend/src/api/interface/host.ts index 32b4717b5..a39fcd95d 100644 --- a/frontend/src/api/interface/host.ts +++ b/frontend/src/api/interface/host.ts @@ -137,6 +137,7 @@ export namespace Host { export interface MonitorSetting { defaultNetwork: string; + defaultIO: string; monitorStatus: string; monitorStoreDays: string; monitorInterval: string; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index a22b2ed4c..b9911c75d 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -1168,11 +1168,13 @@ const message = { }, monitor: { globalFilter: 'Global Filter', - enableMonitor: 'Enable', - storeDays: 'Expiration days', - defaultNetwork: 'Default Network Adapter', - defaultNetworkHelper: 'Network adapter option displayed in the default monitoring and overview interface', - cleanMonitor: 'Clean monitoring records', + enableMonitor: 'Monitoring Status', + storeDays: 'Retention Days', + defaultNetwork: 'Default Network Card', + defaultNetworkHelper: 'Default network card option displayed in monitoring and overview interfaces', + defaultIO: 'Default Disk', + defaultIOHelper: 'Default disk option displayed in monitoring and overview interfaces', + cleanMonitor: 'Clear Monitoring Records', avgLoad: 'Load average', loadDetail: 'Load detail', @@ -1193,7 +1195,8 @@ const message = { network: 'Network', up: 'Up', down: 'Down', - interval: 'Interval(minute)', + interval: 'Collection Interval', + intervalHelper: 'Please enter an appropriate monitoring collection interval (5 seconds - 12 hours)', gpuUtil: 'GPU Utilization', temperature: 'Temperature', diff --git a/frontend/src/lang/modules/es-es.ts b/frontend/src/lang/modules/es-es.ts index c61110dda..594466957 100644 --- a/frontend/src/lang/modules/es-es.ts +++ b/frontend/src/lang/modules/es-es.ts @@ -1171,13 +1171,16 @@ const message = { }, }, monitor: { - globalFilter: 'Filtro global', - enableMonitor: 'Habilitar', - storeDays: 'Días de retención', - defaultNetwork: 'Adaptador de red predeterminado', + globalFilter: 'Filtro Global', + enableMonitor: 'Estado de Monitoreo', + storeDays: 'Días de Retención', + defaultNetwork: 'Tarjeta de Red Predeterminada', defaultNetworkHelper: - 'Opción de adaptador de red mostrada en la vista predeterminada de monitorización y resumen', - cleanMonitor: 'Limpiar registros de monitorización', + 'Opción de tarjeta de red predeterminada mostrada en las interfaces de monitoreo y resumen', + defaultIO: 'Disco Predeterminado', + defaultIOHelper: 'Opción de disco predeterminada mostrada en las interfaces de monitoreo y resumen', + cleanMonitor: 'Limpiar Registros de Monitoreo', + avgLoad: 'Carga promedio', loadDetail: 'Detalle de carga', resourceUsage: 'Utilización', @@ -1197,7 +1200,8 @@ const message = { network: 'Red', up: 'Subida', down: 'Bajada', - interval: 'Intervalo (minutos)', + interval: 'Intervalo de Recolección', + intervalHelper: 'Ingrese un intervalo de recolección de monitoreo apropiado (5 segundos - 12 horas)', gpuUtil: 'Uso de GPU', temperature: 'Temperatura', performanceState: 'Estado de rendimiento', diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index 3a1f4ede4..2f999e223 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -1131,9 +1131,13 @@ const message = { }, monitor: { globalFilter: 'グローバルフィルター', - enableMonitor: '有効にする', - storeDays: '有効期限', - cleanMonitor: '監視記録をきれいにします', + enableMonitor: '監視ステータス', + storeDays: '保存日数', + defaultNetwork: 'デフォルトネットワークカード', + defaultNetworkHelper: '監視および概要インターフェースに表示されるデフォルトのネットワークカードオプション', + defaultIO: 'デフォルトディスク', + defaultIOHelper: '監視および概要インターフェースに表示されるデフォルトのディスクオプション', + cleanMonitor: '監視記録をクリア', avgLoad: 'ロード平均', loadDetail: '詳細を読み込みます', @@ -1152,7 +1156,8 @@ const message = { network: 'ネットワーク', up: '上', down: '下', - interval: '間隔(分)', + interval: '収集間隔', + intervalHelper: '適切な監視収集間隔を入力してください(5秒 - 12時間)', gpuUtil: 'GPU利用', temperature: '温度', diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index 1a5d2b090..9628b7a71 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -1123,9 +1123,13 @@ const message = { }, monitor: { globalFilter: '전역 필터', - enableMonitor: '활성화', - storeDays: '만료일', - cleanMonitor: '모니터링 기록 정리', + enableMonitor: '모니터링 상태', + storeDays: '보관 일수', + defaultNetwork: '기본 네트워크 카드', + defaultNetworkHelper: '모니터링 및 개요 인터페이스에 표시되는 기본 네트워크 카드 옵션', + defaultIO: '기본 디스크', + defaultIOHelper: '모니터링 및 개요 인터페이스에 표시되는 기본 디스크 옵션', + cleanMonitor: '모니터링 기록 지우기', avgLoad: '평균 부하', loadDetail: '부하 세부사항', @@ -1144,7 +1148,8 @@ const message = { network: '네트워크', up: '업', down: '다운', - interval: '간격(분)', + interval: '수집 간격', + intervalHelper: '적절한 모니터링 수집 간격을 입력하세요 (5초 - 12시간)', gpuUtil: 'GPU 사용률', temperature: '온도', diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index fcc413c9d..78f3bcb2d 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -1163,9 +1163,14 @@ const message = { }, monitor: { globalFilter: 'Penapis Global', - enableMonitor: 'Aktifkan', - storeDays: 'Hari luput', - cleanMonitor: 'Bersihkan rekod pemantauan', + enableMonitor: 'Status Pemantauan', + storeDays: 'Hari Penyimpanan', + defaultNetwork: 'Kad Rangkaian Lalai', + defaultNetworkHelper: + 'Pilihan kad rangkaian lalai yang dipaparkan dalam antara muka pemantauan dan gambaran keseluruhan', + defaultIO: 'Cakera Lalai', + defaultIOHelper: 'Pilihan cakera lalai yang dipaparkan dalam antara muka pemantauan dan gambaran keseluruhan', + cleanMonitor: 'Kosongkan Rekod Pemantauan', avgLoad: 'Purata beban', loadDetail: 'Butiran beban', @@ -1184,7 +1189,8 @@ const message = { network: 'Rangkaian', up: 'Naik', down: 'Turun', - interval: 'Selang (minit)', + interval: 'Selang Kumpulan', + intervalHelper: 'Sila masukkan selang kumpulan pemantauan yang sesuai (5 saat - 12 jam)', gpuUtil: 'Penggunaan GPU', temperature: 'Suhu', diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index cf2b24f65..7d8aa05f3 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -1156,10 +1156,14 @@ const message = { }, }, monitor: { - globalFilter: 'Filtro global', - enableMonitor: 'Ativar', - storeDays: 'Dias de expiração', - cleanMonitor: 'Limpar registros de monitoramento', + globalFilter: 'Filtro Global', + enableMonitor: 'Status de Monitoramento', + storeDays: 'Dias de Retenção', + defaultNetwork: 'Placa de Rede Padrão', + defaultNetworkHelper: 'Opção de placa de rede padrão exibida nas interfaces de monitoramento e visão geral', + defaultIO: 'Disco Padrão', + defaultIOHelper: 'Opção de disco padrão exibida nas interfaces de monitoramento e visão geral', + cleanMonitor: 'Limpar Registros de Monitoramento', avgLoad: 'Média de carga', loadDetail: 'Detalhes da carga', @@ -1178,7 +1182,8 @@ const message = { network: 'Rede', up: 'Para cima', down: 'Para baixo', - interval: 'Intervalo (minuto)', + interval: 'Intervalo de Coleta', + intervalHelper: 'Insira um intervalo de coleta de monitoramento apropriado (5 segundos - 12 horas)', gpuUtil: 'Utilização da GPU', temperature: 'Temperatura', diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index 7d5b1db35..b64a0a69f 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -1160,10 +1160,14 @@ const message = { }, }, monitor: { - globalFilter: 'Глобальный фильтр', - enableMonitor: 'Включить', - storeDays: 'Дни хранения', - cleanMonitor: 'Очистить записи мониторинга', + globalFilter: 'Глобальный Фильтр', + enableMonitor: 'Статус Мониторинга', + storeDays: 'Дни Хранения', + defaultNetwork: 'Сетевая Карта по Умолчанию', + defaultNetworkHelper: 'Опция сетевой карты по умолчанию, отображаемая в интерфейсах мониторинга и обзора', + defaultIO: 'Диск по Умолчанию', + defaultIOHelper: 'Опция диска по умолчанию, отображаемая в интерфейсах мониторинга и обзора', + cleanMonitor: 'Очистить Записи Мониторинга', avgLoad: 'Средняя нагрузка', loadDetail: 'Детали нагрузки', @@ -1182,7 +1186,8 @@ const message = { network: 'Сеть', up: 'Исходящий', down: 'Входящий', - interval: 'Интервал(минут)', + interval: 'Интервал Сбора', + intervalHelper: 'Пожалуйста, введите подходящий интервал сбора мониторинга (5 секунд - 12 часов)', gpuUtil: 'Использование GPU', temperature: 'Температура', diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts index a762e7b05..9ed2cda79 100644 --- a/frontend/src/lang/modules/tr.ts +++ b/frontend/src/lang/modules/tr.ts @@ -1182,11 +1182,13 @@ const message = { }, monitor: { globalFilter: 'Genel Filtre', - enableMonitor: 'Etkinleştir', - storeDays: 'Son kullanma günleri', - defaultNetwork: 'Varsayılan Ağ Adaptörü', - defaultNetworkHelper: 'Varsayılan izleme ve genel bakış arayüzünde görüntülenen ağ adaptörü seçeneği', - cleanMonitor: 'İzleme kayıtlarını temizle', + enableMonitor: 'İzleme Durumu', + storeDays: 'Saklama Günleri', + defaultNetwork: 'Varsayılan Ağ Kartı', + defaultNetworkHelper: 'İzleme ve genel bakış arayüzlerinde görüntülenen varsayılan ağ kartı seçeneği', + defaultIO: 'Varsayılan Disk', + defaultIOHelper: 'İzleme ve genel bakış arayüzlerinde görüntülenen varsayılan disk seçeneği', + cleanMonitor: 'İzleme Kayıtlarını Temizle', avgLoad: 'Ortalama yük', loadDetail: 'Yük detayı', @@ -1207,7 +1209,8 @@ const message = { network: 'Ağ', up: 'Yukarı', down: 'Aşağı', - interval: 'Aralık(dakika)', + interval: 'Toplama Aralığı', + intervalHelper: 'Lütfen uygun bir izleme toplama aralığı girin (5 saniye - 12 saat)', gpuUtil: 'GPU Kullanımı', temperature: 'Sıcaklık', diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts index a56652a3b..952a3b993 100644 --- a/frontend/src/lang/modules/zh-Hant.ts +++ b/frontend/src/lang/modules/zh-Hant.ts @@ -1107,9 +1107,11 @@ const message = { monitor: { globalFilter: '全域過濾', enableMonitor: '監控狀態', - storeDays: '儲存天數', + storeDays: '保存天數', defaultNetwork: '預設網卡', defaultNetworkHelper: '預設監控和概覽介面顯示的網卡選項', + defaultIO: '預設磁碟', + defaultIOHelper: '預設監控和概覽介面顯示的磁碟選項', cleanMonitor: '清空監控記錄', avgLoad: '平均負載', @@ -1131,7 +1133,8 @@ const message = { network: '網路', up: '上行', down: '下行', - interval: '採集間隔(分鐘)', + interval: '採集間隔', + intervalHelper: '請輸入合適的監控採集時間間隔(5秒 - 12小時)', gpuUtil: 'GPU 使用率', temperature: '溫度', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index ceb6ca240..6e902ce14 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1111,6 +1111,8 @@ const message = { storeDays: '保存天数', defaultNetwork: '默认网卡', defaultNetworkHelper: '默认监控和概览界面显示的网卡选项', + defaultIO: '默认磁盘', + defaultIOHelper: '默认监控和概览界面显示的磁盘选项', cleanMonitor: '清空监控记录', avgLoad: '平均负载', @@ -1132,7 +1134,8 @@ const message = { network: '网络', up: '上行', down: '下行', - interval: '采集间隔(分钟)', + interval: '采集间隔', + intervalHelper: '请输入合适的监控采集时间间隔(5秒 - 12小时)', gpuUtil: 'GPU 使用率', temperature: '温度', diff --git a/frontend/src/store/interface/index.ts b/frontend/src/store/interface/index.ts index de954709d..1b3a22c2b 100644 --- a/frontend/src/store/interface/index.ts +++ b/frontend/src/store/interface/index.ts @@ -46,6 +46,7 @@ export interface GlobalState { currentRedisDB: string; showEntranceWarn: boolean; defaultNetwork: string; + defaultIO: string; isFxplay: boolean; isProductPro: boolean; diff --git a/frontend/src/store/modules/global.ts b/frontend/src/store/modules/global.ts index de0781a3f..2547d944f 100644 --- a/frontend/src/store/modules/global.ts +++ b/frontend/src/store/modules/global.ts @@ -40,6 +40,7 @@ const GlobalStore = defineStore({ currentRedisDB: '', showEntranceWarn: true, defaultNetwork: 'all', + defaultIO: 'all', isFxplay: false, isProductPro: false, @@ -117,6 +118,9 @@ const GlobalStore = defineStore({ setDefaultNetwork(net: string) { this.defaultNetwork = net; }, + setDefaultIO(net: string) { + this.defaultIO = net; + }, }, persist: piniaPersistConfig('GlobalState'), }); diff --git a/frontend/src/utils/util.ts b/frontend/src/utils/util.ts index ab97687b2..bc876e6c4 100644 --- a/frontend/src/utils/util.ts +++ b/frontend/src/utils/util.ts @@ -165,7 +165,9 @@ export function dateFormatWithoutYear(dataStr: any) { h = h < 10 ? `0${String(h)}` : h; let minute: string | number = date.getMinutes(); minute = minute < 10 ? `0${String(minute)}` : minute; - return `${String(m)}-${String(d)}\n${String(h)}:${String(minute)}`; + let s: string | number = date.getSeconds(); + s = s < 10 ? `0${String(s)}` : s; + return `${String(m)}-${String(d)}\n${String(h)}:${String(minute)}:${String(s)}`; } // 20221013151302 diff --git a/frontend/src/views/home/index.vue b/frontend/src/views/home/index.vue index 9a2e1a815..307cf8092 100644 --- a/frontend/src/views/home/index.vue +++ b/frontend/src/views/home/index.vue @@ -458,7 +458,7 @@ const onLoadSimpleNode = async () => { const onLoadIOOptions = async () => { const res = await getIOOptions(); ioOptions.value = res.data; - searchInfo.ioOption = ioOptions.value && ioOptions.value[0]; + searchInfo.ioOption = globalStore.defaultIO || (ioOptions.value && ioOptions.value[0]); }; const onLoadBaseInfo = async (isInit: boolean, range: string) => { diff --git a/frontend/src/views/host/monitor/monitor/index.vue b/frontend/src/views/host/monitor/monitor/index.vue index 7df2d8935..2283395da 100644 --- a/frontend/src/views/host/monitor/monitor/index.vue +++ b/frontend/src/views/host/monitor/monitor/index.vue @@ -16,6 +16,7 @@ style="max-width: 360px; width: 100%" :size="mobile ? 'small' : 'default'" > + @@ -118,7 +119,26 @@ - {{ $t('monitor.disk') }} I/O + + {{ $t('monitor.disk') }} I/O{{ $t('commons.colon') }} + + + {{ ioChoose === 'all' ? $t('commons.table.all') : ioChoose }} + + + + + + {{ $t('commons.table.all') }} + + + {{ item }} + + + + + + import { ref, reactive, onMounted, computed } from 'vue'; -import { loadMonitor, getNetworkOptions } from '@/api/modules/host'; +import { loadMonitor, getNetworkOptions, getIOOptions } from '@/api/modules/host'; import { computeSizeFromKBs, dateFormatWithoutYear } from '@/utils/util'; import i18n from '@/lang'; import MonitorRouter from '@/views/host/monitor/index.vue'; @@ -223,6 +243,8 @@ const timeRangeIO = ref<[Date, Date]>([new Date(new Date().setHours(0, 0, 0, 0)) const timeRangeNetwork = ref<[Date, Date]>([new Date(new Date().setHours(0, 0, 0, 0)), new Date()]); const networkChoose = ref(); const netOptions = ref(); +const ioChoose = ref(); +const ioOptions = ref(); const chartsOption = ref({ loadLoadChart: null, loadCPUChart: null, loadMemoryChart: null, loadNetworkChart: null }); const searchTime = ref(); @@ -260,6 +282,7 @@ const search = async (param: string) => { break; case 'io': searchTime.value = timeRangeIO.value; + searchInfo.info = ioChoose.value; break; case 'network': searchTime.value = timeRangeNetwork.value; @@ -366,6 +389,11 @@ const changeNetwork = (item: string) => { search('network'); }; +const changeIO = (item: string) => { + ioChoose.value = item; + search('io'); +}; + const loadNetworkOptions = async () => { const res = await getNetworkOptions(); netOptions.value = res.data; @@ -374,6 +402,14 @@ const loadNetworkOptions = async () => { search('all'); }; +const loadIOOptions = async () => { + const res = await getIOOptions(); + ioOptions.value = res.data; + searchInfo.info = globalStore.defaultIO || (ioOptions.value && ioOptions.value[0]); + ioChoose.value = searchInfo.info; + search('all'); +}; + function initLoadCharts(item: Host.MonitorData) { let itemLoadDate = item.date.length === 0 ? loadEmptyDate(timeRangeLoad.value) : item.date; let loadDate = itemLoadDate.map(function (item: any) { @@ -565,6 +601,7 @@ function getSideWidth(b: boolean) { onMounted(() => { zoomStart.value = dateFormatWithoutYear(new Date(new Date().setHours(0, 0, 0, 0))); loadNetworkOptions(); + loadIOOptions(); }); diff --git a/frontend/src/views/host/monitor/setting/default-io/index.vue b/frontend/src/views/host/monitor/setting/default-io/index.vue new file mode 100644 index 000000000..cdddc11ab --- /dev/null +++ b/frontend/src/views/host/monitor/setting/default-io/index.vue @@ -0,0 +1,87 @@ + + + + + + + + + + + + {{ $t('commons.button.cancel') }} + + {{ $t('commons.button.confirm') }} + + + + + + diff --git a/frontend/src/views/host/monitor/setting/index.vue b/frontend/src/views/host/monitor/setting/index.vue index b4989a411..0d72573f8 100644 --- a/frontend/src/views/host/monitor/setting/index.vue +++ b/frontend/src/views/host/monitor/setting/index.vue @@ -25,8 +25,8 @@ - - + + {{ $t('commons.button.set') }} @@ -44,6 +44,16 @@ {{ $t('monitor.defaultNetworkHelper') }} + + + + + {{ $t('commons.button.set') }} + + + + {{ $t('monitor.defaultIOHelper') }} + {{ $t('monitor.cleanMonitor') }} @@ -56,6 +66,7 @@ + @@ -67,29 +78,42 @@ import MonitorRouter from '@/views/host/monitor/index.vue'; import Interval from '@/views/host/monitor/setting/interval/index.vue'; import StoreDays from '@/views/host/monitor/setting/days/index.vue'; import Network from '@/views/host/monitor/setting/default-network/index.vue'; +import IO from '@/views/host/monitor/setting/default-io/index.vue'; import i18n from '@/lang'; import { MsgSuccess } from '@/utils/message'; +import { splitTimeFromSecond, transTimeUnit } from '@/utils/util'; const loading = ref(); const form = reactive({ monitorStatus: 'Disable', monitorStoreDays: 30, - monitorInterval: 1, + monitorInterval: 300, + timeItem: 5, + timeUnit: 'm', + monitorIntervalItem: '', defaultNetwork: '', + defaultIO: '', }); const panelFormRef = ref(); const intervalRef = ref(); const daysRef = ref(); const networkRef = ref(); +const ioRef = ref(); const search = async () => { const res = await loadMonitorSetting(); form.monitorStatus = res.data.monitorStatus; form.monitorInterval = Number(res.data.monitorInterval); + let item = splitTimeFromSecond(form.monitorInterval); + form.timeItem = item.timeItem; + form.timeUnit = item.timeUnit; + form.monitorIntervalItem = transTimeUnit(form.timeItem + form.timeUnit); + form.monitorStoreDays = Number(res.data.monitorStoreDays); form.defaultNetwork = res.data.defaultNetwork === 'all' ? i18n.global.t('commons.table.all') : res.data.defaultNetwork; + form.defaultIO = res.data.defaultIO === 'all' ? i18n.global.t('commons.table.all') : res.data.defaultIO; }; const onSaveStatus = async () => { @@ -108,11 +132,14 @@ const onChangeStoreDays = () => { daysRef.value.acceptParams({ monitorStoreDays: form.monitorStoreDays }); }; const onChangeInterval = () => { - intervalRef.value.acceptParams({ monitorInterval: form.monitorInterval }); + intervalRef.value.acceptParams({ timeItem: form.timeItem, timeUnit: form.timeUnit }); }; const onChangeNetwork = () => { networkRef.value.acceptParams({ defaultNetwork: form.defaultNetwork }); }; +const onChangeIO = () => { + ioRef.value.acceptParams({ defaultIO: form.defaultIO }); +}; const onClean = async () => { ElMessageBox.confirm(i18n.global.t('commons.msg.clean'), i18n.global.t('monitor.cleanMonitor'), { diff --git a/frontend/src/views/host/monitor/setting/interval/index.vue b/frontend/src/views/host/monitor/setting/interval/index.vue index d3f451702..71639331c 100644 --- a/frontend/src/views/host/monitor/setting/interval/index.vue +++ b/frontend/src/views/host/monitor/setting/interval/index.vue @@ -1,12 +1,16 @@ - - - + + + + + + + + + + + @@ -24,28 +28,48 @@ import { reactive, ref } from 'vue'; import i18n from '@/lang'; import { MsgSuccess } from '@/utils/message'; import { FormInstance } from 'element-plus'; -import { Rules, checkNumberRange } from '@/global/form-rules'; +import { Rules } from '@/global/form-rules'; import { updateMonitorSetting } from '@/api/modules/host'; +import { transferTimeToSecond } from '@/utils/util'; const emit = defineEmits<{ (e: 'search'): void }>(); interface DialogProps { - monitorInterval: number; + timeItem: number; + timeUnit: string; } const drawerVisible = ref(); const loading = ref(); const form = reactive({ - monitorInterval: 1, + timeItem: 5, + timeUnit: 'h', + monitorInterval: 300, +}); + +const verifyInterval = (rule: any, value: any, callback: any) => { + if (value < 10 || value > 43200) { + callback(new Error(i18n.global.t('monitor.intervalHelper'))); + return; + } + callback(); +}; +const rules = reactive({ + monitorInterval: [Rules.integerNumber, { validator: verifyInterval, trigger: 'blur', required: true }], }); const formRef = ref(); const acceptParams = (params: DialogProps): void => { - form.monitorInterval = params.monitorInterval; + form.timeItem = params.timeItem; + form.timeUnit = params.timeUnit; drawerVisible.value = true; }; +const loadInterval = () => { + form.monitorInterval = transferTimeToSecond(form.timeItem + form.timeUnit); +}; + const onSave = async (formEl: FormInstance | undefined) => { if (!formEl) return; formEl.validate(async (valid) => {