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
42ba9e54
Commit
42ba9e54
authored
Jul 24, 2023
by
李科
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 回调推送
parent
dbe68c86
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
343 additions
and
89 deletions
+343
-89
src/bean/entity/alert.go
src/bean/entity/alert.go
+22
-22
src/bean/vo/request/alert.go
src/bean/vo/request/alert.go
+14
-7
src/bean/vo/response/alert.go
src/bean/vo/response/alert.go
+6
-0
src/bean/vo/response/alert_rules.go
src/bean/vo/response/alert_rules.go
+2
-1
src/controller/alert_webhook.go
src/controller/alert_webhook.go
+13
-20
src/pkg/beagle/constant/constant.go
src/pkg/beagle/constant/constant.go
+7
-0
src/service/alert.go
src/service/alert.go
+160
-33
src/service/alert_rules.go
src/service/alert_rules.go
+2
-1
src/service/alert_webhook.go
src/service/alert_webhook.go
+117
-5
No files found.
src/bean/entity/alert.go
View file @
42ba9e54
...
@@ -4,41 +4,41 @@ import (
...
@@ -4,41 +4,41 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
)
)
// Alert 预警
表
// Alert 预警
type
Alert
struct
{
type
Alert
struct
{
Id
int
`json:"id"`
// 预警
列表ID,主键,自增长
Id
int
`json:"id"`
// 预警
id
AlertPoint
string
`json:"alert_point"`
// 预警点
AlertPoint
string
`json:"alert_point"`
// 预警点
:预警分类/预警规则名称 ClassParentName/AlertRulesName
AlertRulesId
string
`json:"alert_rules_id"`
// 告警规则id
AlertRulesId
string
`json:"alert_rules_id"`
// 告警规则id
AlertRulesName
string
`json:"alert_rules_name"`
// 告警规则名称
RiskLevel
int
`json:"risk_level"`
// 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险
RiskLevel
int
`json:"risk_level"`
// 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险
AlertTime
jsontime
.
Time
`json:"alert_time"`
// 预警时间
AlertTime
jsontime
.
Time
`json:"alert_time"`
// 预警时间
ClassId
int
`json:"class_id"`
// 预警对象id(级联:预警分类/预警对象)
ClassId
int
`json:"class_id"`
// 预警对象id(级联:预警分类/预警对象)
ClassParentName
string
`json:"class_parent_name"`
// 预警分类名称 TODO 该字段做关联存储或查询
ClassParentName
string
`json:"class_parent_name"`
// 预警分类名称 TODO 该字段做关联存储或查询
ClassName
string
`json:"class_name"`
// 预警对象名称 TODO 该字段做关联存储或查询
ClassName
string
`json:"class_name"`
// 预警对象名称 TODO 该字段做关联存储或查询
MetricConfigId
string
`json:"metric_config_id"`
// 预警指标id
// 预警指标
MetricConfigId
string
`json:"metric_config_id"`
// 预警指标id
MetricConfigName
string
`json:"metric_config_name"`
// 预警指标名称
MetricConfigName
string
`json:"metric_config_name"`
// 预警指标名称
AlertRuleType
string
`json:"alert_rule_type"`
// 预警规则类型id TODO 该字段做关联存储或查询
AlertRuleType
string
`json:"alert_rule_type"`
// 预警规则类型id TODO 该字段做关联存储或查询
AlertRuleTypeName
string
`json:"alert_rule_type_name"`
// 预警规则类型名称 TODO 该字段做关联存储或查询
AlertRuleTypeName
string
`json:"alert_rule_type_name"`
// 预警规则类型名称 TODO 该字段做关联存储或查询
CurrentValue
float64
`json:"current_value"`
// 当前报警值
CurrentValue
float64
`json:"current_value"`
// 当前报警值
AlertCondition
AlertCondition
`json:"alert_condition"
xorm:"alert_condition"`
AlertCondition
AlertCondition
`json:"alert_condition"
`
// 预警范围
NotificationCount
int
`json:"notification_count"`
// 通知人数
NotificationCount
int
`json:"notification_count"`
// 通知人数
PushCount
int
`json:"push_count"`
// 推送次数
PushCount
int
`json:"push_count"`
// 推送次数
LastPushTime
jsontime
.
Time
`json:"last_push_time"`
// 最近推送时间
LastPushTime
jsontime
.
Time
`json:"last_push_time"`
// 最近推送时间
Status
int
`json:"status"`
// 状态,1:已恢复 2:未恢复 3:已关闭
Status
int
`json:"status"`
// 状态,1:已恢复 2:未恢复 3:已关闭
PushRecords
[]
PushRecord
`json:"push_records"`
PushRecords
[]
PushRecord
`json:"push_records"`
// 推送记录列表
DisposedList
[]
Disposed
List
`json:"disposed_list"`
// 处置列表
DisposedList
[]
Disposed
`json:"disposed_list"`
// 处置列表
IsDisposed
int
`json:"is_disposed"`
// 是否处置(工单管理),1:已处置,2:未处置 通过DisposedList逻辑处理回显
IsDisposed
int
`json:"is_disposed"`
// 是否处置(工单管理),1:已处置,2:未处置 通过DisposedList逻辑处理回显
CloseRemark
string
`json:"close_remark"`
// 关闭备注(预警关闭提醒)
CloseRemark
string
`json:"close_remark"`
// 关闭备注(预警关闭提醒)
CloseUser
string
`json:"close_user"`
// 关闭用户,预警关闭提醒
CloseUser
string
`json:"close_user"`
// 关闭用户,预警关闭提醒
CloseTime
jsontime
.
Time
`json:"close_time"`
// 关闭关闭时间,预警关闭提醒
CloseTime
jsontime
.
Time
`json:"close_time"`
// 关闭关闭时间,预警关闭提醒
DeferPush
int
`json:"defer_push" xorm:"defer_push"`
// 延迟三天推送: 0:否 1:是 三天内将不再自动推送该告警信息给处置人员,可手动推送,但告警数据依然会出现
DeferPush
int
`json:"defer_push"`
// 延迟三天推送: 0:否 1:是 三天内将不再自动推送该告警信息给处置人员,可手动推送,但告警数据依然会出现
CreatedBy
string
`json:"created_by"`
// 创建人
CreatedBy
string
`json:"created_by" xorm:"'created_by'"`
// 创建人
CreatedAt
jsontime
.
Time
`json:"created_at"`
// 创建时间
CreatedAt
jsontime
.
Time
`json:"created_at" xorm:"'created_at'"`
// 创建时间
UpdatedBy
string
`json:"updated_by"`
// 更新人
UpdatedBy
string
`json:"updated_by" xorm:"'updated_by'"`
// 更新人
UpdatedAt
jsontime
.
Time
`json:"updated_at"`
// 更新时间
UpdatedAt
jsontime
.
Time
`json:"updated_at" xorm:"'updated_at'"`
// 更新时间
}
}
type
Disposed
List
struct
{
type
Disposed
struct
{
IsDisposed
int
`json:"is_disposed"`
// 是否处置(工单管理),1:已处置,2:未处置
IsDisposed
int
`json:"is_disposed"`
// 是否处置(工单管理),1:已处置,2:未处置
DisposalContent
string
`json:"disposal_content"`
// 处置内容(工单管理,结果反馈)
DisposalContent
string
`json:"disposal_content"`
// 处置内容(工单管理,结果反馈)
DisposalUser
string
`json:"disposal_user"`
// 处置人(工单管理,结果反馈)
DisposalUser
string
`json:"disposal_user"`
// 处置人(工单管理,结果反馈)
...
...
src/bean/vo/request/alert.go
View file @
42ba9e54
...
@@ -11,6 +11,7 @@ type DetailAlert struct {
...
@@ -11,6 +11,7 @@ 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
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"`
// 预警点/分类/指标
...
@@ -24,13 +25,19 @@ type ExistAlert struct {
...
@@ -24,13 +25,19 @@ type ExistAlert struct {
AlertRulesId
string
`json:"alert_rules_id" form:"'alert_rules_id'"`
// 告警规则id
AlertRulesId
string
`json:"alert_rules_id" form:"'alert_rules_id'"`
// 告警规则id
}
}
type
CreateAlert
struct
{
entity
.
Alert
}
type
UpdateAlert
struct
{
type
UpdateAlert
struct
{
Id
int
`json:"id" form:"id" binding:"required"`
Id
int
`json:"id" form:"id" binding:"required"`
CloseRemark
string
`json:"close_remark" form:"close_remark"`
// 关闭备注
CloseRemark
string
`json:"close_remark" form:"close_remark"`
// 关闭备注
DeferPush
int
`json:"defer_push" form:"defer_push" binding:"omitempty,oneof=0 1"`
// 延迟三天推送: 0:否 1:是 三天内将不再自动推送该告警信息给处置人员,可手动推送,但告警数据依然会出现
DeferPush
int
`json:"defer_push" form:"defer_push" binding:"omitempty,oneof=0 1"`
// 延迟三天推送: 0:否 1:是 三天内将不再自动推送该告警信息给处置人员,可手动推送,但告警数据依然会出现
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:已关闭
CurrentValue
float64
`json:"current_value" form:"current_value"`
// 当前报警值
DisposalContent
string
`json:"disposal_content" form:"disposal_content"`
// 处置内容(工单管理,结果反馈)
DisposalContent
string
`json:"disposal_content" form:"disposal_content"`
// 处置内容(工单管理,结果反馈)
PushCount
int
`json:"push_count" form:"push_count"`
// 推送次数
PushRecords
[]
entity
.
PushRecord
`json:"push_records" form:"push_records"`
PushRecords
[]
entity
.
PushRecord
`json:"push_records" form:"push_records"`
}
}
...
...
src/bean/vo/response/alert.go
View file @
42ba9e54
...
@@ -26,6 +26,12 @@ type CatIndices struct {
...
@@ -26,6 +26,12 @@ type CatIndices struct {
PriStoreSize
string
`json:"pri.store.size"`
PriStoreSize
string
`json:"pri.store.size"`
}
}
type
CatIndexCount
struct
{
Epoch
string
`json:"epoch"`
Timestamp
string
`json:"timestamp"`
Count
string
`json:"count"`
}
type
OpenSearchSource
struct
{
type
OpenSearchSource
struct
{
Took
int
`json:"took"`
Took
int
`json:"took"`
TimedOut
bool
`json:"timed_out"`
TimedOut
bool
`json:"timed_out"`
...
...
src/bean/vo/response/alert_rules.go
View file @
42ba9e54
...
@@ -5,7 +5,8 @@ import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
...
@@ -5,7 +5,8 @@ import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
type
AlertRulesItem
struct
{
type
AlertRulesItem
struct
{
entity
.
AlertRules
`xorm:"extends"`
entity
.
AlertRules
`xorm:"extends"`
Expr
string
`json:"expr" form:"expr"`
// 指标表达式(PromQL语句)
Expr
string
`json:"expr" form:"expr"`
// 指标表达式(PromQL语句)
AlertRuleType
string
`json:"alert_rule_type" xorm:"alert_rule_type"`
// 预警规则类型 关联字典表
AlertRuleType
string
`json:"alert_rule_type" xorm:"alert_rule_type"`
// 预警规则类型
AlertRuleTypeName
string
`json:"alert_rule_type_name"`
// 预警规则类型名称
ClassParentName
string
`json:"class_parent_name" xorm:"class_parent_name"`
ClassParentName
string
`json:"class_parent_name" xorm:"class_parent_name"`
ClassName
string
`json:"class_name" xorm:"class_name"`
ClassName
string
`json:"class_name" xorm:"class_name"`
MetricConfigName
string
`json:"metric_config_name" xorm:"metric_config_name"`
MetricConfigName
string
`json:"metric_config_name" xorm:"metric_config_name"`
...
...
src/controller/alert_webhook.go
View file @
42ba9e54
...
@@ -3,39 +3,32 @@ package controller
...
@@ -3,39 +3,32 @@ 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/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"
"go.uber.org/zap"
"go.uber.org/zap"
)
)
// AlertWebhook 回调
// AlertWebhook 回调
func
AlertWebhook
(
c
*
gin
.
Context
)
{
func
AlertWebhook
(
c
*
gin
.
Context
)
{
// 读取请求体原始数据
var
req
webhook
.
Message
var
req
webhook
.
Message
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
))
/*bodyBytes, err := io.ReadAll(c.Request.Body)
svc
:=
service
.
AlertWebhookSvc
{
User
:
header
.
GetUser
(
c
)}
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
if
err
!=
nil
{
// 处理错误
SendJsonResponse
(
c
,
resp
.
DbConnectError
.
WithError
(
err
),
nil
)
c.String(500, "Error reading request body")
return
return
}*/
}
err
=
svc
.
AlertWebhook
(
db
.
NewSession
(),
req
)
// 输出请求体原始数据到控制台
if
err
!=
nil
{
//log.Printf("原始数据------>\n%s\n<------", string(bodyBytes))
SendJsonResponse
(
c
,
resp
.
FAIL
.
WithError
(
err
),
nil
)
return
// 将请求体数据重新放入请求中,以便后续处理
}
//c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
conf
.
Logger
.
Info
(
"------>webhook.Message------>"
,
zap
.
Any
(
"message"
,
req
))
/*var payload map[string]interface{}
if err := c.ShouldBind(&payload); err != nil {
log.Println("Failed to parse JSON: ", err)
SendJsonResponse(c, err, "")
}*/
SendJsonResponse
(
c
,
resp
.
OK
,
req
)
SendJsonResponse
(
c
,
resp
.
OK
,
req
)
}
}
src/pkg/beagle/constant/constant.go
View file @
42ba9e54
...
@@ -145,3 +145,10 @@ func RiskLeveText(code int) string {
...
@@ -145,3 +145,10 @@ func RiskLeveText(code int) string {
return
""
return
""
}
}
}
}
// 预警状态,1:已恢复 2:未恢复 3:已关闭
const
(
AlertRecovered
=
iota
+
1
AlertNotRecovered
AlertClosed
)
src/service/alert.go
View file @
42ba9e54
...
@@ -14,6 +14,7 @@ import (
...
@@ -14,6 +14,7 @@ import (
"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"
"go.uber.org/zap"
"go.uber.org/zap"
"io"
"io"
...
@@ -52,6 +53,15 @@ var (
...
@@ -52,6 +53,15 @@ var (
"alert_rules_id": {
"alert_rules_id": {
"type": "keyword"
"type": "keyword"
},
},
"alert_rules_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"risk_level": {
"risk_level": {
"type": "integer"
"type": "integer"
},
},
...
@@ -324,7 +334,7 @@ func (a *AlertSvc) Indices() (indices []string, err error) {
...
@@ -324,7 +334,7 @@ func (a *AlertSvc) Indices() (indices []string, err error) {
return
return
}
}
defer
do
.
Body
.
Close
()
defer
do
.
Body
.
Close
()
if
do
.
StatusCode
!=
http
.
StatusOK
{
if
do
.
StatusCode
<
http
.
StatusOK
&&
do
.
StatusCode
>
http
.
StatusIMUsed
{
err
=
errors
.
New
(
do
.
String
())
err
=
errors
.
New
(
do
.
String
())
return
return
}
}
...
@@ -346,7 +356,7 @@ func (a *AlertSvc) Indices() (indices []string, err error) {
...
@@ -346,7 +356,7 @@ func (a *AlertSvc) Indices() (indices []string, err error) {
return
return
}
}
func
(
a
*
AlertSvc
)
Index
Search
(
req
request
.
ListAlert
)
(
resp
response
.
AlertList
,
err
error
)
{
func
(
a
*
AlertSvc
)
Doc
Search
(
req
request
.
ListAlert
)
(
resp
response
.
AlertList
,
err
error
)
{
var
(
var
(
sources
response
.
OpenSearchSource
sources
response
.
OpenSearchSource
)
)
...
@@ -362,6 +372,10 @@ func (a *AlertSvc) IndexSearch(req request.ListAlert) (resp response.AlertList,
...
@@ -362,6 +372,10 @@ func (a *AlertSvc) IndexSearch(req request.ListAlert) (resp response.AlertList,
boolQuery
.
Must
(
elastic
.
NewMatchQuery
(
"id"
,
req
.
Id
))
boolQuery
.
Must
(
elastic
.
NewMatchQuery
(
"id"
,
req
.
Id
))
}
}
if
req
.
AlertRulesId
!=
""
{
boolQuery
.
Must
(
elastic
.
NewMatchQuery
(
"alert_rules_id"
,
req
.
AlertRulesId
))
}
if
req
.
RiskLevel
!=
0
{
if
req
.
RiskLevel
!=
0
{
boolQuery
.
Must
(
elastic
.
NewMatchQuery
(
"risk_level"
,
req
.
RiskLevel
))
boolQuery
.
Must
(
elastic
.
NewMatchQuery
(
"risk_level"
,
req
.
RiskLevel
))
}
}
...
@@ -417,7 +431,7 @@ func (a *AlertSvc) IndexSearch(req request.ListAlert) (resp response.AlertList,
...
@@ -417,7 +431,7 @@ func (a *AlertSvc) IndexSearch(req request.ListAlert) (resp response.AlertList,
return
return
}
}
defer
do
.
Body
.
Close
()
defer
do
.
Body
.
Close
()
if
do
.
StatusCode
!=
http
.
StatusOK
{
if
do
.
StatusCode
<
http
.
StatusOK
&&
do
.
StatusCode
>
http
.
StatusIMUsed
{
err
=
errors
.
New
(
do
.
String
())
err
=
errors
.
New
(
do
.
String
())
return
return
}
}
...
@@ -473,7 +487,7 @@ func (a *AlertSvc) IndexDocExist(req request.ExistAlert) (exist bool, err error)
...
@@ -473,7 +487,7 @@ func (a *AlertSvc) IndexDocExist(req request.ExistAlert) (exist bool, err error)
return
return
}
}
defer
do
.
Body
.
Close
()
defer
do
.
Body
.
Close
()
if
do
.
StatusCode
!=
http
.
StatusOK
{
if
do
.
StatusCode
<
http
.
StatusOK
&&
do
.
StatusCode
>
http
.
StatusIMUsed
{
err
=
errors
.
New
(
do
.
String
())
err
=
errors
.
New
(
do
.
String
())
return
return
}
}
...
@@ -493,7 +507,97 @@ func (a *AlertSvc) IndexDocExist(req request.ExistAlert) (exist bool, err error)
...
@@ -493,7 +507,97 @@ func (a *AlertSvc) IndexDocExist(req request.ExistAlert) (exist bool, err error)
return
return
}
}
func
(
a
*
AlertSvc
)
IndexUpdate
(
req
request
.
UpdateAlert
)
(
err
error
)
{
func
(
a
*
AlertSvc
)
CatCount
(
indexName
...
string
)
(
count
int
)
{
var
(
list
[]
response
.
CatIndexCount
index
string
)
cli
,
err
:=
client
.
GetOpenSearch
()
if
err
!=
nil
{
return
}
if
len
(
indexName
)
>
0
&&
indexName
[
0
]
!=
""
{
index
=
indexName
[
0
]
+
"*"
}
else
{
index
=
OpenSearchIndex
+
"*"
}
res
:=
opensearchapi
.
CatCountRequest
{
Index
:
[]
string
{
index
},
Format
:
"json"
,
}
do
,
err
:=
res
.
Do
(
context
.
Background
(),
cli
)
if
err
!=
nil
{
return
}
defer
do
.
Body
.
Close
()
if
do
.
StatusCode
<
http
.
StatusOK
&&
do
.
StatusCode
>
http
.
StatusIMUsed
{
err
=
errors
.
New
(
do
.
String
())
return
}
body
,
err
:=
io
.
ReadAll
(
do
.
Body
)
if
err
!=
nil
{
return
}
err
=
json
.
Unmarshal
(
body
,
&
list
)
if
err
!=
nil
{
return
}
if
len
(
list
)
>
0
{
count
=
cast
.
ToInt
(
list
[
0
]
.
Count
)
}
return
}
func
(
a
*
AlertSvc
)
DocCreate
(
req
request
.
CreateAlert
)
(
err
error
)
{
var
(
sources
response
.
OpenSearchSource
)
cli
,
err
:=
client
.
GetOpenSearch
()
if
err
!=
nil
{
return
}
b
,
_
:=
json
.
Marshal
(
&
req
.
Alert
)
docStr
:=
string
(
b
)
if
docStr
==
""
{
return
errors
.
New
(
"doc marshal failed"
)
}
content
:=
strings
.
NewReader
(
fmt
.
Sprintf
(
`%s`
,
docStr
))
res
:=
opensearchapi
.
CreateRequest
{
Index
:
OpenSearchIndex
,
DocumentID
:
cast
.
ToString
(
req
.
Id
),
Body
:
content
,
}
do
,
err
:=
res
.
Do
(
context
.
Background
(),
cli
)
if
err
!=
nil
{
return
}
defer
do
.
Body
.
Close
()
if
do
.
StatusCode
<
http
.
StatusOK
&&
do
.
StatusCode
>
http
.
StatusIMUsed
{
err
=
errors
.
New
(
do
.
String
())
return
}
body
,
err
:=
io
.
ReadAll
(
do
.
Body
)
if
err
!=
nil
{
return
}
err
=
json
.
Unmarshal
(
body
,
&
sources
)
if
err
!=
nil
{
return
}
conf
.
Logger
.
Info
(
"--->alert create--->"
,
zap
.
Any
(
"DocCreate"
,
sources
))
return
}
func
(
a
*
AlertSvc
)
DocUpdate
(
req
request
.
UpdateAlert
)
(
err
error
)
{
var
(
var
(
sources
response
.
OpenSearchSource
sources
response
.
OpenSearchSource
now
=
jsontime
.
Now
()
now
=
jsontime
.
Now
()
...
@@ -517,23 +621,15 @@ func (a *AlertSvc) IndexUpdate(req request.UpdateAlert) (err error) {
...
@@ -517,23 +621,15 @@ func (a *AlertSvc) IndexUpdate(req request.UpdateAlert) (err error) {
if
req
.
Status
!=
0
{
if
req
.
Status
!=
0
{
doc
[
"status"
]
=
req
.
Status
doc
[
"status"
]
=
req
.
Status
}
}
doc
[
"updated_at"
]
=
now
if
req
.
CurrentValue
!=
0
{
doc
[
"current_value"
]
=
req
.
CurrentValue
if
req
.
DisposalContent
!=
""
{
var
detailAlert
response
.
AlertItem
detailAlert
,
err
=
a
.
GetDataById
(
request
.
DetailAlert
{
Id
:
req
.
Id
})
if
err
!=
nil
{
return
err
}
disposedList
:=
detailAlert
.
DisposedList
disposedList
=
append
(
disposedList
,
entity
.
DisposedList
{
IsDisposed
:
req
.
Status
,
DisposalContent
:
req
.
DisposalContent
,
DisposalUser
:
a
.
User
.
SystemAccount
,
DisposalTime
:
now
,
})
doc
[
"disposed_list"
]
=
disposedList
}
}
/*if req.CurrentValue != 0 {
doc["current_value"] = req.CurrentValue
}*/
doc
[
"updated_by"
]
=
a
.
User
.
SystemAccount
doc
[
"updated_at"
]
=
now
if
len
(
req
.
PushRecords
)
>
0
{
if
len
(
req
.
PushRecords
)
>
0
{
doc
[
"push_records"
]
=
req
.
PushRecords
doc
[
"push_records"
]
=
req
.
PushRecords
...
@@ -564,7 +660,7 @@ func (a *AlertSvc) IndexUpdate(req request.UpdateAlert) (err error) {
...
@@ -564,7 +660,7 @@ func (a *AlertSvc) IndexUpdate(req request.UpdateAlert) (err error) {
return
return
}
}
defer
do
.
Body
.
Close
()
defer
do
.
Body
.
Close
()
if
do
.
StatusCode
!=
http
.
StatusOK
{
if
do
.
StatusCode
<
http
.
StatusOK
&&
do
.
StatusCode
>
http
.
StatusIMUsed
{
err
=
errors
.
New
(
do
.
String
())
err
=
errors
.
New
(
do
.
String
())
return
return
}
}
...
@@ -578,18 +674,38 @@ func (a *AlertSvc) IndexUpdate(req request.UpdateAlert) (err error) {
...
@@ -578,18 +674,38 @@ func (a *AlertSvc) IndexUpdate(req request.UpdateAlert) (err error) {
return
return
}
}
conf
.
Logger
.
Info
(
"--->alert update--->"
,
zap
.
Any
(
"
Index
Update"
,
sources
))
conf
.
Logger
.
Info
(
"--->alert update--->"
,
zap
.
Any
(
"
Doc
Update"
,
sources
))
return
return
}
}
func
(
a
*
AlertSvc
)
Create
()
error
{
cli
,
err
:=
client
.
GetOpenSearch
()
if
err
!=
nil
{
return
err
}
res
:=
opensearchapi
.
IndicesCreateRequest
{
Index
:
OpenSearchIndex
,
Body
:
Mapping
,
}
do
,
err
:=
res
.
Do
(
context
.
Background
(),
cli
)
if
err
!=
nil
{
return
err
}
defer
do
.
Body
.
Close
()
if
do
.
StatusCode
!=
http
.
StatusOK
{
return
errors
.
New
(
do
.
String
())
}
return
nil
}
func
(
a
*
AlertSvc
)
Update
(
req
request
.
UpdateAlert
)
error
{
func
(
a
*
AlertSvc
)
Update
(
req
request
.
UpdateAlert
)
error
{
err
:=
a
.
Index
Update
(
req
)
err
:=
a
.
Doc
Update
(
req
)
return
err
return
err
}
}
func
(
a
*
AlertSvc
)
BatchPushAlert
(
req
request
.
BatchPushAlert
)
(
err
error
)
{
func
(
a
*
AlertSvc
)
BatchPushAlert
(
req
request
.
BatchPushAlert
)
(
err
error
)
{
now
:=
jsontime
.
Now
()
now
:=
jsontime
.
Now
()
resp
,
err
:=
a
.
Index
Search
(
request
.
ListAlert
{
Ids
:
req
.
Ids
})
resp
,
err
:=
a
.
Doc
Search
(
request
.
ListAlert
{
Ids
:
req
.
Ids
})
if
err
!=
nil
{
if
err
!=
nil
{
return
return
}
}
...
@@ -619,7 +735,7 @@ func (a *AlertSvc) BatchPushAlert(req request.BatchPushAlert) (err error) {
...
@@ -619,7 +735,7 @@ func (a *AlertSvc) BatchPushAlert(req request.BatchPushAlert) (err error) {
pushRecords
=
append
(
pushRecords
,
data
)
pushRecords
=
append
(
pushRecords
,
data
)
}
}
err
=
a
.
Index
Update
(
request
.
UpdateAlert
{
err
=
a
.
Doc
Update
(
request
.
UpdateAlert
{
Id
:
alert
.
Id
,
Id
:
alert
.
Id
,
PushRecords
:
pushRecords
,
PushRecords
:
pushRecords
,
})
})
...
@@ -642,7 +758,7 @@ func (a *AlertSvc) BatchCloseAlert(req request.BatchCloseAlert) (err error) {
...
@@ -642,7 +758,7 @@ func (a *AlertSvc) BatchCloseAlert(req request.BatchCloseAlert) (err error) {
ids
=
append
(
ids
,
req
.
Id
)
ids
=
append
(
ids
,
req
.
Id
)
}
}
for
_
,
id
:=
range
ids
{
for
_
,
id
:=
range
ids
{
err
=
a
.
Index
Update
(
request
.
UpdateAlert
{
err
=
a
.
Doc
Update
(
request
.
UpdateAlert
{
Id
:
id
,
Id
:
id
,
CloseRemark
:
req
.
CloseRemark
,
CloseRemark
:
req
.
CloseRemark
,
DeferPush
:
req
.
DeferPush
,
DeferPush
:
req
.
DeferPush
,
...
@@ -658,15 +774,26 @@ func (a *AlertSvc) BatchCloseAlert(req request.BatchCloseAlert) (err error) {
...
@@ -658,15 +774,26 @@ func (a *AlertSvc) BatchCloseAlert(req request.BatchCloseAlert) (err error) {
}
}
func
(
a
*
AlertSvc
)
GetDataById
(
req
request
.
DetailAlert
)
(
resp
response
.
AlertItem
,
err
error
)
{
func
(
a
*
AlertSvc
)
GetDataById
(
req
request
.
DetailAlert
)
(
resp
response
.
AlertItem
,
err
error
)
{
list
,
err
:=
a
.
IndexSearch
(
request
.
ListAlert
{
Id
:
req
.
Id
})
list
,
err
:=
a
.
DocSearch
(
request
.
ListAlert
{
Id
:
req
.
Id
})
if
len
(
list
.
List
)
>
0
{
resp
=
list
.
List
[
0
]
}
return
}
func
(
a
*
AlertSvc
)
GetDataByAlertRulesIdAndRiskLevel
(
alertRulesId
string
,
riskLevel
int
,
status
int
)
(
resp
response
.
AlertItem
,
err
error
)
{
list
,
err
:=
a
.
DocSearch
(
request
.
ListAlert
{
AlertRulesId
:
alertRulesId
,
RiskLevel
:
riskLevel
,
Status
:
status
})
if
len
(
list
.
List
)
>
0
{
if
len
(
list
.
List
)
>
0
{
resp
=
list
.
List
[
0
]
resp
=
list
.
List
[
0
]
}
}
/*if resp.Id == 0 {
err = errors.New("no data found")
}*/
return
return
}
}
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
.
Index
Search
(
req
)
resp
,
err
=
a
.
Doc
Search
(
req
)
resp
.
TotalCount
=
int64
(
len
(
resp
.
List
))
resp
.
TotalCount
=
int64
(
len
(
resp
.
List
))
return
return
}
}
...
@@ -684,10 +811,10 @@ func (a *AlertSvc) DisposeAlert(req request.DisposeAlert) (err error) {
...
@@ -684,10 +811,10 @@ func (a *AlertSvc) DisposeAlert(req request.DisposeAlert) (err error) {
return
err
return
err
}
}
if
detailAlert
.
Status
==
1
{
if
detailAlert
.
Status
==
constant
.
AlertRecovered
{
return
errors
.
New
(
"alert has been restored"
)
return
errors
.
New
(
"alert has been restored"
)
}
}
if
detailAlert
.
Status
==
3
{
if
detailAlert
.
Status
==
constant
.
AlertClosed
{
return
errors
.
New
(
"alert has been closed"
)
return
errors
.
New
(
"alert has been closed"
)
}
}
...
@@ -700,7 +827,7 @@ func (a *AlertSvc) DisposeAlert(req request.DisposeAlert) (err error) {
...
@@ -700,7 +827,7 @@ func (a *AlertSvc) DisposeAlert(req request.DisposeAlert) (err error) {
doc
[
"status"
]
=
req
.
Status
doc
[
"status"
]
=
req
.
Status
if
req
.
DisposalContent
!=
""
{
if
req
.
DisposalContent
!=
""
{
disposedList
:=
detailAlert
.
DisposedList
disposedList
:=
detailAlert
.
DisposedList
disposedList
=
append
(
disposedList
,
entity
.
Disposed
List
{
disposedList
=
append
(
disposedList
,
entity
.
Disposed
{
IsDisposed
:
req
.
Status
,
IsDisposed
:
req
.
Status
,
DisposalContent
:
req
.
DisposalContent
,
DisposalContent
:
req
.
DisposalContent
,
DisposalUser
:
a
.
User
.
SystemAccount
,
DisposalUser
:
a
.
User
.
SystemAccount
,
...
@@ -730,7 +857,7 @@ func (a *AlertSvc) DisposeAlert(req request.DisposeAlert) (err error) {
...
@@ -730,7 +857,7 @@ func (a *AlertSvc) DisposeAlert(req request.DisposeAlert) (err error) {
return
return
}
}
defer
do
.
Body
.
Close
()
defer
do
.
Body
.
Close
()
if
do
.
StatusCode
!=
http
.
StatusOK
{
if
do
.
StatusCode
<
http
.
StatusOK
&&
do
.
StatusCode
>
http
.
StatusIMUsed
{
err
=
errors
.
New
(
do
.
String
())
err
=
errors
.
New
(
do
.
String
())
return
return
}
}
...
...
src/service/alert_rules.go
View file @
42ba9e54
...
@@ -279,10 +279,11 @@ func (a *AlertRulesSvc) List(req request.ListAlertRules) (resp response.AlertRul
...
@@ -279,10 +279,11 @@ func (a *AlertRulesSvc) List(req request.ListAlertRules) (resp response.AlertRul
}
}
session
:=
db
.
NewSession
()
session
:=
db
.
NewSession
()
defer
session
.
Close
()
defer
session
.
Close
()
session
.
Table
(
new
(
entity
.
AlertRules
))
.
Alias
(
"r"
)
.
Select
(
"r.*,acp.class_name class_parent_name,ac.class_name,mc.expr,mc.metric_name metric_config_name,mc.alert_rule_type"
)
session
.
Table
(
new
(
entity
.
AlertRules
))
.
Alias
(
"r"
)
.
Select
(
"r.*,acp.class_name class_parent_name,ac.class_name,mc.expr,mc.metric_name metric_config_name,mc.alert_rule_type
,dict.name alert_rule_type_name
"
)
session
.
Join
(
"LEFT"
,
"metric_config mc"
,
"mc.id = r.metric_config_id"
)
session
.
Join
(
"LEFT"
,
"metric_config mc"
,
"mc.id = r.metric_config_id"
)
session
.
Join
(
"LEFT"
,
"alert_class ac"
,
"ac.class_id = r.class_id"
)
session
.
Join
(
"LEFT"
,
"alert_class ac"
,
"ac.class_id = r.class_id"
)
session
.
Join
(
"LEFT"
,
"alert_class acp"
,
"acp.class_id = ac.parent_id"
)
session
.
Join
(
"LEFT"
,
"alert_class acp"
,
"acp.class_id = ac.parent_id"
)
session
.
Join
(
"LEFT"
,
"dict"
,
"dict.id = mc.alert_rule_type"
)
if
req
.
Id
!=
""
{
if
req
.
Id
!=
""
{
session
.
Where
(
"r.id = ?"
,
req
.
Id
)
session
.
Where
(
"r.id = ?"
,
req
.
Id
)
}
}
...
...
src/service/alert_webhook.go
View file @
42ba9e54
package
service
package
service
import
(
import
(
"errors"
"github.com/prometheus/alertmanager/notify/webhook"
"github.com/prometheus/alertmanager/notify/webhook"
"github.com/spf13/cast"
"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/response"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
"xorm.io/xorm"
"xorm.io/xorm"
)
)
...
@@ -10,10 +16,116 @@ type AlertWebhookSvc struct {
...
@@ -10,10 +16,116 @@ type AlertWebhookSvc struct {
User
entity
.
SystemUserInfo
User
entity
.
SystemUserInfo
}
}
// TODO AlertManager 回调接口
// AlertWebhook Alertmanager 回调接口
func
(
a
*
AlertWebhookSvc
)
AlertWebhook
(
session
*
xorm
.
Session
,
req
webhook
.
Message
)
(
id
string
,
err
error
)
{
func
(
a
*
AlertWebhookSvc
)
AlertWebhook
(
session
*
xorm
.
Session
,
req
webhook
.
Message
)
(
err
error
)
{
// 1.判断该opensearch数据是否恢复
now
:=
jsontime
.
Now
()
// 1.1.如果恢复,则查询当前opensearch最大id值,插入新的数据到预警列表
alertSvc
:=
AlertSvc
{
User
:
a
.
User
}
// 1.2如果未恢复,根据id更新该条数据
alertRulesSvc
:=
AlertRulesSvc
{
User
:
a
.
User
}
for
_
,
alert
:=
range
req
.
Alerts
{
var
(
alertRulesId
string
riskLevelStr
string
riskLevel
int
currentValueStr
string
currentValue
float64
ok
bool
alertItem
response
.
AlertItem
alertRulesItem
response
.
AlertRulesItem
alertStatus
int
alertCondition
entity
.
AlertCondition
)
if
alertRulesId
,
ok
=
alert
.
Labels
[
"alert_rules_id"
];
!
ok
{
return
errors
.
New
(
"alert_rules_id not found in the map"
)
}
if
riskLevelStr
,
ok
=
alert
.
Labels
[
"risk_level"
];
!
ok
{
return
errors
.
New
(
"risk_level not found in the map"
)
}
riskLevel
=
cast
.
ToInt
(
riskLevelStr
)
if
currentValueStr
,
ok
=
alert
.
Annotations
[
"value"
];
!
ok
{
return
errors
.
New
(
"value not found in the map"
)
}
currentValue
=
cast
.
ToFloat64
(
currentValueStr
)
alertRulesItem
,
err
=
alertRulesSvc
.
GetDataById
(
request
.
DetailAlertRules
{
Id
:
alertRulesId
})
if
err
!=
nil
{
return
}
alertItem
,
err
=
alertSvc
.
GetDataByAlertRulesIdAndRiskLevel
(
alertRulesId
,
riskLevel
,
2
)
if
err
!=
nil
{
return
}
var
newData
bool
if
alertItem
.
Id
==
0
{
// 新数据
newData
=
true
}
switch
newData
{
case
true
:
// 新增数据到OpenSearch
max
:=
alertSvc
.
CatCount
(
OpenSearchIndex
)
if
max
==
0
{
return
}
alertId
:=
max
+
1
for
_
,
v
:=
range
alertRulesItem
.
AlertCondition
{
if
v
.
RiskLevel
==
riskLevel
{
alertCondition
=
v
break
}
}
err
=
alertSvc
.
DocCreate
(
request
.
CreateAlert
{
Alert
:
entity
.
Alert
{
Id
:
alertId
,
AlertPoint
:
alertRulesItem
.
ClassParentName
+
"/"
+
alertRulesItem
.
MetricName
,
AlertRulesId
:
alertRulesItem
.
Id
,
AlertRulesName
:
alertRulesItem
.
MetricName
,
RiskLevel
:
riskLevel
,
AlertTime
:
jsontime
.
Time
(
alert
.
StartsAt
),
ClassId
:
alertRulesItem
.
ClassId
,
ClassParentName
:
alertRulesItem
.
ClassParentName
,
ClassName
:
alertRulesItem
.
ClassName
,
MetricConfigId
:
alertRulesItem
.
MetricConfigId
,
MetricConfigName
:
alertRulesItem
.
MetricConfigName
,
AlertRuleType
:
alertRulesItem
.
AlertRuleType
,
AlertRuleTypeName
:
alertRulesItem
.
AlertRuleTypeName
,
CurrentValue
:
currentValue
,
AlertCondition
:
alertCondition
,
NotificationCount
:
len
(
alertRulesItem
.
NotifyRecipients
),
PushCount
:
1
,
LastPushTime
:
now
,
Status
:
constant
.
AlertNotRecovered
,
CreatedBy
:
a
.
User
.
SystemAccount
,
CreatedAt
:
now
,
UpdatedBy
:
a
.
User
.
SystemAccount
,
UpdatedAt
:
now
,
}})
if
err
!=
nil
{
return
}
default
:
// 旧数据,更新或解决
switch
alert
.
Status
{
case
"firing"
:
alertStatus
=
constant
.
AlertNotRecovered
case
"resolved"
:
alertStatus
=
constant
.
AlertRecovered
}
err
=
alertSvc
.
Update
(
request
.
UpdateAlert
{
Id
:
alertItem
.
Id
,
CurrentValue
:
currentValue
,
RiskLevel
:
riskLevel
,
Status
:
alertStatus
,
})
}
}
return
return
}
}
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