mirror of
https://github.com/tnb-labs/panel.git
synced 2026-08-31 01:12:17 +08:00
feat: 监控采集间隔支持设置
This commit is contained in:
@@ -15,6 +15,7 @@ const (
|
||||
SettingKeyChannel SettingKey = "channel"
|
||||
SettingKeyMonitor SettingKey = "monitor"
|
||||
SettingKeyMonitorDays SettingKey = "monitor_days"
|
||||
SettingKeyMonitorInterval SettingKey = "monitor_interval"
|
||||
SettingKeyBackupPath SettingKey = "backup_path"
|
||||
SettingKeyWebsitePath SettingKey = "website_path"
|
||||
SettingKeyProjectPath SettingKey = "project_path"
|
||||
|
||||
@@ -31,10 +31,15 @@ func (r monitorRepo) GetSetting() (*request.MonitorSetting, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
monitorInterval, err := r.setting.GetInt(biz.SettingKeyMonitorInterval, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setting := new(request.MonitorSetting)
|
||||
setting.Enabled = cast.ToBool(monitor)
|
||||
setting.Days = cast.ToUint(monitorDays)
|
||||
setting.Interval = uint(monitorInterval)
|
||||
|
||||
return setting, nil
|
||||
}
|
||||
@@ -46,6 +51,9 @@ func (r monitorRepo) UpdateSetting(setting *request.MonitorSetting) error {
|
||||
if err := r.setting.Set(biz.SettingKeyMonitorDays, cast.ToString(setting.Days)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := r.setting.Set(biz.SettingKeyMonitorInterval, cast.ToString(setting.Interval)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package request
|
||||
|
||||
type MonitorSetting struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Days uint `json:"days"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Days uint `json:"days"`
|
||||
Interval uint `json:"interval" validate:"required|min:1|max:120"` // 采集间隔(分钟),最小 1
|
||||
}
|
||||
|
||||
type MonitorList struct {
|
||||
|
||||
@@ -17,6 +17,7 @@ type Monitoring struct {
|
||||
db *gorm.DB
|
||||
log *slog.Logger
|
||||
settingRepo biz.SettingRepo
|
||||
lastRun time.Time
|
||||
}
|
||||
|
||||
func NewMonitoring(db *gorm.DB, log *slog.Logger, setting biz.SettingRepo) *Monitoring {
|
||||
@@ -37,6 +38,16 @@ func (r *Monitoring) Run() {
|
||||
return
|
||||
}
|
||||
|
||||
// 根据采集间隔判断是否该采集
|
||||
interval, _ := r.settingRepo.GetInt(biz.SettingKeyMonitorInterval, 1)
|
||||
if interval < 1 {
|
||||
interval = 1
|
||||
}
|
||||
if !r.lastRun.IsZero() && time.Since(r.lastRun) < time.Duration(interval)*time.Minute-30*time.Second {
|
||||
return
|
||||
}
|
||||
r.lastRun = time.Now()
|
||||
|
||||
info := tools.CurrentInfo(nil, nil)
|
||||
info.TopProcesses = tools.CollectTopProcesses()
|
||||
|
||||
|
||||
@@ -1039,6 +1039,7 @@ func (s *CliService) Init(ctx context.Context, cmd *cli.Command) error {
|
||||
{Key: biz.SettingKeyVersion, Value: app.Version},
|
||||
{Key: biz.SettingKeyMonitor, Value: "true"},
|
||||
{Key: biz.SettingKeyMonitorDays, Value: "30"},
|
||||
{Key: biz.SettingKeyMonitorInterval, Value: "1"},
|
||||
{Key: biz.SettingKeyBackupPath, Value: filepath.Join(app.Root, "backup")},
|
||||
{Key: biz.SettingKeyWebsitePath, Value: filepath.Join(app.Root, "sites")},
|
||||
{Key: biz.SettingKeyProjectPath, Value: filepath.Join(app.Root, "projects")},
|
||||
|
||||
@@ -118,6 +118,12 @@ func (s *MonitorService) List(w http.ResponseWriter, r *http.Request) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 计算与上一条记录的时间差(秒),用于速率计算
|
||||
elapsed := monitor.CreatedAt.Sub(monitors[i-1].CreatedAt).Seconds()
|
||||
if elapsed < 1 {
|
||||
elapsed = 1
|
||||
}
|
||||
|
||||
// 处理网络数据
|
||||
for _, net := range monitor.Info.Net {
|
||||
if net.Name == "lo" {
|
||||
@@ -136,8 +142,8 @@ func (s *MonitorService) List(w http.ResponseWriter, r *http.Request) {
|
||||
device := netDeviceData[net.Name]
|
||||
device.Sent = append(device.Sent, fmt.Sprintf("%.2f", float64(net.BytesSent)/1024/1024))
|
||||
device.Recv = append(device.Recv, fmt.Sprintf("%.2f", float64(net.BytesRecv)/1024/1024))
|
||||
device.Tx = append(device.Tx, fmt.Sprintf("%.2f", float64(net.BytesSent-prev.sent)/60/1024/1024))
|
||||
device.Rx = append(device.Rx, fmt.Sprintf("%.2f", float64(net.BytesRecv-prev.recv)/60/1024/1024))
|
||||
device.Tx = append(device.Tx, fmt.Sprintf("%.2f", float64(net.BytesSent-prev.sent)/elapsed/1024/1024))
|
||||
device.Rx = append(device.Rx, fmt.Sprintf("%.2f", float64(net.BytesRecv-prev.recv)/elapsed/1024/1024))
|
||||
netDevicePrev[net.Name] = struct {
|
||||
sent uint64
|
||||
recv uint64
|
||||
@@ -157,9 +163,9 @@ func (s *MonitorService) List(w http.ResponseWriter, r *http.Request) {
|
||||
diskData := diskIOData[disk.Name]
|
||||
diskData.ReadBytes = append(diskData.ReadBytes, fmt.Sprintf("%.2f", float64(disk.ReadBytes)/1024/1024))
|
||||
diskData.WriteBytes = append(diskData.WriteBytes, fmt.Sprintf("%.2f", float64(disk.WriteBytes)/1024/1024))
|
||||
// 监控频率为 1 分钟,所以这里除以 60 即可得到每秒的速度 (KB/s)
|
||||
diskData.ReadSpeed = append(diskData.ReadSpeed, fmt.Sprintf("%.2f", float64(disk.ReadBytes-prev.read)/60/1024))
|
||||
diskData.WriteSpeed = append(diskData.WriteSpeed, fmt.Sprintf("%.2f", float64(disk.WriteBytes-prev.write)/60/1024))
|
||||
// 根据实际时间差计算每秒速度 (KB/s)
|
||||
diskData.ReadSpeed = append(diskData.ReadSpeed, fmt.Sprintf("%.2f", float64(disk.ReadBytes-prev.read)/elapsed/1024))
|
||||
diskData.WriteSpeed = append(diskData.WriteSpeed, fmt.Sprintf("%.2f", float64(disk.WriteBytes-prev.write)/elapsed/1024))
|
||||
diskIOPrev[disk.Name] = struct {
|
||||
read uint64
|
||||
write uint64
|
||||
|
||||
@@ -3,9 +3,9 @@ import { http } from '@/utils'
|
||||
export default {
|
||||
// 开关
|
||||
setting: (): any => http.Get('/monitor/setting'),
|
||||
// 保存天数
|
||||
updateSetting: (enabled: boolean, days: number): any =>
|
||||
http.Post('/monitor/setting', { enabled, days }),
|
||||
// 保存设置
|
||||
updateSetting: (enabled: boolean, days: number, interval: number): any =>
|
||||
http.Post('/monitor/setting', { enabled, days, interval }),
|
||||
// 清空监控记录
|
||||
clear: (): any => http.Post('/monitor/clear'),
|
||||
// 监控记录
|
||||
|
||||
@@ -34,11 +34,13 @@ use([
|
||||
// 监控设置
|
||||
const monitorSwitch = ref(false)
|
||||
const saveDay = ref(30)
|
||||
const monitorInterval = ref(1)
|
||||
const updateLoading = ref(false)
|
||||
|
||||
useRequest(monitor.setting()).onSuccess(({ data }) => {
|
||||
monitorSwitch.value = data.enabled
|
||||
saveDay.value = data.days
|
||||
monitorInterval.value = data.interval
|
||||
})
|
||||
|
||||
// 时间预设选项
|
||||
@@ -688,7 +690,7 @@ const diskIOOption = computed<EChartsOption>(() => {
|
||||
// 操作函数
|
||||
const handleUpdate = async () => {
|
||||
updateLoading.value = true
|
||||
useRequest(monitor.updateSetting(monitorSwitch.value, saveDay.value))
|
||||
useRequest(monitor.updateSetting(monitorSwitch.value, saveDay.value, monitorInterval.value))
|
||||
.onSuccess(() => {
|
||||
window.$message.success($gettext('Operation successful'))
|
||||
})
|
||||
@@ -719,6 +721,12 @@ const handleClear = async () => {
|
||||
<template #suffix> {{ $gettext('days') }} </template>
|
||||
</n-input-number>
|
||||
</div>
|
||||
<div class="pl-20 flex gap-10 items-center">
|
||||
{{ $gettext('Collection Interval') }}
|
||||
<n-input-number v-model:value="monitorInterval" :min="1" :max="120">
|
||||
<template #suffix> {{ $gettext('minutes') }} </template>
|
||||
</n-input-number>
|
||||
</div>
|
||||
<div>
|
||||
<n-button type="primary" :loading="updateLoading" :disabled="updateLoading" @click="handleUpdate">{{ $gettext('Confirm') }}</n-button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user