mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-30 17:13:08 +08:00
fix(monitor): monitor notify international and 3.6 bugfix
1.修复项目下无法查看报警记录 2.修复报警策略切换所属范围signature失败 3.国际化问题处理
This commit is contained in:
@@ -6,4 +6,4 @@
|
||||
资源数量:{{len .matches}}
|
||||
资源名称:{{.resource_name}}
|
||||
|
||||
详情地址: {{.web_url}}/commonalerts
|
||||
详情地址: {{.web_url}}
|
||||
+1
-1
@@ -92,7 +92,7 @@
|
||||
</table>
|
||||
<table class="table" style="padding-top: 6px; padding-bottom: 10px;">
|
||||
<tr>
|
||||
<td style="padding-left: 20px; font-size: 14px;">若要查看详情信息,<a class="link" target="_blank" href="{{.web_url}}/commonalerts
|
||||
<td style="padding-left: 20px; font-size: 14px;">若要查看详情信息,<a class="link" target="_blank" href="{{.web_url}}
|
||||
">请登录平台进行查看</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -6,4 +6,4 @@ TriggerCondition: {{.description | unescaped}}
|
||||
ResourceCount: {{len .matches}}
|
||||
ResourceName: {{.resource_name}}
|
||||
|
||||
WebUrl: {{.web_url}}/commonalerts
|
||||
WebUrl: {{.web_url}}
|
||||
|
||||
+3
-3
@@ -33,7 +33,7 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
.td {
|
||||
width: 80px;
|
||||
width: 120px;
|
||||
padding-left: 20px;
|
||||
height: 35px;
|
||||
font-weight: 400;
|
||||
@@ -92,8 +92,8 @@
|
||||
</table>
|
||||
<table class="table" style="padding-top: 6px; padding-bottom: 10px;">
|
||||
<tr>
|
||||
<td style="padding-left: 20px; font-size: 14px;">To view details,<a class="link" target="_blank" href="{{.web_url}}/commonalerts
|
||||
">Please log in to the platform to view</a></td>
|
||||
<td style="padding-left: 20px; font-size: 14px;">To view details,<a class="link" target="_blank" href="{{.web_url}}
|
||||
">Please login to the platform to view</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table border="0" cellspacing="0" cellpadding="0" class="table pb-3">
|
||||
|
||||
@@ -128,7 +128,7 @@ func (c *EvalContext) GetCallbackURLPrefix() string {
|
||||
return ""
|
||||
}
|
||||
url, _ := config.GetString("config", "default", "api_server")
|
||||
return url
|
||||
return url + "/alertrecord"
|
||||
}
|
||||
|
||||
// GetNewState returns the new state from the alert rule evaluation.
|
||||
@@ -207,7 +207,11 @@ func (c *EvalContext) GetNotificationTemplateConfig() monitor.NotificationTempla
|
||||
|
||||
func (c *EvalContext) GetEvalMatches() []monitor.EvalMatch {
|
||||
ret := make([]monitor.EvalMatch, 0)
|
||||
for _, c := range c.EvalMatches {
|
||||
matches := c.EvalMatches
|
||||
if !c.Firing {
|
||||
matches = c.AlertOkEvalMatches
|
||||
}
|
||||
for _, c := range matches {
|
||||
ret = append(ret, monitor.EvalMatch{
|
||||
Condition: c.Condition,
|
||||
Value: c.Value,
|
||||
|
||||
@@ -170,10 +170,23 @@ func (n *notificationService) createAlertRecordWhenNotify(evalCtx *EvalContext)
|
||||
}
|
||||
recordCreateInput.ResType = recordCreateInput.AlertRule.ResType
|
||||
createData := recordCreateInput.JSON(recordCreateInput)
|
||||
record, err := db.DoCreate(models.AlertRecordManager, evalCtx.Ctx, evalCtx.UserCred, jsonutils.NewDict(), createData, evalCtx.UserCred)
|
||||
alert, _ := models.CommonAlertManager.GetAlert(evalCtx.Rule.Id)
|
||||
log.Errorf("alert:%v", jsonutils.Marshal(alert))
|
||||
record, err := db.DoCreate(models.AlertRecordManager, evalCtx.Ctx, evalCtx.UserCred, jsonutils.NewDict(),
|
||||
createData, evalCtx.UserCred)
|
||||
if err != nil {
|
||||
log.Errorf("create alert record err:%v", err)
|
||||
}
|
||||
alertData := jsonutils.Marshal(alert)
|
||||
alertData.(*jsonutils.JSONDict).Set("project_id", jsonutils.NewString(alert.GetProjectId()))
|
||||
db.PerformSetScope(evalCtx.Ctx, record.(*models.SAlertRecord), evalCtx.UserCred, alertData)
|
||||
dbMatches, _ := record.(*models.SAlertRecord).GetEvalData()
|
||||
if !evalCtx.Firing {
|
||||
evalCtx.AlertOkEvalMatches = make([]*monitor.EvalMatch, len(dbMatches))
|
||||
for i, _ := range dbMatches {
|
||||
evalCtx.AlertOkEvalMatches[i] = &dbMatches[i]
|
||||
}
|
||||
}
|
||||
record.PostCreate(evalCtx.Ctx, evalCtx.UserCred, evalCtx.UserCred, nil, createData)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,9 @@ package notifiers
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -32,6 +34,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/i18n"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/notify"
|
||||
"yunion.io/x/onecloud/pkg/monitor/alerting"
|
||||
"yunion.io/x/onecloud/pkg/monitor/alerting/notifiers/templates"
|
||||
@@ -39,7 +42,18 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/monitor/options"
|
||||
)
|
||||
|
||||
const (
|
||||
SUFFIX = "onecloudNotifier"
|
||||
)
|
||||
|
||||
var (
|
||||
i18nTable = i18n.Table{}
|
||||
i18nEnTry = i18n.NewTableEntry().EN("en").CN("cn")
|
||||
)
|
||||
|
||||
func init() {
|
||||
i18nTable.Set(SUFFIX, i18nEnTry)
|
||||
|
||||
alerting.RegisterNotifier(&alerting.NotifierPlugin{
|
||||
Type: monitor.AlertNotificationTypeOneCloud,
|
||||
Factory: newOneCloudNotifier,
|
||||
@@ -153,16 +167,42 @@ func GetNotifyTemplateConfigOfEN(ctx *alerting.EvalContext) monitor.Notification
|
||||
// Notify sends the alert notification.
|
||||
func (oc *OneCloudNotifier) Notify(ctx *alerting.EvalContext, _ jsonutils.JSONObject) error {
|
||||
log.Infof("Sending alert notification %s to onecloud", ctx.GetRuleTitle())
|
||||
oc.Ctx = i18n.WithLangTag(oc.Ctx, language.Chinese)
|
||||
langIdsMap, err := GetUserLangIdsMap(oc.Setting.UserIds)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "OneCloudNotifier getIds:%s userLang err", oc.Setting.UserIds)
|
||||
}
|
||||
langNotifyGroup, _ := errgroup.WithContext(ctx.Ctx)
|
||||
for lang, _ := range langIdsMap {
|
||||
ids := langIdsMap[lang]
|
||||
langTag, _ := language.Parse(lang)
|
||||
langStr := i18nTable.LookupByLang(langTag, SUFFIX)
|
||||
langContext := i18n.WithLangTag(context.Background(), getLangBystr(langStr))
|
||||
langNotifyGroup.Go(func() error {
|
||||
return oc.notifyByContextLang(langContext, ctx, ids)
|
||||
})
|
||||
}
|
||||
return langNotifyGroup.Wait()
|
||||
}
|
||||
|
||||
func getLangBystr(str string) language.Tag {
|
||||
for lang, val := range i18nEnTry {
|
||||
if val == str {
|
||||
return lang
|
||||
}
|
||||
}
|
||||
return language.English
|
||||
}
|
||||
|
||||
func (oc *OneCloudNotifier) notifyByContextLang(ctx context.Context, evalCtx *alerting.EvalContext, uids []string) error {
|
||||
var config monitor.NotificationTemplateConfig
|
||||
lang := i18n.Lang(oc.Ctx)
|
||||
lang := i18n.Lang(ctx)
|
||||
switch lang {
|
||||
case language.English:
|
||||
config = GetNotifyTemplateConfigOfEN(ctx)
|
||||
config = GetNotifyTemplateConfigOfEN(evalCtx)
|
||||
default:
|
||||
config = GetNotifyTemplateConfig(ctx)
|
||||
config = GetNotifyTemplateConfig(evalCtx)
|
||||
}
|
||||
oc.filterMatchTagsForConfig(&config)
|
||||
oc.filterMatchTagsForConfig(&config, ctx)
|
||||
|
||||
contentConfig := oc.buildContent(config)
|
||||
|
||||
@@ -179,7 +219,7 @@ func (oc *OneCloudNotifier) Notify(ctx *alerting.EvalContext, _ jsonutils.JSONOb
|
||||
}
|
||||
|
||||
msg := notify.SNotifyMessage{
|
||||
Uid: oc.Setting.UserIds,
|
||||
Uid: uids,
|
||||
ContactType: notify.TNotifyChannel(oc.Setting.Channel),
|
||||
Topic: config.Title,
|
||||
Priority: notify.TNotifyPriority(config.Priority),
|
||||
@@ -192,12 +232,36 @@ func (oc *OneCloudNotifier) Notify(ctx *alerting.EvalContext, _ jsonutils.JSONOb
|
||||
return sendImp.send()
|
||||
}
|
||||
|
||||
func GetUserLangIdsMap(ids []string) (map[string][]string, error) {
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
langIdsMap := make(map[string][]string)
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("filter", jsonutils.NewString(fmt.Sprintf("id.in(%s)", strings.Join(ids, ","))))
|
||||
params.Set("details", jsonutils.JSONFalse)
|
||||
params.Set("scope", jsonutils.NewString("system"))
|
||||
params.Set("system", jsonutils.JSONTrue)
|
||||
ret, err := modules.UsersV3.List(session, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range ret.Data {
|
||||
id, _ := ret.Data[i].GetString("id")
|
||||
langStr, _ := ret.Data[i].GetString("lang")
|
||||
if _, ok := langIdsMap[langStr]; ok {
|
||||
langIdsMap[langStr] = append(langIdsMap[langStr], id)
|
||||
continue
|
||||
}
|
||||
langIdsMap[langStr] = []string{id}
|
||||
}
|
||||
return langIdsMap, nil
|
||||
}
|
||||
|
||||
var (
|
||||
companyInfo models.SCompanyInfo
|
||||
)
|
||||
|
||||
func (oc *OneCloudNotifier) filterMatchTagsForConfig(config *monitor.NotificationTemplateConfig) {
|
||||
sCompanyInfo, err := models.GetCompanyInfo(oc.Ctx)
|
||||
func (oc *OneCloudNotifier) filterMatchTagsForConfig(config *monitor.NotificationTemplateConfig, ctx context.Context) {
|
||||
sCompanyInfo, err := models.GetCompanyInfo(ctx)
|
||||
if err != nil {
|
||||
log.Errorf("GetCompanyInfo error:%#v", err)
|
||||
return
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
@@ -108,45 +107,6 @@ func (manager *SAlertRecordManager) ListItemFilter(
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (man *SAlertRecordManager) CustomizeFilterList(
|
||||
ctx context.Context, q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential, query jsonutils.JSONObject) (
|
||||
*db.CustomizeListFilters, error) {
|
||||
filters := db.NewCustomizeListFilters()
|
||||
input := new(monitor.AlertRecordListInput)
|
||||
if err := query.Unmarshal(input); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wrapF := func(f func(obj *SAlertRecord) (bool, error)) func(object jsonutils.JSONObject) (bool, error) {
|
||||
return func(data jsonutils.JSONObject) (bool, error) {
|
||||
id, err := data.GetString("id")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
obj, err := man.GetAlertRecord(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return f(obj)
|
||||
}
|
||||
}
|
||||
|
||||
if len(input.ResType) != 0 {
|
||||
mF := func(obj *SAlertRecord) (bool, error) {
|
||||
rule := new(monitor.AlertRecordRule)
|
||||
if err := obj.AlertRule.Unmarshal(rule); err != nil {
|
||||
return false, errors.Wrapf(err, "alert %s unmarshal", obj.GetId())
|
||||
}
|
||||
if ok, _ := utils.InStringArray(rule.ResType, input.ResType); ok {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
filters.Append(wrapF(mF))
|
||||
}
|
||||
return filters, nil
|
||||
}
|
||||
|
||||
func (man *SAlertRecordManager) GetAlertRecord(id string) (*SAlertRecord, error) {
|
||||
obj, err := man.FetchById(id)
|
||||
if err != nil {
|
||||
@@ -251,6 +211,10 @@ func (record *SAlertRecord) CustomizeCreate(
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) error {
|
||||
err := record.SMonitorScopedResource.CustomizeCreate(ctx, userCred, ownerId, query, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
obj, err := db.NewModelObject(AlertRecordManager)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "NewModelObject %s", AlertRecordManager.Keyword())
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
@@ -20,6 +22,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/hostman/hostinfo/hostconsts"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/i18n"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
@@ -36,7 +39,7 @@ const (
|
||||
CommonAlertMetadataPointStr = "point_str"
|
||||
CommonAlertMetadataName = "meta_name"
|
||||
|
||||
COMPANY_COPYRIGHT_ONECLOUD = "北京云联万维技术有限公司"
|
||||
COMPANY_COPYRIGHT_ONECLOUD = "云联"
|
||||
BRAND_ONECLOUD_NAME_CN = "云联壹云"
|
||||
BRAND_ONECLOUD_NAME_EN = "YunionCloud"
|
||||
)
|
||||
@@ -1101,13 +1104,13 @@ func GetCompanyInfo(ctx context.Context) (SCompanyInfo, error) {
|
||||
return SCompanyInfo{}, err
|
||||
}
|
||||
if strings.Contains(info.Copyright, COMPANY_COPYRIGHT_ONECLOUD) {
|
||||
//lang := i18n.Lang(ctx)
|
||||
//switch lang {
|
||||
//case language.English:
|
||||
// info.Name = BRAND_ONECLOUD_NAME_EN
|
||||
//default:
|
||||
//}
|
||||
info.Name = BRAND_ONECLOUD_NAME_CN
|
||||
lang := i18n.Lang(ctx)
|
||||
switch lang {
|
||||
case language.English:
|
||||
info.Name = BRAND_ONECLOUD_NAME_EN
|
||||
default:
|
||||
info.Name = BRAND_ONECLOUD_NAME_CN
|
||||
}
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ func ValidateQuerySignature(input jsonutils.JSONObject) error {
|
||||
return errors.Wrap(err, "get signature")
|
||||
}
|
||||
if signature != digestQuerySignature(data) {
|
||||
|
||||
return httperrors.NewBadRequestError("signature error")
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -190,7 +190,9 @@ func (self *SUnifiedMonitorManager) AllowPerformQuery(ctx context.Context, userC
|
||||
}
|
||||
|
||||
func (self *SUnifiedMonitorManager) PerformQuery(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if err := ValidateQuerySignature(data); err != nil {
|
||||
tmp := jsonutils.DeepCopy(data)
|
||||
self.handleDataPreSignature(tmp)
|
||||
if err := ValidateQuerySignature(tmp); err != nil {
|
||||
return nil, errors.Wrap(err, "ValidateQuerySignature")
|
||||
}
|
||||
inputQuery := new(monitor.MetricInputQuery)
|
||||
@@ -233,6 +235,25 @@ func (self *SUnifiedMonitorManager) PerformQuery(ctx context.Context, userCred m
|
||||
return jsonutils.Marshal(rtn), nil
|
||||
}
|
||||
|
||||
func (self *SUnifiedMonitorManager) handleDataPreSignature(data jsonutils.JSONObject) {
|
||||
scope, _ := data.GetString("scope")
|
||||
switch scope {
|
||||
case "system":
|
||||
case "domain":
|
||||
domain, err := data.GetString("project_domain")
|
||||
if err == nil {
|
||||
data.(*jsonutils.JSONDict).Remove("project_domain")
|
||||
data.(*jsonutils.JSONDict).Set("domain_id", jsonutils.NewString(domain))
|
||||
}
|
||||
default:
|
||||
project, err := data.GetString("project")
|
||||
if err == nil {
|
||||
data.(*jsonutils.JSONDict).Remove("project")
|
||||
data.(*jsonutils.JSONDict).Set("project_id", jsonutils.NewString(project))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func doQuery(query monitor.MetricInputQuery) (*mq.Metrics, error) {
|
||||
conditions := make([]*monitor.AlertCondition, 0)
|
||||
for _, q := range query.MetricQuery {
|
||||
|
||||
Reference in New Issue
Block a user