Skip to content

Commit

Permalink
Update feishu notification (#4920)
Browse files Browse the repository at this point in the history
* update kafka monitor

* update feishu notification
  • Loading branch information
wallyxjh authored Aug 12, 2024
1 parent 9caf45a commit 525b4dd
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 119 deletions.
10 changes: 10 additions & 0 deletions service/exceptionmonitor/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ var (
MemMonitorNamespaceMap = make(map[string]bool)
LastBackupStatusMap = make(map[string]string)
IsSendBackupStatusMap = make(map[string]string)
DatabaseNamespaceMap = make(map[string]string)
ExceededQuotaException = "exceeded quota"
DiskException = "Writing to log file failed"
OwnerLabel = "user.sealos.io/owner"
Expand All @@ -67,11 +68,20 @@ var (
DatabaseExceptionMonitorThreshold float64
DatabaseCPUMonitorThreshold float64
DatabaseMemMonitorThreshold float64
APPID string
APPSECRET string
DatabaseStatusMessageIDMap = make(map[string]string)
DatabaseDiskMessageIDMap = make(map[string]string)
DatabaseCPUMessageIDMap = make(map[string]string)
DatabaseMemMessageIDMap = make(map[string]string)
DatabaseBackupMessageIDMap = make(map[string]string)
)

func GetENV() error {
var missingEnvVars []string

APPID = getEnvWithCheck("APPID", &missingEnvVars)
APPSECRET = getEnvWithCheck("APPSECRET", &missingEnvVars)
BaseURL = getEnvWithCheck("BaseURL", &missingEnvVars)
ClusterName = getEnvWithCheck("ClusterName", &missingEnvVars)
MonitorType = getEnvWithCheck("MonitorType", &missingEnvVars)
Expand Down
4 changes: 4 additions & 0 deletions service/exceptionmonitor/deploy/manifests/deploy.yaml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ spec:
value: ""
- name: DatabaseMemMonitorThreshold
value: ""
- name: APPID
value: ""
- name: APPSECRET
value: ""
volumeMounts:
- name: kubeconfig
mountPath: /home/nonroot/kubeconfig
Expand Down
1 change: 1 addition & 0 deletions service/exceptionmonitor/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ require (
github.com/jinzhu/now v1.1.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/larksuite/oapi-sdk-go/v3 v3.2.9 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matoous/go-nanoid/v2 v2.0.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
Expand Down
8 changes: 8 additions & 0 deletions service/exceptionmonitor/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
Expand Down Expand Up @@ -93,6 +95,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/larksuite/oapi-sdk-go v1.1.48 h1:RHRr5LW68AibBzXVRXObUpkbS6TXapl4TAyhITVvB4w=
github.com/larksuite/oapi-sdk-go v1.1.48/go.mod h1:7ybKAbVdKBjXuX0YrMTfnWUyCaIe/zeI1wqjNfN9XOk=
github.com/larksuite/oapi-sdk-go/v3 v3.2.9 h1:9zQAGrzhibNwdaGRkWUP1cAd2k2dJJDpbSffcfK0wPw=
github.com/larksuite/oapi-sdk-go/v3 v3.2.9/go.mod h1:ZEplY+kwuIrj/nqw5uSCINNATcH3KdxSN7y+UxYY5fI=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/matoous/go-nanoid v1.5.0/go.mod h1:zyD2a71IubI24efhpvkJz+ZwfwagzgSO6UNiFsZKN7U=
Expand Down Expand Up @@ -175,6 +181,7 @@ golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -271,3 +278,4 @@ sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+s
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
112 changes: 38 additions & 74 deletions service/exceptionmonitor/helper/monitor/database_backup_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ package monitor

import (
"context"
"fmt"
"log"
"strings"
"time"

"k8s.io/apimachinery/pkg/api/errors"

"github.com/labring/sealos/service/exceptionmonitor/api"
"github.com/labring/sealos/service/exceptionmonitor/helper/notification"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -25,7 +29,7 @@ func DatabaseBackupMonitor() {
if err := checkDatabaseBackups(); err != nil {
log.Printf("Failed to check database backups: %v", err)
}
time.Sleep(1 * time.Hour)
time.Sleep(1 * time.Minute)
}
}

Expand All @@ -50,84 +54,44 @@ func processBackup(backup unstructured.Unstructured) {
if !found || status != "Failed" {
return
}
fmt.Println(backupName, namespace)
debt, _, _ := checkDebt(namespace)
if !debt {
return
}
backupPolicyName, _, _ := unstructured.NestedString(backup.Object, "spec", "backupPolicyName")
databaseName := getPrefix(backupPolicyName)
fmt.Println(databaseName)
cluster, err := api.DynamicClient.Resource(databaseClusterGVR).Namespace(namespace).Get(context.Background(), databaseName, metav1.GetOptions{})
if cluster != nil && errors.IsNotFound(err) {
return
}
dbStatus, _, _ := unstructured.NestedString(cluster.Object, "status", "phase")
if dbStatus == "Stopped" {
return
}
fmt.Println(dbStatus)
notificationInfo := notification.Info{
DatabaseClusterName: backupName,
Namespace: namespace,
Status: status,
ExceptionType: "备份",
PerformanceType: "Backup",
NotificationType: "exception",
}
if _, ok := api.LastBackupStatusMap[backupName]; !ok {
message := notification.GetBackupMessage("exception", namespace, backupName, status, startTime, "")
if err := notification.SendFeishuNotification(message, api.FeishuWebhookURLMap["FeishuWebhookURLBackup"]); err != nil {
if err := notification.SendFeishuNotification(notificationInfo, message, api.FeishuWebhookURLMap["FeishuWebhookURLBackup"]); err != nil {
log.Printf("Error sending exception notification:%v", err)
}
} else {
api.LastBackupStatusMap[backupName] = status
}
//backupPolicyName, found, err := unstructured.NestedString(backup.Object, "spec", "backupPolicyName")
//if err != nil || !found {
// log.Printf("Unable to get %s backupPolicyName in ns %s:%v", backupName, namespace, err)
// return
//}
//handleBackupStatus(backupName, namespace, status, startTime, backupPolicyName)
}

//func handleBackupStatus(backupName, namespace, status, startTime, backupPolicyName string) {
// //if status == "Completed" {
// // handleBackupCompletion(backupName, namespace, status, startTime)
// // return
// //}
// //if CheckackupFailure(backupName, namespace, status, backupPolicyName) {
// // err := api.DynamicClient.Resource(backupGVR).Namespace(namespace).Delete(context.Background(), backupName, metav1.DeleteOptions{})
// // if err != nil {
// // log.Printf("Failed to delete%s in ns %s:%v", backupName, namespace, err)
// // }
// //}
//
//}

//func handleBackupCompletion(backupName, namespace, status, startTime string) {
// if _, ok := api.LastBackupStatusMap[backupName]; ok {
// message := notification.GetBackupMessage("recovery", namespace, backupName, status, startTime, "")
// if err := notification.SendFeishuNotification(message, api.FeishuWebhookURLMap["FeishuWebhookURLBackup"]); err != nil {
// log.Printf("Error sending recovery notification:%v", err)
// }
// delete(api.LastBackupStatusMap, backupName)
// delete(api.IsSendBackupStatusMap, backupName)
// }
//}
//
//func CheckackupFailure(backupName, namespace, status, backupPolicyName string) bool {
// if _, ok := api.LastBackupStatusMap[backupName]; !ok {
// api.LastBackupStatusMap[backupName] = status
// return false
// }
// if _, ok := api.IsSendBackupStatusMap[backupName]; ok {
// return false
// }
//
// if ok, _ := checkFailedBackup(backupPolicyName, namespace); ok {
// message := notification.GetBackupMessage("exception", namespace, backupName, "Failed", "", "")
// if err := notification.SendFeishuNotification(message, api.FeishuWebhookURLMap["FeishuWebhookURLBackup"]); err != nil {
// log.Printf("Error sending exception notification:%v", err)
// }
// return true
// }
// return false
//}
//
//func checkFailedBackup(backupPolicyName, namespace string) (bool, error) {
// databaseName := getPrefix(backupPolicyName)
// podList, err := api.ClientSet.CoreV1().Pods(namespace).List(context.Background(), metav1.ListOptions{})
// if err != nil {
// return false, err
// }
// for _, pod := range podList.Items {
// if strings.HasPrefix(pod.GetName(), databaseName) {
// return true, nil
// }
// }
// return false, nil
//}
//
//func getPrefix(backupPolicyName string) string {
// parts := strings.Split(backupPolicyName, "-")
// if len(parts) < 3 {
// return ""
// }
// return strings.Join(parts[:len(parts)-2], "-")
//}
func getPrefix(backupPolicyName string) string {
parts := strings.Split(backupPolicyName, "-")
if len(parts) < 3 {
return ""
}
return strings.Join(parts[:len(parts)-3], "-")
}
42 changes: 28 additions & 14 deletions service/exceptionmonitor/helper/monitor/database_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"strings"
"time"

"k8s.io/apimachinery/pkg/api/errors"

"github.com/labring/sealos/service/exceptionmonitor/api"
"github.com/labring/sealos/service/exceptionmonitor/helper/notification"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -35,13 +37,23 @@ var (

func DatabaseExceptionMonitor() {
for api.DatabaseMonitor {
checkDeletedDatabases()
if err := checkDatabases(api.ClusterNS); err != nil {
log.Printf("Failed to check databases: %v", err)
}
time.Sleep(5 * time.Minute)
}
}

func checkDeletedDatabases() {
for databaseName := range api.LastDatabaseClusterStatus {
cluster, err := api.DynamicClient.Resource(databaseClusterGVR).Namespace(api.DatabaseNamespaceMap[databaseName]).Get(context.Background(), databaseName, metav1.GetOptions{})
if cluster == nil && errors.IsNotFound(err) {
handleClusterRecovery(databaseName, "", "Deleted")
}
}
}

func checkDatabases(namespaces []string) error {
if api.MonitorType == api.MonitorTypeALL {
if err := checkDatabasesInNamespace(""); err != nil {
Expand Down Expand Up @@ -89,9 +101,10 @@ func processCluster(cluster metav1unstructured.Unstructured) {
case api.StatusUnknown:
if _, ok := api.LastDatabaseClusterStatus[databaseClusterName]; !ok {
api.LastDatabaseClusterStatus[databaseClusterName] = status
api.DatabaseNamespaceMap[databaseClusterName] = namespace
api.ExceptionDatabaseMap[databaseClusterName] = true
alertMessage, feishuWebHook := prepareAlertMessage(databaseClusterName, namespace, status, "", "status is empty", 0)
if err := sendAlert(alertMessage, feishuWebHook, databaseClusterName); err != nil {
alertMessage, feishuWebHook, notification := prepareAlertMessage(databaseClusterName, namespace, status, "", "status is empty", 0)
if err := sendAlert(alertMessage, feishuWebHook, notification); err != nil {
log.Printf("Failed to send feishu %s in ns %s: %v", databaseClusterName, namespace, err)
}
}
Expand All @@ -110,7 +123,7 @@ func handleClusterRecovery(databaseClusterName, namespace, status string) {
NotificationType: "recovery",
}
recoveryMessage := notification.GetNotificationMessage(notificationInfo)
if err := notification.SendFeishuNotification(recoveryMessage, api.FeishuWebHookMap[databaseClusterName]); err != nil {
if err := notification.SendFeishuNotification(notificationInfo, recoveryMessage, api.FeishuWebHookMap[databaseClusterName]); err != nil {
log.Printf("Error sending recovery notification: %v", err)
}
cleanClusterStatus(databaseClusterName)
Expand All @@ -122,11 +135,13 @@ func cleanClusterStatus(databaseClusterName string) {
delete(api.DiskFullNamespaceMap, databaseClusterName)
delete(api.FeishuWebHookMap, databaseClusterName)
delete(api.ExceptionDatabaseMap, databaseClusterName)
delete(api.DatabaseNamespaceMap, databaseClusterName)
}

func handleClusterException(databaseClusterName, namespace, databaseType, status string) {
if _, ok := api.LastDatabaseClusterStatus[databaseClusterName]; !ok && !api.DebtNamespaceMap[namespace] {
api.LastDatabaseClusterStatus[databaseClusterName] = status
api.DatabaseNamespaceMap[databaseClusterName] = namespace
api.ExceptionDatabaseMap[databaseClusterName] = true
if err := processClusterException(databaseClusterName, namespace, databaseType, status); err != nil {
log.Printf("Failed to process cluster %s exception in ns %s: %v", databaseClusterName, namespace, err)
Expand All @@ -146,9 +161,8 @@ func processClusterException(databaseClusterName, namespace, databaseType, statu
if err != nil {
return err
}

alertMessage, feishuWebHook := prepareAlertMessage(databaseClusterName, namespace, status, debtLevel, databaseEvents, maxUsage)
if err := sendAlert(alertMessage, feishuWebHook, databaseClusterName); err != nil {
alertMessage, feishuWebHook, notification := prepareAlertMessage(databaseClusterName, namespace, status, debtLevel, databaseEvents, maxUsage)
if err := sendAlert(alertMessage, feishuWebHook, notification); err != nil {
return err
}
} else {
Expand Down Expand Up @@ -183,7 +197,7 @@ func databaseQuotaExceptionFilter(databaseEvents string) bool {
return !strings.Contains(databaseEvents, api.ExceededQuotaException)
}

func prepareAlertMessage(databaseClusterName, namespace, status, debtLevel, databaseEvents string, maxUsage float64) (string, string) {
func prepareAlertMessage(databaseClusterName, namespace, status, debtLevel, databaseEvents string, maxUsage float64) (string, string, notification.Info) {
alertMessage, feishuWebHook := "", ""
notificationInfo := notification.Info{
DatabaseClusterName: databaseClusterName,
Expand All @@ -207,16 +221,16 @@ func prepareAlertMessage(databaseClusterName, namespace, status, debtLevel, data
feishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLOther"]
notificationInfo.Reason = "disk is full"
alertMessage = notification.GetNotificationMessage(notificationInfo)
notification.CreateNotification(namespace, databaseClusterName, status, "disk is full")
notification.CreateNotification(namespace, databaseClusterName, status, "disk is full", "磁盘满了")
}
api.DiskFullNamespaceMap[databaseClusterName] = true
}
return alertMessage, feishuWebHook
return alertMessage, feishuWebHook, notificationInfo
}

func sendAlert(alertMessage, feishuWebHook, databaseClusterName string) error {
api.FeishuWebHookMap[databaseClusterName] = feishuWebHook
return notification.SendFeishuNotification(alertMessage, feishuWebHook)
func sendAlert(alertMessage, feishuWebHook string, notificationInfo notification.Info) error {
api.FeishuWebHookMap[notificationInfo.DatabaseClusterName] = feishuWebHook
return notification.SendFeishuNotification(notificationInfo, alertMessage, feishuWebHook)
}

func notifyQuotaExceeded(databaseClusterName, namespace, status, debtLevel string) error {
Expand All @@ -230,6 +244,6 @@ func notifyQuotaExceeded(databaseClusterName, namespace, status, debtLevel strin
NotificationType: "exception",
}
alertMessage := notification.GetNotificationMessage(notificationInfo)
notification.CreateNotification(namespace, databaseClusterName, status, api.ExceededQuotaException)
return notification.SendFeishuNotification(alertMessage, api.FeishuWebhookURLMap["FeishuWebhookURLOther"])
notification.CreateNotification(namespace, databaseClusterName, status, api.ExceededQuotaException, "Quato满了")
return notification.SendFeishuNotification(notificationInfo, alertMessage, api.FeishuWebhookURLMap["FeishuWebhookURLOther"])
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func processUsage(usage float64, threshold float64, performanceType, UID string,
}
if usage >= threshold && !monitorMap[UID] {
alertMessage := notification.GetNotificationMessage(info)
if err := notification.SendFeishuNotification(alertMessage, api.FeishuWebhookURLMap["FeishuWebhookURLImportant"]); err != nil {
if err := notification.SendFeishuNotification(info, alertMessage, api.FeishuWebhookURLMap["FeishuWebhookURLImportant"]); err != nil {
log.Printf("Failed to send notification: %v", err)
}
monitorMap[UID] = true
Expand All @@ -132,7 +132,7 @@ func processUsage(usage float64, threshold float64, performanceType, UID string,
} else if usage < threshold && monitorMap[UID] {
info.NotificationType = "recovery"
alertMessage := notification.GetNotificationMessage(info)
if err := notification.SendFeishuNotification(alertMessage, api.FeishuWebhookURLMap["FeishuWebhookURLImportant"]); err != nil {
if err := notification.SendFeishuNotification(info, alertMessage, api.FeishuWebhookURLMap["FeishuWebhookURLImportant"]); err != nil {
log.Printf("Failed to send notification: %v", err)
}
delete(monitorMap, UID)
Expand Down
13 changes: 7 additions & 6 deletions service/exceptionmonitor/helper/notification/desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func randString(n int) (string, error) {
return string(b), nil
}

func CreateNotification(namespace, name, status, notificationMessage string) {
func CreateNotification(namespace, name, status, notificationMessage, zhNotificationMessage string) {
gvr := schema.GroupVersionResource{
Group: "notification.sealos.io",
Version: "v1",
Expand All @@ -40,7 +40,8 @@ func CreateNotification(namespace, name, status, notificationMessage string) {

randomSuffix, _ := randString(5)
now := time.Now().UTC().Unix()
message := fmt.Sprintf("database : %s is %s. Please check in time.", name, status)
message := fmt.Sprintf("Because %s , Database %s current status : %s , Please check in time.", notificationMessage, name, status)
zhMessage := fmt.Sprintf("因为 %s , 数据库 %s 当前状态 : %s , 请及时检查.", zhNotificationMessage, name, status)
notification := &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "notification.sealos.io/v1",
Expand All @@ -56,10 +57,10 @@ func CreateNotification(namespace, name, status, notificationMessage string) {
"importance": "High",
"desktopPopup": true,
"i18ns": map[string]interface{}{
"en": map[string]interface{}{
"title": "Database Exception",
"message": notificationMessage,
"from": "Database Exception",
"zh": map[string]interface{}{
"title": "数据库异常告警",
"message": zhMessage,
"from": "数据库异常",
},
},
},
Expand Down
Loading

0 comments on commit 525b4dd

Please sign in to comment.