From cca1863b632491072ae43707ccf600e443aaa688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=98=AD?= <81747598+lan-yonghui@users.noreply.github.com> Date: Wed, 23 Jul 2025 16:58:24 +0800 Subject: [PATCH] feat: Adjust alarm settings (#9616) --- agent/app/dto/alert.go | 4 +- agent/app/model/alert.go | 1 + agent/app/repo/alert.go | 6 +- agent/app/service/alert_helper.go | 47 ++++++---- agent/init/migration/migrate.go | 1 + agent/init/migration/migrations/init.go | 17 +++- agent/utils/alert/alert.go | 11 ++- agent/utils/alert_push/alert_push.go | 11 +-- frontend/src/api/interface/setting.ts | 6 ++ frontend/src/api/modules/setting.ts | 2 +- .../views/cronjob/cronjob/operate/index.vue | 2 +- .../src/views/setting/alert/setting/index.vue | 70 +++++++++++--- .../setting/alert/setting/phone/index.vue | 15 ++- .../alert/setting/time-range/index.vue | 93 +++++++------------ 14 files changed, 174 insertions(+), 112 deletions(-) diff --git a/agent/app/dto/alert.go b/agent/app/dto/alert.go index dd4d40dce..fcf2d202f 100644 --- a/agent/app/dto/alert.go +++ b/agent/app/dto/alert.go @@ -307,13 +307,13 @@ type AlertSendTimeRange struct { } type AlertCommonConfig struct { - AlertDailyNum uint `json:"alertDailyNum"` IsOffline string `json:"isOffline"` AlertSendTimeRange AlertSendTimeRange `json:"alertSendTimeRange"` } type AlertSmsConfig struct { - Phone string `json:"phone"` + Phone string `json:"phone"` + AlertDailyNum uint `json:"alertDailyNum"` } type AlertEmailConfig struct { diff --git a/agent/app/model/alert.go b/agent/app/model/alert.go index 9820c418e..a697a602f 100644 --- a/agent/app/model/alert.go +++ b/agent/app/model/alert.go @@ -18,6 +18,7 @@ type AlertTask struct { Type string `gorm:"type:varchar(64);not null" json:"type"` Quota string `gorm:"type:varchar(64)" json:"quota"` QuotaType string `gorm:"type:varchar(64)" json:"quotaType"` + Method string `gorm:"type:varchar(64);not null;default:'sms" json:"method"` } type AlertLog struct { diff --git a/agent/app/repo/alert.go b/agent/app/repo/alert.go index 0194387ca..40fa07d4a 100644 --- a/agent/app/repo/alert.go +++ b/agent/app/repo/alert.go @@ -44,7 +44,7 @@ type IAlertRepo interface { GetAlertTask(opts ...DBOption) (model.AlertTask, error) LoadTaskCount(alertType string, project string) (uint, uint, error) GetTaskLog(alertType string, alertId uint) (time.Time, error) - GetLicensePushCount() (uint, error) + GetLicensePushCount(method string) (uint, error) GetConfig(opts ...DBOption) (model.AlertConfig, error) AlertConfigList(opts ...DBOption) ([]model.AlertConfig, error) @@ -267,14 +267,14 @@ func getAlertDB(opts ...DBOption) (*gorm.DB, error) { return db, nil } -func (a *AlertRepo) GetLicensePushCount() (uint, error) { +func (a *AlertRepo) GetLicensePushCount(method string) (uint, error) { var ( todayCount int64 ) now := time.Now() todayMidnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) tomorrowMidnight := todayMidnight.Add(24 * time.Hour) - err := global.AlertDB.Model(&model.AlertTask{}).Where("created_at > ? AND created_at < ?", todayMidnight, tomorrowMidnight).Count(&todayCount).Error + err := global.AlertDB.Model(&model.AlertTask{}).Where("created_at > ? AND created_at < ? AND method = ?", todayMidnight, tomorrowMidnight, method).Count(&todayCount).Error return uint(todayCount), err } diff --git a/agent/app/service/alert_helper.go b/agent/app/service/alert_helper.go index b50095304..538f14142 100644 --- a/agent/app/service/alert_helper.go +++ b/agent/app/service/alert_helper.go @@ -87,9 +87,6 @@ func (m *AlertTaskHelper) InitTask(alertType string) { func resourceTask(resourceAlert []dto.AlertDTO) { for _, alert := range resourceAlert { - if !alertUtil.CheckTaskFrequency() { - return - } if !alertUtil.CheckSendTimeRange(alert.Type) { continue } @@ -109,9 +106,6 @@ func resourceTask(resourceAlert []dto.AlertDTO) { func baseTask(baseAlert []dto.AlertDTO) { for _, alert := range baseAlert { - if !alertUtil.CheckTaskFrequency() { - return - } if !alertUtil.CheckSendTimeRange(alert.Type) { continue } @@ -245,7 +239,11 @@ func loadSSLInfo(alert dto.AlertDTO) { params = createAlertBaseParams(strconv.Itoa(len(primaryDomain)), strconv.Itoa(daysDifference)) switch m { case constant.SMS: + if !alertUtil.CheckTaskFrequency(constant.SMS) { + continue + } _ = xpack.CreateSMSAlertLog(alert, create, primaryDomain, params, constant.SMS) + alertUtil.CreateNewAlertTask(alert.Project, alert.Type, projectJSON, constant.SMS) case constant.Email: alertDetail := alertUtil.ProcessAlertDetail(alert, primaryDomain, params, constant.Email) alertRule := alertUtil.ProcessAlertRule(alert) @@ -253,12 +251,11 @@ func loadSSLInfo(alert dto.AlertDTO) { create.AlertDetail = alertDetail transport := xpack.LoadRequestTransport() _ = alertUtil.CreateEmailAlertLog(create, alert, params, transport) + alertUtil.CreateNewAlertTask(alert.Project, alert.Type, projectJSON, constant.Email) default: } } } - - alertUtil.CreateNewAlertTask(alert.Project, alert.Type, projectJSON) global.LOG.Info("SSL alert push successful") } } @@ -305,7 +302,11 @@ func loadWebsiteInfo(alert dto.AlertDTO) { params = createAlertBaseParams(strconv.Itoa(len(websites)), strconv.Itoa(daysDifference)) switch m { case constant.SMS: + if !alertUtil.CheckTaskFrequency(constant.SMS) { + continue + } _ = xpack.CreateSMSAlertLog(alert, create, primaryDomain, params, constant.SMS) + alertUtil.CreateNewAlertTask(alert.Project, alert.Type, projectJSON, constant.SMS) case constant.Email: alertDetail := alertUtil.ProcessAlertDetail(alert, primaryDomain, params, constant.Email) alertRule := alertUtil.ProcessAlertRule(alert) @@ -313,11 +314,11 @@ func loadWebsiteInfo(alert dto.AlertDTO) { create.AlertRule = alertRule transport := xpack.LoadRequestTransport() _ = alertUtil.CreateEmailAlertLog(create, alert, params, transport) + alertUtil.CreateNewAlertTask(alert.Project, alert.Type, projectJSON, constant.Email) default: } } } - alertUtil.CreateNewAlertTask(alert.Project, alert.Type, projectJSON) global.LOG.Info("website expiration alert push successful") } } @@ -358,7 +359,11 @@ func loadPanelPwd(alert dto.AlertDTO) { m = strings.TrimSpace(m) switch m { case constant.SMS: + if !alertUtil.CheckTaskFrequency(constant.SMS) { + continue + } _ = xpack.CreateSMSAlertLog(alert, create, strconv.Itoa(daysDifference), params, constant.SMS) + alertUtil.CreateNewAlertTask(expirationTime.Value, alert.Type, expirationTime.Value, constant.SMS) case constant.Email: alertDetail := alertUtil.ProcessAlertDetail(alert, strconv.Itoa(daysDifference), params, constant.Email) alertRule := alertUtil.ProcessAlertRule(alert) @@ -366,10 +371,10 @@ func loadPanelPwd(alert dto.AlertDTO) { create.AlertDetail = alertDetail transport := xpack.LoadRequestTransport() _ = alertUtil.CreateEmailAlertLog(create, alert, params, transport) + alertUtil.CreateNewAlertTask(expirationTime.Value, alert.Type, expirationTime.Value, constant.Email) default: } } - alertUtil.CreateNewAlertTask(expirationTime.Value, alert.Type, expirationTime.Value) global.LOG.Info("panel password expiration alert push successful") } } @@ -411,7 +416,11 @@ func loadPanelUpdate(alert dto.AlertDTO) { m = strings.TrimSpace(m) switch m { case constant.SMS: + if !alertUtil.CheckTaskFrequency(constant.SMS) { + continue + } _ = xpack.CreateSMSAlertLog(alert, create, version, params, constant.SMS) + alertUtil.CreateNewAlertTask(version, alert.Type, version, constant.SMS) case constant.Email: alertDetail := alertUtil.ProcessAlertDetail(alert, version, params, constant.Email) alertRule := alertUtil.ProcessAlertRule(alert) @@ -419,10 +428,10 @@ func loadPanelUpdate(alert dto.AlertDTO) { create.AlertDetail = alertDetail transport := xpack.LoadRequestTransport() _ = alertUtil.CreateEmailAlertLog(create, alert, params, transport) + alertUtil.CreateNewAlertTask(version, alert.Type, version, constant.Email) default: } } - alertUtil.CreateNewAlertTask(version, alert.Type, version) global.LOG.Info("panel update alert push successful") } @@ -586,7 +595,11 @@ func createAndLogAlert(alert dto.AlertDTO, avgUsage float64, todayCount uint) { m = strings.TrimSpace(m) switch m { case constant.SMS: + if !alertUtil.CheckTaskFrequency(constant.SMS) { + continue + } _ = xpack.CreateSMSAlertLog(alert, create, avgUsagePercent, params, constant.SMS) + alertUtil.CreateNewAlertTask(avgUsagePercent, alert.Type, strconv.Itoa(int(alert.Cycle)), constant.SMS) case constant.Email: alertDetail := alertUtil.ProcessAlertDetail(alert, avgUsagePercent, params, constant.Email) alertRule := alertUtil.ProcessAlertRule(alert) @@ -594,10 +607,10 @@ func createAndLogAlert(alert dto.AlertDTO, avgUsage float64, todayCount uint) { create.AlertDetail = alertDetail transport := xpack.LoadRequestTransport() _ = alertUtil.CreateEmailAlertLog(create, alert, params, transport) + alertUtil.CreateNewAlertTask(avgUsagePercent, alert.Type, strconv.Itoa(int(alert.Cycle)), constant.Email) default: } } - alertUtil.CreateNewAlertTask(avgUsagePercent, alert.Type, strconv.Itoa(int(alert.Cycle))) } func getModule(alertType string) string { @@ -649,25 +662,20 @@ func processAllDisks(alert dto.AlertDTO, todayCount uint) error { flag = true } } - if flag { - alertUtil.CreateNewAlertTask(strconv.Itoa(int(alert.Cycle)), alert.Type, alert.Project) global.LOG.Info("all disk alert push successful") } return nil } func processSingleDisk(alert dto.AlertDTO, todayCount uint) error { - success, err := checkAndCreateDiskAlert(alert, alert.Project, todayCount) if err != nil { return err } if success { - alertUtil.CreateNewAlertTask(strconv.Itoa(int(alert.Cycle)), alert.Type, alert.Project) global.LOG.Info("disk alert push successful") } - return nil } @@ -700,7 +708,11 @@ func checkAndCreateDiskAlert(alert dto.AlertDTO, path string, todayCount uint) ( m = strings.TrimSpace(m) switch m { case constant.SMS: + if !alertUtil.CheckTaskFrequency(constant.SMS) { + continue + } _ = xpack.CreateSMSAlertLog(alert, create, path, params, constant.SMS) + alertUtil.CreateNewAlertTask(strconv.Itoa(int(alert.Cycle)), alert.Type, alert.Project, constant.SMS) case constant.Email: alertDetail := alertUtil.ProcessAlertDetail(alert, path, params, constant.Email) alertRule := alertUtil.ProcessAlertRule(alert) @@ -708,6 +720,7 @@ func checkAndCreateDiskAlert(alert dto.AlertDTO, path string, todayCount uint) ( create.AlertDetail = alertDetail transport := xpack.LoadRequestTransport() _ = alertUtil.CreateEmailAlertLog(create, alert, params, transport) + alertUtil.CreateNewAlertTask(strconv.Itoa(int(alert.Cycle)), alert.Type, alert.Project, constant.Email) default: } } diff --git a/agent/init/migration/migrate.go b/agent/init/migration/migrate.go index af155c583..fe27532af 100644 --- a/agent/init/migration/migrate.go +++ b/agent/init/migration/migrate.go @@ -32,6 +32,7 @@ func InitAgentDB() { migrations.AddTableAlert, migrations.InitAlertConfig, migrations.AddMethodToAlertLog, + migrations.AddMethodToAlertTask, }) 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 f50d3784e..3314d9a7e 100644 --- a/agent/init/migration/migrations/init.go +++ b/agent/init/migration/migrations/init.go @@ -376,13 +376,13 @@ var InitAlertConfig = &gormigrate.Migration{ Type: "sms", Title: "xpack.alert.smsConfig", Status: "Enable", - Config: "{}", + Config: `{"alertDailyNum":50}`, }, { Type: "common", Title: "xpack.alert.commonConfig", Status: "Enable", - Config: `{"alertDailyNum":50,"isOffline":"Disable","alertSendTimeRange":{"noticeAlert":{"sendTimeRange":"08:00:00 - 23:59:59","type":["ssl","siteEndTime","panelPwdEndTime","panelUpdate"]},"resourceAlert":{"sendTimeRange":"00:00:00 - 23:59:59","type":["clams","cronJob","cpu","memory","load","disk"]}}}`, + Config: `{"isOffline":"Disable","alertSendTimeRange":{"noticeAlert":{"sendTimeRange":"08:00:00 - 23:59:59","type":["ssl","siteEndTime","panelPwdEndTime","panelUpdate"]},"resourceAlert":{"sendTimeRange":"00:00:00 - 23:59:59","type":["clams","cronJob","cpu","memory","load","disk"]}}}`, }, } for _, r := range records { @@ -406,3 +406,16 @@ var AddMethodToAlertLog = &gormigrate.Migration{ return nil }, } + +var AddMethodToAlertTask = &gormigrate.Migration{ + ID: "20250723-add-method-to-alert_task", + Migrate: func(tx *gorm.DB) error { + if err := global.AlertDB.AutoMigrate(&model.AlertTask{}); err != nil { + return err + } + if err := global.AlertDB.Model(&model.AlertTask{}).Where("method IS NULL OR method = ''").Update("method", "sms").Error; err != nil { + return err + } + return nil + }, +} diff --git a/agent/utils/alert/alert.go b/agent/utils/alert/alert.go index 879a95cc0..82b68aa67 100644 --- a/agent/utils/alert/alert.go +++ b/agent/utils/alert/alert.go @@ -100,12 +100,13 @@ func SaveAlertLog(create dto.AlertLogCreate, alertLog *model.AlertLog) error { return nil } -func CreateNewAlertTask(quota, alertType, quotaType string) { +func CreateNewAlertTask(quota, alertType, quotaType, method string) { alertRepo := repo.NewIAlertRepo() taskBase := model.AlertTask{ Type: alertType, Quota: quota, QuotaType: quotaType, + Method: method, } err := alertRepo.CreateAlertTask(&taskBase) if err != nil { @@ -190,20 +191,20 @@ func CreateAlertParams(param string) []dto.Param { var checkTaskMutex sync.Mutex -func CheckTaskFrequency() bool { +func CheckTaskFrequency(method string) bool { alertRepo := repo.NewIAlertRepo() - config, err := alertRepo.GetConfig(alertRepo.WithByType(constant.CommonConfig)) + config, err := alertRepo.GetConfig(alertRepo.WithByType(constant.SMSConfig)) if err != nil { return false } - var cfg dto.AlertCommonConfig + var cfg dto.AlertSmsConfig err = json.Unmarshal([]byte(config.Config), &cfg) if err != nil { return false } limitCount := cfg.AlertDailyNum checkTaskMutex.Lock() - todayCount, err := repo.NewIAlertRepo().GetLicensePushCount() + todayCount, err := alertRepo.GetLicensePushCount(method) defer checkTaskMutex.Unlock() if err != nil { global.LOG.Errorf("error getting license push count info, err: %v", err) diff --git a/agent/utils/alert_push/alert_push.go b/agent/utils/alert_push/alert_push.go index cf7f566c8..7a8401df1 100644 --- a/agent/utils/alert_push/alert_push.go +++ b/agent/utils/alert_push/alert_push.go @@ -13,10 +13,6 @@ import ( ) func PushAlert(pushAlert dto.PushAlert) error { - if !alertUtil.CheckTaskFrequency() { - return nil - } - if !alertUtil.CheckSendTimeRange(alertUtil.GetCronJobType(pushAlert.AlertType)) { return nil } @@ -45,18 +41,21 @@ func PushAlert(pushAlert dto.PushAlert) error { m = strings.TrimSpace(m) switch m { case constant.SMS: + if !alertUtil.CheckTaskFrequency(constant.SMS) { + continue + } _ = xpack.CreateTaskScanSMSAlertLog(alert, create, pushAlert, constant.SMS) + alertUtil.CreateNewAlertTask(strconv.Itoa(int(pushAlert.EntryID)), alertUtil.GetCronJobType(alert.Type), strconv.Itoa(int(pushAlert.EntryID)), constant.SMS) case constant.Email: transport := xpack.LoadRequestTransport() err := alertUtil.CreateTaskScanEmailAlertLog(alert, create, pushAlert, constant.Email, transport) if err != nil { return err } + alertUtil.CreateNewAlertTask(strconv.Itoa(int(pushAlert.EntryID)), alertUtil.GetCronJobType(alert.Type), strconv.Itoa(int(pushAlert.EntryID)), constant.Email) default: } } - // 处理告警任务 - alertUtil.CreateNewAlertTask(strconv.Itoa(int(pushAlert.EntryID)), alertUtil.GetCronJobType(alert.Type), strconv.Itoa(int(pushAlert.EntryID))) global.LOG.Infof("%s alert push successful", alert.Type) return nil } diff --git a/frontend/src/api/interface/setting.ts b/frontend/src/api/interface/setting.ts index e3e7f597f..e22db8876 100644 --- a/frontend/src/api/interface/setting.ts +++ b/frontend/src/api/interface/setting.ts @@ -253,4 +253,10 @@ export namespace Setting { force: boolean; withDockerRestart: boolean; } + + export interface SmsInfo { + licenseName: string; + smsUsed: number; + smsTotal: number; + } } diff --git a/frontend/src/api/modules/setting.ts b/frontend/src/api/modules/setting.ts index 0f7d97915..353a34709 100644 --- a/frontend/src/api/modules/setting.ts +++ b/frontend/src/api/modules/setting.ts @@ -49,7 +49,7 @@ export const listAllNodes = () => { }; export const getLicenseSmsInfo = () => { - return http.get(`/core/licenses/sms/info`); + return http.get(`/core/licenses/sms/info`); }; // agent diff --git a/frontend/src/views/cronjob/cronjob/operate/index.vue b/frontend/src/views/cronjob/cronjob/operate/index.vue index 042fe784c..a65de827a 100644 --- a/frontend/src/views/cronjob/cronjob/operate/index.vue +++ b/frontend/src/views/cronjob/cronjob/operate/index.vue @@ -818,7 +818,7 @@ const form = reactive({ status: '', secret: '', hasAlert: false, - alertCount: 0, + alertCount: 3, alertTitle: '', alertMethod: '', alertMethodItems: [], diff --git a/frontend/src/views/setting/alert/setting/index.vue b/frontend/src/views/setting/alert/setting/index.vue index 91e7dcf0d..2a4e97969 100644 --- a/frontend/src/views/setting/alert/setting/index.vue +++ b/frontend/src/views/setting/alert/setting/index.vue @@ -19,10 +19,6 @@ > - - {{ commonConfig.config.alertDailyNum }} - - {{ sendTimeRange }} @@ -111,19 +107,40 @@ v-if="globalStore.isProductPro && !globalStore.isIntl" >
-
{{ $t('xpack.alert.smsConfig') }}
+
+ {{ $t('xpack.alert.smsConfig') }} +
{{ $t('commons.button.edit') }}
-
{{ $t('xpack.alert.smsConfigHelper') }}
+ +
+ {{ $t('xpack.alert.alertSmsHelper', [totalSms, usedSms]) }} + + {{ $t('xpack.alert.goBuy') }} + +
- - {{ smsConfig.config.phone }} - {{ $t('xpack.alert.defaultPhone') }} - + @@ -147,6 +164,7 @@ import { storeToRefs } from 'pinia'; import { MsgSuccess } from '@/utils/message'; import EmailDrawer from '@/views/setting/alert/setting/email/index.vue'; import { Alert } from '@/api/interface/alert'; +import { getLicenseSmsInfo } from '@/api/modules/setting'; const globalStore = GlobalStore(); const { isMaster } = storeToRefs(globalStore); @@ -201,7 +219,6 @@ export interface CommonConfig { status: string; config: { isOffline?: string; - alertDailyNum?: number; alertSendTimeRange?: string; }; } @@ -209,9 +226,8 @@ const defaultCommonConfig: CommonConfig = { id: undefined, type: 'common', title: 'xpack.alert.commonConfig', - status: 'Ena ble', + status: 'Enable', config: { - alertDailyNum: 50, alertSendTimeRange: i18n.global.t('xpack.alert.noticeAlert') + ': ' + @@ -233,6 +249,7 @@ export interface SmsConfig { status: string; config: { phone?: string; + alertDailyNum?: number; }; } const defaultSmsConfig: SmsConfig = { @@ -242,6 +259,7 @@ const defaultSmsConfig: SmsConfig = { status: 'Enable', config: { phone: '', + alertDailyNum: 50, }, }; const smsConfig = ref({ ...defaultSmsConfig }); @@ -253,6 +271,9 @@ const config = ref({ status: '', config: '', }); +const licenseName = ref('-'); +const totalSms = ref(0); +const usedSms = ref(0); const mobile = computed(() => { return globalStore.isMobile(); }); @@ -314,13 +335,16 @@ const search = async () => { }; const onChangePhone = (id: any) => { - phoneRef.value.acceptParams({ id: id, phone: smsConfig.value.config.phone }); + phoneRef.value.acceptParams({ + id: id, + phone: smsConfig.value.config.phone, + dailyAlertNum: smsConfig.value.config.alertDailyNum, + }); }; const onChangeCommon = (id: any) => { sendTimeRangeRef.value.acceptParams({ id: id, - dailyAlertNum: commonConfig.value.config.alertDailyNum, sendTimeRange: sendTimeRangeValue.value, isOffline: commonConfig.value.config.isOffline, }); @@ -378,8 +402,24 @@ const onDelete = (id: number) => { await search(); }); }; + +const getSmsInfo = async () => { + const res = await getLicenseSmsInfo(); + licenseName.value = res.data.licenseName; + usedSms.value = res.data.smsUsed; + totalSms.value = res.data.smsTotal; +}; + +const goBuy = async () => { + const uri = licenseName.value === '-' ? '' : `${licenseName.value}/buy-sms`; + window.open('https://www.lxware.cn/uc/cloud/licenses/' + uri, '_blank', 'noopener,noreferrer'); +}; + onMounted(async () => { await search(); + if (globalStore.isProductPro && !globalStore.isIntl) { + await getSmsInfo(); + } });