Skip to content

Commit

Permalink
etcdserver: add server range duration metrics\n Signed-off-by: Daniel…
Browse files Browse the repository at this point in the history
… Tripp <thedtripp@github.com>

Signed-off-by: Daniel Tripp <38776199+thedtripp@users.noreply.github.com>
  • Loading branch information
thedtripp committed May 11, 2024
1 parent 58a71a2 commit fd4e82e
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
16 changes: 16 additions & 0 deletions server/etcdserver/txn/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,29 @@ var (
Buckets: prometheus.ExponentialBuckets(0.0001, 2, 20),
},
[]string{"version", "op", "success"})
rangeSec = prometheus.NewHistogramVec(prometheus.HistogramOpts{
Namespace: "etcd",
Subsystem: "server",
Name: "range_duration_seconds",
Help: "The latency distributions of txn.Range",

// lowest bucket start of upper bound 0.0001 sec (0.1 ms) with factor 2
// highest bucket start of 0.0001 sec * 2^19 == 52.4288 sec
Buckets: prometheus.ExponentialBuckets(0.0001, 2, 20),
},
[]string{"op", "success"})
)

func ApplySecObserve(version, op string, success bool, latency time.Duration) {
applySec.WithLabelValues(version, op, strconv.FormatBool(success)).Observe(float64(latency.Microseconds()) / 1000000.0)
}

func RangeSecObserve(op string, success bool, latency time.Duration) {
rangeSec.WithLabelValues(op, strconv.FormatBool(success)).Observe(float64(latency.Microseconds()) / 1000000.0)
}

func init() {
prometheus.MustRegister(applySec)
prometheus.MustRegister(rangeSec)
prometheus.MustRegister(slowApplies)
}
61 changes: 61 additions & 0 deletions server/etcdserver/txn/metrics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2022 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package txn

import (
"strings"
"testing"
"time"

"github.com/prometheus/client_golang/prometheus/testutil"
)

func TestRangeSecObserve(t *testing.T) {
// Simulate a range operation taking 500 milliseconds.
latency := 500 * time.Millisecond
RangeSecObserve("range", true, latency)

// Use testutil to collect the results and check against expected value
expected := `
# HELP etcd_server_range_duration_seconds The latency distributions of txn.Range
# TYPE etcd_server_range_duration_seconds histogram
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.0001"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.0002"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.0004"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.0008"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.0016"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.0032"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.0064"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.0128"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.0256"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.0512"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.1024"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.2048"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.4096"} 0
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="0.8192"} 1
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="1.6384"} 1
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="3.2768"} 1
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="6.5536"} 1
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="13.1072"} 1
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="26.2144"} 1
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="52.4288"} 1
etcd_server_range_duration_seconds_bucket{op="range",success="true",le="+Inf"} 1
etcd_server_range_duration_seconds_sum{op="range",success="true"} 0.5
etcd_server_range_duration_seconds_count{op="range",success="true"} 1
`
if err := testutil.CollectAndCompare(rangeSec, strings.NewReader(expected)); err != nil {
t.Errorf("Collected metrics did not match expected metrics: %v", err)
}
}
6 changes: 6 additions & 0 deletions server/etcdserver/txn/txn.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"context"
"fmt"
"sort"
"time"

"go.uber.org/zap"

Expand Down Expand Up @@ -138,6 +139,11 @@ func Range(ctx context.Context, lg *zap.Logger, kv mvcc.KV, r *pb.RangeRequest)
trace = traceutil.New("range", lg)
ctx = context.WithValue(ctx, traceutil.TraceKey{}, trace)
}
op := "range"
defer func(start time.Time) {
success := err == nil
RangeSecObserve(op, success, time.Since(start))
}(time.Now())
txnRead := kv.Read(mvcc.ConcurrentReadTxMode, trace)
defer txnRead.End()
resp, err = executeRange(ctx, lg, txnRead, r)
Expand Down

0 comments on commit fd4e82e

Please sign in to comment.