Commit f90898aa authored by 李科's avatar 李科

perf: 代码迁移

parent 01beca36
...@@ -32,6 +32,7 @@ require ( ...@@ -32,6 +32,7 @@ require (
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/tealeg/xlsx v1.0.5 github.com/tealeg/xlsx v1.0.5
github.com/thoas/go-funk v0.9.3 github.com/thoas/go-funk v0.9.3
github.com/tidwall/gjson v1.16.0
github.com/valyala/fasthttp v1.47.0 github.com/valyala/fasthttp v1.47.0
github.com/wanghuiyt/ding v0.0.2 github.com/wanghuiyt/ding v0.0.2
go.uber.org/zap v1.24.0 go.uber.org/zap v1.24.0
...@@ -108,7 +109,6 @@ require ( ...@@ -108,7 +109,6 @@ require (
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect
github.com/sirupsen/logrus v1.9.2 // indirect github.com/sirupsen/logrus v1.9.2 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/tidwall/gjson v1.16.0 // indirect
github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/pretty v1.2.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
......
...@@ -9,6 +9,7 @@ type AddAlertClass struct { ...@@ -9,6 +9,7 @@ type AddAlertClass struct {
type UpdateAlertClass struct { type UpdateAlertClass struct {
ClassId int `json:"class_id" form:"class_id" binding:"required"` ClassId int `json:"class_id" form:"class_id" binding:"required"`
ParentId int `json:"parent_id" form:"parent_id"`
ClassName string `json:"class_name" form:"class_name" binding:"required"` ClassName string `json:"class_name" form:"class_name" binding:"required"`
} }
......
...@@ -33,7 +33,7 @@ type UpdateAlertRules struct { ...@@ -33,7 +33,7 @@ type UpdateAlertRules struct {
ClassId int `json:"class_id" form:"class_id" binding:"required_if=DetectionType 1"` // 预警对象id(级联:预警分类/预警对象) ClassId int `json:"class_id" form:"class_id" binding:"required_if=DetectionType 1"` // 预警对象id(级联:预警分类/预警对象)
ClassParentName string `json:"class_parent_name" form:"class_parent_name" binding:"required_if=DetectionType 2"` // 预警分类名称 ClassParentName string `json:"class_parent_name" form:"class_parent_name" binding:"required_if=DetectionType 2"` // 预警分类名称
ClassName string `json:"class_name" form:"class_name" binding:"required_if=DetectionType 2"` // 预警对象名称 ClassName string `json:"class_name" form:"class_name" binding:"required_if=DetectionType 2"` // 预警对象名称
MetricConfigId string `json:"metric_config_id" form:"'metric_config_id'" binding:"required_if=DetectionType 1"` // 预警指标id MetricConfigId string `json:"metric_config_id" form:"metric_config_id" binding:"required_if=DetectionType 1"` // 预警指标id
MetricConfigName string `json:"metric_config_name" form:"metric_config_name" binding:"required_if=DetectionType 2"` // 预警指标名称(映射entity.MetricConfig.MetricName) MetricConfigName string `json:"metric_config_name" form:"metric_config_name" binding:"required_if=DetectionType 2"` // 预警指标名称(映射entity.MetricConfig.MetricName)
Expr string `json:"expr" form:"expr" binding:"required_if=DetectionType 2"` // 指标表达式(PromQL语句) Expr string `json:"expr" form:"expr" binding:"required_if=DetectionType 2"` // 指标表达式(PromQL语句)
AlertCondition []entity.AlertCondition `json:"alert_condition" form:"alert_condition" binding:"required"` // 预警规则 字典值 AlertCondition []entity.AlertCondition `json:"alert_condition" form:"alert_condition" binding:"required"` // 预警规则 字典值
......
...@@ -10,7 +10,7 @@ type AddAlertWebhook struct { ...@@ -10,7 +10,7 @@ type AddAlertWebhook struct {
ClassId int `json:"class_id" form:"class_id" binding:"required_if=DetectionType 1"` // 预警对象id(级联:预警分类/预警对象) ClassId int `json:"class_id" form:"class_id" binding:"required_if=DetectionType 1"` // 预警对象id(级联:预警分类/预警对象)
ClassParentName string `json:"class_parent_name" form:"class_parent_name" binding:"required_if=DetectionType 2"` // 预警分类名称 ClassParentName string `json:"class_parent_name" form:"class_parent_name" binding:"required_if=DetectionType 2"` // 预警分类名称
ClassName string `json:"class_name" form:"class_name" binding:"required_if=DetectionType 2"` // 预警对象名称 ClassName string `json:"class_name" form:"class_name" binding:"required_if=DetectionType 2"` // 预警对象名称
MetricConfigId string `json:"metric_config_id" form:"'metric_config_id'" binding:"required_if=DetectionType 1"` // 预警指标id MetricConfigId string `json:"metric_config_id" form:"metric_config_id" binding:"required_if=DetectionType 1"` // 预警指标id
MetricConfigName string `json:"metric_config_name" form:"metric_config_name" binding:"required_if=DetectionType 2"` // 预警指标名称(映射entity.MetricConfig.MetricName) MetricConfigName string `json:"metric_config_name" form:"metric_config_name" binding:"required_if=DetectionType 2"` // 预警指标名称(映射entity.MetricConfig.MetricName)
Expr string `json:"expr" form:"expr" binding:"required_if=DetectionType 2"` // 指标表达式(PromQL语句) Expr string `json:"expr" form:"expr" binding:"required_if=DetectionType 2"` // 指标表达式(PromQL语句)
AlertCondition []entity.AlertCondition `json:"alert_condition" form:"alert_condition" binding:"required,dive"` // 预警规则 字典值 AlertCondition []entity.AlertCondition `json:"alert_condition" form:"alert_condition" binding:"required,dive"` // 预警规则 字典值
......
...@@ -31,7 +31,7 @@ type Config struct { ...@@ -31,7 +31,7 @@ type Config struct {
MinioSecretKey string MinioSecretKey string
MinioBucket string MinioBucket string
//TempDirPrefix string //TempDirPrefix string
PrometheusHost string
AccessRuleModeKey string AccessRuleModeKey string
LocationUrl string LocationUrl string
LocationKey string LocationKey string
...@@ -49,9 +49,20 @@ type Config struct { ...@@ -49,9 +49,20 @@ type Config struct {
AweRestURL string AweRestURL string
KubernetesToken string KubernetesToken string
OpenSearchIndex string
OpenSearchAddresses string OpenSearchAddresses string
OpenSearchUserName string OpenSearchUserName string
OpenSearchPassword string OpenSearchPassword string
MonitorApiVersion string
MonitorMatchNs string
MonitorMatchLabelsStr string
MonitorMatchLabels map[string]interface{}
Namespace string
PrometheusHost string
PrometheusRuleLabel string
PrometheusRuleNamePrefix string
} }
const ( const (
......
...@@ -3,10 +3,10 @@ package controller ...@@ -3,10 +3,10 @@ package controller
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/prometheus/alertmanager/notify/webhook" "github.com/prometheus/alertmanager/notify/webhook"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/service" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/service"
"go.uber.org/zap" "go.uber.org/zap"
) )
...@@ -14,12 +14,18 @@ import ( ...@@ -14,12 +14,18 @@ import (
// AlertWebhook 回调 // AlertWebhook 回调
func AlertWebhook(c *gin.Context) { func AlertWebhook(c *gin.Context) {
var req webhook.Message var req webhook.Message
conf.Logger.Info("------>webhook.start------>")
if err := c.ShouldBind(&req); err != nil { if err := c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return return
} }
conf.Logger.Info("------>webhook.Message------>", zap.Any("message", req)) conf.Logger.Info("------>webhook.Message------>", zap.Any("message", req))
svc := service.AlertWebhookSvc{User: header.GetUser(c)} svc := service.AlertWebhookSvc{User: entity.SystemUserInfo{
Name: "prometheus",
SystemAccount: "prometheus",
OrganizationId: "",
State: 1,
}}
db, err := client.GetDbClient() db, err := client.GetDbClient()
if err != nil { if err != nil {
SendJsonResponse(c, resp.DbConnectError.WithError(err), nil) SendJsonResponse(c, resp.DbConnectError.WithError(err), nil)
......
...@@ -48,7 +48,7 @@ func main() { ...@@ -48,7 +48,7 @@ func main() {
// 初始化OpenSearch的索引 // 初始化OpenSearch的索引
err := service.CheckAndCreateIndex() err := service.CheckAndCreateIndex()
if err != nil { if err != nil {
conf.Logger.Fatal("failed to init OpenSearch index.", zap.Error(err)) conf.Logger.Error("failed to init OpenSearch index", zap.Error(err))
} }
//启动定时任务 //启动定时任务
...@@ -70,17 +70,16 @@ func initConfig() { ...@@ -70,17 +70,16 @@ func initConfig() {
RedisURL: util.SetEnvStr("REDIS_URL", "localhost:7001"), RedisURL: util.SetEnvStr("REDIS_URL", "localhost:7001"),
RedisDB: 0, RedisDB: 0,
RedisTag: "bg", RedisTag: "bg",
LogDirPrefix: util.SetEnvStr("LOG_DIR_PREFIX", "/app/log"), // 日志目录 LogDirPrefix: util.SetEnvStr("LOG_DIR_PREFIX", "/app/log"), // 日志目录
LogDirName: util.SetEnvStr("LOG_NAME", "syslog"), // 日志名称 LogDirName: util.SetEnvStr("LOG_NAME", "syslog"), // 日志名称
LogSaveDays: util.SetEnvInt("LOG_SAVE_DAYS", 7), // 日志最大存储天数 LogSaveDays: util.SetEnvInt("LOG_SAVE_DAYS", 7), // 日志最大存储天数
LogMode: util.SetEnvInt("LOG_MODE", 1), // 1.标准打印 2.输出文件 LogMode: util.SetEnvInt("LOG_MODE", 1), // 1.标准打印 2.输出文件
ArgBool: util.SetEnvBool("ARG_BOOL", false), // 示例参数 ArgBool: util.SetEnvBool("ARG_BOOL", false), // 示例参数
ArgInt: util.SetEnvInt("ARG_INT", 10), // 示例参数 ArgInt: util.SetEnvInt("ARG_INT", 10), // 示例参数
MinioServer: util.SetEnvStr("MINIO_SERVER", "https://cache.wodcloud.com"), // Minio 服务地址 MinioServer: util.SetEnvStr("MINIO_SERVER", "https://cache.wodcloud.com"), // Minio 服务地址
MinioAccessKey: util.SetEnvStr("MINIO_ACCESS_KEY", "beagleadmin"), // Minio Access Key MinioAccessKey: util.SetEnvStr("MINIO_ACCESS_KEY", "beagleadmin"), // Minio Access Key
MinioSecretKey: util.SetEnvStr("MINIO_SECRET_KEY", "H76cPmwvH7vJ"), // Minio Secret MinioSecretKey: util.SetEnvStr("MINIO_SECRET_KEY", "H76cPmwvH7vJ"), // Minio Secret
MinioBucket: util.SetEnvStr("MINIO_BUCKET", "so-operation"), // Minio Bucket MinioBucket: util.SetEnvStr("MINIO_BUCKET", "so-operation"), // Minio Bucket
PrometheusHost: util.SetEnvStr("PROMETHEUS_HOST", "https://prometheus.wodcloud.com"), // Prometheus Host
AccessRuleModeKey: "accessRuleMode", AccessRuleModeKey: "accessRuleMode",
LocationUrl: util.SetEnvStr("LOCATION_URL", "https://apis.map.qq.com/ws/location/v1/ip"), LocationUrl: util.SetEnvStr("LOCATION_URL", "https://apis.map.qq.com/ws/location/v1/ip"),
LocationKey: util.SetEnvStr("LOCATION_KEY", "QKFBZ-PGGWJ-VZQFF-FHPA7-QWT5H-YHF4T"), LocationKey: util.SetEnvStr("LOCATION_KEY", "QKFBZ-PGGWJ-VZQFF-FHPA7-QWT5H-YHF4T"),
...@@ -91,14 +90,26 @@ func initConfig() { ...@@ -91,14 +90,26 @@ func initConfig() {
SmsAccessKeyId: util.SetEnvStr("SMS_ACCESS_KEY", "LTAI4GBcVubRjzX7ABPcHnhB"), // 短信key SmsAccessKeyId: util.SetEnvStr("SMS_ACCESS_KEY", "LTAI4GBcVubRjzX7ABPcHnhB"), // 短信key
SmsAccessSecret: util.SetEnvStr("SMS_ACCESS_SECRET", "dYE2dtABFOqYtK1ijcrits0yedHkw7"), // 短信secret SmsAccessSecret: util.SetEnvStr("SMS_ACCESS_SECRET", "dYE2dtABFOqYtK1ijcrits0yedHkw7"), // 短信secret
SmsTemplateLogin: util.SetEnvStr("SMS_TEMPLATE_LOGIN", "SMS_212925130"), // 短信验证码模板 SmsTemplateLogin: util.SetEnvStr("SMS_TEMPLATE_LOGIN", "SMS_212925130"), // 短信验证码模板
SmsTemplateAlert: util.SetEnvStr("Sms_Template_Alert", "SMS_461975765"), // 预警短信模板 // 短信工单下发模板 SmsTemplateAlert: util.SetEnvStr("SMS_TEMPLATE_ALERT", "SMS_461975765"), // 预警短信模板 // 短信工单下发模板
SmsWorkOrderTemplate: util.SetEnvStr("SMS_TEMPLATE_LOGIN", "SMS_462020767"), // 短信工单下发模板 SmsWorkOrderTemplate: util.SetEnvStr("SMS_TEMPLATE_LOGIN", "SMS_462020767"), // 短信工单下发模板
SmsSignName: util.SetEnvStr("SMS_SIGN_NAME", "比格数据"), // 签名 SmsSignName: util.SetEnvStr("SMS_SIGN_NAME", "比格数据"), // 签名
AweRestURL: util.SetEnvStr("AWE_REST_URL", "http://awecloud-rest.beagle-system/awecloud/rest"), // awecloud-rest AweRestURL: util.SetEnvStr("AWE_REST_URL", "http://awecloud-rest.beagle-system/awecloud/rest"), // awecloud-rest
KubernetesToken: util.SetEnvStr("AWE_REST_K8S_TOKEN", "eyJhbGciOiJSUzI1NiIsImtpZCI6InJ1alJzNEVGamN5UC0wRU1rS1BKQ0JZVUtNNWpzR0t2bmlrSlJhY2Q3R00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJiZWFnbGUtc3lzdGVtIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InJvb3QiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicm9vdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjRlMDM0OTI3LTc0ZTMtNDQ5Yy1hN2RlLWExMGE3MjU1NGYyMCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpiZWFnbGUtc3lzdGVtOnJvb3QifQ.YPLE_E2kIeo-YFQtKScBt5p4KhnniJF9n3iWN2i9UMYS06lIsq2-2wBrgON-YsJihWJupYyDQRiZ9h8bUWTrQzhnpsnuJ_aUclKyAw3QOT9rjvZhJp7qP--27dmdspSHncKtvIiprWE7UTUKzvF33WsMB0fSYFqYXOggNFMoT-fXmWwUXjgar3op0iOl3c3deJ_GeBzFyLSHEuGM7OVdjU8032aUmTen0Kji_P1yB4-O3Iqd0OdVs33BQy_tycjbxhQ8TDEpqrqhLnXjAwJCprLDEpFMx7ODZbjB9Wmuns8yJhaRDxTO47rTME7ZIAxjZ-zLR_QybtW97rlwnUTaNw"), KubernetesToken: util.SetEnvStr("AWE_REST_K8S_TOKEN", "eyJhbGciOiJSUzI1NiIsImtpZCI6InJ1alJzNEVGamN5UC0wRU1rS1BKQ0JZVUtNNWpzR0t2bmlrSlJhY2Q3R00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJiZWFnbGUtc3lzdGVtIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InJvb3QiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicm9vdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjRlMDM0OTI3LTc0ZTMtNDQ5Yy1hN2RlLWExMGE3MjU1NGYyMCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpiZWFnbGUtc3lzdGVtOnJvb3QifQ.YPLE_E2kIeo-YFQtKScBt5p4KhnniJF9n3iWN2i9UMYS06lIsq2-2wBrgON-YsJihWJupYyDQRiZ9h8bUWTrQzhnpsnuJ_aUclKyAw3QOT9rjvZhJp7qP--27dmdspSHncKtvIiprWE7UTUKzvF33WsMB0fSYFqYXOggNFMoT-fXmWwUXjgar3op0iOl3c3deJ_GeBzFyLSHEuGM7OVdjU8032aUmTen0Kji_P1yB4-O3Iqd0OdVs33BQy_tycjbxhQ8TDEpqrqhLnXjAwJCprLDEpFMx7ODZbjB9Wmuns8yJhaRDxTO47rTME7ZIAxjZ-zLR_QybtW97rlwnUTaNw"),
OpenSearchAddresses: util.SetEnvStr("Open_Search_Addresses", "https://so-opensearch.wodcloud.com"), // OpenSearch连接地址
OpenSearchUserName: util.SetEnvStr("Open_Search_User_Name", ""), // OpenSearch用户名 OpenSearchIndex: util.SetEnvStr("OPEN_SEARCH_INDEX", "so_alert"),
OpenSearchPassword: util.SetEnvStr("Open_Search_Password", ""), // OpenSearch密码 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
} }
} }
......
...@@ -5,12 +5,11 @@ import ( ...@@ -5,12 +5,11 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
) )
// InitAlertWebhookRouter 初始化预警回调路由 // InitAlertWebhookRouter 初始化预警回调路由
func InitAlertWebhookRouter(e *gin.Engine) { func InitAlertWebhookRouter(e *gin.Engine) {
group := e.Group(fmt.Sprintf("%s/alert_webhook", conf.Options.Prefix), header.SetContext) group := e.Group(fmt.Sprintf("%s/alert_webhook", conf.Options.Prefix))
{ {
group.POST("", controller.AlertWebhook) group.POST("", controller.AlertWebhook)
} }
......
...@@ -32,8 +32,7 @@ type AlertSvc struct { ...@@ -32,8 +32,7 @@ type AlertSvc struct {
} }
var ( var (
OpenSearchIndex = "so_alert" Mapping = strings.NewReader(`{
Mapping = strings.NewReader(`{
"settings": { "settings": {
"number_of_shards": 1, "number_of_shards": 1,
"number_of_replicas": 0, "number_of_replicas": 0,
...@@ -284,7 +283,7 @@ var ( ...@@ -284,7 +283,7 @@ var (
) )
func CheckAndCreateIndex() (err error) { func CheckAndCreateIndex() (err error) {
exist, err := checkIndexExists(OpenSearchIndex) exist, err := checkIndexExists(conf.Options.OpenSearchIndex)
if err != nil { if err != nil {
return return
} }
...@@ -293,7 +292,7 @@ func CheckAndCreateIndex() (err error) { ...@@ -293,7 +292,7 @@ func CheckAndCreateIndex() (err error) {
return nil return nil
} }
err = CreateIndex(OpenSearchIndex) err = CreateIndex(conf.Options.OpenSearchIndex)
if err != nil { if err != nil {
return err return err
} }
...@@ -346,7 +345,7 @@ func (a *AlertSvc) DeleteIndex() error { ...@@ -346,7 +345,7 @@ func (a *AlertSvc) DeleteIndex() error {
return err return err
} }
res := opensearchapi.IndicesDeleteRequest{ res := opensearchapi.IndicesDeleteRequest{
Index: []string{OpenSearchIndex}, Index: []string{conf.Options.OpenSearchIndex},
} }
do, err := res.Do(context.Background(), cli) do, err := res.Do(context.Background(), cli)
if err != nil { if err != nil {
...@@ -427,8 +426,11 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er ...@@ -427,8 +426,11 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er
// 请输入预警点/分类/指标 // 请输入预警点/分类/指标
if req.Keyword != "" { if req.Keyword != "" {
subBoolQuery := elastic.NewBoolQuery() subBoolQuery := elastic.NewBoolQuery()
subBoolQuery.Should(elastic.NewMultiMatchQuery(req.Keyword, "alert_point", "class_parent_name", "class_name", "metric_config_name")) //subBoolQuery.Should(elastic.NewMultiMatchQuery(req.Keyword, "alert_point", "class_parent_name", "class_name", "metric_config_name"))
//subBoolQuery.Should(elastic.NewMatchQuery("class_name", req.Keyword)) subBoolQuery.Should(elastic.NewPrefixQuery("alert_point.keyword", req.Keyword))
subBoolQuery.Should(elastic.NewPrefixQuery("class_parent_name.keyword", req.Keyword))
subBoolQuery.Should(elastic.NewPrefixQuery("class_name.keyword", req.Keyword))
subBoolQuery.Should(elastic.NewPrefixQuery("metric_config_name.keyword", req.Keyword))
boolQuery.Must(subBoolQuery) boolQuery.Must(subBoolQuery)
} }
...@@ -467,7 +469,7 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er ...@@ -467,7 +469,7 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er
"size": %d}`, string(b), req.GetPageSize()*(req.GetPage()-1), req.GetPageSize())) "size": %d}`, string(b), req.GetPageSize()*(req.GetPage()-1), req.GetPageSize()))
res := opensearchapi.SearchRequest{ res := opensearchapi.SearchRequest{
Index: []string{OpenSearchIndex}, Index: []string{conf.Options.OpenSearchIndex},
Body: content, Body: content,
Sort: []string{"id"}, Sort: []string{"id"},
} }
...@@ -493,6 +495,38 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er ...@@ -493,6 +495,38 @@ func (a *AlertSvc) DocSearch(req request.ListAlert) (resp response.AlertList, er
for _, hit := range sources.Hits.Hits { for _, hit := range sources.Hits.Hits {
resp.List = append(resp.List, hit.Source) resp.List = append(resp.List, hit.Source)
} }
// 推送人数:推送记录中去重的人数
// 推送次数:发起推送的总次数(钉钉、短信、工单算单次)
for i := 0; i < len(resp.List); i++ {
var userSet []string
var pushCountSet []string
mergedData := make(map[string]entity.PushRecord)
for _, record := range resp.List[i].PushRecords {
userSet = append(userSet, record.SystemAccount)
pushCountSet = append(pushCountSet, record.PushTime.String())
key := record.AlertRulesId + record.PushTime.String()
// 映射中已存在相同键的数据,则合并user_id
if existingRecord, found := mergedData[key]; found {
existingRecord.SystemAccount += ", " + record.SystemAccount
existingRecord.UserName += ", " + record.UserName
mergedData[key] = existingRecord
} else {
mergedData[key] = record
}
}
var mergedRecords []entity.PushRecord
for _, v := range mergedData {
mergedRecords = append(mergedRecords, v)
}
resp.List[i].PushRecords = mergedRecords
resp.List[i].NotificationCount = len(funk.UniqString(userSet))
resp.List[i].PushCount = len(funk.UniqString(pushCountSet))
}
resp.TotalCount = int64(sources.Hits.Total.Value) resp.TotalCount = int64(sources.Hits.Total.Value)
return return
} }
...@@ -524,7 +558,7 @@ func (a *AlertSvc) IndexDocExist(req request.ExistAlert) (exist bool, err error) ...@@ -524,7 +558,7 @@ func (a *AlertSvc) IndexDocExist(req request.ExistAlert) (exist bool, err error)
"size": %d}`, string(b), 0, 1)) "size": %d}`, string(b), 0, 1))
res := opensearchapi.SearchRequest{ res := opensearchapi.SearchRequest{
Index: []string{OpenSearchIndex}, Index: []string{conf.Options.OpenSearchIndex},
Body: content, Body: content,
Sort: []string{"id"}, Sort: []string{"id"},
} }
...@@ -567,7 +601,7 @@ func (a *AlertSvc) CatCount(indexName ...string) (count int) { ...@@ -567,7 +601,7 @@ func (a *AlertSvc) CatCount(indexName ...string) (count int) {
if len(indexName) > 0 && indexName[0] != "" { if len(indexName) > 0 && indexName[0] != "" {
index = indexName[0] + "*" index = indexName[0] + "*"
} else { } else {
index = OpenSearchIndex + "*" index = conf.Options.OpenSearchIndex + "*"
} }
res := opensearchapi.CatCountRequest{ res := opensearchapi.CatCountRequest{
...@@ -597,6 +631,66 @@ func (a *AlertSvc) CatCount(indexName ...string) (count int) { ...@@ -597,6 +631,66 @@ func (a *AlertSvc) CatCount(indexName ...string) (count int) {
return return
} }
func (a *AlertSvc) GetIndexMaxID(indexName ...string) (maxId int, err error) {
var (
index string
)
cli, err := client.GetOpenSearch()
if err != nil {
return 0, err
}
if len(indexName) > 0 && indexName[0] != "" {
index = indexName[0]
} else {
index = conf.Options.OpenSearchIndex
}
// 构建 aggregation 查询
aggregationQuery := `
{
"size": 0,
"aggs": {
"max_id": {
"max": {
"field": "id"
}
}
}
}
`
res := opensearchapi.SearchRequest{
Index: []string{index},
Body: strings.NewReader(aggregationQuery),
}
do, err := res.Do(context.Background(), cli)
if err != nil {
return 0, err
}
defer do.Body.Close()
if do.StatusCode < http.StatusOK && do.StatusCode > http.StatusIMUsed {
return 0, errors.New(do.String())
}
// 解析聚合结果
var responseMap map[string]interface{}
err = json.NewDecoder(do.Body).Decode(&responseMap)
if err != nil {
return 0, err
}
// 提取最大值
aggregations := responseMap["aggregations"].(map[string]interface{})
maxIDAgg := aggregations["max_id"].(map[string]interface{})
maxIDValue := maxIDAgg["value"]
maxId = int(maxIDValue.(float64))
return maxId, nil
}
func (a *AlertSvc) DocCreate(req request.CreateAlert) (err error) { func (a *AlertSvc) DocCreate(req request.CreateAlert) (err error) {
var ( var (
sources response.OpenSearchSource sources response.OpenSearchSource
...@@ -616,7 +710,7 @@ func (a *AlertSvc) DocCreate(req request.CreateAlert) (err error) { ...@@ -616,7 +710,7 @@ func (a *AlertSvc) DocCreate(req request.CreateAlert) (err error) {
content := strings.NewReader(fmt.Sprintf(`%s`, docStr)) content := strings.NewReader(fmt.Sprintf(`%s`, docStr))
res := opensearchapi.CreateRequest{ res := opensearchapi.CreateRequest{
Index: OpenSearchIndex, Index: conf.Options.OpenSearchIndex,
DocumentID: cast.ToString(req.Id), DocumentID: cast.ToString(req.Id),
Body: content, Body: content,
} }
...@@ -696,7 +790,7 @@ func (a *AlertSvc) DocUpdate(req request.UpdateAlert) (err error) { ...@@ -696,7 +790,7 @@ func (a *AlertSvc) DocUpdate(req request.UpdateAlert) (err error) {
}`, docStr)) }`, docStr))
res := opensearchapi.UpdateRequest{ res := opensearchapi.UpdateRequest{
Index: OpenSearchIndex, Index: conf.Options.OpenSearchIndex,
DocumentID: cast.ToString(req.Id), DocumentID: cast.ToString(req.Id),
Body: content, Body: content,
Source: []string{"true"}, Source: []string{"true"},
...@@ -730,7 +824,7 @@ func (a *AlertSvc) Create() error { ...@@ -730,7 +824,7 @@ func (a *AlertSvc) Create() error {
return err return err
} }
res := opensearchapi.IndicesCreateRequest{ res := opensearchapi.IndicesCreateRequest{
Index: OpenSearchIndex, Index: conf.Options.OpenSearchIndex,
Body: Mapping, Body: Mapping,
} }
do, err := res.Do(context.Background(), cli) do, err := res.Do(context.Background(), cli)
...@@ -926,7 +1020,7 @@ func (a *AlertSvc) DisposeAlert(req request.DisposeAlert) (err error) { ...@@ -926,7 +1020,7 @@ func (a *AlertSvc) DisposeAlert(req request.DisposeAlert) (err error) {
}`, docStr)) }`, docStr))
res := opensearchapi.UpdateRequest{ res := opensearchapi.UpdateRequest{
Index: OpenSearchIndex, Index: conf.Options.OpenSearchIndex,
DocumentID: cast.ToString(req.Id), DocumentID: cast.ToString(req.Id),
Body: content, Body: content,
Source: []string{"true"}, Source: []string{"true"},
......
...@@ -52,7 +52,7 @@ func (a *AlertClassSvc) Update(session *xorm.Session, req request.UpdateAlertCla ...@@ -52,7 +52,7 @@ func (a *AlertClassSvc) Update(session *xorm.Session, req request.UpdateAlertCla
UpdatedAt: now, UpdatedAt: now,
} }
_ = copier.Copy(&data, &req) _ = copier.Copy(&data, &req)
_, err := session.Cols("class_name", "updated_by", "updated_at").ID(data.ClassId).Update(&data) _, err := session.Cols("parent_id", "class_name", "updated_by", "updated_at").ID(data.ClassId).Update(&data)
if err != nil { if err != nil {
return err return err
} }
...@@ -150,6 +150,9 @@ func (a *AlertClassSvc) List(req request.ListAlertClass) (resp response.AlertCla ...@@ -150,6 +150,9 @@ func (a *AlertClassSvc) List(req request.ListAlertClass) (resp response.AlertCla
if req.ClassName != "" { if req.ClassName != "" {
session.Where("class_name LIKE ?", "%"+req.ClassName+"%") session.Where("class_name LIKE ?", "%"+req.ClassName+"%")
} }
if req.Page == -1 {
req.PageSize = 100000
}
resp.TotalCount, err = session.Limit(req.GetPageSize(), (req.GetPage()-1)*req.GetPageSize()). resp.TotalCount, err = session.Limit(req.GetPageSize(), (req.GetPage()-1)*req.GetPageSize()).
OrderBy("sort_order").FindAndCount(&resp.List) OrderBy("sort_order").FindAndCount(&resp.List)
return return
...@@ -234,8 +237,61 @@ func (a *AlertClassSvc) SortOrderMax(parentId int) (max int, err error) { ...@@ -234,8 +237,61 @@ func (a *AlertClassSvc) SortOrderMax(parentId int) (max int, err error) {
func (a *AlertClassSvc) Delete(ids []int) (err error) { func (a *AlertClassSvc) Delete(ids []int) (err error) {
db, err := client.GetDbClient() db, err := client.GetDbClient()
if err != nil { if err != nil {
return return err
} }
_, err = db.NewSession().In("class_id", ids).Delete(&entity.AlertClass{})
return var classes []entity.AlertClass
err = db.In("class_id", ids).Find(&classes)
// 检查是否所有指定的 ids 都存在于数据库中
if len(ids) > len(classes) {
return errors.New("部分数据不存在")
}
var notExist []int
idSet := make(map[int]bool)
for _, v := range classes {
idSet[v.ClassId] = true
}
for _, id := range ids {
if !idSet[id] {
notExist = append(notExist, id)
}
}
if len(notExist) > 0 {
return errors.New(fmt.Sprintf("指标分类或对象id为%v的数据未查询到", notExist))
}
for _, v := range classes {
if v.ParentId == 0 {
// 如果是父级数据,判断是否存在子集
var num int
has, err := db.Table(new(entity.AlertClass)).Select("count(*)").Where("parent_id = ?", v.ClassId).Get(&num)
if err != nil {
return err
}
if has && num > 0 {
return errors.New("当前分类存在指标对象子集数据,不允许删除")
}
} else {
// 如果为子集数据,判断是否存在指标配置关联
var configCount int
has, err := db.Table(new(entity.MetricConfig)).Select("count(*)").Where("class_id = ?", v.ClassId).Get(&configCount)
if err != nil {
return err
}
if has && configCount > 0 {
return errors.New("指标对象存在指标配置关联,不允许删除")
}
}
// 删除数据
_, err = db.ID(v.ClassId).Delete(v)
if err != nil {
return err
}
}
return nil
} }
...@@ -14,6 +14,7 @@ import ( ...@@ -14,6 +14,7 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
"io" "io"
...@@ -132,7 +133,7 @@ func (a *AlertOverviewSvc) AlertOverview(req request.DetailAlertOverview) (resp ...@@ -132,7 +133,7 @@ func (a *AlertOverviewSvc) AlertOverview(req request.DetailAlertOverview) (resp
} }
}`, req.StartTime, req.EndTime) }`, req.StartTime, req.EndTime)
body, err := executeQuery(cli, OpenSearchIndex, content) body, err := executeQuery(cli, conf.Options.OpenSearchIndex, content)
if err != nil { if err != nil {
return return
} }
...@@ -190,7 +191,7 @@ func (a *AlertOverviewSvc) RiskLevelDistribution(req request.DetailAlertOverview ...@@ -190,7 +191,7 @@ func (a *AlertOverviewSvc) RiskLevelDistribution(req request.DetailAlertOverview
req.EndTime = time.Now().Add(time.Hour * 24).Format("2006-01-02") req.EndTime = time.Now().Add(time.Hour * 24).Format("2006-01-02")
} }
body, err := executeQuery(cli, OpenSearchIndex, buildAggQueryContent(req.StartTime, req.EndTime, "risk_level")) body, err := executeQuery(cli, conf.Options.OpenSearchIndex, buildAggQueryContent(req.StartTime, req.EndTime, "risk_level"))
if err != nil { if err != nil {
return return
} }
...@@ -235,7 +236,7 @@ func (a *AlertOverviewSvc) AlertStatusDistribution(req request.DetailAlertOvervi ...@@ -235,7 +236,7 @@ func (a *AlertOverviewSvc) AlertStatusDistribution(req request.DetailAlertOvervi
req.EndTime = time.Now().Add(time.Hour * 24).Format("2006-01-02") req.EndTime = time.Now().Add(time.Hour * 24).Format("2006-01-02")
} }
body, err := executeQuery(cli, OpenSearchIndex, buildAggQueryContent(req.StartTime, req.EndTime, "status")) body, err := executeQuery(cli, conf.Options.OpenSearchIndex, buildAggQueryContent(req.StartTime, req.EndTime, "status"))
if err != nil { if err != nil {
return return
} }
...@@ -279,7 +280,7 @@ func (a *AlertOverviewSvc) AlertClassDistribution(req request.DetailAlertOvervie ...@@ -279,7 +280,7 @@ func (a *AlertOverviewSvc) AlertClassDistribution(req request.DetailAlertOvervie
req.EndTime = time.Now().Add(time.Hour * 24).Format("2006-01-02") req.EndTime = time.Now().Add(time.Hour * 24).Format("2006-01-02")
} }
body, err := executeQuery(cli, OpenSearchIndex, buildAggQueryContent(req.StartTime, req.EndTime, "class_id")) body, err := executeQuery(cli, conf.Options.OpenSearchIndex, buildAggQueryContent(req.StartTime, req.EndTime, "class_id"))
if err != nil { if err != nil {
return return
} }
...@@ -355,7 +356,7 @@ func (a *AlertOverviewSvc) AlertFrequencyDistribution(req request.DetailAlertOve ...@@ -355,7 +356,7 @@ func (a *AlertOverviewSvc) AlertFrequencyDistribution(req request.DetailAlertOve
} }
}` }`
body, err := executeQuery(cli, OpenSearchIndex, content) body, err := executeQuery(cli, conf.Options.OpenSearchIndex, content)
if err != nil { if err != nil {
return return
} }
......
...@@ -74,12 +74,14 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) { ...@@ -74,12 +74,14 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) {
return nil, err return nil, err
} }
data.ClassId = classId data.ClassId = classId
req.ClassId = classId
// 添加指标配置 // 添加指标配置
metricConfigSvc := MetricConfigSvc{User: a.User} metricConfigSvc := MetricConfigSvc{User: a.User}
_ = copier.Copy(&addMetricConfig, &req) _ = copier.Copy(&addMetricConfig, &req)
addMetricConfig.Source = constant.SourceCustom addMetricConfig.Source = constant.SourceCustom
addMetricConfig.MetricName = req.MetricConfigName addMetricConfig.MetricName = req.MetricConfigName
addMetricConfig.ClassId = classId
metricConfigId, err = metricConfigSvc.Add(session, addMetricConfig) metricConfigId, err = metricConfigSvc.Add(session, addMetricConfig)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -88,14 +90,22 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) { ...@@ -88,14 +90,22 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) {
// 添加预警规则配置 // 添加预警规则配置
_, err = session.Insert(&data) _, err = session.Insert(&data)
if err != nil {
return nil, err
}
return nil, err return nil, err
}) })
err = a.CreatePrometheusRule(req.IsEnabled, data.Id, db, "")
if err != nil { if err != nil {
return err return err
} }
} }
err = a.CreatePrometheusRule(req.IsEnabled, data.Id, db, "") err = a.CreatePrometheusRule(req.IsEnabled, data.Id, db, "")
if err != nil {
return err
}
return nil return nil
} }
...@@ -125,7 +135,11 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) { ...@@ -125,7 +135,11 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) {
} }
switch req.DetectionType { switch req.DetectionType {
case 1: case 1:
_, err = db.ID(data.Id).Update(&data) _, err = db.ID(data.Id).MustCols("duration").Update(&data)
if err != nil {
return err
}
err = a.CreatePrometheusRule(req.IsEnabled, data.Id, db, "update")
if err != nil { if err != nil {
return err return err
} }
...@@ -134,24 +148,37 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) { ...@@ -134,24 +148,37 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) {
// 更新自定义分类 // 更新自定义分类
var ( var (
updateMetricConfig request.UpdateMetricConfig updateMetricConfig request.UpdateMetricConfig
alertClassItem response.AlertClassItem alertClass response.AlertClassItem
alertParentClass response.AlertClassItem
) )
alertClassSvc := AlertClassSvc{User: a.User} alertClassSvc := AlertClassSvc{User: a.User}
alertClassItem, err = alertClassSvc.GetDataById(request.DetailAlertClass{ClassId: dbAlertRules.ClassId}) alertClass, err = alertClassSvc.GetDataById(request.DetailAlertClass{ClassId: dbAlertRules.ClassId})
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = alertClassSvc.Update(session, request.UpdateAlertClass{ err = alertClassSvc.Update(session, request.UpdateAlertClass{
ClassId: dbAlertRules.ClassId, ClassId: dbAlertRules.ClassId,
ClassName: req.ClassName, ClassName: req.ClassName,
ParentId: alertClass.ParentId,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
if alertClass.ParentId == 0 {
return nil, errors.New("预警分类为空")
}
alertParentClass, err = alertClassSvc.GetDataById(request.DetailAlertClass{ClassId: alertClass.ParentId})
if err != nil {
return nil, err
}
err = alertClassSvc.Update(session, request.UpdateAlertClass{ err = alertClassSvc.Update(session, request.UpdateAlertClass{
ClassId: alertClassItem.ParentId, ClassId: alertClass.ParentId,
ClassName: req.ClassParentName, ClassName: req.ClassParentName,
ParentId: alertParentClass.ParentId,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -166,11 +193,12 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) { ...@@ -166,11 +193,12 @@ func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) (err error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
// 更新预警规则配置
_, err = session.ID(data.Id).Update(&data)
return nil, err return nil, err
}) })
// 更新预警策略配置
_, err = session.ID(data.Id).MustCols("duration").Update(&data)
err = a.CreatePrometheusRule(req.IsEnabled, data.Id, db, "update")
if err != nil { if err != nil {
return err return err
} }
...@@ -312,7 +340,7 @@ func (a *AlertRulesSvc) List(req request.ListAlertRules) (resp response.AlertRul ...@@ -312,7 +340,7 @@ func (a *AlertRulesSvc) List(req request.ListAlertRules) (resp response.AlertRul
Or("acp.class_name LIKE ?", "%"+req.Keyword+"%") Or("acp.class_name LIKE ?", "%"+req.Keyword+"%")
} }
resp.TotalCount, err = session.Limit(req.GetPageSize(), (req.GetPage()-1)*req.GetPageSize()). resp.TotalCount, err = session.Limit(req.GetPageSize(), (req.GetPage()-1)*req.GetPageSize()).
OrderBy("r.created_at desc"). OrderBy("r.is_enabled asc,r.created_at desc").
FindAndCount(&resp.List) FindAndCount(&resp.List)
for i := 0; i < len(resp.List); i++ { for i := 0; i < len(resp.List); i++ {
_ = json.Unmarshal([]byte(resp.List[i].AlertRules.AlertCondition), &resp.List[i].AlertCondition) _ = json.Unmarshal([]byte(resp.List[i].AlertRules.AlertCondition), &resp.List[i].AlertCondition)
......
...@@ -7,8 +7,11 @@ import ( ...@@ -7,8 +7,11 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
"go.uber.org/zap"
"time"
"xorm.io/xorm" "xorm.io/xorm"
) )
...@@ -37,16 +40,20 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag ...@@ -37,16 +40,20 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag
) )
if alertRulesId, ok = alert.Labels["alert_rules_id"]; !ok { if alertRulesId, ok = alert.Labels["alert_rules_id"]; !ok {
return errors.New("alert_rules_id not found in the map") err = errors.New("alert_rules_id not found in the map")
conf.Logger.Error("err", zap.Error(err))
} }
if riskLevelStr, ok = alert.Labels["risk_level"]; !ok { if riskLevelStr, ok = alert.Labels["risk_level"]; !ok {
return errors.New("risk_level not found in the map") err = errors.New("risk_level not found in the map")
conf.Logger.Error("err", zap.Error(err))
} }
riskLevel = cast.ToInt(riskLevelStr) riskLevel = cast.ToInt(riskLevelStr)
if currentValueStr, ok = alert.Annotations["value"]; !ok { if currentValueStr, ok = alert.Annotations["value"]; !ok {
return errors.New("value not found in the map") err = errors.New("value not found in the map")
conf.Logger.Error("err", zap.Error(err))
return
} }
currentValue = cast.ToFloat64(currentValueStr) currentValue = cast.ToFloat64(currentValueStr)
...@@ -55,6 +62,11 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag ...@@ -55,6 +62,11 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag
return return
} }
if alertRulesItem.Id == "" {
conf.Logger.Error("err", zap.Error(errors.New("告警规则查询为空")))
return
}
alertItem, err = alertSvc.GetDataByAlertRulesIdAndRiskLevel(alertRulesId, riskLevel, 2) alertItem, err = alertSvc.GetDataByAlertRulesIdAndRiskLevel(alertRulesId, riskLevel, 2)
if err != nil { if err != nil {
return return
...@@ -68,12 +80,18 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag ...@@ -68,12 +80,18 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag
switch isNewAlert { switch isNewAlert {
case true: // 新增数据到OpenSearch case true: // 新增数据到OpenSearch
max := alertSvc.CatCount(OpenSearchIndex) var max int
max, err = alertSvc.GetIndexMaxID(conf.Options.OpenSearchIndex)
if err != nil {
// 获取id最大值
max = alertSvc.CatCount(conf.Options.OpenSearchIndex)
}
if max == 0 { if max == 0 {
err = errors.New("failed to get doc count for index") err = errors.New("failed to get doc count for index")
conf.Logger.Error("err", zap.Error(err))
return return
} }
alertId := max + 1 id := max + 1
for _, v := range alertRulesItem.AlertCondition { for _, v := range alertRulesItem.AlertCondition {
if v.RiskLevel == riskLevel { if v.RiskLevel == riskLevel {
alertCondition = v alertCondition = v
...@@ -81,12 +99,12 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag ...@@ -81,12 +99,12 @@ func (a *AlertWebhookSvc) AlertWebhook(session *xorm.Session, req webhook.Messag
} }
} }
createAlert := request.CreateAlert{Alert: entity.Alert{ createAlert := request.CreateAlert{Alert: entity.Alert{
Id: alertId, Id: id,
AlertPoint: alertRulesItem.ClassParentName + "/" + alertRulesItem.MetricName, AlertPoint: alertRulesItem.ClassParentName + "/" + alertRulesItem.MetricName,
AlertRulesId: alertRulesItem.Id, AlertRulesId: alertRulesItem.Id,
AlertRulesName: alertRulesItem.MetricName, AlertRulesName: alertRulesItem.MetricName,
RiskLevel: riskLevel, RiskLevel: riskLevel,
AlertTime: jsontime.Time(alert.StartsAt), AlertTime: jsontime.Time(alert.StartsAt.Add(time.Hour * 8)),
ClassId: alertRulesItem.ClassId, ClassId: alertRulesItem.ClassId,
ClassParentName: alertRulesItem.ClassParentName, ClassParentName: alertRulesItem.ClassParentName,
ClassName: alertRulesItem.ClassName, ClassName: alertRulesItem.ClassName,
......
...@@ -6,30 +6,46 @@ import ( ...@@ -6,30 +6,46 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"strings" "strings"
"sync"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
) )
var ( var (
PrometheusRuleGroup = "monitoring.beagle.io" // kubectl api-resources | grep -i prome promOnce sync.Once
PrometheusRuleVersion = "v1" prometheusRuleName string
PrometheusRuleKind = "PrometheusRule"
Namespace = "beagle-monitoring" alertOnce sync.Once
PrometheusRuleApiVersion = PrometheusRuleGroup + "/" + PrometheusRuleVersion alertDefLabels map[string]string
PrometheusRuleName = strings.ToLower(PrometheusRuleKind) + "s." + PrometheusRuleGroup
PrometheusRuleNamePrefix = "beagle-prometheus-so-operation-api-rules" // beagle-monitoring beagle-prometheus-prometheus-operator 43d
) )
var AlertDefLabels = map[string]string{ func GetPrometheusRuleCRDName() string {
"app": "prometheus", promOnce.Do(func() {
"app.bd-apaas.com/cluster-component": "monitoring", url := conf.Options.MonitorApiVersion // 请确保 conf 和其他相关配置可用
"prometheus-operator": "monitoring", parts := strings.Split(url, "/")
"release": "beagle-prometheus", if len(parts) == 0 || parts[0] == "" {
prometheusRuleName = "prometheusrules.monitoring.beagle.io"
} else {
prometheusRuleName = fmt.Sprintf("prometheusrules.%s", parts[0])
}
})
return prometheusRuleName
}
func GetAlertDefLabels() map[string]string {
alertOnce.Do(func() {
alertDefLabels = make(map[string]string)
err := json.Unmarshal([]byte(conf.Options.MonitorMatchLabelsStr), &alertDefLabels)
if err != nil {
fmt.Println("Error parsing JSON:", err)
}
})
return alertDefLabels
} }
// GetPrometheusRuleName 获取规则CRD名称 // GetPrometheusRuleId 获取规则CRD名称
func GetPrometheusRuleName(alertRulesId string) string { func GetPrometheusRuleId(alertPolicyId string) string {
return fmt.Sprintf("%s-%s", PrometheusRuleNamePrefix, alertRulesId) return fmt.Sprintf("%s-%s", conf.Options.PrometheusRuleNamePrefix, alertPolicyId)
} }
// GetPrometheusRuleGroupName 获取规则组名称 // GetPrometheusRuleGroupName 获取规则组名称
...@@ -43,19 +59,19 @@ type PrometheusRule struct { ...@@ -43,19 +59,19 @@ type PrometheusRule struct {
func (p PrometheusRule) Create(pRule *monitoringv1.PrometheusRule) error { func (p PrometheusRule) Create(pRule *monitoringv1.PrometheusRule) error {
k8sSvc := K8sSvc{Header: p.Header} k8sSvc := K8sSvc{Header: p.Header}
c := &Content{Kind: PrometheusRuleKind, ApiVersion: PrometheusRuleApiVersion, Metadata: pRule.ObjectMeta, Spec: pRule.Spec} c := &Content{Kind: "PrometheusRule", ApiVersion: conf.Options.MonitorApiVersion, Metadata: pRule.ObjectMeta, Spec: pRule.Spec}
_, err := k8sSvc.SendFile(c) _, err := k8sSvc.SendFile(c)
return err return err
} }
func (p PrometheusRule) Delete(namespace string, name string) error { func (p PrometheusRule) Delete(namespace string, name string) error {
delUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, PrometheusRuleName, namespace, name) delUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, GetPrometheusRuleCRDName(), namespace, name)
_, err := util.ProxySendRes("DELETE", delUrl, "", p.Header) _, err := util.ProxySendRes("DELETE", delUrl, "", p.Header)
return err return err
} }
func (p PrometheusRule) Update(pRule *monitoringv1.PrometheusRule) error { func (p PrometheusRule) Update(pRule *monitoringv1.PrometheusRule) error {
updateUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, PrometheusRuleName, pRule.Namespace, pRule.Name) updateUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, GetPrometheusRuleCRDName(), pRule.Namespace, pRule.Name)
body, _ := json.Marshal(pRule) body, _ := json.Marshal(pRule)
p.Header["Content-Type"] = "application/json" p.Header["Content-Type"] = "application/json"
_, err := util.ProxySendRes("PUT", updateUrl, string(body), p.Header) _, err := util.ProxySendRes("PUT", updateUrl, string(body), p.Header)
...@@ -63,7 +79,7 @@ func (p PrometheusRule) Update(pRule *monitoringv1.PrometheusRule) error { ...@@ -63,7 +79,7 @@ func (p PrometheusRule) Update(pRule *monitoringv1.PrometheusRule) error {
} }
func (p PrometheusRule) Get(namespace string, name string) (obj *monitoringv1.PrometheusRule, err error) { func (p PrometheusRule) Get(namespace string, name string) (obj *monitoringv1.PrometheusRule, err error) {
getUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, PrometheusRuleName, namespace, name) getUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, GetPrometheusRuleCRDName(), namespace, name)
res, err := util.ProxySendRes("GET", getUrl, "", p.Header) res, err := util.ProxySendRes("GET", getUrl, "", p.Header)
if err != nil { if err != nil {
return return
......
...@@ -26,10 +26,10 @@ func (p *PrometheusSvc) Label(req request.PrometheusLabel) (resp response.Promet ...@@ -26,10 +26,10 @@ func (p *PrometheusSvc) Label(req request.PrometheusLabel) (resp response.Promet
if req.LabelName != "" { if req.LabelName != "" {
url := fmt.Sprintf("%s%s", conf.Options.PrometheusHost, "/api/v1/series") url := fmt.Sprintf("%s%s", conf.Options.PrometheusHost, "/api/v1/series")
bytes, _ := util.Request(url, http.MethodPost, response, _ := util.Request(url, http.MethodPost,
[]byte(fmt.Sprintf("match[]=%s", req.LabelName)), []byte(fmt.Sprintf("match[]=%s", req.LabelName)),
map[string]string{"Content-Type": util.MediaTypeForm}) map[string]string{"Content-Type": util.MediaTypeForm})
_ = json.Unmarshal(bytes, &prometheusSeries) _ = json.Unmarshal(response.Body(), &prometheusSeries)
for _, v := range prometheusSeries.Data { for _, v := range prometheusSeries.Data {
for k, _ := range v { for k, _ := range v {
resp.List = append(resp.List, k) resp.List = append(resp.List, k)
...@@ -41,8 +41,8 @@ func (p *PrometheusSvc) Label(req request.PrometheusLabel) (resp response.Promet ...@@ -41,8 +41,8 @@ func (p *PrometheusSvc) Label(req request.PrometheusLabel) (resp response.Promet
} else { } else {
url := fmt.Sprintf("%s%s", conf.Options.PrometheusHost, "/api/v1/label/__name__/values") url := fmt.Sprintf("%s%s", conf.Options.PrometheusHost, "/api/v1/label/__name__/values")
bytes, _ := util.Request(url, http.MethodGet, nil, nil) response, _ := util.Request(url, http.MethodGet, nil, nil)
_ = json.Unmarshal(bytes, &prometheusLabel) _ = json.Unmarshal(response.Body(), &prometheusLabel)
resp.TotalCount = int64(len(prometheusLabel.Data)) resp.TotalCount = int64(len(prometheusLabel.Data))
resp.List = prometheusLabel.Data resp.List = prometheusLabel.Data
} }
...@@ -57,10 +57,10 @@ func (p *PrometheusSvc) LabelValue(req request.PrometheusLabelValue) (resp respo ...@@ -57,10 +57,10 @@ func (p *PrometheusSvc) LabelValue(req request.PrometheusLabelValue) (resp respo
) )
url := fmt.Sprintf("%s%s", conf.Options.PrometheusHost, "/api/v1/series") url := fmt.Sprintf("%s%s", conf.Options.PrometheusHost, "/api/v1/series")
bytes, _ := util.Request(url, http.MethodPost, response, _ := util.Request(url, http.MethodPost,
[]byte(fmt.Sprintf("match[]=%s", req.MetricName)), []byte(fmt.Sprintf("match[]=%s", req.MetricName)),
map[string]string{"Content-Type": util.MediaTypeForm}) map[string]string{"Content-Type": util.MediaTypeForm})
_ = json.Unmarshal(bytes, &prometheusSeries) _ = json.Unmarshal(response.Body(), &prometheusSeries)
for _, v := range prometheusSeries.Data { for _, v := range prometheusSeries.Data {
for key, value := range v { for key, value := range v {
metricLabelMap[key] = append(metricLabelMap[key], value) metricLabelMap[key] = append(metricLabelMap[key], value)
......
package service package service
import ( import (
"errors"
"fmt" "fmt"
json "github.com/json-iterator/go"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"github.com/spf13/cast" "github.com/spf13/cast"
"github.com/tidwall/gjson"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/service/k8s" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/service/k8s"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"go.uber.org/zap" "go.uber.org/zap"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"net/http"
"net/url"
"strings" "strings"
"sync"
) )
var prometheusRuleLabel map[string]string
var once sync.Once
func initPrometheusRuleLabel() {
once.Do(func() {
str := conf.Options.PrometheusRuleLabel
err := json.Unmarshal([]byte(str), &prometheusRuleLabel)
if err != nil {
prometheusRuleLabel = map[string]string{ // 返回默认标签
"source": "aiops-systemmonitor-api",
}
}
})
}
// GetPrometheusRuleLabel 返回 prometheusRuleLabel 单例
func GetPrometheusRuleLabel() map[string]string {
initPrometheusRuleLabel()
return prometheusRuleLabel
}
type PrometheusRuleSvc struct { type PrometheusRuleSvc struct {
User entity.SystemUserInfo User entity.SystemUserInfo
} }
func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) { func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) {
prometheusRuleName := k8s.GetPrometheusRuleName(data.Id) prometheusRuleObjName := k8s.GetPrometheusRuleId(data.Id)
pr := monitoringv1.PrometheusRule{ pr := monitoringv1.PrometheusRule{
ObjectMeta: v1.ObjectMeta{ ObjectMeta: v1.ObjectMeta{
Name: prometheusRuleName, Name: prometheusRuleObjName,
Namespace: k8s.Namespace, Namespace: conf.Options.MonitorMatchNs,
Labels: k8s.AlertDefLabels, Labels: k8s.GetAlertDefLabels(),
}, },
} }
...@@ -38,17 +66,24 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) { ...@@ -38,17 +66,24 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) {
item := fmt.Sprintf(`%s%s"%s"`, v.MetricLabel, v.Compare, v.Value) // http_requests_total{method="GET",pod="LeaseGrant"} item := fmt.Sprintf(`%s%s"%s"`, v.MetricLabel, v.Compare, v.Value) // http_requests_total{method="GET",pod="LeaseGrant"}
data.Expr = strings.ReplaceAll(data.Expr, v.VariableName, item) data.Expr = strings.ReplaceAll(data.Expr, v.VariableName, item)
} }
for _, v := range data.AlertCondition { for k, v := range data.AlertCondition {
labels := map[string]string{
"severity": "warning",
"risk_level": cast.ToString(v.RiskLevel),
"risk_level_name": constant.RiskLeveText(v.RiskLevel),
"namespace": conf.Options.MonitorMatchNs,
"alert_rules_id": data.Id,
"metric_config_id": data.MetricConfigId,
}
for key, value := range GetPrometheusRuleLabel() {
labels[key] = value
}
rule := monitoringv1.Rule{ rule := monitoringv1.Rule{
Alert: data.MetricConfigName, // promhttp超过5万次告警-prom指标控制器请求数-较大风险-3
For: &ruleFor, Alert: fmt.Sprintf("%s-%s-%s-%d", data.MetricName, data.MetricConfigName, constant.RiskLeveText(v.RiskLevel), k+1),
Labels: map[string]string{ For: &ruleFor,
"severity": "warning", Labels: labels,
"risk_level": cast.ToString(v.RiskLevel),
"risk_level_name": constant.RiskLeveText(v.RiskLevel),
"source": "so-operation-api",
"alert_rules_id": data.MetricConfigId,
},
Annotations: map[string]string{ Annotations: map[string]string{
"value": "{{ $value }}", "value": "{{ $value }}",
"summary": fmt.Sprintf("分组名:%s, 检查周期:%s, 持续时间:%s", group.Name, string(groupInterval), string(ruleFor)), "summary": fmt.Sprintf("分组名:%s, 检查周期:%s, 持续时间:%s", group.Name, string(groupInterval), string(ruleFor)),
...@@ -68,6 +103,11 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) { ...@@ -68,6 +103,11 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) {
condition += 2 condition += 2
} }
// 为"空"状态下,默认表达式已经有比较判断,故直接使用表达式即可
if data.AlertRuleTypeName == "空" {
condition = 0
}
switch condition { switch condition {
default: default:
expr = data.Expr expr = data.Expr
...@@ -79,6 +119,12 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) { ...@@ -79,6 +119,12 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) {
expr = fmt.Sprintf("%s <= %s <=%s", cast.ToString(v.ThresholdsMin), data.Expr, cast.ToString(v.ThresholdsMax)) expr = fmt.Sprintf("%s <= %s <=%s", cast.ToString(v.ThresholdsMin), data.Expr, cast.ToString(v.ThresholdsMax))
} }
// 校验表达式正确性
err = CheckPrometheusQuerySyntax(expr)
if err != nil {
return
}
rule.Expr = intstr.FromString(expr) rule.Expr = intstr.FromString(expr)
group.Rules = append(group.Rules, rule) group.Rules = append(group.Rules, rule)
} }
...@@ -91,12 +137,12 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) { ...@@ -91,12 +137,12 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) {
} }
func (p *PrometheusRuleSvc) Get(data response.AlertRulesItem) (obj *monitoringv1.PrometheusRule, exist bool, err error) { func (p *PrometheusRuleSvc) Get(data response.AlertRulesItem) (obj *monitoringv1.PrometheusRule, exist bool, err error) {
prometheusRuleName := k8s.GetPrometheusRuleName(data.Id) prometheusRuleObjName := k8s.GetPrometheusRuleId(data.Id)
pr := monitoringv1.PrometheusRule{ pr := monitoringv1.PrometheusRule{
ObjectMeta: v1.ObjectMeta{ ObjectMeta: v1.ObjectMeta{
Name: prometheusRuleName, Name: prometheusRuleObjName,
Namespace: k8s.Namespace, Namespace: conf.Options.MonitorMatchNs,
Labels: k8s.AlertDefLabels, Labels: k8s.GetAlertDefLabels(),
}, },
} }
header := map[string]string{"Authorization": "Bearer " + conf.Options.KubernetesToken} header := map[string]string{"Authorization": "Bearer " + conf.Options.KubernetesToken}
...@@ -109,13 +155,26 @@ func (p *PrometheusRuleSvc) Get(data response.AlertRulesItem) (obj *monitoringv1 ...@@ -109,13 +155,26 @@ func (p *PrometheusRuleSvc) Get(data response.AlertRulesItem) (obj *monitoringv1
return return
} }
// CheckPrometheusQuerySyntax 校验普罗米修斯语法正确性
func CheckPrometheusQuerySyntax(expr string) error {
params := url.Values{}
params.Add("query", expr)
query := params.Encode()
webUrl := fmt.Sprintf("%s%s%s", conf.Options.PrometheusHost, "/api/v1/query?", query)
resp, _ := util.Request(webUrl, http.MethodGet, nil, nil)
if resp.StatusCode() != http.StatusOK {
return errors.New(fmt.Sprintf("%s, err: %s", "普罗米修斯语法PromQL错误", gjson.GetBytes(resp.Body(), "error").String()))
}
return nil
}
func (p *PrometheusRuleSvc) Delete(data response.AlertRulesItem) (err error) { func (p *PrometheusRuleSvc) Delete(data response.AlertRulesItem) (err error) {
prometheusRuleName := k8s.GetPrometheusRuleName(data.Id) prometheusRuleObjName := k8s.GetPrometheusRuleId(data.Id)
pr := monitoringv1.PrometheusRule{ pr := monitoringv1.PrometheusRule{
ObjectMeta: v1.ObjectMeta{ ObjectMeta: v1.ObjectMeta{
Name: prometheusRuleName, Name: prometheusRuleObjName,
Namespace: k8s.Namespace, Namespace: conf.Options.MonitorMatchNs,
Labels: k8s.AlertDefLabels, Labels: k8s.GetAlertDefLabels(),
}, },
} }
......
...@@ -60,7 +60,7 @@ Request("https://httpbin.org/put", ...@@ -60,7 +60,7 @@ Request("https://httpbin.org/put",
"Cookie": "aweToken=3ab9f63f-b0b3-4935-80ec-405d76ac111d", "Cookie": "aweToken=3ab9f63f-b0b3-4935-80ec-405d76ac111d",
}) })
*/ */
func Request(url string, method string, body []byte, headers map[string]string) ([]byte, error) { func Request(url string, method string, body []byte, headers map[string]string) (*fasthttp.Response, error) {
req := fasthttp.AcquireRequest() req := fasthttp.AcquireRequest()
defer fasthttp.ReleaseRequest(req) defer fasthttp.ReleaseRequest(req)
...@@ -98,8 +98,11 @@ func Request(url string, method string, body []byte, headers map[string]string) ...@@ -98,8 +98,11 @@ func Request(url string, method string, body []byte, headers map[string]string)
return nil, err return nil, err
} }
result := new(fasthttp.Response)
resp.CopyTo(result)
// 返回响应体和错误信息 // 返回响应体和错误信息
return resp.Body(), nil return result, nil
} }
// HttpSend , http请求 GET/DELETE/POST/PUT // HttpSend , http请求 GET/DELETE/POST/PUT
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment