mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-09-02 08:27:14 +00:00
feat(memory): add memory threshold alerts (#5366)
* feat(memory): add memory threshold alerts
Add memory (RAM) threshold alerts following the same architecture as
CPU alerts: CheckMemJob with @every 1m cadence, memoryAlarmWanted gate,
tgMemory/smtpMemory per-subscriber settings (default 80%), EventBusCheckboxes
with inline threshold input, i18n for en-US/ru-RU with English defaults.
# Conflicts:
# internal/web/translation/ar-EG.json
# internal/web/translation/es-ES.json
# internal/web/translation/fa-IR.json
# internal/web/translation/id-ID.json
# internal/web/translation/ja-JP.json
# internal/web/translation/pt-BR.json
# internal/web/translation/ru-RU.json
# internal/web/translation/tr-TR.json
# internal/web/translation/uk-UA.json
# internal/web/translation/vi-VN.json
# internal/web/translation/zh-CN.json
# internal/web/translation/zh-TW.json
* fix: address code review findings for memory alerts
- Remove dead settingService field from CheckMemJob
- Fix cpuThreshold double-emoji in 12 locale files (code prepends 🔴)
- Align TgCpu/TgMemory fields in entity.go
- Add missing SetTgMemory function
* fix: restore settingService in CheckMemJob for consistency with CheckCpuJob
This commit is contained in:
@@ -148,6 +148,19 @@ func (s *Subscriber) formatMessage(e eventbus.Event) (subject, body string) {
|
||||
body = wrap(subject, content)
|
||||
}
|
||||
|
||||
case eventbus.EventMemoryHigh:
|
||||
if data, ok := e.Data.(*eventbus.SystemMetricData); ok {
|
||||
smtpMemory, err := s.settingService.GetSmtpMemory()
|
||||
if err != nil || smtpMemory <= 0 || data.Percent <= float64(smtpMemory) {
|
||||
return
|
||||
}
|
||||
subject = host + " " + i18n("tgbot.messages.memoryThreshold",
|
||||
"Percent=="+strconv.FormatFloat(data.Percent, 'f', 2, 64),
|
||||
"Threshold=="+fmt.Sprintf("%d", smtpMemory))
|
||||
content := kv(i18n("email.labelStatus"), `<span style="color:orange">`+i18n("email.statusHigh")+`</span>`)
|
||||
body = wrap(subject, content)
|
||||
}
|
||||
|
||||
case eventbus.EventLoginAttempt:
|
||||
if data, ok := e.Data.(*eventbus.LoginEventData); ok {
|
||||
if data.Status == "success" {
|
||||
|
||||
@@ -63,6 +63,7 @@ var defaultValueMap = map[string]string{
|
||||
"tgRunTime": "@daily",
|
||||
"tgBotBackup": "false",
|
||||
"tgCpu": "80",
|
||||
"tgMemory": "80",
|
||||
"tgLang": "en-US",
|
||||
"twoFactorEnable": "false",
|
||||
"twoFactorToken": "",
|
||||
@@ -131,6 +132,7 @@ var defaultValueMap = map[string]string{
|
||||
"tgEnabledEvents": "login.attempt,cpu.high",
|
||||
"smtpEnabledEvents": "login.attempt,cpu.high",
|
||||
"smtpCpu": "80",
|
||||
"smtpMemory": "80",
|
||||
|
||||
// Email (SMTP) notifications
|
||||
"smtpEnable": "false",
|
||||
@@ -531,6 +533,14 @@ func (s *SettingService) GetTgCpu() (int, error) {
|
||||
return s.getInt("tgCpu")
|
||||
}
|
||||
|
||||
func (s *SettingService) GetTgMemory() (int, error) {
|
||||
return s.getInt("tgMemory")
|
||||
}
|
||||
|
||||
func (s *SettingService) SetTgMemory(value int) error {
|
||||
return s.setInt("tgMemory", value)
|
||||
}
|
||||
|
||||
func (s *SettingService) GetTgLang() (string, error) {
|
||||
return s.getString("tgLang")
|
||||
}
|
||||
@@ -1017,6 +1027,14 @@ func (s *SettingService) SetSmtpCpu(value int) error {
|
||||
return s.setInt("smtpCpu", value)
|
||||
}
|
||||
|
||||
func (s *SettingService) GetSmtpMemory() (int, error) {
|
||||
return s.getInt("smtpMemory")
|
||||
}
|
||||
|
||||
func (s *SettingService) SetSmtpMemory(value int) error {
|
||||
return s.setInt("smtpMemory", value)
|
||||
}
|
||||
|
||||
func (s *SettingService) UpdateAllSetting(allSetting *entity.AllSetting) error {
|
||||
if err := s.preserveRedactedSecrets(allSetting); err != nil {
|
||||
return err
|
||||
|
||||
@@ -123,6 +123,18 @@ func (t *Tgbot) formatEventMessage(e eventbus.Event) string {
|
||||
}
|
||||
return ""
|
||||
|
||||
case eventbus.EventMemoryHigh:
|
||||
if data, ok := e.Data.(*eventbus.SystemMetricData); ok {
|
||||
tgMemory, err := t.settingService.GetTgMemory()
|
||||
if err != nil || tgMemory <= 0 || data.Percent <= float64(tgMemory) {
|
||||
return ""
|
||||
}
|
||||
return header + "🔴 " + t.I18nBot("tgbot.messages.memoryThreshold",
|
||||
"Percent=="+strconv.FormatFloat(data.Percent, 'f', 2, 64),
|
||||
"Threshold=="+strconv.Itoa(tgMemory))
|
||||
}
|
||||
return ""
|
||||
|
||||
case eventbus.EventLoginAttempt:
|
||||
if data, ok := e.Data.(*eventbus.LoginEventData); ok {
|
||||
if data.Status == "success" {
|
||||
|
||||
Reference in New Issue
Block a user