...

Source file src/go.etcd.io/etcd/server/v3/etcdserver/api/v2http/metrics.go

Documentation: go.etcd.io/etcd/server/v3/etcdserver/api/v2http

     1  // Copyright 2015 The etcd Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package v2http
    16  
    17  import (
    18  	"net/http"
    19  	"strconv"
    20  	"time"
    21  
    22  	"go.etcd.io/etcd/api/v3/etcdserverpb"
    23  	"go.etcd.io/etcd/server/v3/etcdserver/api/v2error"
    24  	"go.etcd.io/etcd/server/v3/etcdserver/api/v2http/httptypes"
    25  
    26  	"github.com/prometheus/client_golang/prometheus"
    27  )
    28  
    29  var (
    30  	incomingEvents = prometheus.NewCounterVec(
    31  		prometheus.CounterOpts{
    32  			Namespace: "etcd",
    33  			Subsystem: "http",
    34  			Name:      "received_total",
    35  			Help:      "Counter of requests received into the system (successfully parsed and authd).",
    36  		}, []string{"method"})
    37  
    38  	failedEvents = prometheus.NewCounterVec(
    39  		prometheus.CounterOpts{
    40  			Namespace: "etcd",
    41  			Subsystem: "http",
    42  			Name:      "failed_total",
    43  			Help:      "Counter of handle failures of requests (non-watches), by method (GET/PUT etc.) and code (400, 500 etc.).",
    44  		}, []string{"method", "code"})
    45  
    46  	successfulEventsHandlingSec = prometheus.NewHistogramVec(
    47  		prometheus.HistogramOpts{
    48  			Namespace: "etcd",
    49  			Subsystem: "http",
    50  			Name:      "successful_duration_seconds",
    51  			Help:      "Bucketed histogram of processing time (s) of successfully handled requests (non-watches), by method (GET/PUT etc.).",
    52  
    53  			// lowest bucket start of upper bound 0.0005 sec (0.5 ms) with factor 2
    54  			// highest bucket start of 0.0005 sec * 2^12 == 2.048 sec
    55  			Buckets: prometheus.ExponentialBuckets(0.0005, 2, 13),
    56  		}, []string{"method"})
    57  )
    58  
    59  func init() {
    60  	prometheus.MustRegister(incomingEvents)
    61  	prometheus.MustRegister(failedEvents)
    62  	prometheus.MustRegister(successfulEventsHandlingSec)
    63  }
    64  
    65  func reportRequestReceived(request etcdserverpb.Request) {
    66  	incomingEvents.WithLabelValues(methodFromRequest(request)).Inc()
    67  }
    68  
    69  func reportRequestCompleted(request etcdserverpb.Request, startTime time.Time) {
    70  	method := methodFromRequest(request)
    71  	successfulEventsHandlingSec.WithLabelValues(method).Observe(time.Since(startTime).Seconds())
    72  }
    73  
    74  func reportRequestFailed(request etcdserverpb.Request, err error) {
    75  	method := methodFromRequest(request)
    76  	failedEvents.WithLabelValues(method, strconv.Itoa(codeFromError(err))).Inc()
    77  }
    78  
    79  func methodFromRequest(request etcdserverpb.Request) string {
    80  	if request.Method == "GET" && request.Quorum {
    81  		return "QGET"
    82  	}
    83  	return request.Method
    84  }
    85  
    86  func codeFromError(err error) int {
    87  	if err == nil {
    88  		return http.StatusInternalServerError
    89  	}
    90  	switch e := err.(type) {
    91  	case *v2error.Error:
    92  		return e.StatusCode()
    93  	case *httptypes.HTTPError:
    94  		return e.Code
    95  	default:
    96  		return http.StatusInternalServerError
    97  	}
    98  }
    99  

View as plain text