diff --git a/cmd/cloudflared/macos_service.go b/cmd/cloudflared/macos_service.go index 0424123f..b0ce57b3 100644 --- a/cmd/cloudflared/macos_service.go +++ b/cmd/cloudflared/macos_service.go @@ -61,16 +61,14 @@ var launchdTemplate = ServiceTemplate{ } func installPath(launchAgentIdentifier string) string { - const pathPattern = "%s/Library/LaunchAgents/%s.plist" + pathPattern := "~/Library/LaunchAgents/%s.plist" - pathPrefix := "~" - - // User is root, use /Library instead of home directory + // User is root, use /Library/LaunchDaemons instead of home directory if os.Geteuid() == 0 { - pathPrefix = "" + pathPattern = "/Library/LaunchDaemons/%s.plist" } - return fmt.Sprintf(pathPattern, pathPrefix, launchAgentIdentifier) + return fmt.Sprintf(pathPattern, launchAgentIdentifier) } func installLaunchd(c *cli.Context) error { diff --git a/metrics/config.go b/metrics/config.go new file mode 100644 index 00000000..4891bb0f --- /dev/null +++ b/metrics/config.go @@ -0,0 +1,7 @@ +package metrics + +type HistogramConfig struct { + BucketsStart float64 + BucketsWidth float64 + BucketsCount int +} diff --git a/metrics/timer.go b/metrics/timer.go new file mode 100644 index 00000000..7733e7fc --- /dev/null +++ b/metrics/timer.go @@ -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) +} diff --git a/metrics/timer_test.go b/metrics/timer_test.go new file mode 100644 index 00000000..a800d193 --- /dev/null +++ b/metrics/timer_test.go @@ -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")) +} diff --git a/tunneldns/https_upstream.go b/tunneldns/https_upstream.go index eee448c4..1c681dfc 100644 --- a/tunneldns/https_upstream.go +++ b/tunneldns/https_upstream.go @@ -13,6 +13,7 @@ import ( "github.com/pkg/errors" log "github.com/sirupsen/logrus" "golang.org/x/net/context" + "golang.org/x/net/http2" ) const ( @@ -34,9 +35,16 @@ func NewUpstreamHTTPS(endpoint string) (Upstream, error) { // Update TLS and HTTP client configuration tls := &tls.Config{ServerName: u.Hostname()} + transport := &http.Transport{ + TLSClientConfig: tls, + DisableCompression: true, + MaxIdleConns: 1, + } + http2.ConfigureTransport(transport) + client := &http.Client{ Timeout: time.Second * defaultTimeout, - Transport: &http.Transport{TLSClientConfig: tls}, + Transport: transport, } return &UpstreamHTTPS{client: client, endpoint: u}, nil