github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/util/metric/graphite_exporter.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package metric
    12  
    13  import (
    14  	"context"
    15  	"fmt"
    16  	"os"
    17  	"time"
    18  
    19  	"github.com/cockroachdb/cockroach/pkg/util/log"
    20  	"github.com/cockroachdb/errors"
    21  	"github.com/prometheus/client_golang/prometheus/graphite"
    22  )
    23  
    24  var errNoEndpoint = errors.New("external.graphite.endpoint is not set")
    25  
    26  // GraphiteExporter scrapes PrometheusExporter for metrics and pushes
    27  // them to a Graphite or Carbon server.
    28  type GraphiteExporter struct {
    29  	pm *PrometheusExporter
    30  }
    31  
    32  // MakeGraphiteExporter returns an initialized graphite exporter.
    33  func MakeGraphiteExporter(pm *PrometheusExporter) GraphiteExporter {
    34  	return GraphiteExporter{pm: pm}
    35  }
    36  
    37  type loggerFunc func(...interface{})
    38  
    39  // Println implements graphite.Logger.
    40  func (lf loggerFunc) Println(v ...interface{}) {
    41  	lf(v...)
    42  }
    43  
    44  // Push metrics scraped from registry to Graphite or Carbon server.
    45  // It converts the same metrics that are pulled by Prometheus into Graphite-format.
    46  func (ge *GraphiteExporter) Push(ctx context.Context, endpoint string) error {
    47  	if endpoint == "" {
    48  		return errNoEndpoint
    49  	}
    50  	h, err := os.Hostname()
    51  	if err != nil {
    52  		return err
    53  	}
    54  	// Make the bridge.
    55  	var b *graphite.Bridge
    56  	if b, err = graphite.NewBridge(&graphite.Config{
    57  		URL:           endpoint,
    58  		Gatherer:      ge.pm,
    59  		Prefix:        fmt.Sprintf("%s.cockroach", h),
    60  		Timeout:       10 * time.Second,
    61  		ErrorHandling: graphite.AbortOnError,
    62  		Logger: loggerFunc(func(args ...interface{}) {
    63  			log.InfofDepth(ctx, 1, "", args...)
    64  		}),
    65  	}); err != nil {
    66  		return err
    67  	}
    68  	// Regardless of whether Push() errors, clear metrics. Only latest metrics
    69  	// are pushed. If there is an error, this will cause a gap in receiver. The
    70  	// receiver associates timestamp with when metric arrived, so storing missed
    71  	// metrics has no benefit.
    72  	defer ge.pm.clearMetrics()
    73  	return b.Push()
    74  }