Commit de712f7c authored by 黄智's avatar 黄智

Merge remote-tracking branch 'origin/dev' into dev

parents 847da67f b4a16368
...@@ -26,11 +26,13 @@ require ( ...@@ -26,11 +26,13 @@ require (
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.66.0 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.66.0
github.com/prometheus/alertmanager v0.25.0 github.com/prometheus/alertmanager v0.25.0
github.com/robfig/cron v1.2.0 github.com/robfig/cron v1.2.0
github.com/robfig/cron/v3 v3.0.1
github.com/satori/go.uuid v1.2.0 github.com/satori/go.uuid v1.2.0
github.com/spf13/cast v1.5.0 github.com/spf13/cast v1.5.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/tealeg/xlsx v1.0.5 github.com/tealeg/xlsx v1.0.5
github.com/thoas/go-funk v0.9.3 github.com/thoas/go-funk v0.9.3
github.com/tidwall/gjson v1.16.0
github.com/valyala/fasthttp v1.47.0 github.com/valyala/fasthttp v1.47.0
github.com/wanghuiyt/ding v0.0.2 github.com/wanghuiyt/ding v0.0.2
go.uber.org/zap v1.24.0 go.uber.org/zap v1.24.0
...@@ -107,6 +109,8 @@ require ( ...@@ -107,6 +109,8 @@ require (
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect
github.com/sirupsen/logrus v1.9.2 // indirect github.com/sirupsen/logrus v1.9.2 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.9 // indirect github.com/ugorji/go/codec v1.2.9 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
......
...@@ -579,6 +579,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O ...@@ -579,6 +579,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
...@@ -645,6 +647,12 @@ github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE= ...@@ -645,6 +647,12 @@ github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM= github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw= github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw=
github.com/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= github.com/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg=
github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
......
...@@ -3,15 +3,15 @@ package entity ...@@ -3,15 +3,15 @@ package entity
import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
type AlertClass struct { type AlertClass struct {
ClassId int `json:"class_id" xorm:"'class_id' pk autoincr"` // 主键id ClassId int `json:"class_id" xorm:"'class_id' pk autoincr"` // 主键id
ClassName string `json:"class_name" xorm:"'class_name'"` // 分类名称 ClassName string `json:"class_name" xorm:"'class_name'"` // 分类名称
ParentId int `json:"parent_id" xorm:"'parent_id'"` // 父级id ParentId int `json:"parent_id" xorm:"'parent_id'"` // 父级id
SortOrder int `json:"sort_order" xorm:"'sort_order'"` // 排序 SortOrder int `json:"sort_order" xorm:"'sort_order'"` // 排序
SourceFrom int `json:"source_from" xorm:"source_from"` // 数据来源 1:默认 2:自定义 Source int `json:"source" xorm:"source"` // 数据来源 1:默认 2:自定义
CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人 CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人
CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间 CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间
UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人 UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人
UpdatedAt jsontime.Time `json:"updated_at" xorm:"'updated_at'"` // 更新时间 UpdatedAt jsontime.Time `json:"updated_at" xorm:"'updated_at'"` // 更新时间
} }
func (m *AlertClass) TableName() string { func (m *AlertClass) TableName() string {
......
...@@ -21,25 +21,9 @@ type AlertArray struct { ...@@ -21,25 +21,9 @@ type AlertArray struct {
TotalCount int `json:"total_count"` // 总预警数 TotalCount int `json:"total_count"` // 总预警数
} }
type RiskLevelDistribution struct { type AlertDistribution struct {
Name string `json:"name"` // 名称 Name string `json:"name"` // 名称
//RiskLevel int `json:"risk_level"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险 Value int `json:"value"`
//Percentage string `json:"percentage"` // 百分比
Value int `json:"value"`
}
type AlertStatusDistribution struct {
Name string `json:"name"` // 名称
//Status int `json:"status"` // 状态,1:已恢复 2:未恢复 3:已关闭
//Percentage string `json:"percentage"` // 百分比
Value int `json:"value"`
}
type AlertClassDistribution struct {
Name string `json:"name"` // 名称
//ClassId int `json:"class_id"` // 预警分类id
//Percentage string `json:"percentage"` // 百分比
Value int `json:"value"`
} }
type AlertFrequencyDistribution struct { type AlertFrequencyDistribution struct {
......
package entity
import (
"github.com/prometheus/alertmanager/notify/webhook"
)
type Message webhook.Message
...@@ -13,7 +13,7 @@ type MetricConfig struct { ...@@ -13,7 +13,7 @@ type MetricConfig struct {
CheckPeriod int `json:"check_period" xorm:"'check_period'"` // 检查周期 单位:分钟 CheckPeriod int `json:"check_period" xorm:"'check_period'"` // 检查周期 单位:分钟
IsEnabled int `json:"is_enabled" xorm:"'is_enabled'"` // 是否开启 1:是 2:否 IsEnabled int `json:"is_enabled" xorm:"'is_enabled'"` // 是否开启 1:是 2:否
AlertRuleType string `json:"alert_rule_type" xorm:"'alert_rule_type'"` // 预警规则类型 关联字典表 AlertRuleType string `json:"alert_rule_type" xorm:"'alert_rule_type'"` // 预警规则类型 关联字典表
SourceFrom int `json:"source_from" xorm:"source_from"` // 数据来源 1:默认 2:自定义 Source int `json:"source" xorm:"source"` // 数据来源 1:默认 2:自定义
CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人 CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人
CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间 CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间
UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人 UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人
......
...@@ -25,9 +25,9 @@ type SystemUser struct { ...@@ -25,9 +25,9 @@ type SystemUser struct {
} }
type SystemUserInfo struct { type SystemUserInfo struct {
Id int `json:"id" xorm:"pk autoincr" ` // id Id int `json:"id" xorm:"pk autoincr"` // id
Name string `json:"name" ` // 名称 Name string `json:"name" ` // 名称
SystemAccount string `json:"system_account" ` // 账号 SystemAccount string `json:"system_account"` // 账号
OrganizationId string `json:"organization_id" xorm:"organization_id"` // 所属组织 OrganizationId string `json:"organization_id" xorm:"organization_id"` // 所属组织
Password string `json:"password,omitempty"` // 密码 Password string `json:"password,omitempty"` // 密码
State int `json:"state" xorm:"state"` // 状态0禁用1启用 State int `json:"state" xorm:"state"` // 状态0禁用1启用
......
package entity package entity
import "time" import (
"time"
)
type WorkOrder struct { type WorkOrder struct {
Id int `json:"id" xorm:"pk autoincr" ` // id Id int `json:"id" xorm:"pk autoincr" ` // id
OrderName string `json:"order_name" xorm:"order_name"` // 工单名称 OrderName string `json:"order_name" xorm:"order_name"` // 工单名称
OrderLevel int `json:"order_level" xorm:"order_level"` // 工单等级(1紧急任务 2重要任务 3一般任务) OrderLevel int `json:"order_level" xorm:"order_level"` // 工单等级(1紧急任务 2重要任务 3一般任务)
OrderDesc string `json:"order_desc" xorm:"order_desc"` // 工单描述 OrderDesc string `json:"order_desc" xorm:"order_desc"` // 工单描述
OrderCnt int `json:"order_cnt" xorm:"order_cnt"` // 实例工单数 //OrderCnt int `json:"order_cnt" xorm:"order_cnt"` // 实例工单数
PushObj string `json:"push_obj" xorm:"push_obj"` // 推送对象 PushObj string `json:"push_obj" xorm:"push_obj"` // 推送对象
TimingType int `json:"timing_type" xorm:"timing_type"` // 定时类型(1手动下发 2按周 3自定义时间) TimingType int `json:"timing_type" xorm:"timing_type"` // 定时类型(1手动下发 2按周 3自定义时间)
TimingRule string `json:"timing_rule" xorm:"timing_rule"` // 定时规则 TimingRule string `json:"timing_rule" xorm:"timing_rule"` // 定时规则
......
...@@ -9,14 +9,15 @@ type DetailAlert struct { ...@@ -9,14 +9,15 @@ type DetailAlert struct {
} }
type ListAlert struct { type ListAlert struct {
Id int `json:"id" form:"id"` Id int `json:"id" form:"id"`
Ids []int `json:"ids" form:"ids"` // 预警ids Ids []int `json:"ids" form:"ids"` // 预警ids
AlertRulesId string `json:"alert_rules_id" form:"alert_rules_id"` // 告警规则id AlertRulesId string `json:"alert_rules_id" form:"alert_rules_id"` // 告警规则id
RiskLevel int `json:"risk_level" form:"risk_level" binding:"omitempty,oneof=1 2 3 4"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险 RiskLevel int `json:"risk_level" form:"risk_level" binding:"omitempty,oneof=1 2 3 4"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险
Status int `json:"status" form:"status" binding:"omitempty,oneof=1 2 3"` // 状态,1:已恢复 2:未恢复 3:已关闭 Status int `json:"status" form:"status" binding:"omitempty,oneof=1 2 3"` // 状态,1:已恢复 2:未恢复 3:已关闭
Keyword string `json:"keyword" form:"keyword"` // 预警点/分类/指标 Keyword string `json:"keyword" form:"keyword"` // 预警点/分类/指标
StartTime string `json:"start_time" form:"start_time" binding:"omitempty,datetime=2006-01-02 15:04:05"` SystemAccount string `json:"system_account" form:"system_account"` // 预警推送用户
EndTime string `json:"end_time" form:"end_time" binding:"omitempty,datetime=2006-01-02 15:04:05"` StartTime string `json:"start_time" form:"start_time" binding:"omitempty,datetime=2006-01-02 15:04:05"`
EndTime string `json:"end_time" form:"end_time" binding:"omitempty,datetime=2006-01-02 15:04:05"`
Pagination Pagination
} }
......
package request package request
type AddAlertClass struct { type AddAlertClass struct {
ClassName string `json:"class_name" form:"class_name" binding:"required"` ClassName string `json:"class_name" form:"class_name" binding:"required"`
ParentId int `json:"parent_id" form:"parent_id" binding:"omitempty,oneof=0 1"` ParentId int `json:"parent_id" form:"parent_id"`
SortOrder int `json:"sort_order" form:"sort_order"` SortOrder int `json:"sort_order" form:"sort_order"`
SourceFrom int `json:"source_from" form:"source_from" binding:"omitempty,oneof=1 2"` // 数据来源 1:默认 2:自定义 Source int `json:"source" form:"source" binding:"omitempty,oneof=1 2"` // 数据来源 1:默认 2:自定义
} }
type UpdateAlertClass struct { type UpdateAlertClass struct {
ClassId int `json:"class_id" form:"class_id" binding:"required"` ClassId int `json:"class_id" form:"class_id" binding:"required"`
ParentId int `json:"parent_id" form:"parent_id"`
ClassName string `json:"class_name" form:"class_name" binding:"required"` ClassName string `json:"class_name" form:"class_name" binding:"required"`
} }
......
...@@ -33,7 +33,7 @@ type UpdateAlertRules struct { ...@@ -33,7 +33,7 @@ type UpdateAlertRules struct {
ClassId int `json:"class_id" form:"class_id" binding:"required_if=DetectionType 1"` // 预警对象id(级联:预警分类/预警对象) ClassId int `json:"class_id" form:"class_id" binding:"required_if=DetectionType 1"` // 预警对象id(级联:预警分类/预警对象)
ClassParentName string `json:"class_parent_name" form:"class_parent_name" binding:"required_if=DetectionType 2"` // 预警分类名称 ClassParentName string `json:"class_parent_name" form:"class_parent_name" binding:"required_if=DetectionType 2"` // 预警分类名称
ClassName string `json:"class_name" form:"class_name" binding:"required_if=DetectionType 2"` // 预警对象名称 ClassName string `json:"class_name" form:"class_name" binding:"required_if=DetectionType 2"` // 预警对象名称
MetricConfigId string `json:"metric_config_id" form:"'metric_config_id'" binding:"required_if=DetectionType 1"` // 预警指标id MetricConfigId string `json:"metric_config_id" form:"metric_config_id" binding:"required_if=DetectionType 1"` // 预警指标id
MetricConfigName string `json:"metric_config_name" form:"metric_config_name" binding:"required_if=DetectionType 2"` // 预警指标名称(映射entity.MetricConfig.MetricName) MetricConfigName string `json:"metric_config_name" form:"metric_config_name" binding:"required_if=DetectionType 2"` // 预警指标名称(映射entity.MetricConfig.MetricName)
Expr string `json:"expr" form:"expr" binding:"required_if=DetectionType 2"` // 指标表达式(PromQL语句) Expr string `json:"expr" form:"expr" binding:"required_if=DetectionType 2"` // 指标表达式(PromQL语句)
AlertCondition []entity.AlertCondition `json:"alert_condition" form:"alert_condition" binding:"required"` // 预警规则 字典值 AlertCondition []entity.AlertCondition `json:"alert_condition" form:"alert_condition" binding:"required"` // 预警规则 字典值
......
...@@ -10,7 +10,7 @@ type AddAlertWebhook struct { ...@@ -10,7 +10,7 @@ type AddAlertWebhook struct {
ClassId int `json:"class_id" form:"class_id" binding:"required_if=DetectionType 1"` // 预警对象id(级联:预警分类/预警对象) ClassId int `json:"class_id" form:"class_id" binding:"required_if=DetectionType 1"` // 预警对象id(级联:预警分类/预警对象)
ClassParentName string `json:"class_parent_name" form:"class_parent_name" binding:"required_if=DetectionType 2"` // 预警分类名称 ClassParentName string `json:"class_parent_name" form:"class_parent_name" binding:"required_if=DetectionType 2"` // 预警分类名称
ClassName string `json:"class_name" form:"class_name" binding:"required_if=DetectionType 2"` // 预警对象名称 ClassName string `json:"class_name" form:"class_name" binding:"required_if=DetectionType 2"` // 预警对象名称
MetricConfigId string `json:"metric_config_id" form:"'metric_config_id'" binding:"required_if=DetectionType 1"` // 预警指标id MetricConfigId string `json:"metric_config_id" form:"metric_config_id" binding:"required_if=DetectionType 1"` // 预警指标id
MetricConfigName string `json:"metric_config_name" form:"metric_config_name" binding:"required_if=DetectionType 2"` // 预警指标名称(映射entity.MetricConfig.MetricName) MetricConfigName string `json:"metric_config_name" form:"metric_config_name" binding:"required_if=DetectionType 2"` // 预警指标名称(映射entity.MetricConfig.MetricName)
Expr string `json:"expr" form:"expr" binding:"required_if=DetectionType 2"` // 指标表达式(PromQL语句) Expr string `json:"expr" form:"expr" binding:"required_if=DetectionType 2"` // 指标表达式(PromQL语句)
AlertCondition []entity.AlertCondition `json:"alert_condition" form:"alert_condition" binding:"required,dive"` // 预警规则 字典值 AlertCondition []entity.AlertCondition `json:"alert_condition" form:"alert_condition" binding:"required,dive"` // 预警规则 字典值
......
...@@ -12,7 +12,7 @@ type AddMetricConfig struct { ...@@ -12,7 +12,7 @@ type AddMetricConfig struct {
CheckPeriod int `json:"check_period" form:"check_period" binding:"oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟 CheckPeriod int `json:"check_period" form:"check_period" binding:"oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟
IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"omitempty,oneof=1 2"` // 是否开启 1:是 2:否 IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"omitempty,oneof=1 2"` // 是否开启 1:是 2:否
AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type" binding:"required"` // 预警规则类型 关联字典表 AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type" binding:"required"` // 预警规则类型 关联字典表
SourceFrom int `json:"source_from" form:"source_from" binding:"omitempty,oneof=1 2"` // 数据来源 1:默认 2:自定义 Source int `json:"source" form:"source" binding:"omitempty,oneof=1 2"` // 数据来源(自定义为非正常数据) 1:默认 2:自定义
} }
type UpdateMetricConfig struct { type UpdateMetricConfig struct {
...@@ -26,7 +26,7 @@ type UpdateMetricConfig struct { ...@@ -26,7 +26,7 @@ type UpdateMetricConfig struct {
CheckPeriod int `json:"check_period" form:"check_period" binding:"omitempty,oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟 CheckPeriod int `json:"check_period" form:"check_period" binding:"omitempty,oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟
IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"omitempty,oneof=1 2"` // 是否开启 1:是 2:否 IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"omitempty,oneof=1 2"` // 是否开启 1:是 2:否
AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type"` // 预警规则类型 关联字典表 AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type"` // 预警规则类型 关联字典表
SourceFrom int `json:"source_from" form:"source_from" binding:"omitempty,oneof=1 2"` // 数据来源 1:默认 2:自定义 Source int `json:"source" form:"source" binding:"omitempty,oneof=1 2"` // 数据来源 1:默认 2:自定义
} }
type DeleteMetricConfig struct { type DeleteMetricConfig struct {
......
package request package request
type AddWorkOrderReq struct { type AddWorkOrderReq struct {
IsPush int `json:"is_push"` // 是否立刻下发(0否 1是) IsPush int `json:"is_push" binding:"oneof=0 1"` // 是否立刻下发(0否 1是)
OrderName string `json:"order_name" binding:"required"` // 工单名称 OrderName string `json:"order_name" binding:"required"` // 工单名称
OrderLevel int `json:"order_level" binding:"oneof=1 2 3"` // 工单等级(1紧急任务 2重要任务 3一般任务) OrderLevel int `json:"order_level" binding:"oneof=1 2 3"` // 工单等级(1紧急任务 2重要任务 3一般任务)
OrderDesc string `json:"order_desc" binding:"required"` // 工单描述 OrderDesc string `json:"order_desc" binding:"required"` // 工单描述
...@@ -36,7 +36,7 @@ type TimingCustom struct { ...@@ -36,7 +36,7 @@ type TimingCustom struct {
} }
type EditWorkOrderReq struct { type EditWorkOrderReq struct {
IsPush int `json:"is_push" binding:"required"` // 是否立刻下发(0否 1是) IsPush int `json:"is_push" binding:"oneof=0 1"` // 是否立刻下发(0否 1是)
Id int `json:"id" binding:"required"` // 主键id Id int `json:"id" binding:"required"` // 主键id
OrderLevel int `json:"order_level" binding:"oneof=1 2 3"` // 工单等级(1紧急任务 2重要任务 3一般任务) OrderLevel int `json:"order_level" binding:"oneof=1 2 3"` // 工单等级(1紧急任务 2重要任务 3一般任务)
OrderDesc string `json:"order_desc" binding:"required"` // 工单描述 OrderDesc string `json:"order_desc" binding:"required"` // 工单描述
......
...@@ -62,3 +62,46 @@ type Hits struct { ...@@ -62,3 +62,46 @@ type Hits struct {
MaxScore float64 `json:"max_score"` MaxScore float64 `json:"max_score"`
Hits []SubHits `json:"hits"` Hits []SubHits `json:"hits"`
} }
type AggAlertOverview struct {
Group struct {
DocCountErrorUpperBound int `json:"doc_count_error_upper_bound"`
SumOtherDocCount int `json:"sum_other_doc_count"`
Buckets []struct {
Key int `json:"key"`
DocCount int `json:"doc_count"`
Group struct {
DocCountErrorUpperBound int `json:"doc_count_error_upper_bound"`
SumOtherDocCount int `json:"sum_other_doc_count"`
Buckets []struct {
Key string `json:"key"`
DocCount int `json:"doc_count"`
UnresolvedCount struct {
DocCount int `json:"doc_count"`
} `json:"unresolved_count"`
} `json:"buckets"`
} `json:"group"`
} `json:"buckets"`
} `json:"group"`
}
type AlertDistributionGroup struct {
Group struct {
DocCountErrorUpperBound int `json:"doc_count_error_upper_bound"`
SumOtherDocCount int `json:"sum_other_doc_count"`
Buckets []struct {
Key int `json:"key"`
DocCount int `json:"doc_count"`
} `json:"buckets"`
} `json:"group"`
}
type DateHistogramGroup struct {
Group struct {
Buckets []struct {
KeyAsString string `json:"key_as_string"`
Key int64 `json:"key"`
DocCount int `json:"doc_count"`
} `json:"buckets"`
} `json:"group"`
}
...@@ -6,9 +6,9 @@ import ( ...@@ -6,9 +6,9 @@ import (
type AlertOverviewItem struct { type AlertOverviewItem struct {
AlertOverview []entity.AlertOverview `json:"alert_overview"` AlertOverview []entity.AlertOverview `json:"alert_overview"`
RiskLevelDistribution []entity.RiskLevelDistribution `json:"risk_level_distribution"` RiskLevelDistribution []entity.AlertDistribution `json:"risk_level_distribution"`
AlertStatusDistribution []entity.AlertStatusDistribution `json:"alert_status_distribution"` AlertStatusDistribution []entity.AlertDistribution `json:"alert_status_distribution"`
AlertClassDistribution []entity.AlertClassDistribution `json:"alert_class_distribution"` AlertClassDistribution []entity.AlertDistribution `json:"alert_class_distribution"`
AlertFrequencyDistribution entity.AlertFrequencyDistribution `json:"alert_frequency_distribution"` AlertFrequencyDistribution entity.AlertFrequencyDistribution `json:"alert_frequency_distribution"`
} }
......
...@@ -31,7 +31,7 @@ type Config struct { ...@@ -31,7 +31,7 @@ type Config struct {
MinioSecretKey string MinioSecretKey string
MinioBucket string MinioBucket string
//TempDirPrefix string //TempDirPrefix string
PrometheusHost string
AccessRuleModeKey string AccessRuleModeKey string
LocationUrl string LocationUrl string
LocationKey string LocationKey string
...@@ -49,9 +49,20 @@ type Config struct { ...@@ -49,9 +49,20 @@ type Config struct {
AweRestURL string AweRestURL string
KubernetesToken string KubernetesToken string
OpenSearchIndex string
OpenSearchAddresses string OpenSearchAddresses string
OpenSearchUserName string OpenSearchUserName string
OpenSearchPassword string OpenSearchPassword string
MonitorApiVersion string
MonitorMatchNs string
MonitorMatchLabelsStr string
MonitorMatchLabels map[string]interface{}
Namespace string
PrometheusHost string
PrometheusRuleLabel string
PrometheusRuleNamePrefix string
} }
const ( const (
......
...@@ -31,6 +31,7 @@ func ListAlert(c *gin.Context) { ...@@ -31,6 +31,7 @@ func ListAlert(c *gin.Context) {
return return
} }
svc := service.AlertSvc{User: header.GetUser(c)} svc := service.AlertSvc{User: header.GetUser(c)}
// TODO 我的预警工单
data, err := svc.List(req) data, err := svc.List(req)
if err != nil { if err != nil {
SendJsonResponse(c, resp.FAIL.WithError(err), nil) SendJsonResponse(c, resp.FAIL.WithError(err), nil)
......
...@@ -3,10 +3,10 @@ package controller ...@@ -3,10 +3,10 @@ package controller
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/prometheus/alertmanager/notify/webhook" "github.com/prometheus/alertmanager/notify/webhook"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/service" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/service"
"go.uber.org/zap" "go.uber.org/zap"
) )
...@@ -14,12 +14,18 @@ import ( ...@@ -14,12 +14,18 @@ import (
// AlertWebhook 回调 // AlertWebhook 回调
func AlertWebhook(c *gin.Context) { func AlertWebhook(c *gin.Context) {
var req webhook.Message var req webhook.Message
conf.Logger.Info("------>webhook.start------>")
if err := c.ShouldBind(&req); err != nil { if err := c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return return
} }
conf.Logger.Info("------>webhook.Message------>", zap.Any("message", req)) conf.Logger.Info("------>webhook.Message------>", zap.Any("message", req))
svc := service.AlertWebhookSvc{User: header.GetUser(c)} svc := service.AlertWebhookSvc{User: entity.SystemUserInfo{
Name: "prometheus",
SystemAccount: "prometheus",
OrganizationId: "",
State: 1,
}}
db, err := client.GetDbClient() db, err := client.GetDbClient()
if err != nil { if err != nil {
SendJsonResponse(c, resp.DbConnectError.WithError(err), nil) SendJsonResponse(c, resp.DbConnectError.WithError(err), nil)
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/spf13/cast" "github.com/spf13/cast"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/service" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/service"
...@@ -243,3 +244,36 @@ func ListWorkOrderMe(c *gin.Context) { ...@@ -243,3 +244,36 @@ func ListWorkOrderMe(c *gin.Context) {
} }
SendJsonPageResponse(c, resp.OK, list, total) SendJsonPageResponse(c, resp.OK, list, total)
} }
// WorkOrderListAlert 我的预警工单
func WorkOrderListAlert(c *gin.Context) {
var req request.ListAlert
if err := c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
user := header.GetUser(c)
req.SystemAccount = user.SystemAccount
if user.SystemAccount == "" {
SendJsonResponse(c, resp.FAIL.WithError(errors.New("system_account cannot be empty")), nil)
return
}
svc := service.AlertSvc{User: user}
data, err := svc.List(req)
// 回显使用:内部字段对外覆盖处理
// disposed_list[].is_disposed --映射--> is_disposed
for i := 0; i < len(data.List); i++ {
for j := 0; j < len(data.List[i].DisposedList); j++ {
if data.List[i].IsDisposed != constant.IsDisposedYes {
if data.List[i].DisposedList[j].DisposalUser == user.SystemAccount {
data.List[i].IsDisposed = constant.IsDisposedYes
}
}
}
}
if err != nil {
SendJsonResponse(c, resp.FAIL.WithError(err), nil)
return
}
SendJsonResponse(c, resp.OK, data)
}
...@@ -45,9 +45,15 @@ func main() { ...@@ -45,9 +45,15 @@ func main() {
// redis client // redis client
go client.GetRedisClient() go client.GetRedisClient()
// 初始化OpenSearch的索引
err := service.CheckAndCreateIndex()
if err != nil {
conf.Logger.Error("failed to init OpenSearch index", zap.Error(err))
}
//启动定时任务 //启动定时任务
cron.StartCron() cron.StartCron()
service.PushWorkOrderMessage() service.CronPushWorkOrder()
// server start... // server start...
conf.Logger.Info("config info", zap.Any("options", conf.Options)) conf.Logger.Info("config info", zap.Any("options", conf.Options))
conf.Logger.Error("server start err", zap.Error(newServer().ListenAndServe())) conf.Logger.Error("server start err", zap.Error(newServer().ListenAndServe()))
...@@ -64,17 +70,16 @@ func initConfig() { ...@@ -64,17 +70,16 @@ func initConfig() {
RedisURL: util.SetEnvStr("REDIS_URL", "localhost:7001"), RedisURL: util.SetEnvStr("REDIS_URL", "localhost:7001"),
RedisDB: 0, RedisDB: 0,
RedisTag: "bg", RedisTag: "bg",
LogDirPrefix: util.SetEnvStr("LOG_DIR_PREFIX", "/app/log"), // 日志目录 LogDirPrefix: util.SetEnvStr("LOG_DIR_PREFIX", "/app/log"), // 日志目录
LogDirName: util.SetEnvStr("LOG_NAME", "syslog"), // 日志名称 LogDirName: util.SetEnvStr("LOG_NAME", "syslog"), // 日志名称
LogSaveDays: util.SetEnvInt("LOG_SAVE_DAYS", 7), // 日志最大存储天数 LogSaveDays: util.SetEnvInt("LOG_SAVE_DAYS", 7), // 日志最大存储天数
LogMode: util.SetEnvInt("LOG_MODE", 1), // 1.标准打印 2.输出文件 LogMode: util.SetEnvInt("LOG_MODE", 1), // 1.标准打印 2.输出文件
ArgBool: util.SetEnvBool("ARG_BOOL", false), // 示例参数 ArgBool: util.SetEnvBool("ARG_BOOL", false), // 示例参数
ArgInt: util.SetEnvInt("ARG_INT", 10), // 示例参数 ArgInt: util.SetEnvInt("ARG_INT", 10), // 示例参数
MinioServer: util.SetEnvStr("MINIO_SERVER", "https://cache.wodcloud.com"), // Minio 服务地址 MinioServer: util.SetEnvStr("MINIO_SERVER", "https://cache.wodcloud.com"), // Minio 服务地址
MinioAccessKey: util.SetEnvStr("MINIO_ACCESS_KEY", "beagleadmin"), // Minio Access Key MinioAccessKey: util.SetEnvStr("MINIO_ACCESS_KEY", "beagleadmin"), // Minio Access Key
MinioSecretKey: util.SetEnvStr("MINIO_SECRET_KEY", "H76cPmwvH7vJ"), // Minio Secret MinioSecretKey: util.SetEnvStr("MINIO_SECRET_KEY", "H76cPmwvH7vJ"), // Minio Secret
MinioBucket: util.SetEnvStr("MINIO_BUCKET", "so-operation"), // Minio Bucket MinioBucket: util.SetEnvStr("MINIO_BUCKET", "so-operation"), // Minio Bucket
PrometheusHost: util.SetEnvStr("PROMETHEUS_HOST", "https://prometheus.wodcloud.com"), // Prometheus Host
AccessRuleModeKey: "accessRuleMode", AccessRuleModeKey: "accessRuleMode",
LocationUrl: util.SetEnvStr("LOCATION_URL", "https://apis.map.qq.com/ws/location/v1/ip"), LocationUrl: util.SetEnvStr("LOCATION_URL", "https://apis.map.qq.com/ws/location/v1/ip"),
LocationKey: util.SetEnvStr("LOCATION_KEY", "QKFBZ-PGGWJ-VZQFF-FHPA7-QWT5H-YHF4T"), LocationKey: util.SetEnvStr("LOCATION_KEY", "QKFBZ-PGGWJ-VZQFF-FHPA7-QWT5H-YHF4T"),
...@@ -85,14 +90,26 @@ func initConfig() { ...@@ -85,14 +90,26 @@ func initConfig() {
SmsAccessKeyId: util.SetEnvStr("SMS_ACCESS_KEY", "LTAI4GBcVubRjzX7ABPcHnhB"), // 短信key SmsAccessKeyId: util.SetEnvStr("SMS_ACCESS_KEY", "LTAI4GBcVubRjzX7ABPcHnhB"), // 短信key
SmsAccessSecret: util.SetEnvStr("SMS_ACCESS_SECRET", "dYE2dtABFOqYtK1ijcrits0yedHkw7"), // 短信secret SmsAccessSecret: util.SetEnvStr("SMS_ACCESS_SECRET", "dYE2dtABFOqYtK1ijcrits0yedHkw7"), // 短信secret
SmsTemplateLogin: util.SetEnvStr("SMS_TEMPLATE_LOGIN", "SMS_212925130"), // 短信验证码模板 SmsTemplateLogin: util.SetEnvStr("SMS_TEMPLATE_LOGIN", "SMS_212925130"), // 短信验证码模板
SmsTemplateAlert: util.SetEnvStr("Sms_Template_Alert", "SMS_461975765"), // 预警短信模板 // 短信工单下发模板 SmsTemplateAlert: util.SetEnvStr("SMS_TEMPLATE_ALERT", "SMS_461975765"), // 预警短信模板 // 短信工单下发模板
SmsWorkOrderTemplate: util.SetEnvStr("SMS_TEMPLATE_LOGIN", "SMS_462020767"), // 短信工单下发模板 SmsWorkOrderTemplate: util.SetEnvStr("SMS_TEMPLATE_LOGIN", "SMS_462020767"), // 短信工单下发模板
SmsSignName: util.SetEnvStr("SMS_SIGN_NAME", "比格数据"), // 签名 SmsSignName: util.SetEnvStr("SMS_SIGN_NAME", "比格数据"), // 签名
AweRestURL: util.SetEnvStr("AWE_REST_URL", "http://awecloud-rest.beagle-system/awecloud/rest"), // awecloud-rest AweRestURL: util.SetEnvStr("AWE_REST_URL", "http://awecloud-rest.beagle-system/awecloud/rest"), // awecloud-rest
KubernetesToken: util.SetEnvStr("AWE_REST_K8S_TOKEN", "eyJhbGciOiJSUzI1NiIsImtpZCI6InJ1alJzNEVGamN5UC0wRU1rS1BKQ0JZVUtNNWpzR0t2bmlrSlJhY2Q3R00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJiZWFnbGUtc3lzdGVtIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InJvb3QiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicm9vdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjRlMDM0OTI3LTc0ZTMtNDQ5Yy1hN2RlLWExMGE3MjU1NGYyMCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpiZWFnbGUtc3lzdGVtOnJvb3QifQ.YPLE_E2kIeo-YFQtKScBt5p4KhnniJF9n3iWN2i9UMYS06lIsq2-2wBrgON-YsJihWJupYyDQRiZ9h8bUWTrQzhnpsnuJ_aUclKyAw3QOT9rjvZhJp7qP--27dmdspSHncKtvIiprWE7UTUKzvF33WsMB0fSYFqYXOggNFMoT-fXmWwUXjgar3op0iOl3c3deJ_GeBzFyLSHEuGM7OVdjU8032aUmTen0Kji_P1yB4-O3Iqd0OdVs33BQy_tycjbxhQ8TDEpqrqhLnXjAwJCprLDEpFMx7ODZbjB9Wmuns8yJhaRDxTO47rTME7ZIAxjZ-zLR_QybtW97rlwnUTaNw"), KubernetesToken: util.SetEnvStr("AWE_REST_K8S_TOKEN", "eyJhbGciOiJSUzI1NiIsImtpZCI6InJ1alJzNEVGamN5UC0wRU1rS1BKQ0JZVUtNNWpzR0t2bmlrSlJhY2Q3R00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJiZWFnbGUtc3lzdGVtIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InJvb3QiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicm9vdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjRlMDM0OTI3LTc0ZTMtNDQ5Yy1hN2RlLWExMGE3MjU1NGYyMCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpiZWFnbGUtc3lzdGVtOnJvb3QifQ.YPLE_E2kIeo-YFQtKScBt5p4KhnniJF9n3iWN2i9UMYS06lIsq2-2wBrgON-YsJihWJupYyDQRiZ9h8bUWTrQzhnpsnuJ_aUclKyAw3QOT9rjvZhJp7qP--27dmdspSHncKtvIiprWE7UTUKzvF33WsMB0fSYFqYXOggNFMoT-fXmWwUXjgar3op0iOl3c3deJ_GeBzFyLSHEuGM7OVdjU8032aUmTen0Kji_P1yB4-O3Iqd0OdVs33BQy_tycjbxhQ8TDEpqrqhLnXjAwJCprLDEpFMx7ODZbjB9Wmuns8yJhaRDxTO47rTME7ZIAxjZ-zLR_QybtW97rlwnUTaNw"),
OpenSearchAddresses: util.SetEnvStr("Open_Search_Addresses", "https://so-opensearch.wodcloud.com"), // 短信验证码模板
OpenSearchUserName: util.SetEnvStr("Open_Search_User_Name", ""), // 短信验证码模板 OpenSearchIndex: util.SetEnvStr("OPEN_SEARCH_INDEX", "so_alert"),
OpenSearchPassword: util.SetEnvStr("Open_Search_Password", ""), // 短信验证码模板 OpenSearchAddresses: util.SetEnvStr("OPEN_SEARCH_ADDRESSES", "https://so-opensearch.wodcloud.com"), // OpenSearch连接地址
OpenSearchUserName: util.SetEnvStr("OPEN_SEARCH_USER_NAME", ""), // OpenSearch用户名
OpenSearchPassword: util.SetEnvStr("OPEN_SEARCH_PASSWORD", ""), // OpenSearch密码
Namespace: util.SetEnvStr("NAMESPACE", "smart-manage"), //采集器部署命名空间
PrometheusHost: util.SetEnvStr("PROMETHEUS_HOST", "https://prometheus.wodcloud.com"), // Prometheus Host
PrometheusRuleNamePrefix: util.SetEnvStr("PROMETHEUS_RULE_NAME_PREFIX", "beagle-prometheus-so-operation-api-rules"), // prometheusrules资源名前缀
PrometheusRuleLabel: util.SetEnvStr("PROMETHEUS_RULE_LABEL", `{"source":"so-operation-api","severity":"warning"}`), // prometheusrules标签,用于区分项目来源
MonitorApiVersion: util.SetEnvStr("MONITOR_API_VERSION", "monitoring.beagle.io/v1"), //Prometheus Operator 资源版本
MonitorMatchNs: util.SetEnvStr("MONITOR_MATCH_NS", "beagle-monitoring"), //Monitor匹配 命名空间
MonitorMatchLabelsStr: util.SetEnvStr("MONITOR_MATCH_LABELS", `{"prometheus-operator":"monitoring"}`), //Monitor匹配 标签JSON
} }
} }
...@@ -145,12 +162,6 @@ func initAnsibleHosts() { ...@@ -145,12 +162,6 @@ func initAnsibleHosts() {
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
} }
//else {
// _, err := f.Write([]byte("[web]\n"))
// if err != nil {
// fmt.Println(err.Error())
// }
//}
} }
func initTempDirPrefix() { func initTempDirPrefix() {
...@@ -175,14 +186,4 @@ func initAnsibleSSH() { ...@@ -175,14 +186,4 @@ func initAnsibleSSH() {
fmt.Println(err.Error()) fmt.Println(err.Error())
} }
} }
//f2, err := os.CreateIndex("/root/.ssh/id_rsa.pub")
//defer f2.Close()
//if err != nil {
// fmt.Println(err.Error())
//} else {
// _, err := f.Write([]byte(conf.Options.PublicKeySSH))
// if err != nil {
// fmt.Println(err.Error())
// }
//}
} }
...@@ -123,6 +123,12 @@ var OpTypeIntMap = map[OpType]int{ ...@@ -123,6 +123,12 @@ var OpTypeIntMap = map[OpType]int{
Export: 14, Export: 14,
} }
// 数据来源(自定义为非正常数据) 1:默认 2:自定义
const (
SourceDefault = 1
SourceCustom = 2
)
// RiskLevel 风险等级 // RiskLevel 风险等级
const ( const (
RiskLevelLow = iota + 1 // 1:低风险 RiskLevelLow = iota + 1 // 1:低风险
...@@ -142,7 +148,7 @@ func RiskLeveText(code int) string { ...@@ -142,7 +148,7 @@ func RiskLeveText(code int) string {
case RiskLevelCritical: case RiskLevelCritical:
return "重大风险" return "重大风险"
default: default:
return "" return "未知"
} }
} }
...@@ -152,3 +158,40 @@ const ( ...@@ -152,3 +158,40 @@ const (
AlertNotRecovered AlertNotRecovered
AlertClosed AlertClosed
) )
func AlertStatusText(code int) string {
switch code {
case AlertRecovered:
return "已恢复"
case AlertNotRecovered:
return "未恢复"
case AlertClosed:
return "已关闭"
default:
return "未知"
}
}
// 是否处置(工单管理),1:已处置,2:未处置
const (
IsDisposedYes = 1
IsDisposedNo = 2
)
func DisposedStatusText(code int) string {
switch code {
case IsDisposedYes:
return "已处置"
case IsDisposedNo:
return "未处置"
default:
return "未知"
}
}
// 工单定时类型
const (
TimingClick = 1 //手动下发
TimingWeekly = 2 //按周
TimingCustom = 3 //自定义时间
)
...@@ -5,11 +5,12 @@ import ( ...@@ -5,11 +5,12 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
) )
// InitAlertListRouter 初始化预警列表配置路由 // InitAlertListRouter 初始化预警列表配置路由
func InitAlertListRouter(e *gin.Engine) { func InitAlertListRouter(e *gin.Engine) {
group := e.Group(fmt.Sprintf("%s/alert", conf.Options.Prefix)) group := e.Group(fmt.Sprintf("%s/alert", conf.Options.Prefix), header.SetContext)
{ {
group.GET("", controller.DetailAlert) group.GET("", controller.DetailAlert)
group.GET("list", controller.ListAlert) group.GET("list", controller.ListAlert)
......
...@@ -5,11 +5,12 @@ import ( ...@@ -5,11 +5,12 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
) )
// InitAlertRulesRouter 初始化预警规则配置路由 // InitAlertRulesRouter 初始化预警规则配置路由
func InitAlertRulesRouter(e *gin.Engine) { func InitAlertRulesRouter(e *gin.Engine) {
group := e.Group(fmt.Sprintf("%s/alert_rules", conf.Options.Prefix)) group := e.Group(fmt.Sprintf("%s/alert_rules", conf.Options.Prefix), header.SetContext)
{ {
group.POST("", controller.AddAlertRules) group.POST("", controller.AddAlertRules)
group.PUT("", controller.UpdateAlertRules) group.PUT("", controller.UpdateAlertRules)
......
...@@ -5,11 +5,12 @@ import ( ...@@ -5,11 +5,12 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
) )
// InitMetricConfigRouter 初始化指标配置路由 // InitMetricConfigRouter 初始化指标配置路由
func InitMetricConfigRouter(e *gin.Engine) { func InitMetricConfigRouter(e *gin.Engine) {
mcGroup := e.Group(fmt.Sprintf("%s/metric_config", conf.Options.Prefix)) mcGroup := e.Group(fmt.Sprintf("%s/metric_config", conf.Options.Prefix), header.SetContext)
{ {
mcGroup.POST("", controller.AddMetricConfig) mcGroup.POST("", controller.AddMetricConfig)
mcGroup.PUT("", controller.UpdateMetricConfig) mcGroup.PUT("", controller.UpdateMetricConfig)
...@@ -18,7 +19,7 @@ func InitMetricConfigRouter(e *gin.Engine) { ...@@ -18,7 +19,7 @@ func InitMetricConfigRouter(e *gin.Engine) {
mcGroup.GET("list", controller.ListMetricConfig) mcGroup.GET("list", controller.ListMetricConfig)
} }
acGroup := e.Group(fmt.Sprintf("%s/alert_class", conf.Options.Prefix)) acGroup := e.Group(fmt.Sprintf("%s/alert_class", conf.Options.Prefix), header.SetContext)
{ {
acGroup.POST("", controller.AddAlertClass) acGroup.POST("", controller.AddAlertClass)
acGroup.PUT("move/:direction", controller.MoveAlertClass) acGroup.PUT("move/:direction", controller.MoveAlertClass)
......
...@@ -10,13 +10,13 @@ import ( ...@@ -10,13 +10,13 @@ import (
// InitWorkOrderRouter 初始化工单路由 // InitWorkOrderRouter 初始化工单路由
func InitWorkOrderRouter(e *gin.Engine) { func InitWorkOrderRouter(e *gin.Engine) {
so := e.Group(fmt.Sprintf("%s/work_order", conf.Options.Prefix)) so := e.Group(fmt.Sprintf("%s/work_order", conf.Options.Prefix), header.SetContext)
//预警工单管理 //预警工单管理
alert := so.Group("/alert") alert := so.Group("/alert")
{ {
alert.GET("", controller.DetailAlert) // 详情 alert.GET("", controller.DetailAlert) // 详情
alert.GET("/list", controller.ListAlert) // 列表 alert.GET("/list", controller.WorkOrderListAlert) // 列表
alert.PUT("/dispose", controller.DisposeAlert) // 处置反馈 alert.PUT("/dispose", controller.DisposeAlert) // 处置反馈
} }
//业务工单管理 //业务工单管理
...@@ -46,5 +46,4 @@ func InitWorkOrderRouter(e *gin.Engine) { ...@@ -46,5 +46,4 @@ func InitWorkOrderRouter(e *gin.Engine) {
me.PUT("/feedback", controller.FeedbackWorkOrderMe) // 处置反馈 me.PUT("/feedback", controller.FeedbackWorkOrderMe) // 处置反馈
me.GET("/list", controller.ListWorkOrderMe) // 我的业务工单列表 me.GET("/list", controller.ListWorkOrderMe) // 我的业务工单列表
} }
//so.POST("/note_sg", controller.WorkOrderPushNoteMsg)
} }
This diff is collapsed.
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"sort" "sort"
...@@ -26,6 +27,9 @@ func (a *AlertClassSvc) Add(session *xorm.Session, req request.AddAlertClass) (c ...@@ -26,6 +27,9 @@ func (a *AlertClassSvc) Add(session *xorm.Session, req request.AddAlertClass) (c
UpdatedBy: a.User.SystemAccount, UpdatedBy: a.User.SystemAccount,
UpdatedAt: now, UpdatedAt: now,
} }
if req.Source != constant.SourceCustom {
req.Source = constant.SourceDefault
}
_ = copier.Copy(&data, &req) _ = copier.Copy(&data, &req)
var max int var max int
...@@ -48,7 +52,7 @@ func (a *AlertClassSvc) Update(session *xorm.Session, req request.UpdateAlertCla ...@@ -48,7 +52,7 @@ func (a *AlertClassSvc) Update(session *xorm.Session, req request.UpdateAlertCla
UpdatedAt: now, UpdatedAt: now,
} }
_ = copier.Copy(&data, &req) _ = copier.Copy(&data, &req)
_, err := session.Cols("class_name", "updated_by", "updated_at").ID(data.ClassId).Update(&data) _, err := session.Cols("parent_id", "class_name", "updated_by", "updated_at").ID(data.ClassId).Update(&data)
if err != nil { if err != nil {
return err return err
} }
...@@ -66,7 +70,7 @@ func (a *AlertClassSvc) Move(req request.MoveAlertClass) (err error) { ...@@ -66,7 +70,7 @@ func (a *AlertClassSvc) Move(req request.MoveAlertClass) (err error) {
_ = copier.Copy(&data, &req) _ = copier.Copy(&data, &req)
var list []entity.AlertClass var list []entity.AlertClass
_, err = db.NewSession().Where("class_id = ?", req.ClassId).Get(&data) _, err = db.NewSession().Where("class_id = ?", req.ClassId).Get(&data)
err = db.NewSession().Where("parent_id = ?", data.ParentId).Where("source_from = 1").OrderBy("sort_order asc").Find(&list) err = db.NewSession().Where("parent_id = ?", data.ParentId).Where("source = 1").OrderBy("sort_order asc").Find(&list)
var previousIndex int var previousIndex int
var nextIndex int var nextIndex int
for i := 0; i < len(list); i++ { for i := 0; i < len(list); i++ {
...@@ -139,18 +143,33 @@ func (a *AlertClassSvc) List(req request.ListAlertClass) (resp response.AlertCla ...@@ -139,18 +143,33 @@ func (a *AlertClassSvc) List(req request.ListAlertClass) (resp response.AlertCla
} }
session := db.NewSession() session := db.NewSession()
defer session.Close() defer session.Close()
session.Where("source_from = 1") session.Where("source = 1")
if req.ClassId != 0 { if req.ClassId != 0 {
session.Where("class_id = ?", req.ClassId) session.Where("class_id = ?", req.ClassId)
} }
if req.ClassName != "" { if req.ClassName != "" {
session.Where("class_name LIKE ?", "%"+req.ClassName+"%") session.Where("class_name LIKE ?", "%"+req.ClassName+"%")
} }
if req.Page == -1 {
req.PageSize = 100000
}
resp.TotalCount, err = session.Limit(req.GetPageSize(), (req.GetPage()-1)*req.GetPageSize()). resp.TotalCount, err = session.Limit(req.GetPageSize(), (req.GetPage()-1)*req.GetPageSize()).
OrderBy("sort_order").FindAndCount(&resp.List) OrderBy("sort_order").FindAndCount(&resp.List)
return return
} }
func (a *AlertClassSvc) AlertObjectList() (resp response.AlertClassList, err error) {
db, err := client.GetDbClient()
if err != nil {
return
}
session := db.NewSession()
defer session.Close()
session.Where("parent_id <> 0")
resp.TotalCount, err = session.OrderBy("sort_order").FindAndCount(&resp.List)
return
}
func (a *AlertClassSvc) Tree(req request.ListAlertClass) (resp []*response.AlertClassNode, err error) { func (a *AlertClassSvc) Tree(req request.ListAlertClass) (resp []*response.AlertClassNode, err error) {
db, err := client.GetDbClient() db, err := client.GetDbClient()
if err != nil { if err != nil {
...@@ -159,7 +178,7 @@ func (a *AlertClassSvc) Tree(req request.ListAlertClass) (resp []*response.Alert ...@@ -159,7 +178,7 @@ func (a *AlertClassSvc) Tree(req request.ListAlertClass) (resp []*response.Alert
session := db.NewSession() session := db.NewSession()
defer session.Close() defer session.Close()
var list []entity.AlertClass var list []entity.AlertClass
session.Where("source_from = 1") session.Where("source = 1")
_, err = session.OrderBy("sort_order").FindAndCount(&list) _, err = session.OrderBy("sort_order").FindAndCount(&list)
// TODO 对req进行过滤 // TODO 对req进行过滤
resp, err = AlertClassTree(list) resp, err = AlertClassTree(list)
...@@ -211,15 +230,68 @@ func (a *AlertClassSvc) SortOrderMax(parentId int) (max int, err error) { ...@@ -211,15 +230,68 @@ func (a *AlertClassSvc) SortOrderMax(parentId int) (max int, err error) {
} }
_, err = db.NewSession().Table(new(entity.AlertClass)). _, err = db.NewSession().Table(new(entity.AlertClass)).
Select("max(sort_order)"). Select("max(sort_order)").
Where("parent_id = ?", parentId).Where("source_from = 1").Get(&max) Where("parent_id = ?", parentId).Where("source = 1").Get(&max)
return return
} }
func (a *AlertClassSvc) Delete(ids []int) (err error) { func (a *AlertClassSvc) Delete(ids []int) (err error) {
db, err := client.GetDbClient() db, err := client.GetDbClient()
if err != nil { if err != nil {
return return err
} }
_, err = db.NewSession().In("class_id", ids).Delete(&entity.AlertClass{})
return var classes []entity.AlertClass
err = db.In("class_id", ids).Find(&classes)
// 检查是否所有指定的 ids 都存在于数据库中
if len(ids) > len(classes) {
return errors.New("部分数据不存在")
}
var notExist []int
idSet := make(map[int]bool)
for _, v := range classes {
idSet[v.ClassId] = true
}
for _, id := range ids {
if !idSet[id] {
notExist = append(notExist, id)
}
}
if len(notExist) > 0 {
return errors.New(fmt.Sprintf("指标分类或对象id为%v的数据未查询到", notExist))
}
for _, v := range classes {
if v.ParentId == 0 {
// 如果是父级数据,判断是否存在子集
var num int
has, err := db.Table(new(entity.AlertClass)).Select("count(*)").Where("parent_id = ?", v.ClassId).Get(&num)
if err != nil {
return err
}
if has && num > 0 {
return errors.New("当前分类存在指标对象子集数据,不允许删除")
}
} else {
// 如果为子集数据,判断是否存在指标配置关联
var configCount int
has, err := db.Table(new(entity.MetricConfig)).Select("count(*)").Where("class_id = ?", v.ClassId).Get(&configCount)
if err != nil {
return err
}
if has && configCount > 0 {
return errors.New("指标对象存在指标配置关联,不允许删除")
}
}
// 删除数据
_, err = db.ID(v.ClassId).Delete(v)
if err != nil {
return err
}
}
return nil
} }
This diff is collapsed.
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
...@@ -56,29 +57,31 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) { ...@@ -56,29 +57,31 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) {
alertClassSvc := AlertClassSvc{User: a.User} alertClassSvc := AlertClassSvc{User: a.User}
classParentId, err = alertClassSvc.Add(session, request.AddAlertClass{ classParentId, err = alertClassSvc.Add(session, request.AddAlertClass{
ClassName: req.ClassParentName, ClassName: req.ClassParentName,
SortOrder: -1, SortOrder: -1,
SourceFrom: 2, Source: constant.SourceCustom,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
classId, err = alertClassSvc.Add(session, request.AddAlertClass{ classId, err = alertClassSvc.Add(session, request.AddAlertClass{
ClassName: req.ClassName, ClassName: req.ClassName,
ParentId: classParentId, ParentId: classParentId,
SortOrder: -1, SortOrder: -1,
SourceFrom: 2, Source: constant.SourceCustom,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
data.ClassId = classId data.ClassId = classId
req.ClassId = classId
// 添加指标配置 // 添加指标配置
metricConfigSvc := MetricConfigSvc{User: a.User} metricConfigSvc := MetricConfigSvc{User: a.User}
_ = copier.Copy(&addMetricConfig, &req) _ = copier.Copy(&addMetricConfig, &req)
addMetricConfig.SourceFrom = 2 addMetricConfig.Source = constant.SourceCustom
addMetricConfig.MetricName = req.MetricConfigName addMetricConfig.MetricName = req.MetricConfigName
addMetricConfig.ClassId = classId
metricConfigId, err = metricConfigSvc.Add(session, addMetricConfig) metricConfigId, err = metricConfigSvc.Add(session, addMetricConfig)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -87,14 +90,22 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) { ...@@ -87,14 +90,22 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) {
// 添加预警规则配置 // 添加预警规则配置
_, err = session.Insert(&data) _, err = session.Insert(&data)
if err != nil {
return nil, err
}
return nil, err return nil, err
}) })
err = a.CreatePrometheusRule(req.IsEnabled, data.Id, db, "")
if err != nil { if err != nil {
return err return err
} }
} }
err = a.CreatePrometheusRule(req.IsEnabled, data.Id, db, "") err = a.CreatePrometheusRule(req.IsEnabled, data.Id, db, "")
if err != nil {
return err
}
return nil return nil
} }
...@@ -124,7 +135,11 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) { ...@@ -124,7 +135,11 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) {
} }
switch req.DetectionType { switch req.DetectionType {
case 1: case 1:
_, err = db.ID(data.Id).Update(&data) _, err = db.ID(data.Id).MustCols("duration").Update(&data)
if err != nil {
return err
}
err = a.CreatePrometheusRule(req.IsEnabled, data.Id, db, "update")
if err != nil { if err != nil {
return err return err
} }
...@@ -133,24 +148,37 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) { ...@@ -133,24 +148,37 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) {
// 更新自定义分类 // 更新自定义分类
var ( var (
updateMetricConfig request.UpdateMetricConfig updateMetricConfig request.UpdateMetricConfig
alertClassItem response.AlertClassItem alertClass response.AlertClassItem
alertParentClass response.AlertClassItem
) )
alertClassSvc := AlertClassSvc{User: a.User} alertClassSvc := AlertClassSvc{User: a.User}
alertClassItem, err = alertClassSvc.GetDataById(request.DetailAlertClass{ClassId: dbAlertRules.ClassId}) alertClass, err = alertClassSvc.GetDataById(request.DetailAlertClass{ClassId: dbAlertRules.ClassId})
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = alertClassSvc.Update(session, request.UpdateAlertClass{ err = alertClassSvc.Update(session, request.UpdateAlertClass{
ClassId: dbAlertRules.ClassId, ClassId: dbAlertRules.ClassId,
ClassName: req.ClassName, ClassName: req.ClassName,
ParentId: alertClass.ParentId,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
if alertClass.ParentId == 0 {
return nil, errors.New("预警分类为空")
}
alertParentClass, err = alertClassSvc.GetDataById(request.DetailAlertClass{ClassId: alertClass.ParentId})
if err != nil {
return nil, err
}
err = alertClassSvc.Update(session, request.UpdateAlertClass{ err = alertClassSvc.Update(session, request.UpdateAlertClass{
ClassId: alertClassItem.ParentId, ClassId: alertClass.ParentId,
ClassName: req.ClassParentName, ClassName: req.ClassParentName,
ParentId: alertParentClass.ParentId,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -159,17 +187,18 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) { ...@@ -159,17 +187,18 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) {
// 更新指标配置 // 更新指标配置
metricConfigSvc := MetricConfigSvc{User: a.User} metricConfigSvc := MetricConfigSvc{User: a.User}
_ = copier.Copy(&updateMetricConfig, &req) _ = copier.Copy(&updateMetricConfig, &req)
updateMetricConfig.SourceFrom = 2 updateMetricConfig.Source = constant.SourceCustom
updateMetricConfig.Id = dbAlertRules.MetricConfigId updateMetricConfig.Id = dbAlertRules.MetricConfigId
err = metricConfigSvc.Update(session, updateMetricConfig) err = metricConfigSvc.Update(session, updateMetricConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// 更新预警规则配置
_, err = session.ID(data.Id).Update(&data)
return nil, err return nil, err
}) })
// 更新预警策略配置
_, err = session.ID(data.Id).MustCols("duration").Update(&data)
err = a.CreatePrometheusRule(req.IsEnabled, data.Id, db, "update")
if err != nil { if err != nil {
return err return err
} }
...@@ -237,16 +266,20 @@ func (a *AlertRulesSvc) UpdateIsEnabled(req request.UpdateIsEnabledAlertRules) ( ...@@ -237,16 +266,20 @@ func (a *AlertRulesSvc) UpdateIsEnabled(req request.UpdateIsEnabledAlertRules) (
return return
} }
if req.IsEnabled == 2 { if req.IsEnabled == 2 {
if item.IsEnabled == 1 { prSvc := PrometheusRuleSvc{User: a.User}
prSvc := PrometheusRuleSvc{User: a.User} var exist bool
_, exist, err = prSvc.Get(item)
if exist {
err = prSvc.Delete(item) err = prSvc.Delete(item)
if err != nil { if err != nil {
return return
} }
} }
} else if req.IsEnabled == 1 { } else if req.IsEnabled == 1 {
if item.IsEnabled == 2 { prSvc := PrometheusRuleSvc{User: a.User}
prSvc := PrometheusRuleSvc{User: a.User} var exist bool
_, exist, err = prSvc.Get(item)
if !exist {
err = prSvc.Create(item) err = prSvc.Create(item)
if err != nil { if err != nil {
return return
...@@ -307,7 +340,7 @@ func (a *AlertRulesSvc) List(req request.ListAlertRules) (resp response.AlertRul ...@@ -307,7 +340,7 @@ func (a *AlertRulesSvc) List(req request.ListAlertRules) (resp response.AlertRul
Or("acp.class_name LIKE ?", "%"+req.Keyword+"%") Or("acp.class_name LIKE ?", "%"+req.Keyword+"%")
} }
resp.TotalCount, err = session.Limit(req.GetPageSize(), (req.GetPage()-1)*req.GetPageSize()). resp.TotalCount, err = session.Limit(req.GetPageSize(), (req.GetPage()-1)*req.GetPageSize()).
OrderBy("r.created_at desc"). OrderBy("r.is_enabled asc,r.created_at desc").
FindAndCount(&resp.List) FindAndCount(&resp.List)
for i := 0; i < len(resp.List); i++ { for i := 0; i < len(resp.List); i++ {
_ = json.Unmarshal([]byte(resp.List[i].AlertRules.AlertCondition), &resp.List[i].AlertCondition) _ = json.Unmarshal([]byte(resp.List[i].AlertRules.AlertCondition), &resp.List[i].AlertCondition)
...@@ -332,14 +365,15 @@ func (a *AlertRulesSvc) Delete(ids []string) (err error) { ...@@ -332,14 +365,15 @@ func (a *AlertRulesSvc) Delete(ids []string) (err error) {
} }
if !exist { if !exist {
prSvc := PrometheusRuleSvc{User: a.User} prSvc := PrometheusRuleSvc{User: a.User}
err = prSvc.Delete(response.AlertRulesItem{AlertRules: entity.AlertRules{Id: id}}) var has bool
if err != nil { _, has, err = prSvc.Get(response.AlertRulesItem{AlertRules: entity.AlertRules{Id: id}})
return if has {
err = prSvc.Delete(response.AlertRulesItem{AlertRules: entity.AlertRules{Id: id}})
if err != nil {
return
}
} }
_, err = db.NewSession().Where("id = ?", id).Delete(new(entity.AlertRules)) _, err = db.NewSession().Where("id = ?", id).Delete(new(entity.AlertRules))
if err != nil {
return
}
} else { } else {
return errors.New("alert_rules_id already exists in opensearch") return errors.New("alert_rules_id already exists in opensearch")
} }
......
...@@ -7,8 +7,11 @@ import ( ...@@ -7,8 +7,11 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
"go.uber.org/zap"
"time"
"xorm.io/xorm" "xorm.io/xorm"
) )
...@@ -37,16 +40,20 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag ...@@ -37,16 +40,20 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag
) )
if alertRulesId, ok = alert.Labels["alert_rules_id"]; !ok { if alertRulesId, ok = alert.Labels["alert_rules_id"]; !ok {
return errors.New("alert_rules_id not found in the map") err = errors.New("alert_rules_id not found in the map")
conf.Logger.Error("err", zap.Error(err))
} }
if riskLevelStr, ok = alert.Labels["risk_level"]; !ok { if riskLevelStr, ok = alert.Labels["risk_level"]; !ok {
return errors.New("risk_level not found in the map") err = errors.New("risk_level not found in the map")
conf.Logger.Error("err", zap.Error(err))
} }
riskLevel = cast.ToInt(riskLevelStr) riskLevel = cast.ToInt(riskLevelStr)
if currentValueStr, ok = alert.Annotations["value"]; !ok { if currentValueStr, ok = alert.Annotations["value"]; !ok {
return errors.New("value not found in the map") err = errors.New("value not found in the map")
conf.Logger.Error("err", zap.Error(err))
return
} }
currentValue = cast.ToFloat64(currentValueStr) currentValue = cast.ToFloat64(currentValueStr)
...@@ -55,6 +62,11 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag ...@@ -55,6 +62,11 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag
return return
} }
if alertRulesItem.Id == "" {
conf.Logger.Error("err", zap.Error(errors.New("告警规则查询为空")))
return
}
alertItem, err = alertSvc.GetDataByAlertRulesIdAndRiskLevel(alertRulesId, riskLevel, 2) alertItem, err = alertSvc.GetDataByAlertRulesIdAndRiskLevel(alertRulesId, riskLevel, 2)
if err != nil { if err != nil {
return return
...@@ -68,12 +80,18 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag ...@@ -68,12 +80,18 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag
switch isNewAlert { switch isNewAlert {
case true: // 新增数据到OpenSearch case true: // 新增数据到OpenSearch
max := alertSvc.CatCount(OpenSearchIndex) var max int
max, err = alertSvc.GetIndexMaxID(conf.Options.OpenSearchIndex)
if err != nil {
// 获取id最大值
max = alertSvc.CatCount(conf.Options.OpenSearchIndex)
}
if max == 0 { if max == 0 {
err = errors.New("failed to get doc count for index") err = errors.New("failed to get doc count for index")
conf.Logger.Error("err", zap.Error(err))
return return
} }
alertId := max + 1 id := max + 1
for _, v := range alertRulesItem.AlertCondition { for _, v := range alertRulesItem.AlertCondition {
if v.RiskLevel == riskLevel { if v.RiskLevel == riskLevel {
alertCondition = v alertCondition = v
...@@ -81,12 +99,12 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag ...@@ -81,12 +99,12 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag
} }
} }
createAlert := request.CreateAlert{Alert: entity.Alert{ createAlert := request.CreateAlert{Alert: entity.Alert{
Id: alertId, Id: id,
AlertPoint: alertRulesItem.ClassParentName + "/" + alertRulesItem.MetricName, AlertPoint: alertRulesItem.ClassParentName + "/" + alertRulesItem.MetricName,
AlertRulesId: alertRulesItem.Id, AlertRulesId: alertRulesItem.Id,
AlertRulesName: alertRulesItem.MetricName, AlertRulesName: alertRulesItem.MetricName,
RiskLevel: riskLevel, RiskLevel: riskLevel,
AlertTime: jsontime.Time(alert.StartsAt), AlertTime: jsontime.Time(alert.StartsAt.Add(time.Hour * 8)),
ClassId: alertRulesItem.ClassId, ClassId: alertRulesItem.ClassId,
ClassParentName: alertRulesItem.ClassParentName, ClassParentName: alertRulesItem.ClassParentName,
ClassName: alertRulesItem.ClassName, ClassName: alertRulesItem.ClassName,
......
...@@ -10,6 +10,4 @@ func StartCron() { ...@@ -10,6 +10,4 @@ func StartCron() {
defer c.Start() defer c.Start()
c.AddFunc("0 0 0 * * *", service.CronStatusDetection) // 每天凌晨0点状态检测 c.AddFunc("0 0 0 * * *", service.CronStatusDetection) // 每天凌晨0点状态检测
c.AddFunc("0 0 0 * * *", service.CronWorkOrderIssuance) // 每天凌晨0点扫描当天需下发工单
} }
...@@ -6,30 +6,46 @@ import ( ...@@ -6,30 +6,46 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"strings" "strings"
"sync"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
) )
var ( var (
PrometheusRuleGroup = "monitoring.beagle.io" // kubectl api-resources | grep -i prome promOnce sync.Once
PrometheusRuleVersion = "v1" prometheusRuleName string
PrometheusRuleKind = "PrometheusRule"
Namespace = "beagle-monitoring" alertOnce sync.Once
PrometheusRuleApiVersion = PrometheusRuleGroup + "/" + PrometheusRuleVersion alertDefLabels map[string]string
PrometheusRuleName = strings.ToLower(PrometheusRuleKind) + "s." + PrometheusRuleGroup
PrometheusRuleNamePrefix = "beagle-prometheus-so-operation-api-rules" // beagle-monitoring beagle-prometheus-prometheus-operator 43d
) )
var AlertDefLabels = map[string]string{ func GetPrometheusRuleCRDName() string {
"app": "prometheus", promOnce.Do(func() {
"app.bd-apaas.com/cluster-component": "monitoring", url := conf.Options.MonitorApiVersion // 请确保 conf 和其他相关配置可用
"prometheus-operator": "monitoring", parts := strings.Split(url, "/")
"release": "beagle-prometheus", if len(parts) == 0 || parts[0] == "" {
prometheusRuleName = "prometheusrules.monitoring.beagle.io"
} else {
prometheusRuleName = fmt.Sprintf("prometheusrules.%s", parts[0])
}
})
return prometheusRuleName
}
func GetAlertDefLabels() map[string]string {
alertOnce.Do(func() {
alertDefLabels = make(map[string]string)
err := json.Unmarshal([]byte(conf.Options.MonitorMatchLabelsStr), &alertDefLabels)
if err != nil {
fmt.Println("Error parsing JSON:", err)
}
})
return alertDefLabels
} }
// GetPrometheusRuleName 获取规则CRD名称 // GetPrometheusRuleId 获取规则CRD名称
func GetPrometheusRuleName(alertRulesId string) string { func GetPrometheusRuleId(alertPolicyId string) string {
return fmt.Sprintf("%s-%s", PrometheusRuleNamePrefix, alertRulesId) return fmt.Sprintf("%s-%s", conf.Options.PrometheusRuleNamePrefix, alertPolicyId)
} }
// GetPrometheusRuleGroupName 获取规则组名称 // GetPrometheusRuleGroupName 获取规则组名称
...@@ -43,19 +59,19 @@ type PrometheusRule struct { ...@@ -43,19 +59,19 @@ type PrometheusRule struct {
func (p PrometheusRule) Create(pRule *monitoringv1.PrometheusRule) error { func (p PrometheusRule) Create(pRule *monitoringv1.PrometheusRule) error {
k8sSvc := K8sSvc{Header: p.Header} k8sSvc := K8sSvc{Header: p.Header}
c := &Content{Kind: PrometheusRuleKind, ApiVersion: PrometheusRuleApiVersion, Metadata: pRule.ObjectMeta, Spec: pRule.Spec} c := &Content{Kind: "PrometheusRule", ApiVersion: conf.Options.MonitorApiVersion, Metadata: pRule.ObjectMeta, Spec: pRule.Spec}
_, err := k8sSvc.SendFile(c) _, err := k8sSvc.SendFile(c)
return err return err
} }
func (p PrometheusRule) Delete(namespace string, name string) error { func (p PrometheusRule) Delete(namespace string, name string) error {
delUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, PrometheusRuleName, namespace, name) delUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, GetPrometheusRuleCRDName(), namespace, name)
_, err := util.ProxySendRes("DELETE", delUrl, "", p.Header) _, err := util.ProxySendRes("DELETE", delUrl, "", p.Header)
return err return err
} }
func (p PrometheusRule) Update(pRule *monitoringv1.PrometheusRule) error { func (p PrometheusRule) Update(pRule *monitoringv1.PrometheusRule) error {
updateUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, PrometheusRuleName, pRule.Namespace, pRule.Name) updateUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, GetPrometheusRuleCRDName(), pRule.Namespace, pRule.Name)
body, _ := json.Marshal(pRule) body, _ := json.Marshal(pRule)
p.Header["Content-Type"] = "application/json" p.Header["Content-Type"] = "application/json"
_, err := util.ProxySendRes("PUT", updateUrl, string(body), p.Header) _, err := util.ProxySendRes("PUT", updateUrl, string(body), p.Header)
...@@ -63,7 +79,7 @@ func (p PrometheusRule) Update(pRule *monitoringv1.PrometheusRule) error { ...@@ -63,7 +79,7 @@ func (p PrometheusRule) Update(pRule *monitoringv1.PrometheusRule) error {
} }
func (p PrometheusRule) Get(namespace string, name string) (obj *monitoringv1.PrometheusRule, err error) { func (p PrometheusRule) Get(namespace string, name string) (obj *monitoringv1.PrometheusRule, err error) {
getUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, PrometheusRuleName, namespace, name) getUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, GetPrometheusRuleCRDName(), namespace, name)
res, err := util.ProxySendRes("GET", getUrl, "", p.Header) res, err := util.ProxySendRes("GET", getUrl, "", p.Header)
if err != nil { if err != nil {
return return
......
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"xorm.io/xorm" "xorm.io/xorm"
...@@ -25,6 +26,9 @@ func (m *MetricConfigSvc) Add(session *xorm.Session, req request.AddMetricConfig ...@@ -25,6 +26,9 @@ func (m *MetricConfigSvc) Add(session *xorm.Session, req request.AddMetricConfig
UpdatedBy: m.User.SystemAccount, UpdatedBy: m.User.SystemAccount,
UpdatedAt: now, UpdatedAt: now,
} }
if req.Source != constant.SourceCustom {
req.Source = constant.SourceDefault
}
_ = copier.Copy(&data, &req) _ = copier.Copy(&data, &req)
data.AlertRange = util.ConvertToString(req.AlertRange) data.AlertRange = util.ConvertToString(req.AlertRange)
_, err = session.Insert(&data) _, err = session.Insert(&data)
...@@ -89,6 +93,17 @@ func (m *MetricConfigSvc) List(req request.ListMetricConfig) (resp response.Metr ...@@ -89,6 +93,17 @@ func (m *MetricConfigSvc) List(req request.ListMetricConfig) (resp response.Metr
return return
} }
func (m *MetricConfigSvc) NameList() (resp response.MetricConfigList, err error) {
db, err := client.GetDbClient()
if err != nil {
return
}
session := db.NewSession()
defer session.Close()
resp.TotalCount, err = session.Select("id,metric_name").FindAndCount(&resp.List)
return
}
func (m *MetricConfigSvc) Delete(ids []string) (err error) { func (m *MetricConfigSvc) Delete(ids []string) (err error) {
db, err := client.GetDbClient() db, err := client.GetDbClient()
if err != nil { if err != nil {
......
...@@ -26,10 +26,10 @@ func (p *PrometheusSvc) Label(req request.PrometheusLabel) (resp response.Promet ...@@ -26,10 +26,10 @@ func (p *PrometheusSvc) Label(req request.PrometheusLabel) (resp response.Promet
if req.LabelName != "" { if req.LabelName != "" {
url := fmt.Sprintf("%s%s", conf.Options.PrometheusHost, "/api/v1/series") url := fmt.Sprintf("%s%s", conf.Options.PrometheusHost, "/api/v1/series")
bytes, _ := util.Request(url, http.MethodPost, response, _ := util.Request(url, http.MethodPost,
[]byte(fmt.Sprintf("match[]=%s", req.LabelName)), []byte(fmt.Sprintf("match[]=%s", req.LabelName)),
map[string]string{"Content-Type": util.MediaTypeForm}) map[string]string{"Content-Type": util.MediaTypeForm})
_ = json.Unmarshal(bytes, &prometheusSeries) _ = json.Unmarshal(response.Body(), &prometheusSeries)
for _, v := range prometheusSeries.Data { for _, v := range prometheusSeries.Data {
for k, _ := range v { for k, _ := range v {
resp.List = append(resp.List, k) resp.List = append(resp.List, k)
...@@ -41,8 +41,8 @@ func (p *PrometheusSvc) Label(req request.PrometheusLabel) (resp response.Promet ...@@ -41,8 +41,8 @@ func (p *PrometheusSvc) Label(req request.PrometheusLabel) (resp response.Promet
} else { } else {
url := fmt.Sprintf("%s%s", conf.Options.PrometheusHost, "/api/v1/label/__name__/values") url := fmt.Sprintf("%s%s", conf.Options.PrometheusHost, "/api/v1/label/__name__/values")
bytes, _ := util.Request(url, http.MethodGet, nil, nil) response, _ := util.Request(url, http.MethodGet, nil, nil)
_ = json.Unmarshal(bytes, &prometheusLabel) _ = json.Unmarshal(response.Body(), &prometheusLabel)
resp.TotalCount = int64(len(prometheusLabel.Data)) resp.TotalCount = int64(len(prometheusLabel.Data))
resp.List = prometheusLabel.Data resp.List = prometheusLabel.Data
} }
...@@ -57,10 +57,10 @@ func (p *PrometheusSvc) LabelValue(req request.PrometheusLabelValue) (resp respo ...@@ -57,10 +57,10 @@ func (p *PrometheusSvc) LabelValue(req request.PrometheusLabelValue) (resp respo
) )
url := fmt.Sprintf("%s%s", conf.Options.PrometheusHost, "/api/v1/series") url := fmt.Sprintf("%s%s", conf.Options.PrometheusHost, "/api/v1/series")
bytes, _ := util.Request(url, http.MethodPost, response, _ := util.Request(url, http.MethodPost,
[]byte(fmt.Sprintf("match[]=%s", req.MetricName)), []byte(fmt.Sprintf("match[]=%s", req.MetricName)),
map[string]string{"Content-Type": util.MediaTypeForm}) map[string]string{"Content-Type": util.MediaTypeForm})
_ = json.Unmarshal(bytes, &prometheusSeries) _ = json.Unmarshal(response.Body(), &prometheusSeries)
for _, v := range prometheusSeries.Data { for _, v := range prometheusSeries.Data {
for key, value := range v { for key, value := range v {
metricLabelMap[key] = append(metricLabelMap[key], value) metricLabelMap[key] = append(metricLabelMap[key], value)
......
package service package service
import ( import (
"errors"
"fmt" "fmt"
json "github.com/json-iterator/go"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"github.com/spf13/cast" "github.com/spf13/cast"
"github.com/tidwall/gjson"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/service/k8s" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/service/k8s"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"go.uber.org/zap" "go.uber.org/zap"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"net/http"
"net/url"
"strings" "strings"
"sync"
) )
var prometheusRuleLabel map[string]string
var once sync.Once
func initPrometheusRuleLabel() {
once.Do(func() {
str := conf.Options.PrometheusRuleLabel
err := json.Unmarshal([]byte(str), &prometheusRuleLabel)
if err != nil {
prometheusRuleLabel = map[string]string{ // 返回默认标签
"source": "aiops-systemmonitor-api",
}
}
})
}
// GetPrometheusRuleLabel 返回 prometheusRuleLabel 单例
func GetPrometheusRuleLabel() map[string]string {
initPrometheusRuleLabel()
return prometheusRuleLabel
}
type PrometheusRuleSvc struct { type PrometheusRuleSvc struct {
User entity.SystemUserInfo User entity.SystemUserInfo
} }
func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) { func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) {
prometheusRuleName := k8s.GetPrometheusRuleName(data.Id) prometheusRuleObjName := k8s.GetPrometheusRuleId(data.Id)
pr := monitoringv1.PrometheusRule{ pr := monitoringv1.PrometheusRule{
ObjectMeta: v1.ObjectMeta{ ObjectMeta: v1.ObjectMeta{
Name: prometheusRuleName, Name: prometheusRuleObjName,
Namespace: k8s.Namespace, Namespace: conf.Options.MonitorMatchNs,
Labels: k8s.AlertDefLabels, Labels: k8s.GetAlertDefLabels(),
}, },
} }
...@@ -38,17 +66,24 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) { ...@@ -38,17 +66,24 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) {
item := fmt.Sprintf(`%s%s"%s"`, v.MetricLabel, v.Compare, v.Value) // http_requests_total{method="GET",pod="LeaseGrant"} item := fmt.Sprintf(`%s%s"%s"`, v.MetricLabel, v.Compare, v.Value) // http_requests_total{method="GET",pod="LeaseGrant"}
data.Expr = strings.ReplaceAll(data.Expr, v.VariableName, item) data.Expr = strings.ReplaceAll(data.Expr, v.VariableName, item)
} }
for _, v := range data.AlertCondition { for k, v := range data.AlertCondition {
labels := map[string]string{
"severity": "warning",
"risk_level": cast.ToString(v.RiskLevel),
"risk_level_name": constant.RiskLeveText(v.RiskLevel),
"namespace": conf.Options.MonitorMatchNs,
"alert_rules_id": data.Id,
"metric_config_id": data.MetricConfigId,
}
for key, value := range GetPrometheusRuleLabel() {
labels[key] = value
}
rule := monitoringv1.Rule{ rule := monitoringv1.Rule{
Alert: data.MetricConfigName, // promhttp超过5万次告警-prom指标控制器请求数-较大风险-3
For: &ruleFor, Alert: fmt.Sprintf("%s-%s-%s-%d", data.MetricName, data.MetricConfigName, constant.RiskLeveText(v.RiskLevel), k+1),
Labels: map[string]string{ For: &ruleFor,
"severity": "warning", Labels: labels,
"risk_level": cast.ToString(v.RiskLevel),
"risk_level_name": constant.RiskLeveText(v.RiskLevel),
"source": "so-operation-api",
"alert_rules_id": data.MetricConfigId,
},
Annotations: map[string]string{ Annotations: map[string]string{
"value": "{{ $value }}", "value": "{{ $value }}",
"summary": fmt.Sprintf("分组名:%s, 检查周期:%s, 持续时间:%s", group.Name, string(groupInterval), string(ruleFor)), "summary": fmt.Sprintf("分组名:%s, 检查周期:%s, 持续时间:%s", group.Name, string(groupInterval), string(ruleFor)),
...@@ -68,6 +103,11 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) { ...@@ -68,6 +103,11 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) {
condition += 2 condition += 2
} }
// 为"空"状态下,默认表达式已经有比较判断,故直接使用表达式即可
if data.AlertRuleTypeName == "空" {
condition = 0
}
switch condition { switch condition {
default: default:
expr = data.Expr expr = data.Expr
...@@ -79,6 +119,12 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) { ...@@ -79,6 +119,12 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) {
expr = fmt.Sprintf("%s <= %s <=%s", cast.ToString(v.ThresholdsMin), data.Expr, cast.ToString(v.ThresholdsMax)) expr = fmt.Sprintf("%s <= %s <=%s", cast.ToString(v.ThresholdsMin), data.Expr, cast.ToString(v.ThresholdsMax))
} }
// 校验表达式正确性
err = CheckPrometheusQuerySyntax(expr)
if err != nil {
return
}
rule.Expr = intstr.FromString(expr) rule.Expr = intstr.FromString(expr)
group.Rules = append(group.Rules, rule) group.Rules = append(group.Rules, rule)
} }
...@@ -91,12 +137,12 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) { ...@@ -91,12 +137,12 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) {
} }
func (p *PrometheusRuleSvc) Get(data response.AlertRulesItem) (obj *monitoringv1.PrometheusRule, exist bool, err error) { func (p *PrometheusRuleSvc) Get(data response.AlertRulesItem) (obj *monitoringv1.PrometheusRule, exist bool, err error) {
prometheusRuleName := k8s.GetPrometheusRuleName(data.Id) prometheusRuleObjName := k8s.GetPrometheusRuleId(data.Id)
pr := monitoringv1.PrometheusRule{ pr := monitoringv1.PrometheusRule{
ObjectMeta: v1.ObjectMeta{ ObjectMeta: v1.ObjectMeta{
Name: prometheusRuleName, Name: prometheusRuleObjName,
Namespace: k8s.Namespace, Namespace: conf.Options.MonitorMatchNs,
Labels: k8s.AlertDefLabels, Labels: k8s.GetAlertDefLabels(),
}, },
} }
header := map[string]string{"Authorization": "Bearer " + conf.Options.KubernetesToken} header := map[string]string{"Authorization": "Bearer " + conf.Options.KubernetesToken}
...@@ -109,13 +155,26 @@ func (p *PrometheusRuleSvc) Get(data response.AlertRulesItem) (obj *monitoringv1 ...@@ -109,13 +155,26 @@ func (p *PrometheusRuleSvc) Get(data response.AlertRulesItem) (obj *monitoringv1
return return
} }
// CheckPrometheusQuerySyntax 校验普罗米修斯语法正确性
func CheckPrometheusQuerySyntax(expr string) error {
params := url.Values{}
params.Add("query", expr)
query := params.Encode()
webUrl := fmt.Sprintf("%s%s%s", conf.Options.PrometheusHost, "/api/v1/query?", query)
resp, _ := util.Request(webUrl, http.MethodGet, nil, nil)
if resp.StatusCode() != http.StatusOK {
return errors.New(fmt.Sprintf("%s, err: %s", "普罗米修斯语法PromQL错误", gjson.GetBytes(resp.Body(), "error").String()))
}
return nil
}
func (p *PrometheusRuleSvc) Delete(data response.AlertRulesItem) (err error) { func (p *PrometheusRuleSvc) Delete(data response.AlertRulesItem) (err error) {
prometheusRuleName := k8s.GetPrometheusRuleName(data.Id) prometheusRuleObjName := k8s.GetPrometheusRuleId(data.Id)
pr := monitoringv1.PrometheusRule{ pr := monitoringv1.PrometheusRule{
ObjectMeta: v1.ObjectMeta{ ObjectMeta: v1.ObjectMeta{
Name: prometheusRuleName, Name: prometheusRuleObjName,
Namespace: k8s.Namespace, Namespace: conf.Options.MonitorMatchNs,
Labels: k8s.AlertDefLabels, Labels: k8s.GetAlertDefLabels(),
}, },
} }
......
...@@ -272,85 +272,6 @@ func (t *TaskManageSvc) ExecScript(req request.ExecScriptReq, script string) (id ...@@ -272,85 +272,6 @@ func (t *TaskManageSvc) ExecScript(req request.ExecScriptReq, script string) (id
return return
} }
go ExecAnsible(id, req.TaskId, req.Value) go ExecAnsible(id, req.TaskId, req.Value)
////执行ansible命令
//var cmd *exec.Cmd
//if req.Value != "" {
// cmd = exec.Command("ansible-playbook", "-i", "/etc/ansible/hosts_"+fmt.Sprintf("%d", req.TaskId), "/etc/ansible/ansible_"+fmt.Sprintf("%d", req.TaskId)+".yml", "--extra-vars", req.Value)
//} else {
// cmd = exec.Command("ansible-playbook", "-i", "/etc/ansible/hosts_"+fmt.Sprintf("%d", req.TaskId), "/etc/ansible/ansible_"+fmt.Sprintf("%d", req.TaskId)+".yml")
//}
////ansible-playbook -i /tmp/hosts --list-hosts debug.yml
////捕获正常日志
//stdout, err := cmd.StdoutPipe()
//if err != nil {
// err = resp.CmdExecError.WithError(err)
// return
//}
////捕获异常日志
//stderr, err := cmd.StderrPipe()
//if err != nil {
// err = resp.CmdExecError.WithError(err)
// return
//}
////执行cmd命令
//if err = cmd.Start(); err != nil {
// err = resp.CmdExecError.WithError(err)
// return
//}
////获取 正常/异常 输出流
//outputBuf := bufio.NewReader(stdout)
//readerr := bufio.NewReader(stderr)
//
//var out, outErr int
//var execLog string
//for {
//
// //逐行输出日志
// lineOut, err1 := outputBuf.ReadString('\n')
// if (err1 != nil || io.EOF == err1) && out == 0 {
// out = 1
// } else if out == 0 {
// //存储执行日志
// execLog = execLog + lineOut + " \n "
// UpdateExecHistory(request.UpdateExecHistory{
// TaskHistoryId: id,
// ExecLog: execLog,
// })
// }
//
// lineErr, err2 := readerr.ReadString('\n')
// if (err2 != nil || io.EOF == err2) && outErr == 0 {
// outErr = 1
// } else if outErr == 0 {
// //存储异常执行日志
// execLog = execLog + lineErr + " \n "
// UpdateExecHistory(request.UpdateExecHistory{
// TaskHistoryId: id,
// ExecLog: execLog,
// })
// }
//
// if out == 1 && outErr == 1 {
// break
// }
//}
//cmd.Wait()
//
//if cmd.ProcessState.Success() {
// //任务执行成功
// UpdateExecHistory(request.UpdateExecHistory{
// TaskHistoryId: id,
// ExecLog: execLog,
// State: 1,
// })
//} else {
// //任务执行失败
// UpdateExecHistory(request.UpdateExecHistory{
// TaskHistoryId: id,
// ExecLog: execLog,
// State: 2,
// })
//}
return return
} }
......
This diff is collapsed.
...@@ -60,7 +60,7 @@ Request("https://httpbin.org/put", ...@@ -60,7 +60,7 @@ Request("https://httpbin.org/put",
"Cookie": "aweToken=3ab9f63f-b0b3-4935-80ec-405d76ac111d", "Cookie": "aweToken=3ab9f63f-b0b3-4935-80ec-405d76ac111d",
}) })
*/ */
func Request(url string, method string, body []byte, headers map[string]string) ([]byte, error) { func Request(url string, method string, body []byte, headers map[string]string) (*fasthttp.Response, error) {
req := fasthttp.AcquireRequest() req := fasthttp.AcquireRequest()
defer fasthttp.ReleaseRequest(req) defer fasthttp.ReleaseRequest(req)
...@@ -98,8 +98,11 @@ func Request(url string, method string, body []byte, headers map[string]string) ...@@ -98,8 +98,11 @@ func Request(url string, method string, body []byte, headers map[string]string)
return nil, err return nil, err
} }
result := new(fasthttp.Response)
resp.CopyTo(result)
// 返回响应体和错误信息 // 返回响应体和错误信息
return resp.Body(), nil return result, nil
} }
// HttpSend , http请求 GET/DELETE/POST/PUT // HttpSend , http请求 GET/DELETE/POST/PUT
......
...@@ -16,3 +16,14 @@ func ConvertToString(v interface{}) string { ...@@ -16,3 +16,14 @@ func ConvertToString(v interface{}) string {
} }
return string(jsonData) return string(jsonData)
} }
// IntsToStrings 将int切片转换为字符串切片
func IntsToStrings(ints []int) []string {
strs := make([]string, len(ints))
for i, v := range ints {
strs[i] = fmt.Sprint(v)
}
return strs
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment