Skip to content

Commit 20b752d

Browse files
author
Sunser
committed
Refine notification templates
1 parent be1728e commit 20b752d

3 files changed

Lines changed: 79 additions & 17 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ http://你的服务器IP:43210
199199
| `EC_WECHAT_CORPSECRET` | 启用通知时必填 || 企业微信自建应用 Secret。 |
200200
| `EC_WECHAT_AGENTID` | 启用通知时必填 | `0` | 企业微信自建应用 AgentId。 |
201201
| `EC_WECHAT_TOUSER` | 启用通知时必填 || 接收人。单人写 `user1`,多人写 `user1,user2`|
202-
| `EC_NOTIFY_EVENTS` || `auto_start,manual_start,manual_stop,manual_required,traffic_exceeded,error` | 通知事件列表,多个用逗号分隔。 |
202+
| `EC_NOTIFY_EVENTS` || `auto_start`<br>`manual_start`<br>`manual_stop`<br>`manual_required`<br>`traffic_exceeded`<br>`error` | 通知事件列表,多个用逗号分隔。 |
203203

204204
通知使用企业微信自建应用文本消息,不使用群机器人 webhook。
205205

internal/monitor/service.go

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ func (s *Service) Refresh(ctx context.Context) error {
116116
accountTraffic := s.loadAccountTraffic(ctx, client)
117117
accountTrafficAvailable := accountTraffic.Source == "cdt"
118118
accountScopes := trafficScopes(accountTraffic, account.MainlandTrafficLimit, account.OverseasTrafficLimit)
119-
accountUsagePercent := maxTrafficScopeUsage(accountScopes)
119+
maxScope, hasMaxScope := maxTrafficScope(accountScopes)
120+
accountUsagePercent := maxScope.UsagePercent
120121
accountSnapshot := AccountSnapshot{
121122
AccountName: account.Name,
122123
AccountSite: account.Site,
@@ -144,11 +145,15 @@ func (s *Service) Refresh(ctx context.Context) error {
144145
"account": account.Name,
145146
"usage": fmt.Sprintf("%.2f%%", accountUsagePercent),
146147
})
147-
s.notifyEvent(ctx, "traffic_exceeded", "流量超阈值", map[string]string{
148+
fields := map[string]string{
148149
"账号": account.Name,
149150
"事件": "流量超阈值",
150151
"使用率": fmt.Sprintf("%.2f%%", accountUsagePercent),
151-
})
152+
}
153+
if hasMaxScope {
154+
fields["流量分区"] = maxScope.Name
155+
}
156+
s.notifyEvent(ctx, "traffic_exceeded", "流量超阈值", fields)
152157
}
153158
} else {
154159
applog.Warn("account", "cdt traffic unavailable", map[string]string{
@@ -330,13 +335,7 @@ func (s *Service) ManualStop(ctx context.Context, instanceID, requestedStopMode
330335
fields["reason"] = "prepaid_keep_charging"
331336
}
332337
applog.Info("keepalive", "manual stop submitted", fields)
333-
notifyFields := instanceNotificationFields(location.Account.Name, location.Region.RegionID, instance, instanceID, "手工关机已提交")
334-
notifyFields["停机模式"] = stopMode
335-
if stopMode != configuredStopMode {
336-
notifyFields["配置停机模式"] = configuredStopMode
337-
notifyFields["说明"] = "包年包月实例自动使用普通停机"
338-
}
339-
s.notifyEvent(ctx, "manual_stop", "手工关机已提交", notifyFields)
338+
s.notifyEvent(ctx, "manual_stop", "手工关机已提交", manualStopNotificationFields(location.Account.Name, location.Region.RegionID, instance, instanceID, stopMode))
340339
s.patchInstanceAfterOperation(instanceID, "Stopping")
341340
return nil
342341
}
@@ -598,14 +597,16 @@ func regionDisplayName(regionID string) string {
598597
return regionID
599598
}
600599

601-
func maxTrafficScopeUsage(scopes []TrafficScopeSnapshot) float64 {
602-
var maxUsage float64
600+
func maxTrafficScope(scopes []TrafficScopeSnapshot) (TrafficScopeSnapshot, bool) {
601+
var maxScope TrafficScopeSnapshot
602+
var found bool
603603
for _, scope := range scopes {
604-
if scope.UsagePercent > maxUsage {
605-
maxUsage = scope.UsagePercent
604+
if !found || scope.UsagePercent > maxScope.UsagePercent {
605+
maxScope = scope
606+
found = true
606607
}
607608
}
608-
return maxUsage
609+
return maxScope, found
609610
}
610611

611612
func regionTraffic(traffic aliyun.TrafficResult, regionID string, mainlandLimitGB, overseasLimitGB float64) (string, float64, float64, float64) {
@@ -631,7 +632,7 @@ func (s *Service) handleDecision(ctx context.Context, accountName string, snapsh
631632
"usage": fmt.Sprintf("%.2f%%", snapshot.AccountUsagePercent),
632633
})
633634
fields := instanceNotificationFields(accountName, snapshot.RegionID, snapshot, snapshot.InstanceID, "实例需要人工决策")
634-
fields["原因"] = decision.Reason
635+
fields["原因"] = decisionReasonText(decision.Reason)
635636
fields["使用率"] = fmt.Sprintf("%.2f%%", snapshot.AccountUsagePercent)
636637
s.notifyEvent(ctx, "manual_required", "实例需要人工决策", fields)
637638
return
@@ -752,6 +753,23 @@ func instanceNotificationFields(accountName, regionID string, snapshot InstanceS
752753
}
753754
}
754755

756+
func manualStopNotificationFields(accountName, regionID string, snapshot InstanceSnapshot, instanceID, stopMode string) map[string]string {
757+
fields := instanceNotificationFields(accountName, regionID, snapshot, instanceID, "手工关机已提交")
758+
fields["停机模式"] = stopMode
759+
return fields
760+
}
761+
762+
func decisionReasonText(reason string) string {
763+
switch reason {
764+
case "account_traffic_unknown_manual_required":
765+
return "账号流量读取失败,需要人工决策"
766+
case "account_traffic_exceeded_manual_required":
767+
return "流量已达到阈值,需要人工决策"
768+
default:
769+
return reason
770+
}
771+
}
772+
755773
func copyConfig(cfg config.Config) config.Config {
756774
cfg.KeepAlive.IncludeInstanceIDs = append([]string(nil), cfg.KeepAlive.IncludeInstanceIDs...)
757775
cfg.Notification.WeChatToUser = append([]string(nil), cfg.Notification.WeChatToUser...)

internal/monitor/service_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,50 @@ func TestEffectiveStopModeUsesStopChargingForNonPrepaidInstances(t *testing.T) {
8383
}
8484
}
8585

86+
func TestManualStopNotificationFieldsOmitConfiguredFallbackDetails(t *testing.T) {
87+
fields := manualStopNotificationFields("Huhu", "cn-hangzhou", InstanceSnapshot{
88+
InstanceName: "example",
89+
InstanceChargeType: "PrePaid",
90+
}, "i-123", "KeepCharging")
91+
92+
if fields["停机模式"] != "KeepCharging" {
93+
t.Fatalf("stop mode = %q, want KeepCharging", fields["停机模式"])
94+
}
95+
if _, ok := fields["说明"]; ok {
96+
t.Fatalf("manual stop notification should omit explanation: %#v", fields)
97+
}
98+
if _, ok := fields["配置停机模式"]; ok {
99+
t.Fatalf("manual stop notification should omit configured mode: %#v", fields)
100+
}
101+
}
102+
103+
func TestDecisionReasonTextUsesChinese(t *testing.T) {
104+
cases := map[string]string{
105+
"account_traffic_unknown_manual_required": "账号流量读取失败,需要人工决策",
106+
"account_traffic_exceeded_manual_required": "流量已达到阈值,需要人工决策",
107+
}
108+
109+
for reason, want := range cases {
110+
if got := decisionReasonText(reason); got != want {
111+
t.Fatalf("decisionReasonText(%q) = %q, want %q", reason, got, want)
112+
}
113+
}
114+
}
115+
116+
func TestMaxTrafficScopeSelectsScopeName(t *testing.T) {
117+
scope, ok := maxTrafficScope([]TrafficScopeSnapshot{
118+
{Key: aliyun.CDTScopeMainland, Name: "中国内地", UsagePercent: 50},
119+
{Key: aliyun.CDTScopeOverseas, Name: "非中国内地", UsagePercent: 70},
120+
})
121+
122+
if !ok {
123+
t.Fatal("maxTrafficScope() ok = false, want true")
124+
}
125+
if scope.Name != "非中国内地" || scope.UsagePercent != 70 {
126+
t.Fatalf("max scope = %#v, want 非中国内地 70", scope)
127+
}
128+
}
129+
86130
func TestNotificationFieldsWithTimeAddsLocalTime(t *testing.T) {
87131
location := time.FixedZone("CST", 8*60*60)
88132
originalLocal := time.Local

0 commit comments

Comments
 (0)