gorm의prometheus에 대해서 얘기를 해볼게요.

4740 단어 gorm

순서


본고는 주로gorm의prometheus를 연구하였다

Plugin


gorm.io/[email protected]/interfaces.go
// Plugin GORM plugin interface
type Plugin interface {
    Name() string
    Initialize(*DB) error
}

Plugin 인터페이스는 Name, Initialize 방법을 정의합니다.

Prometheus


gorm.io/plugin/[email protected]/prometheus.go
type Prometheus struct {
    *gorm.DB
    *DBStats
    *Config
    refreshOnce, pushOnce sync.Once
    Labels                map[string]string
    collectors            []prometheus.Collector
}

func (p *Prometheus) Name() string {
    return "gorm:prometheus"
}

func (p *Prometheus) Initialize(db *gorm.DB) error { //can be called repeatedly
    p.DB = db

    if p.Config.DBName != "" {
        p.Labels["db_name"] = p.Config.DBName
    }

    p.DBStats = newStats(p.Labels)

    p.refreshOnce.Do(func() {
        for _, mc := range p.MetricsCollector {
            p.collectors = append(p.collectors, mc.Metrics(p)...)
        }

        go func() {
            for range time.Tick(time.Duration(p.Config.RefreshInterval) * time.Second) {
                p.refresh()
            }
        }()
    })

    if p.Config.StartServer {
        go p.startServer()
    }

    if p.PushAddr != "" {
        go p.startPush()
    }

    return nil
}

Prometheus는 Plugin 인터페이스를 실현하여Name, Initialize 방법을 정의했습니다.Initialize 메서드는 p.startServer(), p.startPush() 및 p.refresh()

startServer


gorm.io/plugin/[email protected]/prometheus.go
func (p *Prometheus) startServer() {
    httpServerOnce.Do(func() { //only start once
        mux := http.NewServeMux()
        mux.Handle("/metrics", promhttp.Handler())
        err := http.ListenAndServe(fmt.Sprintf(":%d", p.Config.HTTPServerPort), mux)
        if err != nil {
            p.DB.Logger.Error(context.Background(), "gorm:prometheus listen and serve err: ", err)
        }
    })
}

startServer가 http 서버를 시작했습니다./metrics 커넥터

startPush


gorm.io/plugin/[email protected]/prometheus.go
func (p *Prometheus) startPush() {
    p.pushOnce.Do(func() {
        pusher := push.New(p.PushAddr, p.DBName)

        for _, collector := range p.DBStats.Collectors() {
            pusher = pusher.Collector(collector)
        }

        for _, c := range p.collectors {
            pusher = pusher.Collector(c)
        }

        for range time.Tick(time.Duration(p.Config.RefreshInterval) * time.Second) {
            err := pusher.Push()
            if err != nil {
                p.DB.Logger.Error(context.Background(), "gorm:prometheus push err: ", err)
            }
        }
    })
}

startPush 메서드는 pusher를 실행하기 위해 정시 작업을 시작합니다.Push()

refresh


gorm.io/plugin/[email protected]/prometheus.go
func (p *Prometheus) refresh() {
    if db, err := p.DB.DB(); err == nil {
        p.DBStats.Set(db.Stats())
    } else {
        p.DB.Logger.Error(context.Background(), "gorm:prometheus failed to collect db status, got error: %v", err)
    }
}

refresh 방법은 주로 p.DBStats를 업데이트하는 것입니다.

Use


gorm.io/[email protected]/gorm.go
func (db *DB) Use(plugin Plugin) (err error) {
    name := plugin.Name()
    if _, ok := db.Plugins[name]; !ok {
        if err = plugin.Initialize(db); err == nil {
            db.Plugins[name] = plugin
        }
    } else {
        return ErrRegistered
    }

    return err
}

gorm의 Use 방법은plugin을 시작하는 데 사용되며,plugin을 실행합니다.Initialize(db)

인스턴스

    db.Use(prometheus.New(prometheus.Config{
        DBName:          "db1", //   `DBName`   label
        RefreshInterval: 15,    //  (  15  )
        PushAddr:        "prometheus pusher address", //   `PushAddr`, 
        StartServer:     true,  //   http  
        HTTPServerPort:  8080,  //   http  ,  8080 ( ,  `HTTPServerPort`  )
        MetricsCollector: []prometheus.MetricsCollector {
            &prometheus.MySQL{
                VariableNames: []string{"Threads_running"},
            },
        },  //  
    }))

작은 매듭


gorm의 플러그인 인터페이스는Name, Initialize 방법을 정의합니다.gorm의 Use 방법은plugin을 시작하는 데 사용되며,plugin을 실행합니다.Initialize(db);Prometheus는 Plugin 인터페이스를 실현하여Name, Initialize 방법을 정의했습니다.Initialize 메서드는 p.startServer (), p.startPush () 및 p.refresh () 를 실행합니다.

doc

  • gorm
  • 좋은 웹페이지 즐겨찾기