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
Expand all
Show 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 (
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.66.0
github.com/prometheus/alertmanager v0.25.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/spf13/cast v1.5.0
github.com/spf13/pflag v1.0.5
github.com/tealeg/xlsx v1.0.5
github.com/thoas/go-funk v0.9.3
github.com/tidwall/gjson v1.16.0
github.com/valyala/fasthttp v1.47.0
github.com/wanghuiyt/ding v0.0.2
go.uber.org/zap v1.24.0
...
...
@@ -107,6 +109,8 @@ require (
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect
github.com/sirupsen/logrus v1.9.2 // 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/ugorji/go/codec v1.2.9 // 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
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/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/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
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=
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/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/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
...
...
src/bean/entity/alert_class.go
View file @
de712f7c
...
...
@@ -7,7 +7,7 @@ type AlertClass struct {
ClassName
string
`json:"class_name" xorm:"'class_name'"`
// 分类名称
ParentId
int
`json:"parent_id" xorm:"'parent_id'"`
// 父级id
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'"`
// 创建人
CreatedAt
jsontime
.
Time
`json:"created_at" xorm:"'created_at'"`
// 创建时间
UpdatedBy
string
`json:"updated_by" xorm:"'updated_by'"`
// 更新人
...
...
src/bean/entity/alert_overview.go
View file @
de712f7c
...
...
@@ -21,24 +21,8 @@ type AlertArray struct {
TotalCount
int
`json:"total_count"`
// 总预警数
}
type
RiskLevel
Distribution
struct
{
type
Alert
Distribution
struct
{
Name
string
`json:"name"`
// 名称
//RiskLevel int `json:"risk_level"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险
//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"`
}
...
...
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 {
CheckPeriod
int
`json:"check_period" xorm:"'check_period'"`
// 检查周期 单位:分钟
IsEnabled
int
`json:"is_enabled" xorm:"'is_enabled'"`
// 是否开启 1:是 2:否
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'"`
// 创建人
CreatedAt
jsontime
.
Time
`json:"created_at" xorm:"'created_at'"`
// 创建时间
UpdatedBy
string
`json:"updated_by" xorm:"'updated_by'"`
// 更新人
...
...
src/bean/entity/system_user.go
View file @
de712f7c
...
...
@@ -25,9 +25,9 @@ type SystemUser struct {
}
type
SystemUserInfo
struct
{
Id
int
`json:"id" xorm:"pk autoincr"
`
// id
Id
int
`json:"id" xorm:"pk autoincr"
`
// id
Name
string
`json:"name" `
// 名称
SystemAccount
string
`json:"system_account"
`
// 账号
SystemAccount
string
`json:"system_account"
`
// 账号
OrganizationId
string
`json:"organization_id" xorm:"organization_id"`
// 所属组织
Password
string
`json:"password,omitempty"`
// 密码
State
int
`json:"state" xorm:"state"`
// 状态0禁用1启用
...
...
src/bean/entity/work_order.go
View file @
de712f7c
package
entity
import
"time"
import
(
"time"
)
type
WorkOrder
struct
{
Id
int
`json:"id" xorm:"pk autoincr" `
// id
OrderName
string
`json:"order_name" xorm:"order_name"`
// 工单名称
OrderLevel
int
`json:"order_level" xorm:"order_level"`
// 工单等级(1紧急任务 2重要任务 3一般任务)
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"`
// 推送对象
TimingType
int
`json:"timing_type" xorm:"timing_type"`
// 定时类型(1手动下发 2按周 3自定义时间)
TimingRule
string
`json:"timing_rule" xorm:"timing_rule"`
// 定时规则
...
...
src/bean/vo/request/alert.go
View file @
de712f7c
...
...
@@ -15,6 +15,7 @@ type ListAlert struct {
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:已关闭
Keyword
string
`json:"keyword" form:"keyword"`
// 预警点/分类/指标
SystemAccount
string
`json:"system_account" form:"system_account"`
// 预警推送用户
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
...
...
src/bean/vo/request/alert_class.go
View file @
de712f7c
...
...
@@ -2,13 +2,14 @@ package request
type
AddAlertClass
struct
{
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"`
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
{
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"`
}
...
...
src/bean/vo/request/alert_rules.go
View file @
de712f7c
...
...
@@ -33,7 +33,7 @@ type UpdateAlertRules struct {
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"`
// 预警分类名称
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)
Expr
string
`json:"expr" form:"expr" binding:"required_if=DetectionType 2"`
// 指标表达式(PromQL语句)
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 {
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"`
// 预警分类名称
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)
Expr
string
`json:"expr" form:"expr" binding:"required_if=DetectionType 2"`
// 指标表达式(PromQL语句)
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 {
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:否
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
{
...
...
@@ -26,7 +26,7 @@ type UpdateMetricConfig struct {
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:否
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
{
...
...
src/bean/vo/request/work_order.go
View file @
de712f7c
package
request
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"`
// 工单名称
OrderLevel
int
`json:"order_level" binding:"oneof=1 2 3"`
// 工单等级(1紧急任务 2重要任务 3一般任务)
OrderDesc
string
`json:"order_desc" binding:"required"`
// 工单描述
...
...
@@ -36,7 +36,7 @@ type TimingCustom 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
OrderLevel
int
`json:"order_level" binding:"oneof=1 2 3"`
// 工单等级(1紧急任务 2重要任务 3一般任务)
OrderDesc
string
`json:"order_desc" binding:"required"`
// 工单描述
...
...
src/bean/vo/response/alert.go
View file @
de712f7c
...
...
@@ -62,3 +62,46 @@ type Hits struct {
MaxScore
float64
`json:"max_score"`
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 (
type
AlertOverviewItem
struct
{
AlertOverview
[]
entity
.
AlertOverview
`json:"alert_overview"`
RiskLevelDistribution
[]
entity
.
RiskLevelDistribution
`json:"risk_level_distribution"`
AlertStatusDistribution
[]
entity
.
Alert
StatusDistribution
`json:"alert_status_distribution"`
AlertClassDistribution
[]
entity
.
Alert
ClassDistribution
`json:"alert_class_distribution"`
RiskLevelDistribution
[]
entity
.
AlertDistribution
`json:"risk_level_distribution"`
AlertStatusDistribution
[]
entity
.
Alert
Distribution
`json:"alert_status_distribution"`
AlertClassDistribution
[]
entity
.
Alert
Distribution
`json:"alert_class_distribution"`
AlertFrequencyDistribution
entity
.
AlertFrequencyDistribution
`json:"alert_frequency_distribution"`
}
...
...
src/common/conf/options.go
View file @
de712f7c
...
...
@@ -31,7 +31,7 @@ type Config struct {
MinioSecretKey
string
MinioBucket
string
//TempDirPrefix string
PrometheusHost
string
AccessRuleModeKey
string
LocationUrl
string
LocationKey
string
...
...
@@ -49,9 +49,20 @@ type Config struct {
AweRestURL
string
KubernetesToken
string
OpenSearchIndex
string
OpenSearchAddresses
string
OpenSearchUserName
string
OpenSearchPassword
string
MonitorApiVersion
string
MonitorMatchNs
string
MonitorMatchLabelsStr
string
MonitorMatchLabels
map
[
string
]
interface
{}
Namespace
string
PrometheusHost
string
PrometheusRuleLabel
string
PrometheusRuleNamePrefix
string
}
const
(
...
...
src/controller/alert.go
View file @
de712f7c
...
...
@@ -31,6 +31,7 @@ func ListAlert(c *gin.Context) {
return
}
svc
:=
service
.
AlertSvc
{
User
:
header
.
GetUser
(
c
)}
// TODO 我的预警工单
data
,
err
:=
svc
.
List
(
req
)
if
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
FAIL
.
WithError
(
err
),
nil
)
...
...
src/controller/alert_webhook.go
View file @
de712f7c
...
...
@@ -3,10 +3,10 @@ package controller
import
(
"github.com/gin-gonic/gin"
"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/conf"
"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"
"go.uber.org/zap"
)
...
...
@@ -14,12 +14,18 @@ import (
// AlertWebhook 回调
func
AlertWebhook
(
c
*
gin
.
Context
)
{
var
req
webhook
.
Message
conf
.
Logger
.
Info
(
"------>webhook.start------>"
)
if
err
:=
c
.
ShouldBind
(
&
req
);
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
InvalidParam
.
TranslateError
(
err
),
nil
)
return
}
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
()
if
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
DbConnectError
.
WithError
(
err
),
nil
)
...
...
src/controller/work_order_manage.go
View file @
de712f7c
...
...
@@ -5,6 +5,7 @@ import (
"github.com/gin-gonic/gin"
"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/pkg/beagle/constant"
"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"
...
...
@@ -243,3 +244,36 @@ func ListWorkOrderMe(c *gin.Context) {
}
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() {
// redis client
go
client
.
GetRedisClient
()
// 初始化OpenSearch的索引
err
:=
service
.
CheckAndCreateIndex
()
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"failed to init OpenSearch index"
,
zap
.
Error
(
err
))
}
//启动定时任务
cron
.
StartCron
()
service
.
PushWorkOrderMessage
()
service
.
CronPushWorkOrder
()
// server start...
conf
.
Logger
.
Info
(
"config info"
,
zap
.
Any
(
"options"
,
conf
.
Options
))
conf
.
Logger
.
Error
(
"server start err"
,
zap
.
Error
(
newServer
()
.
ListenAndServe
()))
...
...
@@ -74,7 +80,6 @@ func initConfig() {
MinioAccessKey
:
util
.
SetEnvStr
(
"MINIO_ACCESS_KEY"
,
"beagleadmin"
),
// Minio Access Key
MinioSecretKey
:
util
.
SetEnvStr
(
"MINIO_SECRET_KEY"
,
"H76cPmwvH7vJ"
),
// Minio Secret
MinioBucket
:
util
.
SetEnvStr
(
"MINIO_BUCKET"
,
"so-operation"
),
// Minio Bucket
PrometheusHost
:
util
.
SetEnvStr
(
"PROMETHEUS_HOST"
,
"https://prometheus.wodcloud.com"
),
// Prometheus Host
AccessRuleModeKey
:
"accessRuleMode"
,
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"
),
...
...
@@ -85,14 +90,26 @@ func initConfig() {
SmsAccessKeyId
:
util
.
SetEnvStr
(
"SMS_ACCESS_KEY"
,
"LTAI4GBcVubRjzX7ABPcHnhB"
),
// 短信key
SmsAccessSecret
:
util
.
SetEnvStr
(
"SMS_ACCESS_SECRET"
,
"dYE2dtABFOqYtK1ijcrits0yedHkw7"
),
// 短信secret
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"
),
// 短信工单下发模板
SmsSignName
:
util
.
SetEnvStr
(
"SMS_SIGN_NAME"
,
"比格数据"
),
// 签名
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"
),
OpenSearchAddresses
:
util
.
SetEnvStr
(
"Open_Search_Addresses"
,
"https://so-opensearch.wodcloud.com"
),
// 短信验证码模板
OpenSearchUserName
:
util
.
SetEnvStr
(
"Open_Search_User_Name"
,
""
),
// 短信验证码模板
OpenSearchPassword
:
util
.
SetEnvStr
(
"Open_Search_Password"
,
""
),
// 短信验证码模板
OpenSearchIndex
:
util
.
SetEnvStr
(
"OPEN_SEARCH_INDEX"
,
"so_alert"
),
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() {
if
err
!=
nil
{
fmt
.
Println
(
err
.
Error
())
}
//else {
// _, err := f.Write([]byte("[web]\n"))
// if err != nil {
// fmt.Println(err.Error())
// }
//}
}
func
initTempDirPrefix
()
{
...
...
@@ -175,14 +186,4 @@ func initAnsibleSSH() {
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{
Export
:
14
,
}
// 数据来源(自定义为非正常数据) 1:默认 2:自定义
const
(
SourceDefault
=
1
SourceCustom
=
2
)
// RiskLevel 风险等级
const
(
RiskLevelLow
=
iota
+
1
// 1:低风险
...
...
@@ -142,7 +148,7 @@ func RiskLeveText(code int) string {
case
RiskLevelCritical
:
return
"重大风险"
default
:
return
""
return
"
未知
"
}
}
...
...
@@ -152,3 +158,40 @@ const (
AlertNotRecovered
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 (
"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/controller"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
)
// InitAlertListRouter 初始化预警列表配置路由
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
(
"list"
,
controller
.
ListAlert
)
...
...
src/router/alertrulesrouter.go.go
View file @
de712f7c
...
...
@@ -5,11 +5,12 @@ import (
"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/controller"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
)
// InitAlertRulesRouter 初始化预警规则配置路由
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
.
PUT
(
""
,
controller
.
UpdateAlertRules
)
...
...
src/router/metricconfigrouter.go
View file @
de712f7c
...
...
@@ -5,11 +5,12 @@ import (
"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/controller"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
)
// InitMetricConfigRouter 初始化指标配置路由
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
.
PUT
(
""
,
controller
.
UpdateMetricConfig
)
...
...
@@ -18,7 +19,7 @@ func InitMetricConfigRouter(e *gin.Engine) {
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
.
PUT
(
"move/:direction"
,
controller
.
MoveAlertClass
)
...
...
src/router/workorderrouter.go
View file @
de712f7c
...
...
@@ -10,12 +10,12 @@ import (
// InitWorkOrderRouter 初始化工单路由
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
.
GET
(
""
,
controller
.
DetailAlert
)
// 详情
alert
.
GET
(
"/list"
,
controller
.
ListAlert
)
// 列表
alert
.
GET
(
"/list"
,
controller
.
WorkOrderListAlert
)
// 列表
alert
.
PUT
(
"/dispose"
,
controller
.
DisposeAlert
)
// 处置反馈
}
...
...
@@ -46,5 +46,4 @@ func InitWorkOrderRouter(e *gin.Engine) {
me
.
PUT
(
"/feedback"
,
controller
.
FeedbackWorkOrderMe
)
// 处置反馈
me
.
GET
(
"/list"
,
controller
.
ListWorkOrderMe
)
// 我的业务工单列表
}
//so.POST("/note_sg", controller.WorkOrderPushNoteMsg)
}
src/service/alert.go
View file @
de712f7c
This diff is collapsed.
Click to expand it.
src/service/alert_class.go
View file @
de712f7c
...
...
@@ -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/response"
"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/resp"
"sort"
...
...
@@ -26,6 +27,9 @@ func (a *AlertClassSvc) Add(session *xorm.Session, req request.AddAlertClass) (c
UpdatedBy
:
a
.
User
.
SystemAccount
,
UpdatedAt
:
now
,
}
if
req
.
Source
!=
constant
.
SourceCustom
{
req
.
Source
=
constant
.
SourceDefault
}
_
=
copier
.
Copy
(
&
data
,
&
req
)
var
max
int
...
...
@@ -48,7 +52,7 @@ func (a *AlertClassSvc) Update(session *xorm.Session, req request.UpdateAlertCla
UpdatedAt
:
now
,
}
_
=
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
{
return
err
}
...
...
@@ -66,7 +70,7 @@ func (a *AlertClassSvc) Move(req request.MoveAlertClass) (err error) {
_
=
copier
.
Copy
(
&
data
,
&
req
)
var
list
[]
entity
.
AlertClass
_
,
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
nextIndex
int
for
i
:=
0
;
i
<
len
(
list
);
i
++
{
...
...
@@ -139,18 +143,33 @@ func (a *AlertClassSvc) List(req request.ListAlertClass) (resp response.AlertCla
}
session
:=
db
.
NewSession
()
defer
session
.
Close
()
session
.
Where
(
"source
_from
= 1"
)
session
.
Where
(
"source = 1"
)
if
req
.
ClassId
!=
0
{
session
.
Where
(
"class_id = ?"
,
req
.
ClassId
)
}
if
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
())
.
OrderBy
(
"sort_order"
)
.
FindAndCount
(
&
resp
.
List
)
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
)
{
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
...
...
@@ -159,7 +178,7 @@ func (a *AlertClassSvc) Tree(req request.ListAlertClass) (resp []*response.Alert
session
:=
db
.
NewSession
()
defer
session
.
Close
()
var
list
[]
entity
.
AlertClass
session
.
Where
(
"source
_from
= 1"
)
session
.
Where
(
"source = 1"
)
_
,
err
=
session
.
OrderBy
(
"sort_order"
)
.
FindAndCount
(
&
list
)
// TODO 对req进行过滤
resp
,
err
=
AlertClassTree
(
list
)
...
...
@@ -211,15 +230,68 @@ func (a *AlertClassSvc) SortOrderMax(parentId int) (max int, err error) {
}
_
,
err
=
db
.
NewSession
()
.
Table
(
new
(
entity
.
AlertClass
))
.
Select
(
"max(sort_order)"
)
.
Where
(
"parent_id = ?"
,
parentId
)
.
Where
(
"source
_from
= 1"
)
.
Get
(
&
max
)
Where
(
"parent_id = ?"
,
parentId
)
.
Where
(
"source = 1"
)
.
Get
(
&
max
)
return
}
func
(
a
*
AlertClassSvc
)
Delete
(
ids
[]
int
)
(
err
error
)
{
db
,
err
:=
client
.
GetDbClient
()
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
This diff is collapsed.
Click to expand it.
src/service/alert_rules.go
View file @
de712f7c
...
...
@@ -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/response"
"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/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
...
...
@@ -58,7 +59,7 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) {
classParentId
,
err
=
alertClassSvc
.
Add
(
session
,
request
.
AddAlertClass
{
ClassName
:
req
.
ClassParentName
,
SortOrder
:
-
1
,
Source
From
:
2
,
Source
:
constant
.
SourceCustom
,
})
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -67,18 +68,20 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) {
ClassName
:
req
.
ClassName
,
ParentId
:
classParentId
,
SortOrder
:
-
1
,
Source
From
:
2
,
Source
:
constant
.
SourceCustom
,
})
if
err
!=
nil
{
return
nil
,
err
}
data
.
ClassId
=
classId
req
.
ClassId
=
classId
// 添加指标配置
metricConfigSvc
:=
MetricConfigSvc
{
User
:
a
.
User
}
_
=
copier
.
Copy
(
&
addMetricConfig
,
&
req
)
addMetricConfig
.
Source
From
=
2
addMetricConfig
.
Source
=
constant
.
SourceCustom
addMetricConfig
.
MetricName
=
req
.
MetricConfigName
addMetricConfig
.
ClassId
=
classId
metricConfigId
,
err
=
metricConfigSvc
.
Add
(
session
,
addMetricConfig
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -87,14 +90,22 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) {
// 添加预警规则配置
_
,
err
=
session
.
Insert
(
&
data
)
if
err
!=
nil
{
return
nil
,
err
}
return
nil
,
err
})
err
=
a
.
CreatePrometheusRule
(
req
.
IsEnabled
,
data
.
Id
,
db
,
""
)
if
err
!=
nil
{
return
err
}
}
err
=
a
.
CreatePrometheusRule
(
req
.
IsEnabled
,
data
.
Id
,
db
,
""
)
if
err
!=
nil
{
return
err
}
return
nil
}
...
...
@@ -124,7 +135,11 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) {
}
switch
req
.
DetectionType
{
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
{
return
err
}
...
...
@@ -133,24 +148,37 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) {
// 更新自定义分类
var
(
updateMetricConfig
request
.
UpdateMetricConfig
alertClassItem
response
.
AlertClassItem
alertClass
response
.
AlertClassItem
alertParentClass
response
.
AlertClassItem
)
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
{
return
nil
,
err
}
err
=
alertClassSvc
.
Update
(
session
,
request
.
UpdateAlertClass
{
ClassId
:
dbAlertRules
.
ClassId
,
ClassName
:
req
.
ClassName
,
ParentId
:
alertClass
.
ParentId
,
})
if
err
!=
nil
{
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
{
ClassId
:
alertClass
Item
.
ParentId
,
ClassId
:
alertClass
.
ParentId
,
ClassName
:
req
.
ClassParentName
,
ParentId
:
alertParentClass
.
ParentId
,
})
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -159,17 +187,18 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) {
// 更新指标配置
metricConfigSvc
:=
MetricConfigSvc
{
User
:
a
.
User
}
_
=
copier
.
Copy
(
&
updateMetricConfig
,
&
req
)
updateMetricConfig
.
Source
From
=
2
updateMetricConfig
.
Source
=
constant
.
SourceCustom
updateMetricConfig
.
Id
=
dbAlertRules
.
MetricConfigId
err
=
metricConfigSvc
.
Update
(
session
,
updateMetricConfig
)
if
err
!=
nil
{
return
nil
,
err
}
// 更新预警规则配置
_
,
err
=
session
.
ID
(
data
.
Id
)
.
Update
(
&
data
)
return
nil
,
err
})
// 更新预警策略配置
_
,
err
=
session
.
ID
(
data
.
Id
)
.
MustCols
(
"duration"
)
.
Update
(
&
data
)
err
=
a
.
CreatePrometheusRule
(
req
.
IsEnabled
,
data
.
Id
,
db
,
"update"
)
if
err
!=
nil
{
return
err
}
...
...
@@ -237,16 +266,20 @@ func (a *AlertRulesSvc) UpdateIsEnabled(req request.UpdateIsEnabledAlertRules) (
return
}
if
req
.
IsEnabled
==
2
{
if
item
.
IsEnabled
==
1
{
prSvc
:=
PrometheusRuleSvc
{
User
:
a
.
User
}
var
exist
bool
_
,
exist
,
err
=
prSvc
.
Get
(
item
)
if
exist
{
err
=
prSvc
.
Delete
(
item
)
if
err
!=
nil
{
return
}
}
}
else
if
req
.
IsEnabled
==
1
{
if
item
.
IsEnabled
==
2
{
prSvc
:=
PrometheusRuleSvc
{
User
:
a
.
User
}
var
exist
bool
_
,
exist
,
err
=
prSvc
.
Get
(
item
)
if
!
exist
{
err
=
prSvc
.
Create
(
item
)
if
err
!=
nil
{
return
...
...
@@ -307,7 +340,7 @@ func (a *AlertRulesSvc) List(req request.ListAlertRules) (resp response.AlertRul
Or
(
"acp.class_name LIKE ?"
,
"%"
+
req
.
Keyword
+
"%"
)
}
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
)
for
i
:=
0
;
i
<
len
(
resp
.
List
);
i
++
{
_
=
json
.
Unmarshal
([]
byte
(
resp
.
List
[
i
]
.
AlertRules
.
AlertCondition
),
&
resp
.
List
[
i
]
.
AlertCondition
)
...
...
@@ -332,14 +365,15 @@ func (a *AlertRulesSvc) Delete(ids []string) (err error) {
}
if
!
exist
{
prSvc
:=
PrometheusRuleSvc
{
User
:
a
.
User
}
var
has
bool
_
,
has
,
err
=
prSvc
.
Get
(
response
.
AlertRulesItem
{
AlertRules
:
entity
.
AlertRules
{
Id
:
id
}})
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
))
if
err
!=
nil
{
return
}
_
,
err
=
db
.
NewSession
()
.
Where
(
"id = ?"
,
id
)
.
Delete
(
new
(
entity
.
AlertRules
))
}
else
{
return
errors
.
New
(
"alert_rules_id already exists in opensearch"
)
}
...
...
src/service/alert_webhook.go
View file @
de712f7c
...
...
@@ -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/vo/request"
"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/jsontime"
"go.uber.org/zap"
"time"
"xorm.io/xorm"
)
...
...
@@ -37,16 +40,20 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag
)
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
{
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
)
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
)
...
...
@@ -55,6 +62,11 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag
return
}
if
alertRulesItem
.
Id
==
""
{
conf
.
Logger
.
Error
(
"err"
,
zap
.
Error
(
errors
.
New
(
"告警规则查询为空"
)))
return
}
alertItem
,
err
=
alertSvc
.
GetDataByAlertRulesIdAndRiskLevel
(
alertRulesId
,
riskLevel
,
2
)
if
err
!=
nil
{
return
...
...
@@ -68,12 +80,18 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag
switch
isNewAlert
{
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
{
err
=
errors
.
New
(
"failed to get doc count for index"
)
conf
.
Logger
.
Error
(
"err"
,
zap
.
Error
(
err
))
return
}
alertI
d
:=
max
+
1
i
d
:=
max
+
1
for
_
,
v
:=
range
alertRulesItem
.
AlertCondition
{
if
v
.
RiskLevel
==
riskLevel
{
alertCondition
=
v
...
...
@@ -81,12 +99,12 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag
}
}
createAlert
:=
request
.
CreateAlert
{
Alert
:
entity
.
Alert
{
Id
:
alertI
d
,
Id
:
i
d
,
AlertPoint
:
alertRulesItem
.
ClassParentName
+
"/"
+
alertRulesItem
.
MetricName
,
AlertRulesId
:
alertRulesItem
.
Id
,
AlertRulesName
:
alertRulesItem
.
MetricName
,
RiskLevel
:
riskLevel
,
AlertTime
:
jsontime
.
Time
(
alert
.
StartsAt
),
AlertTime
:
jsontime
.
Time
(
alert
.
StartsAt
.
Add
(
time
.
Hour
*
8
)
),
ClassId
:
alertRulesItem
.
ClassId
,
ClassParentName
:
alertRulesItem
.
ClassParentName
,
ClassName
:
alertRulesItem
.
ClassName
,
...
...
src/service/cron/common.go
View file @
de712f7c
...
...
@@ -10,6 +10,4 @@ func StartCron() {
defer
c
.
Start
()
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 (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"strings"
"sync"
monitoringv1
"github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
)
var
(
PrometheusRuleGroup
=
"monitoring.beagle.io"
// kubectl api-resources | grep -i prome
PrometheusRuleVersion
=
"v1"
PrometheusRuleKind
=
"PrometheusRule"
Namespace
=
"beagle-monitoring"
PrometheusRuleApiVersion
=
PrometheusRuleGroup
+
"/"
+
PrometheusRuleVersion
PrometheusRuleName
=
strings
.
ToLower
(
PrometheusRuleKind
)
+
"s."
+
PrometheusRuleGroup
PrometheusRuleNamePrefix
=
"beagle-prometheus-so-operation-api-rules"
// beagle-monitoring beagle-prometheus-prometheus-operator 43d
promOnce
sync
.
Once
prometheusRuleName
string
alertOnce
sync
.
Once
alertDefLabels
map
[
string
]
string
)
var
AlertDefLabels
=
map
[
string
]
string
{
"app"
:
"prometheus"
,
"app.bd-apaas.com/cluster-component"
:
"monitoring"
,
"prometheus-operator"
:
"monitoring"
,
"release"
:
"beagle-prometheus"
,
func
GetPrometheusRuleCRDName
()
string
{
promOnce
.
Do
(
func
()
{
url
:=
conf
.
Options
.
MonitorApiVersion
// 请确保 conf 和其他相关配置可用
parts
:=
strings
.
Split
(
url
,
"/"
)
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名称
func
GetPrometheusRule
Name
(
alertRules
Id
string
)
string
{
return
fmt
.
Sprintf
(
"%s-%s"
,
PrometheusRuleNamePrefix
,
alertRules
Id
)
// GetPrometheusRule
Id
获取规则CRD名称
func
GetPrometheusRule
Id
(
alertPolicy
Id
string
)
string
{
return
fmt
.
Sprintf
(
"%s-%s"
,
conf
.
Options
.
PrometheusRuleNamePrefix
,
alertPolicy
Id
)
}
// GetPrometheusRuleGroupName 获取规则组名称
...
...
@@ -43,19 +59,19 @@ type PrometheusRule struct {
func
(
p
PrometheusRule
)
Create
(
pRule
*
monitoringv1
.
PrometheusRule
)
error
{
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
)
return
err
}
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
)
return
err
}
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
)
p
.
Header
[
"Content-Type"
]
=
"application/json"
_
,
err
:=
util
.
ProxySendRes
(
"PUT"
,
updateUrl
,
string
(
body
),
p
.
Header
)
...
...
@@ -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
)
{
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
)
if
err
!=
nil
{
return
...
...
src/service/metric_config.go
View file @
de712f7c
...
...
@@ -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/response"
"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/util"
"xorm.io/xorm"
...
...
@@ -25,6 +26,9 @@ func (m *MetricConfigSvc) Add(session *xorm.Session, req request.AddMetricConfig
UpdatedBy
:
m
.
User
.
SystemAccount
,
UpdatedAt
:
now
,
}
if
req
.
Source
!=
constant
.
SourceCustom
{
req
.
Source
=
constant
.
SourceDefault
}
_
=
copier
.
Copy
(
&
data
,
&
req
)
data
.
AlertRange
=
util
.
ConvertToString
(
req
.
AlertRange
)
_
,
err
=
session
.
Insert
(
&
data
)
...
...
@@ -89,6 +93,17 @@ func (m *MetricConfigSvc) List(req request.ListMetricConfig) (resp response.Metr
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
)
{
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
...
...
src/service/prometheus.go
View file @
de712f7c
...
...
@@ -26,10 +26,10 @@ func (p *PrometheusSvc) Label(req request.PrometheusLabel) (resp response.Promet
if
req
.
LabelName
!=
""
{
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
)),
map
[
string
]
string
{
"Content-Type"
:
util
.
MediaTypeForm
})
_
=
json
.
Unmarshal
(
bytes
,
&
prometheusSeries
)
_
=
json
.
Unmarshal
(
response
.
Body
()
,
&
prometheusSeries
)
for
_
,
v
:=
range
prometheusSeries
.
Data
{
for
k
,
_
:=
range
v
{
resp
.
List
=
append
(
resp
.
List
,
k
)
...
...
@@ -41,8 +41,8 @@ func (p *PrometheusSvc) Label(req request.PrometheusLabel) (resp response.Promet
}
else
{
url
:=
fmt
.
Sprintf
(
"%s%s"
,
conf
.
Options
.
PrometheusHost
,
"/api/v1/label/__name__/values"
)
bytes
,
_
:=
util
.
Request
(
url
,
http
.
MethodGet
,
nil
,
nil
)
_
=
json
.
Unmarshal
(
bytes
,
&
prometheusLabel
)
response
,
_
:=
util
.
Request
(
url
,
http
.
MethodGet
,
nil
,
nil
)
_
=
json
.
Unmarshal
(
response
.
Body
()
,
&
prometheusLabel
)
resp
.
TotalCount
=
int64
(
len
(
prometheusLabel
.
Data
))
resp
.
List
=
prometheusLabel
.
Data
}
...
...
@@ -57,10 +57,10 @@ func (p *PrometheusSvc) LabelValue(req request.PrometheusLabelValue) (resp respo
)
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
)),
map
[
string
]
string
{
"Content-Type"
:
util
.
MediaTypeForm
})
_
=
json
.
Unmarshal
(
bytes
,
&
prometheusSeries
)
_
=
json
.
Unmarshal
(
response
.
Body
()
,
&
prometheusSeries
)
for
_
,
v
:=
range
prometheusSeries
.
Data
{
for
key
,
value
:=
range
v
{
metricLabelMap
[
key
]
=
append
(
metricLabelMap
[
key
],
value
)
...
...
src/service/prometheusrule.go
View file @
de712f7c
package
service
import
(
"errors"
"fmt"
json
"github.com/json-iterator/go"
monitoringv1
"github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"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/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/service/k8s"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"go.uber.org/zap"
v1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"net/http"
"net/url"
"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
{
User
entity
.
SystemUserInfo
}
func
(
p
*
PrometheusRuleSvc
)
Create
(
data
response
.
AlertRulesItem
)
(
err
error
)
{
prometheusRule
Name
:=
k8s
.
GetPrometheusRuleName
(
data
.
Id
)
prometheusRule
ObjName
:=
k8s
.
GetPrometheusRuleId
(
data
.
Id
)
pr
:=
monitoringv1
.
PrometheusRule
{
ObjectMeta
:
v1
.
ObjectMeta
{
Name
:
prometheusRuleName
,
Namespace
:
k8s
.
Namespace
,
Labels
:
k8s
.
AlertDefLabels
,
Name
:
prometheusRule
Obj
Name
,
Namespace
:
conf
.
Options
.
MonitorMatchNs
,
Labels
:
k8s
.
GetAlertDefLabels
()
,
},
}
...
...
@@ -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"}
data
.
Expr
=
strings
.
ReplaceAll
(
data
.
Expr
,
v
.
VariableName
,
item
)
}
for
_
,
v
:=
range
data
.
AlertCondition
{
rule
:=
monitoringv1
.
Rule
{
Alert
:
data
.
MetricConfigName
,
For
:
&
ruleFor
,
Labels
:
map
[
string
]
string
{
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
),
"source"
:
"so-operation-api"
,
"alert_rules_id"
:
data
.
MetricConfigId
,
},
"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
{
// promhttp超过5万次告警-prom指标控制器请求数-较大风险-3
Alert
:
fmt
.
Sprintf
(
"%s-%s-%s-%d"
,
data
.
MetricName
,
data
.
MetricConfigName
,
constant
.
RiskLeveText
(
v
.
RiskLevel
),
k
+
1
),
For
:
&
ruleFor
,
Labels
:
labels
,
Annotations
:
map
[
string
]
string
{
"value"
:
"{{ $value }}"
,
"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) {
condition
+=
2
}
// 为"空"状态下,默认表达式已经有比较判断,故直接使用表达式即可
if
data
.
AlertRuleTypeName
==
"空"
{
condition
=
0
}
switch
condition
{
default
:
expr
=
data
.
Expr
...
...
@@ -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
))
}
// 校验表达式正确性
err
=
CheckPrometheusQuerySyntax
(
expr
)
if
err
!=
nil
{
return
}
rule
.
Expr
=
intstr
.
FromString
(
expr
)
group
.
Rules
=
append
(
group
.
Rules
,
rule
)
}
...
...
@@ -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
)
{
prometheusRule
Name
:=
k8s
.
GetPrometheusRuleName
(
data
.
Id
)
prometheusRule
ObjName
:=
k8s
.
GetPrometheusRuleId
(
data
.
Id
)
pr
:=
monitoringv1
.
PrometheusRule
{
ObjectMeta
:
v1
.
ObjectMeta
{
Name
:
prometheusRuleName
,
Namespace
:
k8s
.
Namespace
,
Labels
:
k8s
.
AlertDefLabels
,
Name
:
prometheusRule
Obj
Name
,
Namespace
:
conf
.
Options
.
MonitorMatchNs
,
Labels
:
k8s
.
GetAlertDefLabels
()
,
},
}
header
:=
map
[
string
]
string
{
"Authorization"
:
"Bearer "
+
conf
.
Options
.
KubernetesToken
}
...
...
@@ -109,13 +155,26 @@ func (p *PrometheusRuleSvc) Get(data response.AlertRulesItem) (obj *monitoringv1
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
)
{
prometheusRule
Name
:=
k8s
.
GetPrometheusRuleName
(
data
.
Id
)
prometheusRule
ObjName
:=
k8s
.
GetPrometheusRuleId
(
data
.
Id
)
pr
:=
monitoringv1
.
PrometheusRule
{
ObjectMeta
:
v1
.
ObjectMeta
{
Name
:
prometheusRuleName
,
Namespace
:
k8s
.
Namespace
,
Labels
:
k8s
.
AlertDefLabels
,
Name
:
prometheusRule
Obj
Name
,
Namespace
:
conf
.
Options
.
MonitorMatchNs
,
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
return
}
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
}
...
...
src/service/work_order.go
View file @
de712f7c
This diff is collapsed.
Click to expand it.
src/util/http.go
View file @
de712f7c
...
...
@@ -60,7 +60,7 @@ Request("https://httpbin.org/put",
"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
()
defer
fasthttp
.
ReleaseRequest
(
req
)
...
...
@@ -98,8 +98,11 @@ func Request(url string, method string, body []byte, headers map[string]string)
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
...
...
src/util/serialize.go
View file @
de712f7c
...
...
@@ -16,3 +16,14 @@ func ConvertToString(v interface{}) string {
}
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