TUN-528: Move cloudflared into a separate repo

This commit is contained in:
Areg Harutyunyan
2018-05-01 18:45:06 -05:00
parent e8c621a648
commit d06fc520c7
4726 changed files with 1763680 additions and 0 deletions

7
metrics/config.go Normal file
View File

@@ -0,0 +1,7 @@
package metrics
type HistogramConfig struct {
BucketsStart float64
BucketsWidth float64
BucketsCount int
}

72
metrics/metrics.go Normal file
View File

@@ -0,0 +1,72 @@
package metrics
import (
"net"
"net/http"
_ "net/http/pprof"
"runtime"
"sync"
"time"
"golang.org/x/net/context"
"golang.org/x/net/trace"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/sirupsen/logrus"
)
const (
shutdownTimeout = time.Second * 15
startupTime = time.Millisecond * 500
)
func ServeMetrics(l net.Listener, shutdownC <-chan struct{}, logger *logrus.Logger) (err error) {
var wg sync.WaitGroup
// Metrics port is privileged, so no need for further access control
trace.AuthRequest = func(*http.Request) (bool, bool) { return true, true }
// TODO: parameterize ReadTimeout and WriteTimeout. The maximum time we can
// profile CPU usage depends on WriteTimeout
server := &http.Server{
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
}
http.Handle("/metrics", promhttp.Handler())
wg.Add(1)
go func() {
defer wg.Done()
err = server.Serve(l)
}()
logger.WithField("addr", l.Addr()).Info("Starting metrics server")
// server.Serve will hang if server.Shutdown is called before the server is
// fully started up. So add artificial delay.
time.Sleep(startupTime)
<-shutdownC
ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
server.Shutdown(ctx)
cancel()
wg.Wait()
if err == http.ErrServerClosed {
logger.Info("Metrics server stopped")
return nil
}
logger.WithError(err).Error("Metrics server quit with error")
return err
}
func RegisterBuildInfo(buildTime string, version string) {
buildInfo := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
// Don't namespace build_info, since we want it to be consistent across all Cloudflare services
Name: "build_info",
Help: "Build and version information",
},
[]string{"goversion", "revision", "version"},
)
prometheus.MustRegister(buildInfo)
buildInfo.WithLabelValues(runtime.Version(), buildTime, version).Set(1)
}

47
metrics/timer.go Normal file
View File

@@ -0,0 +1,47 @@
package metrics
import (
"time"
"github.com/prometheus/client_golang/prometheus"
)
// Timer assumes the metrics is partitioned by one label
type Timer struct {
startTime map[string]time.Time
metrics *prometheus.HistogramVec
measureUnit time.Duration
labelKey string
}
func NewTimer(metrics *prometheus.HistogramVec, unit time.Duration, labelKey string) *Timer {
return &Timer{
startTime: make(map[string]time.Time),
measureUnit: unit,
metrics: metrics,
labelKey: labelKey,
}
}
func (i *Timer) Start(labelVal string) {
i.startTime[labelVal] = time.Now()
}
func (i *Timer) End(labelVal string) time.Duration {
if start, ok := i.startTime[labelVal]; ok {
return Latency(start, time.Now())
}
return 0
}
func (i *Timer) Observe(measurement time.Duration, labelVal string) {
metricsLabels := prometheus.Labels{i.labelKey: labelVal}
i.metrics.With(metricsLabels).Observe(float64(measurement / i.measureUnit))
}
func (i *Timer) EndAndObserve(labelVal string) {
i.Observe(i.End(labelVal), labelVal)
}
func Latency(startTime, endTime time.Time) time.Duration {
return endTime.Sub(startTime)
}

24
metrics/timer_test.go Normal file
View File

@@ -0,0 +1,24 @@
package metrics
import (
"testing"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/assert"
)
func TestEnd(t *testing.T) {
m := prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: "TestCallLatencyWithoutMeasurement",
Name: "Latency",
Buckets: prometheus.LinearBuckets(0, 50, 100),
},
[]string{"key"},
)
timer := NewTimer(m, time.Millisecond, "key")
assert.Equal(t, time.Duration(0), timer.End("dne"))
timer.Start("test")
assert.NotEqual(t, time.Duration(0), timer.End("test"))
}