• 监控指标go.mongodb.org/mongodriver的prometheus


    1、定义prometheus指标

    package tool
    
    import (
        "github.com/prometheus/client_golang/prometheus"
    )
    
    const Application = "application"
    const Command = "command"
    const Database = "database"
    const RequestID = "request_id"
    const Status = "status"
    
    type MongoStatusEnum string
    
    const (
        Success MongoStatusEnum = "success"
        Fail    MongoStatusEnum = "fail"
        Start   MongoStatusEnum = "start"
    )
    
    var (
        mongoHistogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{
            Name:    "mongodb_operations_duration_seconds",
            Help:    "mongodb command record",
            Buckets: []float64{0.1, 0.5, 1.0, 1.5, 3.0, 5.0, 10.0},
        }, []string{Application, Command, Database, RequestID, Status})
    )
    
    func init() {
        prometheus.MustRegister(mongoHistogram)
    }
    
    func AddMetrics(labels prometheus.Labels, speed float64) {
        mongoHistogram.With(labels).Observe(speed)
    }

    二、注册mongo监听器收集指标

    import (
        "context"
        "encoding/json"
        "fmt"
        "github.com/gogf/gf/util/gconv"
        "github.com/pkg/errors"
        "github.com/prometheus/client_golang/prometheus"
        "strconv"
        "sync"
    
        "go.mongodb.org/mongo-driver/bson"
        "go.mongodb.org/mongo-driver/event"
        "go.mongodb.org/mongo-driver/mongo"
        "go.mongodb.org/mongo-driver/mongo/options"
        "go.mongodb.org/mongo-driver/mongo/readpref"
        "log"
        "net/http"
        "time"
    )
    
    var RequestIDDatabaseNameMap sync.Map
    
    func Client() *mongo.Client {
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()
        opt := new(options.ClientOptions)
        opt.ApplyURI("mongodb://admin:123456@127.0.0.1:27017/?authSource=admin")
        m := new(event.CommandMonitor)
        m.Started = func(ctx context.Context, startedEvent *event.CommandStartedEvent) {
            RequestIDDatabaseNameMap.Store(strconv.FormatInt(startedEvent.RequestID, 10), startedEvent.DatabaseName)
        }
        m.Succeeded = func(ctx context.Context, succeededEvent *event.CommandSucceededEvent) {
            l := prometheus.Labels{}
            l[Application] = "one"
            l[Command] = succeededEvent.CommandName
            databaseName := ""
            tmp, exist := RequestIDDatabaseNameMap.LoadAndDelete(strconv.FormatInt(succeededEvent.RequestID, 10))
            if exist {
                databaseName = gconv.String(tmp)
            }
            l[Database] = databaseName
            l[Status] = gconv.String(Success)
            l[RequestID] = strconv.FormatInt(succeededEvent.RequestID, 10)
            t, e := time.ParseDuration(fmt.Sprintf("%sns", gconv.String(succeededEvent.DurationNanos)))
            if e != nil {
                panic(e)
            }
            AddMetrics(l, t.Seconds())
        }
        m.Failed = func(ctx context.Context, failedEvent *event.CommandFailedEvent) {
            l := prometheus.Labels{}
            l[Application] = "one"
            l[Command] = failedEvent.CommandName
            databaseName := ""
            tmp, exist := RequestIDDatabaseNameMap.LoadAndDelete(strconv.FormatInt(failedEvent.RequestID, 10))
            if exist {
                databaseName = gconv.String(tmp)
            }
            l[Database] = databaseName
            l[Status] = gconv.String(Fail)
            l[RequestID] = strconv.FormatInt(failedEvent.RequestID, 10)
            t, e := time.ParseDuration(fmt.Sprintf("%sns", gconv.String(failedEvent.DurationNanos)))
            if e != nil {
                panic(e)
            }
            AddMetrics(l, t.Seconds())
        }
        opt.Monitor = m
        client, err := mongo.NewClient(opt)
        if err != nil {
            panic(err)
        }
        err = client.Connect(ctx)
        if err != nil {
            panic(errors.Wrap(err, "connect mongo error"))
        }
        ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second)
        defer cancel()
        err = client.Ping(ctx, readpref.Primary())
        if err != nil {
            panic(errors.Wrap(err, "ping mongo error"))
        }
        return client
    }
    
    
    func find(c *mongo.Client) string {
        _, ee := c.ListDatabases(context.Background(), bson.D{})
        if ee != nil {
            log.Fatalf("list database %s", ee.Error())
        }
        log.Printf("database is %s", c.Database("user").Name())
        ff, _ := c.Database("user").ListCollectionNames(context.Background(), bson.D{})
        dd, _ := json.Marshal(ff)
        fmt.Println(string(dd))
        collection := c.Database("user").Collection("t_incident")
        var result bson.M
        e := collection.FindOne(context.Background(), bson.D{}).Decode(&result)
        if e != nil {
            log.Fatalf("find one %s", e.Error())
        }
        s, _ := json.Marshal(result)
        return string(s)
    }
    
    type Handler struct {
    }
    
    func (m *Handler) ServeHTTP(r http.ResponseWriter, q *http.Request) {
        s := find(Client())
        result := []byte(s)
        _, e := r.Write(result)
        if e != nil {
            log.Fatal(e)
        }
    }

    三、启动服务查看指标

    package main
    
    import (
        "github.com/prometheus/client_golang/prometheus/promhttp"
        "net/http"
        "sangfor.com/tool"
    )
    
    func main() {
        //提供 /metrics HTTP 端点
        http.Handle("/metrics", promhttp.Handler())
        http.Handle("/get", new(tool.Handler))
        //端口号
        http.ListenAndServe(":2112", nil)
    }

    访问 /metrics 可以获取指标信息

  • 相关阅读:
    转:二进制文件和文本文件的区别详解
    python sorted函数,字典排序
    office word交叉引用,文献尾注,公式自动编号
    list作为实参传给函数
    转:python深拷贝和浅拷贝的区别
    文件夹中含有子文件夹,修改子文件夹中的图像存储格式(python实现)
    python遍历文件夹中所有文件夹和文件,os.walk
    cf div3 B Obtaining the String
    cf div3 B Obtaining the String
    poj 3281(最大流)
  • 原文地址:https://www.cnblogs.com/xuweiqiang/p/16532366.html
Copyright © 2020-2023  润新知