SLS SDK支持写入时序数据,但手动维护一系列自定义指标的方式较为繁琐。Prometheus能自动生成多种维度的监控指标并内置维护标签信息,然而,它通常要求对外暴露一个HTTP接口,通过第三方采集器以Pull模式拉取时序数据。在函数计算场景中,由于计算服务无法直接提供此类HTTP接口,无法通过前述Pull模式上报时序数据。本文介绍一种利用Prometheus SDK并基于Push模式上报时序数据的方案。
前提条件
已创建Project和MetricStore。具体操作,请参见管理Project和管理MetricStore。
集成Prometheus
Prometheus能够自动生成多种维度的监控指标并内置维护了各种标签信息,结合Prometheus内置维护的指标信息,上报时序数据到时序库,根据不同场景,有两种模式。
方式 | 说明 |
Pull模式 | Pull模式采集并上报指标数据,包含以下四个阶段:
|
Push模式 | Push模式表示主动推送指标数据到时序库中。日志服务时序库支持两种主动上报时序数据的方式: |
代码示例
使用Prometheus SDK,可以将Pull模式中采集进程
所执行的操作全部合并到原项目进程
中。
Go语言
已安装Go SDK。通过调用Gather()
接口获取所有时序指标,之后再调用Encode
或Decode
接口即可实现。
package main
import (
"bytes"
"fmt"
"time"
"github.com/gogo/protobuf/proto"
"github.com/golang/snappy"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/expfmt"
"github.com/prometheus/prometheus/util/fmtutil"
"io/ioutil"
"math/rand"
"net/http"
)
var durationHistogram = prometheus.NewHistogram(
prometheus.HistogramOpts{
Name: "server_handling_seconds",
Buckets: prometheus.DefBuckets,
},
)
var requestCount = prometheus.NewCounter(
prometheus.CounterOpts{
Name: "server_requests_count",
},
)
func main() {
prometheus.MustRegister(durationHistogram)
// 分别替换 your-project-name, endpoint, your-project-name, your-metricstore-name
u := fmt.Sprintf("https://%s.%s/prometheus/%s/%s/api/v1/write", "your-project-name", "endpoint", "your-project-name", "your-metricstore-name")
for i := 0; i < 300; i++ {
// 更新指标数据
for j := 0; j < 100; j++ {
val := rand.Float64() * 10
durationHistogram.Observe(val)
requestCount.Inc()
}
// 收集已注册的所有指标数据
mfs, err := prometheus.DefaultGatherer.Gather()
if err != nil {
panic(err)
}
// 对指标数据进行编码处理
// 注意:由于Histogram类型的指标是在Encode过程中添加 "+Inf" 这个le标签,所以此处的Encode过程不可省略。
buf := bytes.NewBuffer(nil)
encoder := expfmt.NewEncoder(buf, expfmt.NewFormat(expfmt.TypeTextPlain))
for _, mf := range mfs {
if err := encoder.Encode(mf); err != nil {
panic(err)
}
}
// 对编码后的指标数据做解析处理,并转化成RemoteWrite PB协议的Request
// 当前示例对于错误处理直接结束进程,实际使用中需根据业务特点选择合适的处理方式,例如跳过或者退出重试等
request, err := fmtutil.MetricTextToWriteRequest(buf, nil)
if err != nil {
panic(err)
}
// 对*prompb.WriteRequest做序列化并压缩
data, _ := proto.Marshal(request)
bufBody := snappy.Encode(nil, data)
rwR, err := http.NewRequest("POST", u, ioutil.NopCloser(bytes.NewReader(bufBody)))
if err != nil {
panic(err)
}
rwR.Header.Add("Content-Encoding", "snappy")
rwR.Header.Set("Content-Type", "application/x-protobuf")
// 设置basic auth信息,即AccessKeyId和AccessKeySecret。
rwR.SetBasicAuth("LTAI5t*************", "kaOAL9*************")
// 往SLS时序库发送时序数据
resp, err := http.DefaultClient.Do(rwR)
if err != nil {
panic(err)
}
d, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(d))
time.Sleep(time.Second)
}
}
验证采集数据
文档内容是否对您有帮助?