Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
so-operation-api
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
smart-operation
so-operation-api
Commits
de712f7c
You need to sign in or sign up before continuing.
Commit
de712f7c
authored
Nov 16, 2023
by
黄智
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/dev' into dev
parents
847da67f
b4a16368
Changes
40
Hide whitespace changes
Inline
Side-by-side
Showing
40 changed files
with
1243 additions
and
674 deletions
+1243
-674
go.mod
go.mod
+4
-0
go.sum
go.sum
+8
-0
src/bean/entity/alert_class.go
src/bean/entity/alert_class.go
+9
-9
src/bean/entity/alert_overview.go
src/bean/entity/alert_overview.go
+3
-19
src/bean/entity/alert_webhook.go
src/bean/entity/alert_webhook.go
+0
-7
src/bean/entity/metric_config.go
src/bean/entity/metric_config.go
+1
-1
src/bean/entity/system_user.go
src/bean/entity/system_user.go
+2
-2
src/bean/entity/work_order.go
src/bean/entity/work_order.go
+8
-6
src/bean/vo/request/alert.go
src/bean/vo/request/alert.go
+9
-8
src/bean/vo/request/alert_class.go
src/bean/vo/request/alert_class.go
+5
-4
src/bean/vo/request/alert_rules.go
src/bean/vo/request/alert_rules.go
+1
-1
src/bean/vo/request/alert_webhook.go
src/bean/vo/request/alert_webhook.go
+1
-1
src/bean/vo/request/metric_config.go
src/bean/vo/request/metric_config.go
+2
-2
src/bean/vo/request/work_order.go
src/bean/vo/request/work_order.go
+2
-2
src/bean/vo/response/alert.go
src/bean/vo/response/alert.go
+43
-0
src/bean/vo/response/alert_overview.go
src/bean/vo/response/alert_overview.go
+3
-3
src/common/conf/options.go
src/common/conf/options.go
+12
-1
src/controller/alert.go
src/controller/alert.go
+1
-0
src/controller/alert_webhook.go
src/controller/alert_webhook.go
+8
-2
src/controller/work_order_manage.go
src/controller/work_order_manage.go
+34
-0
src/main.go
src/main.go
+33
-32
src/pkg/beagle/constant/constant.go
src/pkg/beagle/constant/constant.go
+44
-1
src/router/alertrouter.go.go
src/router/alertrouter.go.go
+2
-1
src/router/alertrulesrouter.go.go
src/router/alertrulesrouter.go.go
+2
-1
src/router/metricconfigrouter.go
src/router/metricconfigrouter.go
+3
-2
src/router/workorderrouter.go
src/router/workorderrouter.go
+4
-5
src/service/alert.go
src/service/alert.go
+154
-32
src/service/alert_class.go
src/service/alert_class.go
+80
-8
src/service/alert_overview.go
src/service/alert_overview.go
+390
-198
src/service/alert_rules.go
src/service/alert_rules.go
+61
-27
src/service/alert_webhook.go
src/service/alert_webhook.go
+25
-7
src/service/cron/common.go
src/service/cron/common.go
+0
-2
src/service/k8s/prometheusrule.go
src/service/k8s/prometheusrule.go
+35
-19
src/service/metric_config.go
src/service/metric_config.go
+15
-0
src/service/prometheus.go
src/service/prometheus.go
+6
-6
src/service/prometheusrule.go
src/service/prometheusrule.go
+81
-22
src/service/task_manage.go
src/service/task_manage.go
+0
-79
src/service/work_order.go
src/service/work_order.go
+136
-162
src/util/http.go
src/util/http.go
+5
-2
src/util/serialize.go
src/util/serialize.go
+11
-0
No files found.
go.mod
View file @
de712f7c
...
@@ -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
...
...
go.sum
View file @
de712f7c
...
@@ -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=
...
...
src/bean/entity/alert_class.go
View file @
de712f7c
...
@@ -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'"`
// 排序
Source
From
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
{
...
...
src/bean/entity/alert_overview.go
View file @
de712f7c
...
@@ -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
{
...
...
src/bean/entity/alert_webhook.go
deleted
100644 → 0
View file @
847da67f
package
entity
import
(
"github.com/prometheus/alertmanager/notify/webhook"
)
type
Message
webhook
.
Message
src/bean/entity/metric_config.go
View file @
de712f7c
...
@@ -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'"`
// 预警规则类型 关联字典表
Source
From
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'"`
// 更新人
...
...
src/bean/entity/system_user.go
View file @
de712f7c
...
@@ -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启用
...
...
src/bean/entity/work_order.go
View file @
de712f7c
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"`
// 定时规则
...
...
src/bean/vo/request/alert.go
View file @
de712f7c
...
@@ -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
}
}
...
...
src/bean/vo/request/alert_class.go
View file @
de712f7c
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"`
Source
From
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"`
}
}
...
...
src/bean/vo/request/alert_rules.go
View file @
de712f7c
...
@@ -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"`
// 预警规则 字典值
...
...
src/bean/vo/request/alert_webhook.go
View file @
de712f7c
...
@@ -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"`
// 预警规则 字典值
...
...
src/bean/vo/request/metric_config.go
View file @
de712f7c
...
@@ -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"`
// 预警规则类型 关联字典表
Source
From
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"`
// 预警规则类型 关联字典表
Source
From
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
{
...
...
src/bean/vo/request/work_order.go
View file @
de712f7c
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"`
// 工单描述
...
...
src/bean/vo/response/alert.go
View file @
de712f7c
...
@@ -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"`
}
src/bean/vo/response/alert_overview.go
View file @
de712f7c
...
@@ -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
.
Alert
StatusDistribution
`json:"alert_status_distribution"`
AlertStatusDistribution
[]
entity
.
Alert
Distribution
`json:"alert_status_distribution"`
AlertClassDistribution
[]
entity
.
Alert
ClassDistribution
`json:"alert_class_distribution"`
AlertClassDistribution
[]
entity
.
Alert
Distribution
`json:"alert_class_distribution"`
AlertFrequencyDistribution
entity
.
AlertFrequencyDistribution
`json:"alert_frequency_distribution"`
AlertFrequencyDistribution
entity
.
AlertFrequencyDistribution
`json:"alert_frequency_distribution"`
}
}
...
...
src/common/conf/options.go
View file @
de712f7c
...
@@ -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
(
...
...
src/controller/alert.go
View file @
de712f7c
...
@@ -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
)
...
...
src/controller/alert_webhook.go
View file @
de712f7c
...
@@ -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
)
...
...
src/controller/work_order_manage.go
View file @
de712f7c
...
@@ -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
)
}
src/main.go
View file @
de712f7c
...
@@ -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
(
"S
ms_Template_Alert
"
,
"SMS_461975765"
),
// 预警短信模板 // 短信工单下发模板
SmsTemplateAlert
:
util
.
SetEnvStr
(
"S
MS_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())
// }
//}
}
}
src/pkg/beagle/constant/constant.go
View file @
de712f7c
...
@@ -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
//自定义时间
)
src/router/alertrouter.go.go
View file @
de712f7c
...
@@ -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
)
...
...
src/router/alertrulesrouter.go.go
View file @
de712f7c
...
@@ -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
)
...
...
src/router/metricconfigrouter.go
View file @
de712f7c
...
@@ -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
)
...
...
src/router/workorderrouter.go
View file @
de712f7c
...
@@ -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)
}
}
src/service/alert.go
View file @
de712f7c
...
@@ -32,8 +32,7 @@ type AlertSvc struct {
...
@@ -32,8 +32,7 @@ type AlertSvc struct {
}
}
var
(
var
(
OpenSearchIndex
=
"so_alert"
Mapping
=
strings
.
NewReader
(
`{
Mapping
=
strings
.
NewReader
(
`{
"settings": {
"settings": {
"number_of_shards": 1,
"number_of_shards": 1,
"number_of_replicas": 0,
"number_of_replicas": 0,
...
@@ -283,13 +282,50 @@ var (
...
@@ -283,13 +282,50 @@ var (
}`
)
}`
)
)
)
func
(
a
*
AlertSvc
)
CreateIndex
()
error
{
func
CheckAndCreateIndex
()
(
err
error
)
{
exist
,
err
:=
checkIndexExists
(
conf
.
Options
.
OpenSearchIndex
)
if
err
!=
nil
{
return
}
if
exist
{
return
nil
}
err
=
CreateIndex
(
conf
.
Options
.
OpenSearchIndex
)
if
err
!=
nil
{
return
err
}
return
nil
}
func
checkIndexExists
(
indexName
string
)
(
exist
bool
,
err
error
)
{
cli
,
err
:=
client
.
GetOpenSearch
()
if
err
!=
nil
{
return
}
req
:=
opensearchapi
.
IndicesExistsRequest
{
Index
:
[]
string
{
indexName
}}
res
,
err
:=
req
.
Do
(
context
.
Background
(),
cli
)
if
err
!=
nil
{
return
false
,
err
}
defer
res
.
Body
.
Close
()
if
res
.
StatusCode
==
http
.
StatusOK
{
return
true
,
nil
}
else
if
res
.
StatusCode
==
http
.
StatusNotFound
{
return
false
,
nil
}
else
{
return
false
,
fmt
.
Errorf
(
"请求失败,状态码:%d"
,
res
.
StatusCode
)
}
}
func
CreateIndex
(
indexName
string
)
error
{
cli
,
err
:=
client
.
GetOpenSearch
()
cli
,
err
:=
client
.
GetOpenSearch
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
res
:=
opensearchapi
.
IndicesCreateRequest
{
res
:=
opensearchapi
.
IndicesCreateRequest
{
Index
:
OpenSearchIndex
,
Index
:
indexName
,
Body
:
Mapping
,
Body
:
Mapping
,
}
}
do
,
err
:=
res
.
Do
(
context
.
Background
(),
cli
)
do
,
err
:=
res
.
Do
(
context
.
Background
(),
cli
)
...
@@ -309,7 +345,7 @@ func (a *AlertSvc) DeleteIndex() error {
...
@@ -309,7 +345,7 @@ func (a *AlertSvc) DeleteIndex() error {
return
err
return
err
}
}
res
:=
opensearchapi
.
IndicesDeleteRequest
{
res
:=
opensearchapi
.
IndicesDeleteRequest
{
Index
:
[]
string
{
OpenSearchIndex
},
Index
:
[]
string
{
conf
.
Options
.
OpenSearchIndex
},
}
}
do
,
err
:=
res
.
Do
(
context
.
Background
(),
cli
)
do
,
err
:=
res
.
Do
(
context
.
Background
(),
cli
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -390,8 +426,10 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er
...
@@ -390,8 +426,10 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er
// 请输入预警点/分类/指标
// 请输入预警点/分类/指标
if
req
.
Keyword
!=
""
{
if
req
.
Keyword
!=
""
{
subBoolQuery
:=
elastic
.
NewBoolQuery
()
subBoolQuery
:=
elastic
.
NewBoolQuery
()
subBoolQuery
.
Should
(
elastic
.
NewMultiMatchQuery
(
req
.
Keyword
,
"alert_point"
,
"class_parent_name"
,
"class_name"
,
"metric_config_name"
))
subBoolQuery
.
Should
(
elastic
.
NewWildcardQuery
(
"alert_point.keyword"
,
fmt
.
Sprintf
(
"*%s*"
,
req
.
Keyword
)))
//subBoolQuery.Should(elastic.NewMatchQuery("class_name", req.Keyword))
subBoolQuery
.
Should
(
elastic
.
NewWildcardQuery
(
"class_parent_name.keyword"
,
fmt
.
Sprintf
(
"*%s*"
,
req
.
Keyword
)))
subBoolQuery
.
Should
(
elastic
.
NewWildcardQuery
(
"class_name.keyword"
,
fmt
.
Sprintf
(
"*%s*"
,
req
.
Keyword
)))
subBoolQuery
.
Should
(
elastic
.
NewWildcardQuery
(
"metric_config_name.keyword"
,
fmt
.
Sprintf
(
"*%s*"
,
req
.
Keyword
)))
boolQuery
.
Must
(
subBoolQuery
)
boolQuery
.
Must
(
subBoolQuery
)
}
}
...
@@ -399,6 +437,11 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er
...
@@ -399,6 +437,11 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er
boolQuery
.
Filter
(
elastic
.
NewRangeQuery
(
"created_at"
)
.
Gte
(
req
.
StartTime
)
.
Lte
(
req
.
EndTime
))
boolQuery
.
Filter
(
elastic
.
NewRangeQuery
(
"created_at"
)
.
Gte
(
req
.
StartTime
)
.
Lte
(
req
.
EndTime
))
}
}
if
req
.
SystemAccount
!=
""
{
// 匹配我的预警工单
boolQuery
.
Must
(
elastic
.
NewNestedQuery
(
"push_records"
,
elastic
.
NewTermQuery
(
"push_records.system_account"
,
req
.
SystemAccount
)))
}
querySource
,
_
:=
boolQuery
.
Source
()
querySource
,
_
:=
boolQuery
.
Source
()
b
,
_
:=
json
.
Marshal
(
querySource
)
b
,
_
:=
json
.
Marshal
(
querySource
)
log
.
Printf
(
"es statements: %s
\n
"
,
string
(
b
))
log
.
Printf
(
"es statements: %s
\n
"
,
string
(
b
))
...
@@ -425,7 +468,7 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er
...
@@ -425,7 +468,7 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er
"size": %d}`
,
string
(
b
),
req
.
GetPageSize
()
*
(
req
.
GetPage
()
-
1
),
req
.
GetPageSize
()))
"size": %d}`
,
string
(
b
),
req
.
GetPageSize
()
*
(
req
.
GetPage
()
-
1
),
req
.
GetPageSize
()))
res
:=
opensearchapi
.
SearchRequest
{
res
:=
opensearchapi
.
SearchRequest
{
Index
:
[]
string
{
OpenSearchIndex
},
Index
:
[]
string
{
conf
.
Options
.
OpenSearchIndex
},
Body
:
content
,
Body
:
content
,
Sort
:
[]
string
{
"id"
},
Sort
:
[]
string
{
"id"
},
}
}
...
@@ -451,7 +494,39 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er
...
@@ -451,7 +494,39 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er
for
_
,
hit
:=
range
sources
.
Hits
.
Hits
{
for
_
,
hit
:=
range
sources
.
Hits
.
Hits
{
resp
.
List
=
append
(
resp
.
List
,
hit
.
Source
)
resp
.
List
=
append
(
resp
.
List
,
hit
.
Source
)
}
}
resp
.
TotalCount
=
int64
(
len
(
resp
.
List
))
// 推送人数:推送记录中去重的人数
// 推送次数:发起推送的总次数(钉钉、短信、工单算单次)
for
i
:=
0
;
i
<
len
(
resp
.
List
);
i
++
{
var
userSet
[]
string
var
pushCountSet
[]
string
mergedData
:=
make
(
map
[
string
]
entity
.
PushRecord
)
for
_
,
record
:=
range
resp
.
List
[
i
]
.
PushRecords
{
userSet
=
append
(
userSet
,
record
.
SystemAccount
)
pushCountSet
=
append
(
pushCountSet
,
record
.
PushTime
.
String
())
key
:=
record
.
AlertRulesId
+
record
.
PushTime
.
String
()
// 映射中已存在相同键的数据,则合并user_id
if
existingRecord
,
found
:=
mergedData
[
key
];
found
{
existingRecord
.
SystemAccount
+=
", "
+
record
.
SystemAccount
existingRecord
.
UserName
+=
", "
+
record
.
UserName
mergedData
[
key
]
=
existingRecord
}
else
{
mergedData
[
key
]
=
record
}
}
var
mergedRecords
[]
entity
.
PushRecord
for
_
,
v
:=
range
mergedData
{
mergedRecords
=
append
(
mergedRecords
,
v
)
}
resp
.
List
[
i
]
.
PushRecords
=
mergedRecords
resp
.
List
[
i
]
.
NotificationCount
=
len
(
funk
.
UniqString
(
userSet
))
resp
.
List
[
i
]
.
PushCount
=
len
(
funk
.
UniqString
(
pushCountSet
))
}
resp
.
TotalCount
=
int64
(
sources
.
Hits
.
Total
.
Value
)
return
return
}
}
...
@@ -482,7 +557,7 @@ func (a *AlertSvc) IndexDocExist(req request.ExistAlert) (exist bool, err error)
...
@@ -482,7 +557,7 @@ func (a *AlertSvc) IndexDocExist(req request.ExistAlert) (exist bool, err error)
"size": %d}`
,
string
(
b
),
0
,
1
))
"size": %d}`
,
string
(
b
),
0
,
1
))
res
:=
opensearchapi
.
SearchRequest
{
res
:=
opensearchapi
.
SearchRequest
{
Index
:
[]
string
{
OpenSearchIndex
},
Index
:
[]
string
{
conf
.
Options
.
OpenSearchIndex
},
Body
:
content
,
Body
:
content
,
Sort
:
[]
string
{
"id"
},
Sort
:
[]
string
{
"id"
},
}
}
...
@@ -525,7 +600,7 @@ func (a *AlertSvc) CatCount(indexName ...string) (count int) {
...
@@ -525,7 +600,7 @@ func (a *AlertSvc) CatCount(indexName ...string) (count int) {
if
len
(
indexName
)
>
0
&&
indexName
[
0
]
!=
""
{
if
len
(
indexName
)
>
0
&&
indexName
[
0
]
!=
""
{
index
=
indexName
[
0
]
+
"*"
index
=
indexName
[
0
]
+
"*"
}
else
{
}
else
{
index
=
OpenSearchIndex
+
"*"
index
=
conf
.
Options
.
OpenSearchIndex
+
"*"
}
}
res
:=
opensearchapi
.
CatCountRequest
{
res
:=
opensearchapi
.
CatCountRequest
{
...
@@ -555,6 +630,66 @@ func (a *AlertSvc) CatCount(indexName ...string) (count int) {
...
@@ -555,6 +630,66 @@ func (a *AlertSvc) CatCount(indexName ...string) (count int) {
return
return
}
}
func
(
a
*
AlertSvc
)
GetIndexMaxID
(
indexName
...
string
)
(
maxId
int
,
err
error
)
{
var
(
index
string
)
cli
,
err
:=
client
.
GetOpenSearch
()
if
err
!=
nil
{
return
0
,
err
}
if
len
(
indexName
)
>
0
&&
indexName
[
0
]
!=
""
{
index
=
indexName
[
0
]
}
else
{
index
=
conf
.
Options
.
OpenSearchIndex
}
// 构建 aggregation 查询
aggregationQuery
:=
`
{
"size": 0,
"aggs": {
"max_id": {
"max": {
"field": "id"
}
}
}
}
`
res
:=
opensearchapi
.
SearchRequest
{
Index
:
[]
string
{
index
},
Body
:
strings
.
NewReader
(
aggregationQuery
),
}
do
,
err
:=
res
.
Do
(
context
.
Background
(),
cli
)
if
err
!=
nil
{
return
0
,
err
}
defer
do
.
Body
.
Close
()
if
do
.
StatusCode
<
http
.
StatusOK
&&
do
.
StatusCode
>
http
.
StatusIMUsed
{
return
0
,
errors
.
New
(
do
.
String
())
}
// 解析聚合结果
var
responseMap
map
[
string
]
interface
{}
err
=
json
.
NewDecoder
(
do
.
Body
)
.
Decode
(
&
responseMap
)
if
err
!=
nil
{
return
0
,
err
}
// 提取最大值
aggregations
:=
responseMap
[
"aggregations"
]
.
(
map
[
string
]
interface
{})
maxIDAgg
:=
aggregations
[
"max_id"
]
.
(
map
[
string
]
interface
{})
maxIDValue
:=
maxIDAgg
[
"value"
]
maxId
=
cast
.
ToInt
(
maxIDValue
)
return
maxId
,
nil
}
func
(
a
*
AlertSvc
)
DocCreate
(
req
request
.
CreateAlert
)
(
err
error
)
{
func
(
a
*
AlertSvc
)
DocCreate
(
req
request
.
CreateAlert
)
(
err
error
)
{
var
(
var
(
sources
response
.
OpenSearchSource
sources
response
.
OpenSearchSource
...
@@ -574,7 +709,7 @@ func (a *AlertSvc) DocCreate(req request.CreateAlert) (err error) {
...
@@ -574,7 +709,7 @@ func (a *AlertSvc) DocCreate(req request.CreateAlert) (err error) {
content
:=
strings
.
NewReader
(
fmt
.
Sprintf
(
`%s`
,
docStr
))
content
:=
strings
.
NewReader
(
fmt
.
Sprintf
(
`%s`
,
docStr
))
res
:=
opensearchapi
.
CreateRequest
{
res
:=
opensearchapi
.
CreateRequest
{
Index
:
OpenSearchIndex
,
Index
:
conf
.
Options
.
OpenSearchIndex
,
DocumentID
:
cast
.
ToString
(
req
.
Id
),
DocumentID
:
cast
.
ToString
(
req
.
Id
),
Body
:
content
,
Body
:
content
,
}
}
...
@@ -654,7 +789,7 @@ func (a *AlertSvc) DocUpdate(req request.UpdateAlert) (err error) {
...
@@ -654,7 +789,7 @@ func (a *AlertSvc) DocUpdate(req request.UpdateAlert) (err error) {
}`
,
docStr
))
}`
,
docStr
))
res
:=
opensearchapi
.
UpdateRequest
{
res
:=
opensearchapi
.
UpdateRequest
{
Index
:
OpenSearchIndex
,
Index
:
conf
.
Options
.
OpenSearchIndex
,
DocumentID
:
cast
.
ToString
(
req
.
Id
),
DocumentID
:
cast
.
ToString
(
req
.
Id
),
Body
:
content
,
Body
:
content
,
Source
:
[]
string
{
"true"
},
Source
:
[]
string
{
"true"
},
...
@@ -688,7 +823,7 @@ func (a *AlertSvc) Create() error {
...
@@ -688,7 +823,7 @@ func (a *AlertSvc) Create() error {
return
err
return
err
}
}
res
:=
opensearchapi
.
IndicesCreateRequest
{
res
:=
opensearchapi
.
IndicesCreateRequest
{
Index
:
OpenSearchIndex
,
Index
:
conf
.
Options
.
OpenSearchIndex
,
Body
:
Mapping
,
Body
:
Mapping
,
}
}
do
,
err
:=
res
.
Do
(
context
.
Background
(),
cli
)
do
,
err
:=
res
.
Do
(
context
.
Background
(),
cli
)
...
@@ -715,17 +850,9 @@ func (a *AlertSvc) BatchPushAlert(req request.BatchPushAlert) (err error) {
...
@@ -715,17 +850,9 @@ func (a *AlertSvc) BatchPushAlert(req request.BatchPushAlert) (err error) {
}
}
for
_
,
alert
:=
range
alertList
.
List
{
for
_
,
alert
:=
range
alertList
.
List
{
pushRecords
:=
alert
.
PushRecords
pushRecords
:=
alert
.
PushRecords
// 原始推送记录
// TODO 批量推送短信
//alertRulesSvc := AlertRulesSvc{User: a.User}
/*var alertRulesItem response.AlertRulesItem
alertRulesItem, err = alertRulesSvc.GetDataById(request.DetailAlertRules{Id: alert.AlertRulesId})
if err != nil {
return
}*/
var
phones
[]
string
var
phones
[]
string
for
_
,
v
:=
range
req
.
NotifyRecipients
{
for
_
,
v
:=
range
req
.
NotifyRecipients
{
// +临时推送记录
phones
=
append
(
phones
,
v
.
Phone
)
phones
=
append
(
phones
,
v
.
Phone
)
pushRecords
=
append
(
pushRecords
,
entity
.
PushRecord
{
pushRecords
=
append
(
pushRecords
,
entity
.
PushRecord
{
AlertId
:
alert
.
Id
,
AlertId
:
alert
.
Id
,
...
@@ -745,7 +872,7 @@ func (a *AlertSvc) BatchPushAlert(req request.BatchPushAlert) (err error) {
...
@@ -745,7 +872,7 @@ func (a *AlertSvc) BatchPushAlert(req request.BatchPushAlert) (err error) {
})
})
}
}
for
_
,
method
:=
range
req
.
NotifyMethod
{
for
_
,
method
:=
range
req
.
NotifyMethod
{
// 按照通知方式循环推送
switch
method
{
// dingtalk sms
switch
method
{
// dingtalk sms
case
"sms"
:
// 发送短信
case
"sms"
:
// 发送短信
...
@@ -781,7 +908,7 @@ func (a *AlertSvc) BatchPushAlert(req request.BatchPushAlert) (err error) {
...
@@ -781,7 +908,7 @@ func (a *AlertSvc) BatchPushAlert(req request.BatchPushAlert) (err error) {
}
}
}
}
for
i
:=
0
;
i
<
len
(
pushRecords
);
i
++
{
for
i
:=
0
;
i
<
len
(
pushRecords
);
i
++
{
// id重新序列化
pushRecords
[
i
]
.
Id
=
i
+
1
pushRecords
[
i
]
.
Id
=
i
+
1
}
}
err
=
a
.
DocUpdate
(
request
.
UpdateAlert
{
err
=
a
.
DocUpdate
(
request
.
UpdateAlert
{
...
@@ -793,9 +920,6 @@ func (a *AlertSvc) BatchPushAlert(req request.BatchPushAlert) (err error) {
...
@@ -793,9 +920,6 @@ func (a *AlertSvc) BatchPushAlert(req request.BatchPushAlert) (err error) {
return
return
}
}
}
}
// TODO 批量推送用户告警
conf
.
Logger
.
Info
(
"batch push"
,
zap
.
Any
(
"payload"
,
req
))
time
.
Sleep
(
time
.
Second
)
time
.
Sleep
(
time
.
Second
)
return
nil
return
nil
}
}
...
@@ -844,12 +968,10 @@ func (a *AlertSvc) GetDataByAlertRulesIdAndRiskLevel(alertRulesId string, riskLe
...
@@ -844,12 +968,10 @@ func (a *AlertSvc) GetDataByAlertRulesIdAndRiskLevel(alertRulesId string, riskLe
func
(
a
*
AlertSvc
)
List
(
req
request
.
ListAlert
)
(
resp
response
.
AlertList
,
err
error
)
{
func
(
a
*
AlertSvc
)
List
(
req
request
.
ListAlert
)
(
resp
response
.
AlertList
,
err
error
)
{
resp
,
err
=
a
.
DocSearch
(
req
)
resp
,
err
=
a
.
DocSearch
(
req
)
resp
.
TotalCount
=
int64
(
len
(
resp
.
List
))
return
return
}
}
func
(
a
*
AlertSvc
)
DisposeAlert
(
req
request
.
DisposeAlert
)
(
err
error
)
{
func
(
a
*
AlertSvc
)
DisposeAlert
(
req
request
.
DisposeAlert
)
(
err
error
)
{
// TODO 我的预警工单处置
var
(
var
(
sources
response
.
OpenSearchSource
sources
response
.
OpenSearchSource
now
=
jsontime
.
Now
()
now
=
jsontime
.
Now
()
...
@@ -897,7 +1019,7 @@ func (a *AlertSvc) DisposeAlert(req request.DisposeAlert) (err error) {
...
@@ -897,7 +1019,7 @@ func (a *AlertSvc) DisposeAlert(req request.DisposeAlert) (err error) {
}`
,
docStr
))
}`
,
docStr
))
res
:=
opensearchapi
.
UpdateRequest
{
res
:=
opensearchapi
.
UpdateRequest
{
Index
:
OpenSearchIndex
,
Index
:
conf
.
Options
.
OpenSearchIndex
,
DocumentID
:
cast
.
ToString
(
req
.
Id
),
DocumentID
:
cast
.
ToString
(
req
.
Id
),
Body
:
content
,
Body
:
content
,
Source
:
[]
string
{
"true"
},
Source
:
[]
string
{
"true"
},
...
...
src/service/alert_class.go
View file @
de712f7c
...
@@ -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
}
}
src/service/alert_overview.go
View file @
de712f7c
package
service
package
service
import
(
import
(
"context"
"errors"
"fmt"
"github.com/jinzhu/copier"
"github.com/jinzhu/copier"
json
"github.com/json-iterator/go"
"github.com/opensearch-project/opensearch-go"
"github.com/opensearch-project/opensearch-go/opensearchapi"
"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/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/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/jsontime"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
"io"
"net/http"
"strings"
"time"
"xorm.io/xorm"
"xorm.io/xorm"
)
)
...
@@ -37,207 +51,385 @@ func (a *AlertOverviewSvc) Update(session *xorm.Session, req request.UpdateAlert
...
@@ -37,207 +51,385 @@ func (a *AlertOverviewSvc) Update(session *xorm.Session, req request.UpdateAlert
}
}
func
(
a
*
AlertOverviewSvc
)
Overview
(
req
request
.
DetailAlertOverview
)
(
resp
response
.
AlertOverviewItem
,
err
error
)
{
func
(
a
*
AlertOverviewSvc
)
Overview
(
req
request
.
DetailAlertOverview
)
(
resp
response
.
AlertOverviewItem
,
err
error
)
{
now
:=
jsontime
.
Now
()
alertOverviewList
,
_
:=
a
.
AlertOverview
(
req
)
metricConfigSvc
:=
MetricConfigSvc
{
User
:
a
.
User
}
nameList
,
_
:=
metricConfigSvc
.
NameList
()
for
i
:=
0
;
i
<
len
(
alertOverviewList
);
i
++
{
for
j
:=
0
;
j
<
len
(
alertOverviewList
[
i
]
.
List
);
j
++
{
for
_
,
v
:=
range
nameList
.
List
{
if
v
.
Id
==
alertOverviewList
[
i
]
.
List
[
j
]
.
MetricName
{
alertOverviewList
[
i
]
.
List
[
j
]
.
MetricName
=
v
.
MetricName
break
}
}
}
}
riskLevelDistributions
,
_
:=
a
.
RiskLevelDistribution
(
req
)
alertStatusDistributions
,
_
:=
a
.
AlertStatusDistribution
(
req
)
alertClassDistributions
,
_
:=
a
.
AlertClassDistribution
(
req
)
alertFrequencyDistribution
,
_
:=
a
.
AlertFrequencyDistribution
(
req
)
resp
=
response
.
AlertOverviewItem
{
resp
=
response
.
AlertOverviewItem
{
AlertOverview
:
[]
entity
.
AlertOverview
{
AlertOverview
:
alertOverviewList
,
{
RiskLevelDistribution
:
riskLevelDistributions
,
RiskLevel
:
4
,
AlertStatusDistribution
:
alertStatusDistributions
,
UnresolvedCount
:
10
,
AlertClassDistribution
:
alertClassDistributions
,
TotalCount
:
24
,
AlertFrequencyDistribution
:
alertFrequencyDistribution
,
List
:
[]
entity
.
AlertArray
{
}
{
return
MetricName
:
"CPU使用率过高"
,
}
UnresolvedCount
:
4
,
TotalCount
:
8
,
func
(
a
*
AlertOverviewSvc
)
AlertOverview
(
req
request
.
DetailAlertOverview
)
(
resp
[]
entity
.
AlertOverview
,
err
error
)
{
},
var
(
{
sources
response
.
AggAlertOverview
MetricName
:
"内存不足"
,
)
UnresolvedCount
:
1
,
TotalCount
:
2
,
cli
,
err
:=
client
.
GetOpenSearch
()
},
if
err
!=
nil
{
{
return
MetricName
:
"磁盘空间不足"
,
}
UnresolvedCount
:
3
,
TotalCount
:
4
,
if
req
.
StartTime
==
""
{
},
req
.
StartTime
=
time
.
Now
()
.
Format
(
"2006-01-02"
)
{
}
MetricName
:
"服务中断"
,
if
req
.
EndTime
==
""
{
UnresolvedCount
:
1
,
req
.
EndTime
=
time
.
Now
()
.
Add
(
time
.
Hour
*
24
)
.
Format
(
"2006-01-02"
)
TotalCount
:
4
,
}
},
{
content
:=
fmt
.
Sprintf
(
`{
MetricName
:
"响应时间超时"
,
"size": 0,
UnresolvedCount
:
2
,
"query": {
TotalCount
:
6
,
"range": {
},
"created_at": {
},
"gte": "%s",
CreatedBy
:
"admin"
,
"lte": "%s"
CreatedAt
:
now
,
}
UpdatedBy
:
"admin"
,
}
UpdatedAt
:
now
,
},
},
"aggs": {
{
"group": {
RiskLevel
:
3
,
"terms": {
UnresolvedCount
:
8
,
"field": "risk_level",
TotalCount
:
26
,
"size": 10
List
:
[]
entity
.
AlertArray
{
},
{
"aggs": {
MetricName
:
"CPU使用率过高"
,
"group": {
UnresolvedCount
:
4
,
"terms": {
TotalCount
:
12
,
"field": "metric_config_id",
},
"size": 10
{
},
MetricName
:
"内存不足"
,
"aggs": {
UnresolvedCount
:
1
,
"unresolved_count": {
TotalCount
:
10
,
"filter": {
},
"term": {
{
"status": 2
MetricName
:
"磁盘空间不足"
,
}
UnresolvedCount
:
3
,
}
TotalCount
:
8
,
}
},
}
{
}
MetricName
:
"服务中断"
,
}
UnresolvedCount
:
1
,
}
TotalCount
:
4
,
}
},
}`
,
req
.
StartTime
,
req
.
EndTime
)
{
MetricName
:
"响应时间超时"
,
body
,
err
:=
executeQuery
(
cli
,
conf
.
Options
.
OpenSearchIndex
,
content
)
UnresolvedCount
:
2
,
if
err
!=
nil
{
TotalCount
:
6
,
return
},
}
},
CreatedBy
:
"admin"
,
result
:=
gjson
.
GetBytes
(
body
,
"aggregations"
)
CreatedAt
:
now
,
err
=
json
.
Unmarshal
([]
byte
(
result
.
String
()),
&
sources
)
UpdatedBy
:
"admin"
,
if
err
!=
nil
{
UpdatedAt
:
now
,
return
},
}
{
RiskLevel
:
2
,
now
:=
jsontime
.
Now
()
UnresolvedCount
:
13
,
for
_
,
v
:=
range
sources
.
Group
.
Buckets
{
TotalCount
:
50
,
alertOverview
:=
entity
.
AlertOverview
{
List
:
[]
entity
.
AlertArray
{
RiskLevel
:
v
.
Key
,
{
UnresolvedCount
:
0
,
MetricName
:
"CPU使用率过高"
,
TotalCount
:
v
.
DocCount
,
UnresolvedCount
:
4
,
List
:
nil
,
TotalCount
:
12
,
CreatedBy
:
a
.
User
.
SystemAccount
,
},
CreatedAt
:
now
,
{
UpdatedBy
:
a
.
User
.
SystemAccount
,
MetricName
:
"内存不足"
,
UpdatedAt
:
now
,
UnresolvedCount
:
1
,
}
TotalCount
:
10
,
var
unresolvedCount
int
},
var
alertArray
[]
entity
.
AlertArray
{
for
_
,
bucket
:=
range
v
.
Group
.
Buckets
{
MetricName
:
"磁盘空间不足"
,
alertArray
=
append
(
alertArray
,
entity
.
AlertArray
{
UnresolvedCount
:
3
,
MetricName
:
bucket
.
Key
,
TotalCount
:
8
,
UnresolvedCount
:
bucket
.
UnresolvedCount
.
DocCount
,
},
TotalCount
:
bucket
.
DocCount
,
{
})
MetricName
:
"服务中断"
,
unresolvedCount
+=
bucket
.
UnresolvedCount
.
DocCount
UnresolvedCount
:
1
,
}
TotalCount
:
4
,
alertOverview
.
UnresolvedCount
=
unresolvedCount
},
alertOverview
.
List
=
alertArray
{
resp
=
append
(
resp
,
alertOverview
)
MetricName
:
"响应时间超时"
,
}
UnresolvedCount
:
2
,
return
TotalCount
:
6
,
},
}
},
CreatedBy
:
"admin"
,
func
(
a
*
AlertOverviewSvc
)
RiskLevelDistribution
(
req
request
.
DetailAlertOverview
)
(
resp
[]
entity
.
AlertDistribution
,
err
error
)
{
CreatedAt
:
now
,
var
(
UpdatedBy
:
"admin"
,
sources
response
.
AlertDistributionGroup
UpdatedAt
:
now
,
)
},
{
cli
,
err
:=
client
.
GetOpenSearch
()
RiskLevel
:
1
,
if
err
!=
nil
{
UnresolvedCount
:
8
,
return
TotalCount
:
20
,
}
List
:
[]
entity
.
AlertArray
{
{
if
req
.
StartTime
==
""
{
MetricName
:
"CPU使用率过高"
,
req
.
StartTime
=
time
.
Now
()
.
Format
(
"2006-01-02"
)
UnresolvedCount
:
4
,
}
TotalCount
:
12
,
if
req
.
EndTime
==
""
{
},
req
.
EndTime
=
time
.
Now
()
.
Add
(
time
.
Hour
*
24
)
.
Format
(
"2006-01-02"
)
{
}
MetricName
:
"内存不足"
,
UnresolvedCount
:
1
,
body
,
err
:=
executeQuery
(
cli
,
conf
.
Options
.
OpenSearchIndex
,
buildAggQueryContent
(
req
.
StartTime
,
req
.
EndTime
,
"risk_level"
))
TotalCount
:
10
,
if
err
!=
nil
{
},
return
{
MetricName
:
"磁盘空间不足"
,
UnresolvedCount
:
3
,
TotalCount
:
8
,
},
{
MetricName
:
"服务中断"
,
UnresolvedCount
:
1
,
TotalCount
:
4
,
},
{
MetricName
:
"响应时间超时"
,
UnresolvedCount
:
2
,
TotalCount
:
6
,
},
},
CreatedBy
:
"admin"
,
CreatedAt
:
now
,
UpdatedBy
:
"admin"
,
UpdatedAt
:
now
,
},
},
RiskLevelDistribution
:
[]
entity
.
RiskLevelDistribution
{
{
Name
:
"重大风险"
,
Value
:
1
,
},
{
Name
:
"较大风险"
,
Value
:
2
,
},
{
Name
:
"一般风险"
,
Value
:
3
,
},
{
Name
:
"低风险"
,
Value
:
4
,
},
},
AlertStatusDistribution
:
[]
entity
.
AlertStatusDistribution
{
{
Name
:
"未恢复"
,
Value
:
4
,
},
{
Name
:
"已恢复"
,
Value
:
6
,
},
},
AlertClassDistribution
:
[]
entity
.
AlertClassDistribution
{
{
Name
:
"容器集群"
,
Value
:
1
,
},
{
Name
:
"容器节点"
,
Value
:
2
,
},
{
Name
:
"容器组"
,
Value
:
3
,
},
{
Name
:
"网关"
,
Value
:
4
,
},
},
AlertFrequencyDistribution
:
entity
.
AlertFrequencyDistribution
{
XAxis
:
[]
string
{
"0-3时"
,
"3-6时"
,
"6-9时"
,
"9-12时"
,
"12-15时"
,
"15-18时"
,
"18-21时"
,
"21-24时"
},
Data
:
[]
int
{
12
,
20
,
11
,
50
,
60
,
30
,
16
,
6
},
},
}
}
result
:=
gjson
.
GetBytes
(
body
,
"aggregations"
)
err
=
json
.
Unmarshal
([]
byte
(
result
.
String
()),
&
sources
)
if
err
!=
nil
{
return
}
var
alertDistributions
[]
entity
.
AlertDistribution
riskLevels
:=
[]
int
{
constant
.
RiskLevelLow
,
constant
.
RiskLevelModerate
,
constant
.
RiskLevelHigh
,
constant
.
RiskLevelCritical
}
for
_
,
level
:=
range
riskLevels
{
riskLevelDistribution
:=
entity
.
AlertDistribution
{
Name
:
constant
.
RiskLeveText
(
level
)}
for
_
,
bucket
:=
range
sources
.
Group
.
Buckets
{
if
level
==
bucket
.
Key
{
riskLevelDistribution
.
Value
=
bucket
.
DocCount
break
}
}
alertDistributions
=
append
(
alertDistributions
,
riskLevelDistribution
)
}
resp
=
alertDistributions
return
return
}
func
(
a
*
AlertOverviewSvc
)
AlertStatusDistribution
(
req
request
.
DetailAlertOverview
)
(
resp
[]
entity
.
AlertDistribution
,
err
error
)
{
var
(
sources
response
.
AlertDistributionGroup
)
cli
,
err
:=
client
.
GetOpenSearch
()
if
err
!=
nil
{
return
}
if
req
.
StartTime
==
""
{
req
.
StartTime
=
time
.
Now
()
.
Format
(
"2006-01-02"
)
}
if
req
.
EndTime
==
""
{
req
.
EndTime
=
time
.
Now
()
.
Add
(
time
.
Hour
*
24
)
.
Format
(
"2006-01-02"
)
}
body
,
err
:=
executeQuery
(
cli
,
conf
.
Options
.
OpenSearchIndex
,
buildAggQueryContent
(
req
.
StartTime
,
req
.
EndTime
,
"status"
))
if
err
!=
nil
{
return
}
result
:=
gjson
.
GetBytes
(
body
,
"aggregations"
)
err
=
json
.
Unmarshal
([]
byte
(
result
.
String
()),
&
sources
)
if
err
!=
nil
{
return
}
var
alertDistributions
[]
entity
.
AlertDistribution
alertStatusList
:=
[]
int
{
constant
.
AlertRecovered
,
constant
.
AlertNotRecovered
,
constant
.
AlertClosed
}
for
_
,
status
:=
range
alertStatusList
{
alertStatusDistribution
:=
entity
.
AlertDistribution
{
Name
:
constant
.
AlertStatusText
(
status
)}
for
_
,
bucket
:=
range
sources
.
Group
.
Buckets
{
if
status
==
bucket
.
Key
{
alertStatusDistribution
.
Value
=
bucket
.
DocCount
break
}
}
alertDistributions
=
append
(
alertDistributions
,
alertStatusDistribution
)
}
resp
=
alertDistributions
return
}
func
(
a
*
AlertOverviewSvc
)
AlertClassDistribution
(
req
request
.
DetailAlertOverview
)
(
resp
[]
entity
.
AlertDistribution
,
err
error
)
{
var
(
sources
response
.
AlertDistributionGroup
)
cli
,
err
:=
client
.
GetOpenSearch
()
if
err
!=
nil
{
return
}
if
req
.
StartTime
==
""
{
req
.
StartTime
=
time
.
Now
()
.
Format
(
"2006-01-02"
)
}
if
req
.
EndTime
==
""
{
req
.
EndTime
=
time
.
Now
()
.
Add
(
time
.
Hour
*
24
)
.
Format
(
"2006-01-02"
)
}
body
,
err
:=
executeQuery
(
cli
,
conf
.
Options
.
OpenSearchIndex
,
buildAggQueryContent
(
req
.
StartTime
,
req
.
EndTime
,
"class_id"
))
if
err
!=
nil
{
return
}
result
:=
gjson
.
GetBytes
(
body
,
"aggregations"
)
err
=
json
.
Unmarshal
([]
byte
(
result
.
String
()),
&
sources
)
if
err
!=
nil
{
return
}
alertClassSvc
:=
AlertClassSvc
{
User
:
a
.
User
}
alertObjectList
,
err
:=
alertClassSvc
.
AlertObjectList
()
var
alertDistributions
[]
entity
.
AlertDistribution
for
_
,
bucket
:=
range
sources
.
Group
.
Buckets
{
alertDistribution
:=
entity
.
AlertDistribution
{
Value
:
bucket
.
DocCount
}
for
_
,
object
:=
range
alertObjectList
.
List
{
if
bucket
.
Key
==
object
.
ClassId
{
alertDistribution
.
Name
=
object
.
ClassName
}
}
alertDistributions
=
append
(
alertDistributions
,
alertDistribution
)
}
resp
=
alertDistributions
return
}
func
(
a
*
AlertOverviewSvc
)
AlertFrequencyDistribution
(
req
request
.
DetailAlertOverview
)
(
resp
entity
.
AlertFrequencyDistribution
,
err
error
)
{
var
(
sources
response
.
DateHistogramGroup
)
cli
,
err
:=
client
.
GetOpenSearch
()
if
err
!=
nil
{
return
}
if
req
.
StartTime
==
""
{
req
.
StartTime
=
time
.
Now
()
.
Format
(
"2006-01-02"
)
}
if
req
.
EndTime
==
""
{
req
.
EndTime
=
time
.
Now
()
.
Add
(
time
.
Hour
*
24
)
.
Format
(
"2006-01-02"
)
}
/*
"gte": "now/d",
"lt": "now+1d/d"
*/
/*
"gte": "2023-07-17",
"lte": "2023-07-18"
*/
content
:=
`{
"size": 0,
"query": {
"range": {
"created_at": {
"gte": "now/d",
"lt": "now+1d/d"
}
}
},
"aggs": {
"group": {
"date_histogram": {
"field": "created_at",
"interval": "3h",
"format": "HH",
"time_zone": "+00:00"
}
}
}
}`
body
,
err
:=
executeQuery
(
cli
,
conf
.
Options
.
OpenSearchIndex
,
content
)
if
err
!=
nil
{
return
}
result
:=
gjson
.
GetBytes
(
body
,
"aggregations"
)
err
=
json
.
Unmarshal
([]
byte
(
result
.
String
()),
&
sources
)
if
err
!=
nil
{
return
}
alertFrequencyDistribution
:=
entity
.
AlertFrequencyDistribution
{
XAxis
:
[]
string
{
"0-3时"
,
"3-6时"
,
"6-9时"
,
"9-12时"
,
"12-15时"
,
"15-18时"
,
"18-21时"
,
"21-24时"
},
Data
:
[]
int
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
}
for
i
:=
0
;
i
<
len
(
alertFrequencyDistribution
.
XAxis
);
i
++
{
for
_
,
bucket
:=
range
sources
.
Group
.
Buckets
{
if
cast
.
ToInt
(
bucket
.
KeyAsString
)
==
i
*
3
{
alertFrequencyDistribution
.
Data
[
i
]
=
bucket
.
DocCount
break
}
}
}
resp
=
alertFrequencyDistribution
return
}
func
buildAggQueryContent
(
startTime
,
endTime
string
,
field
string
)
string
{
return
fmt
.
Sprintf
(
`{
"size": 0,
"query": {
"range": {
"created_at": {
"gte": "%s",
"lte": "%s"
}
}
},
"aggs": {
"group": {
"terms": {
"field": "%s",
"size": 10
}
}
}
}`
,
startTime
,
endTime
,
field
)
}
func
executeQuery
(
cli
*
opensearch
.
Client
,
index
string
,
content
string
)
([]
byte
,
error
)
{
res
:=
opensearchapi
.
SearchRequest
{
Index
:
[]
string
{
index
},
Body
:
strings
.
NewReader
(
content
),
}
do
,
err
:=
res
.
Do
(
context
.
Background
(),
cli
)
if
err
!=
nil
{
return
nil
,
err
}
defer
do
.
Body
.
Close
()
if
do
.
StatusCode
<
http
.
StatusOK
&&
do
.
StatusCode
>
http
.
StatusIMUsed
{
return
nil
,
errors
.
New
(
do
.
String
())
}
body
,
err
:=
io
.
ReadAll
(
do
.
Body
)
if
err
!=
nil
{
return
nil
,
err
}
return
body
,
nil
}
}
func
(
a
*
AlertOverviewSvc
)
List
(
req
request
.
ListAlertOverview
)
(
resp
response
.
AlertOverviewList
,
err
error
)
{
func
(
a
*
AlertOverviewSvc
)
List
(
req
request
.
ListAlertOverview
)
(
resp
response
.
AlertOverviewList
,
err
error
)
{
...
@@ -247,7 +439,7 @@ func (a *AlertOverviewSvc) List(req request.ListAlertOverview) (resp response.Al
...
@@ -247,7 +439,7 @@ func (a *AlertOverviewSvc) List(req request.ListAlertOverview) (resp response.Al
}
}
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
)
}
}
...
...
src/service/alert_rules.go
View file @
de712f7c
...
@@ -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
,
Source
From
:
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
,
Source
From
:
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
.
Source
From
=
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
}
alertClass
Item
,
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
:
alertClass
Item
.
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
.
Source
From
=
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"
)
}
}
...
...
src/service/alert_webhook.go
View file @
de712f7c
...
@@ -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
}
}
alertI
d
:=
max
+
1
i
d
:=
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
:
alertI
d
,
Id
:
i
d
,
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
,
...
...
src/service/cron/common.go
View file @
de712f7c
...
@@ -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点扫描当天需下发工单
}
}
src/service/k8s/prometheusrule.go
View file @
de712f7c
...
@@ -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
}
}
// GetPrometheusRule
Name
获取规则CRD名称
// GetPrometheusRule
Id
获取规则CRD名称
func
GetPrometheusRule
Name
(
alertRules
Id
string
)
string
{
func
GetPrometheusRule
Id
(
alertPolicy
Id
string
)
string
{
return
fmt
.
Sprintf
(
"%s-%s"
,
PrometheusRuleNamePrefix
,
alertRules
Id
)
return
fmt
.
Sprintf
(
"%s-%s"
,
conf
.
Options
.
PrometheusRuleNamePrefix
,
alertPolicy
Id
)
}
}
// 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
:
PrometheusRule
ApiVersion
,
Metadata
:
pRule
.
ObjectMeta
,
Spec
:
pRule
.
Spec
}
c
:=
&
Content
{
Kind
:
"PrometheusRule"
,
ApiVersion
:
conf
.
Options
.
Monitor
ApiVersion
,
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
...
...
src/service/metric_config.go
View file @
de712f7c
...
@@ -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
{
...
...
src/service/prometheus.go
View file @
de712f7c
...
@@ -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
)
...
...
src/service/prometheusrule.go
View file @
de712f7c
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
)
{
prometheusRule
Name
:=
k8s
.
GetPrometheusRuleName
(
data
.
Id
)
prometheusRule
ObjName
:=
k8s
.
GetPrometheusRuleId
(
data
.
Id
)
pr
:=
monitoringv1
.
PrometheusRule
{
pr
:=
monitoringv1
.
PrometheusRule
{
ObjectMeta
:
v1
.
ObjectMeta
{
ObjectMeta
:
v1
.
ObjectMeta
{
Name
:
prometheusRuleName
,
Name
:
prometheusRule
Obj
Name
,
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
)
{
prometheusRule
Name
:=
k8s
.
GetPrometheusRuleName
(
data
.
Id
)
prometheusRule
ObjName
:=
k8s
.
GetPrometheusRuleId
(
data
.
Id
)
pr
:=
monitoringv1
.
PrometheusRule
{
pr
:=
monitoringv1
.
PrometheusRule
{
ObjectMeta
:
v1
.
ObjectMeta
{
ObjectMeta
:
v1
.
ObjectMeta
{
Name
:
prometheusRuleName
,
Name
:
prometheusRule
Obj
Name
,
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
)
{
prometheusRule
Name
:=
k8s
.
GetPrometheusRuleName
(
data
.
Id
)
prometheusRule
ObjName
:=
k8s
.
GetPrometheusRuleId
(
data
.
Id
)
pr
:=
monitoringv1
.
PrometheusRule
{
pr
:=
monitoringv1
.
PrometheusRule
{
ObjectMeta
:
v1
.
ObjectMeta
{
ObjectMeta
:
v1
.
ObjectMeta
{
Name
:
prometheusRuleName
,
Name
:
prometheusRule
Obj
Name
,
Namespace
:
k8s
.
Namespace
,
Namespace
:
conf
.
Options
.
MonitorMatchNs
,
Labels
:
k8s
.
AlertDefLabels
,
Labels
:
k8s
.
GetAlertDefLabels
()
,
},
},
}
}
...
...
src/service/task_manage.go
View file @
de712f7c
...
@@ -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
}
}
...
...
src/service/work_order.go
View file @
de712f7c
...
@@ -5,19 +5,24 @@ import (
...
@@ -5,19 +5,24 @@ import (
"fmt"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi"
"github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi"
json
"github.com/json-iterator/go"
json
"github.com/json-iterator/go"
"github.com/robfig/cron/v3"
"github.com/wanghuiyt/ding"
"github.com/wanghuiyt/ding"
"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/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/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"
"go.uber.org/zap"
"go.uber.org/zap"
"strings"
"strings"
"time"
"time"
)
)
var
workOrderCron
=
cron
.
New
(
cron
.
WithSeconds
())
type
WorkOrderManageSvc
struct
{
type
WorkOrderManageSvc
struct
{
User
entity
.
SystemUserInfo
User
entity
.
SystemUserInfo
}
}
...
@@ -151,7 +156,7 @@ func (w *WorkOrderManageSvc) EditWorkOrderManage(req request.EditWorkOrderReq) (
...
@@ -151,7 +156,7 @@ func (w *WorkOrderManageSvc) EditWorkOrderManage(req request.EditWorkOrderReq) (
return
return
}
}
// StateWorkOrderManage
编辑业务工单管理
// StateWorkOrderManage
定时是否启用
func
(
w
*
WorkOrderManageSvc
)
StateWorkOrderManage
(
req
request
.
StateWorkOrderReq
)
(
err
error
)
{
func
(
w
*
WorkOrderManageSvc
)
StateWorkOrderManage
(
req
request
.
StateWorkOrderReq
)
(
err
error
)
{
db
,
err
:=
client
.
GetDbClient
()
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -165,6 +170,10 @@ func (w *WorkOrderManageSvc) StateWorkOrderManage(req request.StateWorkOrderReq)
...
@@ -165,6 +170,10 @@ func (w *WorkOrderManageSvc) StateWorkOrderManage(req request.StateWorkOrderReq)
err
=
resp
.
DbUpdateError
.
WithError
(
err
)
err
=
resp
.
DbUpdateError
.
WithError
(
err
)
return
return
}
}
//创建定时任务
CronPushWorkOrder
()
return
return
}
}
...
@@ -176,11 +185,31 @@ func (w *WorkOrderManageSvc) DelWorkOrderManage(req request.DelWorkOrderReq) (er
...
@@ -176,11 +185,31 @@ func (w *WorkOrderManageSvc) DelWorkOrderManage(req request.DelWorkOrderReq) (er
return
return
}
}
session
:=
db
.
NewSession
()
defer
session
.
Close
()
session
.
Begin
()
_
,
err
=
db
.
Table
(
"work_order_manage"
)
.
In
(
"id"
,
req
.
Id
)
.
Delete
(
&
entity
.
WorkOrder
{})
_
,
err
=
db
.
Table
(
"work_order_manage"
)
.
In
(
"id"
,
req
.
Id
)
.
Delete
(
&
entity
.
WorkOrder
{})
if
err
!=
nil
{
if
err
!=
nil
{
err
=
resp
.
DbDeleteError
.
WithError
(
err
)
err
=
resp
.
DbDeleteError
.
WithError
(
err
)
session
.
Rollback
()
return
}
_
,
err
=
db
.
Table
(
"work_order_issuance"
)
.
In
(
"order_id"
,
req
.
Id
)
.
Delete
(
&
entity
.
WorkOrderIssuance
{})
if
err
!=
nil
{
err
=
resp
.
DbDeleteError
.
WithError
(
err
)
session
.
Rollback
()
return
}
_
,
err
=
db
.
Table
(
"work_order_me"
)
.
In
(
"order_id"
,
req
.
Id
)
.
Delete
(
&
entity
.
WorkOrderMe
{})
if
err
!=
nil
{
err
=
resp
.
DbDeleteError
.
WithError
(
err
)
session
.
Rollback
()
return
return
}
}
session
.
Commit
()
return
return
}
}
...
@@ -251,25 +280,26 @@ func (w *WorkOrderManageSvc) ListWorkOrderManage(req request.ListWorkOrderManage
...
@@ -251,25 +280,26 @@ func (w *WorkOrderManageSvc) ListWorkOrderManage(req request.ListWorkOrderManage
return
return
}
}
finder
:=
db
.
Table
(
"work_order_manage"
)
finder
:=
db
.
Table
(
"work_order_manage"
)
.
Alias
(
"wom"
)
if
req
.
Search
!=
""
{
if
req
.
Search
!=
""
{
finder
.
Where
(
fmt
.
Sprintf
(
"order_name LIKE '%s'"
,
"%"
+
req
.
Search
+
"%"
))
finder
.
Where
(
fmt
.
Sprintf
(
"
wom.
order_name LIKE '%s'"
,
"%"
+
req
.
Search
+
"%"
))
}
}
if
req
.
OrderLevel
!=
0
{
if
req
.
OrderLevel
!=
0
{
finder
.
Where
(
"order_level = ?"
,
req
.
OrderLevel
)
finder
.
Where
(
"
wom.
order_level = ?"
,
req
.
OrderLevel
)
}
}
if
req
.
TimingType
!=
0
{
if
req
.
TimingType
!=
0
{
finder
.
Where
(
"timing_type = ?"
,
req
.
TimingType
)
finder
.
Where
(
"
wom.
timing_type = ?"
,
req
.
TimingType
)
}
}
if
req
.
CreateDateFrom
!=
""
{
if
req
.
CreateDateFrom
!=
""
{
finder
.
Where
(
"create_time >= ?"
,
req
.
CreateDateFrom
)
finder
.
Where
(
"
wom.
create_time >= ?"
,
req
.
CreateDateFrom
)
}
}
if
req
.
CreateDateTo
!=
""
{
if
req
.
CreateDateTo
!=
""
{
finder
.
Where
(
"create_time <= ?"
,
req
.
CreateDateTo
)
finder
.
Where
(
"
wom.
create_time <= ?"
,
req
.
CreateDateTo
)
}
}
finder
.
OrderBy
(
"create_time desc"
)
finder
.
OrderBy
(
"
wom.
create_time desc"
)
//查询任务
//查询任务
total
,
err
=
finder
.
Select
(
"id,order_name,order_level,order_cnt,push_obj,timing_type,timing_state,create_user,create_time"
)
.
total
,
err
=
finder
.
Select
(
"wom.id,wom.order_name,wom.order_level,(select count(*) from work_order_issuance woi "
+
"where woi.order_id = wom.id) as order_cnt,wom.push_obj,wom.timing_type,wom.timing_state,wom.create_user,wom.create_time"
)
.
Limit
(
req
.
PageSize
,
(
req
.
Page
-
1
)
*
req
.
PageSize
)
.
FindAndCount
(
&
workOrderListRes
)
Limit
(
req
.
PageSize
,
(
req
.
Page
-
1
)
*
req
.
PageSize
)
.
FindAndCount
(
&
workOrderListRes
)
if
err
!=
nil
{
if
err
!=
nil
{
err
=
resp
.
DbSelectError
.
WithError
(
err
)
err
=
resp
.
DbSelectError
.
WithError
(
err
)
...
@@ -715,194 +745,138 @@ func WorkOrderPushNoteMsg(orderName string, phone []string, orderLevel int) (err
...
@@ -715,194 +745,138 @@ func WorkOrderPushNoteMsg(orderName string, phone []string, orderLevel int) (err
return
return
}
}
// CronWorkOrderIssuance 定时任务-每天凌晨0点检测当天需下发工单
// PushObjMsg 解析用户并推送消息
func
CronWorkOrderIssuance
()
{
func
PushObjMsg
(
obj
,
orderName
string
,
orderLevel
int
)
(
err
error
)
{
var
pushObj
request
.
PushObj
err
=
json
.
Unmarshal
([]
byte
(
obj
),
&
pushObj
)
if
err
!=
nil
{
return
}
var
phones
[]
string
for
_
,
v
:=
range
pushObj
.
UserObj
{
phones
=
append
(
phones
,
v
.
Phone
)
}
switch
pushObj
.
PushMethod
{
case
1
:
//发送钉钉消息
err
=
WorkOrderPushDingTalkMsg
(
orderName
,
orderLevel
,
phones
)
if
err
!=
nil
{
return
}
case
2
:
//发送短信
err
=
WorkOrderPushNoteMsg
(
orderName
,
phones
,
orderLevel
)
if
err
!=
nil
{
return
}
case
3
:
//发送钉钉消息
err
=
WorkOrderPushDingTalkMsg
(
orderName
,
orderLevel
,
phones
)
if
err
!=
nil
{
return
}
//发送短信
err
=
WorkOrderPushNoteMsg
(
orderName
,
phones
,
orderLevel
)
if
err
!=
nil
{
return
}
}
conf
.
Logger
.
Info
(
"定时下发工单完成,工单名称:"
+
orderName
)
return
}
// CronPushWorkOrder 创建工单下发定时任务
func
CronPushWorkOrder
()
{
db
,
err
:=
client
.
GetDbClient
()
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Println
(
"CronStatusDetection err:"
,
err
.
Error
(
))
conf
.
Logger
.
Error
(
"获取数据库连接"
,
zap
.
Error
(
err
))
return
return
}
}
//查询推送工单
//查询推送工单
workOrderList
:=
make
([]
entity
.
WorkOrder
,
0
)
workOrderList
:=
make
([]
entity
.
WorkOrder
,
0
)
finder
:=
db
.
Table
(
"work_order_manage"
)
.
Where
(
"timing_state = 1 AND (timing_type = 2 OR timing_type = 3)"
)
finder
:=
db
.
Table
(
"work_order_manage"
)
.
Where
(
"timing_state = ? AND (timing_type = ? "
+
"OR timing_type = ?)"
,
constant
.
TimingClick
,
constant
.
TimingWeekly
,
constant
.
TimingCustom
)
err
=
finder
.
Find
(
&
workOrderList
)
err
=
finder
.
Find
(
&
workOrderList
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Println
(
"CronStatusDetection err:"
,
err
.
Error
(
))
conf
.
Logger
.
Error
(
"查询推送工单"
,
zap
.
Error
(
err
))
return
return
}
}
week
:=
map
[
time
.
Weekday
]
int
{
workOrderCron
.
Stop
()
time
.
Monday
:
1
,
defer
workOrderCron
.
Start
()
time
.
Tuesday
:
2
,
time
.
Wednesday
:
3
,
time
.
Thursday
:
4
,
time
.
Friday
:
5
,
time
.
Saturday
:
6
,
time
.
Sunday
:
7
,
}
for
_
,
v
:=
range
workOrderList
{
for
_
,
v
:=
range
workOrderList
{
if
v
.
TimingType
==
2
{
var
pushObj
request
.
PushObj
//按周
err
=
json
.
Unmarshal
([]
byte
(
v
.
PushObj
),
&
pushObj
)
if
err
!=
nil
{
return
}
svc
:=
WorkOrderManageSvc
{
User
:
entity
.
SystemUserInfo
{
SystemAccount
:
v
.
CreateUser
}}
if
v
.
TimingType
==
constant
.
TimingWeekly
{
var
timingWeekly
request
.
TimingWeekly
var
timingWeekly
request
.
TimingWeekly
err
=
json
.
Unmarshal
([]
byte
(
v
.
TimingRule
),
&
timingWeekly
)
err
=
json
.
Unmarshal
([]
byte
(
v
.
TimingRule
),
&
timingWeekly
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Println
(
"CronStatusDetection err:"
,
err
.
Error
(
))
conf
.
Logger
.
Error
(
"反序列化定时规则"
,
zap
.
Error
(
err
))
continue
continue
}
}
days
:=
week
[
time
.
Now
()
.
Weekday
()]
for
_
,
i
:=
range
timingWeekly
.
Week
{
for
k
,
v1
:=
range
timingWeekly
.
Week
{
if
i
==
days
{
if
v1
==
7
{
//写redis
timingWeekly
.
Week
[
k
]
=
0
err
=
PushRedisWorkOrder
(
timingWeekly
.
PointTime
,
v
.
PushObj
,
v
.
OrderName
,
v
.
OrderLevel
)
if
err
!=
nil
{
fmt
.
Println
(
"CronStatusDetection redis set err:"
,
err
.
Error
())
continue
}
break
}
}
}
}
}
else
if
v
.
TimingType
==
3
{
t
,
err
:=
time
.
Parse
(
jsontime
.
LocalTimeFormat
,
timingWeekly
.
PointTime
)
//自定义时间
var
timingCustom
[]
request
.
TimingCustom
err
=
json
.
Unmarshal
([]
byte
(
v
.
TimingRule
),
&
timingCustom
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Println
(
"CronStatusDetection json Unmarshal err:"
,
err
.
Error
(
))
conf
.
Logger
.
Error
(
"时间点类型转换错误"
,
zap
.
Error
(
err
))
continue
continue
}
}
for
_
,
v1
:=
range
timingCustom
{
t
:=
time
.
Now
()
expr
:=
fmt
.
Sprintf
(
"%d %d %d * * %s"
,
t
.
Second
(),
t
.
Minute
(),
t
.
Hour
(),
strings
.
Join
(
util
.
IntsToStrings
(
timingWeekly
.
Week
),
","
))
dateFrom
,
err1
:=
time
.
Parse
(
jsontime
.
LocalDateFormat
,
v1
.
DateFrom
)
//创建定时任务
if
err1
!=
nil
{
workOrderCron
.
AddFunc
(
expr
,
func
()
{
fmt
.
Println
(
"CronStatusDetection dateFrom parse err:"
,
err1
.
Error
())
err
=
svc
.
PushWorkOrderManage
(
request
.
PushWorkOrderReq
{
Id
:
v
.
Id
,
PushObj
:
pushObj
})
continue
//err = PushObjMsg(v.PushObj, v.OrderName, v.OrderLevel)
}
if
err
!=
nil
{
dateTo
,
err1
:=
time
.
Parse
(
jsontime
.
LocalDateFormat
,
v1
.
DateTo
)
conf
.
Logger
.
Error
(
"发送定时消息失败"
,
zap
.
Error
(
err
))
if
err1
!=
nil
{
fmt
.
Println
(
"CronStatusDetection dateTo parse err:"
,
err1
.
Error
())
continue
}
if
t
.
After
(
dateFrom
)
&&
t
.
Before
(
dateTo
)
{
//写redis
err
=
PushRedisWorkOrder
(
v1
.
PointTime
,
v
.
PushObj
,
v
.
OrderName
,
v
.
OrderLevel
)
if
err
!=
nil
{
fmt
.
Println
(
"CronStatusDetection redis set err:"
,
err
.
Error
())
continue
}
break
}
}
})
}
else
{
var
timingCustom
request
.
TimingCustom
err
=
json
.
Unmarshal
([]
byte
(
v
.
TimingRule
),
&
timingCustom
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"反序列化定时规则"
,
zap
.
Error
(
err
))
continue
}
}
}
}
fmt
.
Println
(
"CronPersonalCardDate success!"
)
}
type
CronRedisWorkOrder
struct
{
PointTime
int64
`json:"point_Time"`
// 时间点
PushObj
string
`json:"push_obj"`
//推送对象
OrderName
string
`json:"order_name"`
// 工单名称
OrderLevel
int
`json:"order_level"`
// 工单等级(1紧急任务 2重要任务 3一般任务)
}
func
PushRedisWorkOrder
(
pointTime
,
pushObj
,
orderName
string
,
orderLevel
int
)
(
err
error
)
{
redis
,
err
:=
client
.
GetRedisClient
()
if
err
!=
nil
{
return
}
timeUnix
,
err
:=
time
.
Parse
(
jsontime
.
LocalTimeFormat
,
pointTime
)
dateFrom
,
err
:=
time
.
Parse
(
jsontime
.
LocalDateFormat
,
timingCustom
.
DateFrom
)
if
err
!=
nil
{
return
}
cronRedisWorkOrder
:=
CronRedisWorkOrder
{
PointTime
:
timeUnix
.
Unix
(),
PushObj
:
pushObj
,
OrderName
:
orderName
,
OrderLevel
:
orderLevel
,
}
workOrderObj
,
err
:=
json
.
Marshal
(
cronRedisWorkOrder
)
if
err
!=
nil
{
return
}
//写redis
err
=
redis
.
LPush
(
conf
.
WorkOrderPush
,
fmt
.
Sprintf
(
"%s"
,
workOrderObj
))
if
err
!=
nil
{
return
}
return
}
// PushWorkOrderMessage 工单定时下发消息
func
PushWorkOrderMessage
()
{
go
func
()
{
for
{
redis
,
err
:=
client
.
GetRedisClient
()
if
err
!=
nil
{
if
err
!=
nil
{
zap
.
L
()
.
Error
(
err
.
Error
(
))
conf
.
Logger
.
Error
(
"时间类型转换错误"
,
zap
.
Error
(
err
))
continue
continue
}
}
workOrderList
,
err
:=
redis
.
LRange
(
conf
.
WorkOrderPush
)
dateTo
,
err
:=
time
.
Parse
(
jsontime
.
LocalDateFormat
,
timingCustom
.
DateTo
)
if
err
!=
nil
{
if
err
!=
nil
{
zap
.
L
()
.
Error
(
err
.
Error
())
conf
.
Logger
.
Error
(
"时间类型转换错误"
,
zap
.
Error
(
err
))
continue
}
t
,
err
:=
time
.
Parse
(
jsontime
.
LocalDateFormat
,
timingCustom
.
PointTime
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"时间点类型转换错误"
,
zap
.
Error
(
err
))
continue
continue
}
}
for
_
,
v
:=
range
workOrderList
{
var
cronRedisWorkOrder
CronRedisWorkOrder
err
=
json
.
Unmarshal
([]
byte
(
v
),
&
cronRedisWorkOrder
)
if
err
!=
nil
{
zap
.
L
()
.
Error
(
err
.
Error
())
continue
}
times
,
err1
:=
time
.
Parse
(
jsontime
.
LocalTimeFormat
,
time
.
Now
()
.
Format
(
jsontime
.
LocalTimeFormat
))
if
err1
!=
nil
{
zap
.
L
()
.
Error
(
err1
.
Error
())
return
}
if
cronRedisWorkOrder
.
PointTime
==
times
.
Unix
()
{
var
pushObj
request
.
PushObj
err
=
json
.
Unmarshal
([]
byte
(
cronRedisWorkOrder
.
PushObj
),
&
pushObj
)
if
err
!=
nil
{
zap
.
L
()
.
Error
(
err
.
Error
())
continue
}
var
phones
[]
string
for
_
,
v1
:=
range
pushObj
.
UserObj
{
phones
=
append
(
phones
,
v1
.
Phone
)
}
switch
pushObj
.
PushMethod
{
case
1
:
//发送钉钉消息
err
=
WorkOrderPushDingTalkMsg
(
cronRedisWorkOrder
.
OrderName
,
cronRedisWorkOrder
.
OrderLevel
,
phones
)
if
err
!=
nil
{
zap
.
L
()
.
Error
(
err
.
Error
())
}
case
2
:
//发送短信
err
=
WorkOrderPushNoteMsg
(
cronRedisWorkOrder
.
OrderName
,
phones
,
cronRedisWorkOrder
.
OrderLevel
)
if
err
!=
nil
{
zap
.
L
()
.
Error
(
err
.
Error
())
}
case
3
:
//发送钉钉消息
err
=
WorkOrderPushDingTalkMsg
(
cronRedisWorkOrder
.
OrderName
,
cronRedisWorkOrder
.
OrderLevel
,
phones
)
if
err
!=
nil
{
zap
.
L
()
.
Error
(
err
.
Error
())
}
//发送短信
err
=
WorkOrderPushNoteMsg
(
cronRedisWorkOrder
.
OrderName
,
phones
,
cronRedisWorkOrder
.
OrderLevel
)
if
err
!=
nil
{
zap
.
L
()
.
Error
(
err
.
Error
())
}
}
for
d
:=
dateFrom
;
d
.
Before
(
dateTo
);
d
=
d
.
AddDate
(
0
,
0
,
1
)
{
//删除redis
expr
:=
fmt
.
Sprintf
(
"%d %d %d %d %d %d"
,
t
.
Second
(),
t
.
Minute
(),
t
.
Hour
(),
d
.
Day
(),
d
.
Month
(),
d
.
Year
())
err
=
redis
.
LRem
(
conf
.
WorkOrderPush
,
v
)
//创建定时任务
workOrderCron
.
AddFunc
(
expr
,
func
()
{
err
=
svc
.
PushWorkOrderManage
(
request
.
PushWorkOrderReq
{
Id
:
v
.
Id
,
PushObj
:
pushObj
})
//err = PushObjMsg(v.PushObj, v.OrderName, v.OrderLevel)
if
err
!=
nil
{
if
err
!=
nil
{
zap
.
L
()
.
Error
(
err
.
Error
(
))
conf
.
Logger
.
Error
(
"发送定时消息失败"
,
zap
.
Error
(
err
))
}
}
}
}
)
}
}
}
}
}
()
}
}
}
src/util/http.go
View file @
de712f7c
...
@@ -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
)
(
[]
byt
e
,
error
)
{
func
Request
(
url
string
,
method
string
,
body
[]
byte
,
headers
map
[
string
]
string
)
(
*
fasthttp
.
Respons
e
,
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
res
p
.
Body
()
,
nil
return
res
ult
,
nil
}
}
// HttpSend , http请求 GET/DELETE/POST/PUT
// HttpSend , http请求 GET/DELETE/POST/PUT
...
...
src/util/serialize.go
View file @
de712f7c
...
@@ -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
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment