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
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