本文次要钻研一下dubbo-go的PrometheusReporter

PrometheusReporter

dubbo-go-v1.4.2/metrics/prometheus/reporter.go

const (    reporterName = "prometheus"    serviceKey   = constant.SERVICE_KEY    groupKey     = constant.GROUP_KEY    versionKey   = constant.VERSION_KEY    methodKey    = constant.METHOD_KEY    timeoutKey   = constant.TIMEOUT_KEY    providerKey = "provider"    consumerKey = "consumer"    // to identify the metric's type    histogramSuffix = "_histogram"    // to identify the metric's type    summarySuffix = "_summary")var (    labelNames       = []string{serviceKey, groupKey, versionKey, methodKey, timeoutKey}    namespace        = config.GetApplicationConfig().Name    reporterInstance *PrometheusReporter    reporterInitOnce sync.Once)// should initialize after loading configurationfunc init() {    extension.SetMetricReporter(reporterName, newPrometheusReporter)}// PrometheusReporter// it will collect the data for Prometheus// if you want to use this, you should initialize your prometheus.// https://prometheus.io/docs/guides/go-application/type PrometheusReporter struct {    // report the consumer-side's summary data    consumerSummaryVec *prometheus.SummaryVec    // report the provider-side's summary data    providerSummaryVec *prometheus.SummaryVec    // report the provider-side's histogram data    providerHistogramVec *prometheus.HistogramVec    // report the consumer-side's histogram data    consumerHistogramVec *prometheus.HistogramVec}
  • PrometheusReporter定义了consumerSummaryVec、providerSummaryVec、providerHistogramVec、consumerHistogramVec

newPrometheusReporter

dubbo-go-v1.4.2/metrics/prometheus/reporter.go

// newPrometheusReporter create new prometheusReporter// it will register the metrics into prometheusfunc newPrometheusReporter() metrics.Reporter {    if reporterInstance == nil {        reporterInitOnce.Do(func() {            reporterInstance = &PrometheusReporter{                consumerSummaryVec: newSummaryVec(consumerKey),                providerSummaryVec: newSummaryVec(providerKey),                consumerHistogramVec: newHistogramVec(consumerKey),                providerHistogramVec: newHistogramVec(providerKey),            }            prometheus.MustRegister(reporterInstance.consumerSummaryVec, reporterInstance.providerSummaryVec,                reporterInstance.consumerHistogramVec, reporterInstance.providerHistogramVec)        })    }    return reporterInstance}
  • newPrometheusReporter办法实例化PrometheusReporter

newSummaryVec

dubbo-go-v1.4.2/metrics/prometheus/reporter.go

// newSummaryVec create SummaryVec, the Namespace is dubbo// the objectives is from my experience.func newSummaryVec(side string) *prometheus.SummaryVec {    return prometheus.NewSummaryVec(        prometheus.SummaryOpts{            Namespace: namespace,            Help:      "This is the dubbo's summary metrics",            Subsystem: side,            Name:      serviceKey + summarySuffix,            Objectives: map[float64]float64{                0.5:   0.01,                0.75:  0.01,                0.90:  0.005,                0.98:  0.002,                0.99:  0.001,                0.999: 0.0001,            },        },        labelNames,    )}
  • newSummaryVec办法执行prometheus.NewSummaryVec,其中SummaryOpts设置了0.5、0.75、0.90、0.98、0.99、0.999的Objectives

newHistogramVec

dubbo-go-v1.4.2/metrics/prometheus/reporter.go

func newHistogramVec(side string) *prometheus.HistogramVec {    mc := config.GetMetricConfig()    return prometheus.NewHistogramVec(        prometheus.HistogramOpts{            Namespace: namespace,            Subsystem: side,            Name:      serviceKey + histogramSuffix,            Help:      "This is the dubbo's histogram metrics",            Buckets:   mc.GetHistogramBucket(),        },        labelNames)}
  • newHistogramVec办法执行prometheus.NewHistogramVec

Report

dubbo-go-v1.4.2/metrics/prometheus/reporter.go

// Report report the duration to Prometheus// the role in url must be consumer or provider// or it will be ignoredfunc (reporter *PrometheusReporter) Report(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation, cost time.Duration, res protocol.Result) {    url := invoker.GetUrl()    var sumVec *prometheus.SummaryVec    var hisVec *prometheus.HistogramVec    if isProvider(url) {        sumVec = reporter.providerSummaryVec        hisVec = reporter.providerHistogramVec    } else if isConsumer(url) {        sumVec = reporter.consumerSummaryVec        hisVec = reporter.consumerHistogramVec    } else {        logger.Warnf("The url is not the consumer's or provider's, "+            "so the invocation will be ignored. url: %s", url.String())        return    }    labels := prometheus.Labels{        serviceKey: url.Service(),        groupKey:   url.GetParam(groupKey, ""),        versionKey: url.GetParam(versionKey, ""),        methodKey:  invocation.MethodName(),        timeoutKey: url.GetParam(timeoutKey, ""),    }    costMs := float64(cost.Nanoseconds() / constant.MsToNanoRate)    sumVec.With(labels).Observe(costMs)    hisVec.With(labels).Observe(costMs)}// whether this url represents the application received the request as serverfunc isProvider(url common.URL) bool {    role := url.GetParam(constant.ROLE_KEY, "")    return strings.EqualFold(role, strconv.Itoa(common.PROVIDER))}// whether this url represents the application sent then request as clientfunc isConsumer(url common.URL) bool {    role := url.GetParam(constant.ROLE_KEY, "")    return strings.EqualFold(role, strconv.Itoa(common.CONSUMER))}
  • Report办法依据url来判断是provider还是consumer,若为provider则获取reporter.providerSummaryVec、reporter.providerHistogramVec;若为consumer则获取reporter.consumerSummaryVec、reporter.consumerHistogramVec;之后设置labels,而后执行sumVec.With(labels).Observe(costMs)及hisVec.With(labels).Observe(costMs)

小结

PrometheusReporter定义了consumerSummaryVec、providerSummaryVec、providerHistogramVec、consumerHistogramVec;Report办法依据url来判断是provider还是consumer,若为provider则获取reporter.providerSummaryVec、reporter.providerHistogramVec;若为consumer则获取reporter.consumerSummaryVec、reporter.consumerHistogramVec;之后设置labels,而后执行sumVec.With(labels).Observe(costMs)及hisVec.With(labels).Observe(costMs)

doc

  • reporter