From 2bea8b7c842cbb1f4c2493126064f4e0aa3f238e Mon Sep 17 00:00:00 2001 From: Ulric Qin Date: Tue, 17 May 2022 19:24:06 +0800 Subject: [PATCH] add usage report --- .../{engine/vector.go => common/conv/conv.go} | 2 +- src/server/config/config.go | 39 +++---- src/server/engine/worker.go | 5 +- src/server/router/router_prom.go | 4 +- src/server/server.go | 5 + src/server/usage/usage.go | 101 ++++++++++++++++++ 6 files changed, 132 insertions(+), 24 deletions(-) rename src/server/{engine/vector.go => common/conv/conv.go} (98%) create mode 100644 src/server/usage/usage.go diff --git a/src/server/engine/vector.go b/src/server/common/conv/conv.go similarity index 98% rename from src/server/engine/vector.go rename to src/server/common/conv/conv.go index 4b6ef5eb..561eb51f 100644 --- a/src/server/engine/vector.go +++ b/src/server/common/conv/conv.go @@ -1,4 +1,4 @@ -package engine +package conv import ( "math" diff --git a/src/server/config/config.go b/src/server/config/config.go index cb1a46ed..ae6fe16c 100644 --- a/src/server/config/config.go +++ b/src/server/config/config.go @@ -119,25 +119,26 @@ func MustLoad(fpaths ...string) { } type Config struct { - RunMode string - ClusterName string - BusiGroupLabelKey string - EngineDelay int64 - Log logx.Config - HTTP httpx.Config - BasicAuth gin.Accounts - SMTP SMTPConfig - Heartbeat HeartbeatConfig - Alerting Alerting - NoData NoData - Redis storage.RedisConfig - Gorm storage.Gorm - MySQL storage.MySQL - Postgres storage.Postgres - WriterOpt writer.GlobalOpt - Writers []writer.Options - Reader reader.Options - Ibex Ibex + RunMode string + ClusterName string + BusiGroupLabelKey string + EngineDelay int64 + DisableUsageReport bool + Log logx.Config + HTTP httpx.Config + BasicAuth gin.Accounts + SMTP SMTPConfig + Heartbeat HeartbeatConfig + Alerting Alerting + NoData NoData + Redis storage.RedisConfig + Gorm storage.Gorm + MySQL storage.MySQL + Postgres storage.Postgres + WriterOpt writer.GlobalOpt + Writers []writer.Options + Reader reader.Options + Ibex Ibex } type HeartbeatConfig struct { diff --git a/src/server/engine/worker.go b/src/server/engine/worker.go index 15fa5ab2..66bfe2ef 100644 --- a/src/server/engine/worker.go +++ b/src/server/engine/worker.go @@ -11,6 +11,7 @@ import ( "github.com/toolkits/pkg/str" "github.com/didi/nightingale/v5/src/models" + "github.com/didi/nightingale/v5/src/server/common/conv" "github.com/didi/nightingale/v5/src/server/config" "github.com/didi/nightingale/v5/src/server/memsto" "github.com/didi/nightingale/v5/src/server/naming" @@ -106,7 +107,7 @@ func (r RuleEval) Work() { return } - r.judge(ConvertVectors(value)) + r.judge(conv.ConvertVectors(value)) } type WorkersType struct { @@ -172,7 +173,7 @@ func (ws *WorkersType) Build(rids []int64) { } } -func (r RuleEval) judge(vectors []Vector) { +func (r RuleEval) judge(vectors []conv.Vector) { // 有可能rule的一些配置已经发生变化,比如告警接收人、callbacks等 // 这些信息的修改是不会引起worker restart的,但是确实会影响告警处理逻辑 // 所以,这里直接从memsto.AlertRuleCache中获取并覆盖 diff --git a/src/server/router/router_prom.go b/src/server/router/router_prom.go index ce700521..36e498d6 100644 --- a/src/server/router/router_prom.go +++ b/src/server/router/router_prom.go @@ -13,8 +13,8 @@ import ( "github.com/toolkits/pkg/ginx" "github.com/didi/nightingale/v5/src/server/common" + "github.com/didi/nightingale/v5/src/server/common/conv" "github.com/didi/nightingale/v5/src/server/config" - "github.com/didi/nightingale/v5/src/server/engine" "github.com/didi/nightingale/v5/src/server/idents" "github.com/didi/nightingale/v5/src/server/memsto" "github.com/didi/nightingale/v5/src/server/reader" @@ -41,7 +41,7 @@ func queryPromql(c *gin.Context) { return } - c.JSON(200, engine.ConvertVectors(value)) + c.JSON(200, conv.ConvertVectors(value)) } func remoteWrite(c *gin.Context) { diff --git a/src/server/server.go b/src/server/server.go index f69c336e..c5ca15ad 100644 --- a/src/server/server.go +++ b/src/server/server.go @@ -20,6 +20,7 @@ import ( "github.com/didi/nightingale/v5/src/server/reader" "github.com/didi/nightingale/v5/src/server/router" "github.com/didi/nightingale/v5/src/server/stat" + "github.com/didi/nightingale/v5/src/server/usage" "github.com/didi/nightingale/v5/src/server/writer" "github.com/didi/nightingale/v5/src/storage" ) @@ -153,6 +154,10 @@ func (s Server) initialize() (func(), error) { // register ident and nodata logic idents.Handle(ctx) + if !config.C.DisableUsageReport { + go usage.Report() + } + // release all the resources return fns.Ret(), nil } diff --git a/src/server/usage/usage.go b/src/server/usage/usage.go new file mode 100644 index 00000000..2ce8ab75 --- /dev/null +++ b/src/server/usage/usage.go @@ -0,0 +1,101 @@ +package usage + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "os" + "time" + + "github.com/didi/nightingale/v5/src/server/common/conv" + "github.com/didi/nightingale/v5/src/server/reader" +) + +const ( + url = "http://n9e.io/report" + request = "sum(rate(n9e_server_samples_received_total[5m]))" +) + +type Usage struct { + Samples float64 `json:"samples"` // per second + Maintainer string `json:"maintainer"` + Hostname string `json:"hostname"` +} + +func getSamples() (float64, error) { + value, warns, err := reader.Reader.Client.Query(context.Background(), request, time.Now()) + if err != nil { + return 0, err + } + + if len(warns) > 0 { + return 0, fmt.Errorf("occur some warnings: %v", warns) + } + + lst := conv.ConvertVectors(value) + if len(lst) == 0 { + return 0, fmt.Errorf("convert result is empty") + } + + return lst[0].Value, nil +} + +func Report() { + for { + time.Sleep(time.Minute * 10) + report() + } +} + +func report() { + sps, err := getSamples() + if err != nil { + return + } + + hostname, err := os.Hostname() + if err != nil { + return + } + + maintainer := "blank" + + u := Usage{ + Samples: sps, + Hostname: hostname, + Maintainer: maintainer, + } + + post(u) +} + +func post(u Usage) error { + body, err := json.Marshal(u) + if err != nil { + return err + } + + req, err := http.NewRequest("POST", url, bytes.NewReader(body)) + if err != nil { + return err + } + + cli := http.Client{ + Timeout: time.Second * 10, + } + + resp, err := cli.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != 200 { + return fmt.Errorf("got %s", resp.Status) + } + + _, err = ioutil.ReadAll(resp.Body) + return err +}