首页> 开发语言> 【开发语言】golang-蓝鲸监控采集器开发

[文章]【开发语言】golang-蓝鲸监控采集器开发

收藏
0 1176 0

Golang-蓝鲸监控采集器开发

【摘要】

    蓝鲸平台的监控组件采集器是基于Prometheusexporter,所以当如果自带的组件不满足监控的需求时,可以通过自行开发进行采集器进行扩展。

 

【正文】

1、 理解PrometheusCollector接口

采集器的开发主要是使用PrometheusCollector接口(interface),这里的接口在Golang中可以理解为是一组方法的集合。同时在Golang中定义,如果某个接口中的所有方法都被实现了,那就等于这个接口被实现了。所以需要先对Collector这个接口进行理解。


从以上说明可以得知,Collector这个接口包含两个方法:DescribeCollect

 

2、 实现Collector接口

了解了Collector这个接口之后,我们就可以开始进行实现该接口。一般会通过定义一个结构体(struct)来进行。

type Exporter struct {
memMetric  *prometheus.Desc // 定义用于保存采集到的内存指标

}

这里的指标使用的是 prometheusDesc类型。

 

然后对我们自定义的类型 Exporter 进行定义方法:

// 通过定义方法,实现 Collector 接口的 Describe 方法
func (c *Exporter) Describe(ch chan<- *prometheus.Desc) {

ch <- c.memMetric  // 把指标描述符传递到channel

}

再对类型 Exporter 进行定义Collect方法:

// 通过定义方法,实现 Collector 接口的 Collect 方法
func (c *Exporter) Collect(ch chan<- prometheus.Metric) {
ch <- prometheus.MustNewConstMetric(
       
c.memMetric, // 采集指标的描述符
       
prometheus.CounterValue, // 采集的类型:Counter,Gauge..4
       
getMemUsed(), // 采集到的值,这里通过一个gseMemUsed函数进行返回,float64类型
       
nil, // 维度&标签(label),这里没有
  )
// label
}

到这里我们自定义的类型Exporter就已经具有了两个方法,也就是说使用这个Exporter结构体就等于是使用Prometheus的接口。

 

3、 使用Exporter结构体

Exporter这个结构体已经都具备了DescribeCollect两个方法时,那直接使用这个这个结构体就等于使用这个接口。

由于Exporter中的memMetric这个接收的类型是*Prometheus.Desc,所以只要用“NewDesc”来构造这个类型即可。

/* 当一个接口中的两个方法都被实现,那么就相当于这个接口被实现 */
func newExporter() *Exporter {
  return &Exporter{
    memMetric: prometheus.NewDesc(
    "system_mem_free", // fqName
    "这里是帮助信息:這是一個例子", // help
    []
string{}, // variablelabels 这里是无标签 , 也可返回nil
    nil,        // constLabels
    ),
  }
}

 

4、 编写采集动作

这里的采集动作可以使用函数,也可以使用方法。会定期被Collect去调用并获取数据。这里采集逻辑就不写,以随机数据进行展示。

/* 实际的采集动作 */
func getMemUsed() float64 {
   
// 这里以随机数作展示,在Collector里使用,函数的返回值一定要为 float64()
return rand.Float64() * 100
}

 

5、 注册指标&启动HTTP服务

整条数据链路都走完之后,还需要把这个指标注册到Prometheus才可以使用。Prometheus提供MustRegister的方法进行注册,直接把指标传到这里即可。

然后通过http接口去把我们的指标数据暴露出来,这样就可以被蓝鲸监控抓取到。

func main() {
foo := newExporter()
reg := prometheus.NewPedanticRegistry()
reg.MustRegister(foo) // 注册指标
newGatherers := prometheus.Gatherers{
prometheus.DefaultGatherer,
reg,
}
// 启用http服务
h := promhttp.HandlerFor(
newGatherers,
promhttp.HandlerOpts{
ErrorLog:      log.NewErrorLogger(),
ErrorHandling: promhttp.ContinueOnError,
},
)
//
http.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) { h.ServeHTTP(w, r) })
log.Infoln("Start Server at :8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Errorf("Error occur when start server %v", err)
os.Exit(1)

}
}

 

 

 

6、 本地测试

把项目在本地运行起来后,就可以通过浏览器来访问,然后就能看到返回的指标数据。


 

7、 返回优化

由于这里我们是把数据都传到Prometheus自带的Gatherer里,所以可以看到里面有很多go的指标,为了返回更加清晰一些,我们可以自定义一个Gatherer,只用来展示我们的数据:

func main() {
/*自定义Gatherer,只是为了区别DefaultGatherer,让输出好看一些*/
var parser expfmt.TextParser
var parserText = func() ([]*ido.MetricFamily, error) {
parsed, err := parser.TextToMetricFamilies(strings.NewReader(""))
if err != nil {
return nil, err
}
var result []*ido.MetricFamily
for _, mf := range parsed {
result = append(result, mf)
}
return result, nil
}
/* End */

foo := newExporter()
reg := prometheus.NewPedanticRegistry()
reg.MustRegister(foo) // 注册指标
newGatherers := prometheus.Gatherers{
// prometheus.DefaultGatherer,
prometheus.GathererFunc(parserText),
reg,
}
// 启用http服务
h := promhttp.HandlerFor(
newGatherers,
promhttp.HandlerOpts{
ErrorLog:      log.NewErrorLogger(),
ErrorHandling: promhttp.ContinueOnError,
},
)
//
http.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) { h.ServeHTTP(w, r) })
log.Infoln("Start Server at :8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Errorf("Error occur when start server %v", err)
os.Exit(1)

}
}

      

       这样,再次去访问Url时,就只剩下我们关注的采集数据:

       

 


 

 

开发语言
最近热帖
{{item.Title}} {{item.ViewCount}}
近期热议
{{item.Title}} {{item.PostCount}}