From 5ab5cc3e9363a0bb4a00028bb82dd624d505600c Mon Sep 17 00:00:00 2001 From: Rudraksh Pareek Date: Sun, 19 Sep 2021 19:36:39 +0530 Subject: [PATCH 1/3] add ability to transform to fortio output Signed-off-by: Rudraksh Pareek --- go.sum | 13 - pkg/client/transform.go | 449 +++++++++----------------- pkg/proto/fortio.pb.go | 676 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 831 insertions(+), 307 deletions(-) create mode 100644 pkg/proto/fortio.pb.go diff --git a/go.sum b/go.sum index d36f4f2d..c5ff960e 100644 --- a/go.sum +++ b/go.sum @@ -90,7 +90,6 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -161,7 +160,6 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.8 h1:bbmjRkjmP0ZggMoahdNMmJFFnK7v5H+/j5niP5QH6bg= github.com/envoyproxy/go-control-plane v0.9.8/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= @@ -283,7 +281,6 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -370,7 +367,6 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -552,7 +548,6 @@ github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvH github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -585,7 +580,6 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -698,7 +692,6 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -729,7 +722,6 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -751,7 +743,6 @@ golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634 h1:bNEHhJCnrwMKNMmOx3yAynp5vs5/gRy+XWFtZFu7NBM= golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -796,7 +787,6 @@ golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -826,7 +816,6 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200619004808-3e7fca5c55db h1:Q5+mRMPseAnmi+ah5YkFXuVnZqUTgxmQF6e4PnjSkcE= google.golang.org/genproto v0.0.0-20200619004808-3e7fca5c55db/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c h1:Lq4llNryJoaVFRmvrIwC/ZHH7tNt4tUYIu8+se2aayY= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -843,7 +832,6 @@ google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= @@ -855,7 +843,6 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= diff --git a/pkg/client/transform.go b/pkg/client/transform.go index 9d1535bf..842aa878 100644 --- a/pkg/client/transform.go +++ b/pkg/client/transform.go @@ -1,345 +1,206 @@ package nighthawk import ( - "encoding/json" + "errors" "fmt" - "os/exec" - "strconv" - "strings" "time" - v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - "github.com/golang/protobuf/ptypes/duration" - "github.com/golang/protobuf/ptypes/wrappers" - "github.com/layer5io/meshkit/utils" nighthawk_client "github.com/layer5io/nighthawk-go/pkg/proto" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/types/known/durationpb" ) -type Verbosity struct { - Value string `json:"value"` -} +// func Transform transforms nighthawk's json output to fortio compatible json output +// This implementation is adpated from nighthawk's own transformer +// https://github.com/envoyproxy/nighthawk/blob/main/source/client/output_formatter_impl.cc +func Transform(res *nighthawk_client.ExecutionResponse) ([]byte, error) { + resFortio := &nighthawk_client.FortioResult{} -type OutputFormat struct { - Value string `json:"value"` -} + var workers int + if workers = len(res.Output.Results); workers != 1 { + workers = workers - 1 + } + // TODO resFortio.Label + resFortio.Version = res.Output.GetVersion().GetVersion().String() + resFortio.StartTime = res.Output.GetTimestamp() + resFortio.RequestedQPS = uint32(workers) * res.Output.Options.RequestsPerSecond.GetValue() + resFortio.URL = res.Output.Options.GetUri().GetValue() + resFortio.RequestedDuration = durationpb.New(res.Output.Options.GetDuration().AsDuration()) + // actual duration + avgExecutionDuration, err := getAverageExecutionDuration(res) + if err != nil { + return nil, err + } + resFortio.ActualDuration = avgExecutionDuration.Seconds() + // set jitter + hasJitter := false + if jitter := res.Output.Options.GetJitterUniform(); jitter != nil { + hasJitter = true + } + resFortio.Jitter = hasJitter + resFortio.RunType = "HTTP" + resFortio.NumThreads = res.Output.Options.Connections.GetValue() * uint32(workers) + globalResult := getGlobalResult(res) + if globalResult == nil { + return nil, err + } + resFortio.ActualQPS = float64(getCounterValue(globalResult, "upstream_rq_total", 0).GetValue())/resFortio.ActualDuration + resFortio.BytesReceived = getCounterValue(globalResult, "upstream_cx_rx_bytes_total", 0).GetValue() + resFortio.BytesSent = getCounterValue(globalResult, "upstream_cx_tx_bytes_total", 0).GetValue() + mRetCodes := make(map[string]uint64, 1) + mRetCodes["200"] = getCounterValue(globalResult, "benchmark.http_2xx", 0).GetValue() + resFortio.RetCodes = mRetCodes + statistic := findStatistic(globalResult, "benchmark_http_client.request_to_response") + if statistic != nil { + resFortio.DurationHistogram = renderFortioDurationHistogram(statistic) + } + statistic = findStatistic(globalResult, "benchmark_http_client.response_body_size") + if statistic != nil { + resFortio.Sizes = renderFortioDurationHistogram(statistic) + } + statistic = findStatistic(globalResult, "benchmark_http_client.response_header_size") + if statistic != nil { + resFortio.HeaderSizes = renderFortioDurationHistogram(statistic) + } -type AddressFamily struct { - Value string `json:"value"` -} + out, err := protojson.Marshal(resFortio) + if err != nil { + return nil, err + } -type RequestOption struct { - RequestMethod string `json:"request_method"` - RequestHeaders []*v3.HeaderValueOption `json:"request_headers"` + return out, nil } -type SequencerIdleStrategy struct { - Value string `json:"value"` -} +func getAverageExecutionDuration(res *nighthawk_client.ExecutionResponse) (time.Duration, error) { + resultsLen := len(res.Output.Results) + if resultsLen == 0 { + return 0, errors.New("no results found") + } -type ExperimentalH1ConnectionReuseStrategy struct { - Value string `json:"value"` + avgExecutionDuration := res.Output.Results[resultsLen - 1].ExecutionDuration.AsDuration() + return avgExecutionDuration, nil } -type FailurePredicates struct { - BenchmarkPoolConnectionFailure string `json:"benchmark.pool_connection_failure"` - BenchmarkHTTP4Xx string `json:"benchmark.http_4xx"` - BenchmarkHTTP5Xx string `json:"benchmark.http_5xx"` - RequestsourceUpstreamRq5Xx string `json:"requestsource.upstream_rq_5xx"` +func getGlobalResult(res *nighthawk_client.ExecutionResponse) *nighthawk_client.Result { + for _, result := range res.Output.Results { + if result.GetName() == "global" { + return result + } + } + return nil } -type TransformOptions struct { - RequestsPerSecond int `json:"requests_per_second"` - Connections int `json:"connections"` - Duration string `json:"duration"` - Timeout string `json:"timeout"` - H2 bool `json:"h2"` - Concurrency string `json:"concurrency"` - Verbosity *Verbosity `json:"verbosity"` - OutputFormat *OutputFormat `json:"output_format"` - AddressFamily *AddressFamily `json:"address_family"` - RequestOptions *RequestOption `json:"request_options"` - SequencerIdleStrategy *SequencerIdleStrategy `json:"sequencer_idle_strategy"` - ExperimentalH1ConnectionReuseStrategy *ExperimentalH1ConnectionReuseStrategy `json:"experimental_h1_connection_reuse_strategy"` - TerminationPredicates struct { - } `json:"termination_predicates"` - FailurePredicates *FailurePredicates `json:"failure_predicates"` - Labels []interface{} `json:"labels"` - StatsSinks []interface{} `json:"stats_sinks"` - PrefetchConnections bool `json:"prefetch_connections"` - BurstSize *wrappers.UInt32Value `json:"burst_size"` - MaxPendingRequests int `json:"max_pending_requests"` - MaxActiveRequests int `json:"max_active_requests"` - MaxRequestsPerConnection int64 `json:"max_requests_per_connection"` - URI string `json:"uri"` - Trace string `json:"trace"` - OpenLoop bool `json:"open_loop"` - ExperimentalH2UseMultipleConnections bool `json:"experimental_h2_use_multiple_connections"` - NighthawkService string `json:"nighthawk_service"` - SimpleWarmup bool `json:"simple_warmup"` - StatsFlushInterval int `json:"stats_flush_interval"` - LatencyResponseHeaderName string `json:"latency_response_header_name"` +func getCounterValue(result *nighthawk_client.Result, counterName string, zeroValue uint64) *nighthawk_client.Counter { + for _, counter := range result.Counters { + if counter.GetName() == counterName { + return counter + } + } + return &nighthawk_client.Counter{Value: zeroValue} } -type Percentile struct { - Percentile int `json:"percentile"` - Count string `json:"count"` - Duration string `json:"duration"` +func findStatistic(result *nighthawk_client.Result, statID string) *nighthawk_client.Statistic { + for _, stat := range result.Statistics { + if stat.Id == statID { + return stat + } + } + return nil } -type Statistic struct { - Count string `json:"count"` - ID string `json:"id"` - Percentiles []Percentile `json:"percentiles"` - Mean string `json:"mean,omitempty"` - Pstdev string `json:"pstdev,omitempty"` - Min string `json:"min,omitempty"` - Max string `json:"max,omitempty"` - RawMean int `json:"raw_mean,omitempty"` - RawPstdev int `json:"raw_pstdev,omitempty"` - RawMin string `json:"raw_min,omitempty"` - RawMax string `json:"raw_max,omitempty"` -} +func renderFortioDurationHistogram(stat *nighthawk_client.Statistic) *nighthawk_client.DurationHistogram { + fortioHistogram := &nighthawk_client.DurationHistogram{} -type Counter struct { - Name string `json:"name"` - Value string `json:"value"` -} + var prevFortioCount uint64 = 0 + var prevFortioEnd float64 = 0 -type Result struct { - Name string `json:"name"` - Statistics []Statistic `json:"statistics"` - Counters []Counter `json:"counters"` - ExecutionDuration string `json:"execution_duration"` - ExecutionStart time.Time `json:"execution_start"` -} + for i, p := range stat.Percentiles { + dataEntry := &nighthawk_client.DataEntry{} + dataEntry.Percent = (p.GetPercentile() * 100) + dataEntry.Count = p.GetCount() - prevFortioCount -type TransformResult struct { - Options *TransformOptions `json:"options"` - Results []Result `json:"results"` - Version *v3.BuildVersion `json:"version"` - Timestamp string `json:"timestamp"` -} + var value float64 + if d := p.GetDuration(); d != nil { + value = p.GetDuration().AsDuration().Seconds() + } else { + value = p.GetRawValue() + } -func Transform(res *nighthawk_client.ExecutionResponse, typ string) ([]byte, error) { - results, err := constructResults(res) - if err != nil { - return nil, err - } + dataEntry.End = value - expStrategy := res.Output.Options.ExperimentalH1ConnectionReuseStrategy.String() - if expStrategy == "" { - expStrategy = "DEFAULT" - } + // fortioStart = prevFortioEnd + // If this is the first entry, force the start and end time to be the same. + // This prevents it from starting at 0, making it disproportionally big in the UI. + if i++; i == 0 { + prevFortioEnd = value + } + dataEntry.Start = prevFortioEnd - t := TransformResult{ - Version: res.Output.Version, - Timestamp: time.Now().Format(time.RFC3339), - Options: &TransformOptions{ - RequestsPerSecond: int(res.Output.Options.RequestsPerSecond.GetValue()), - Connections: int(res.Output.Options.Connections.GetValue()), - Duration: formatToNs(res.Output.Options.GetDuration()), - Timeout: formatToNs(res.Output.Options.Timeout), - H2: res.Output.Options.H2.Value, - Concurrency: res.Output.Options.Concurrency.Value, - Verbosity: &Verbosity{ - Value: res.Output.Options.Verbosity.Value.String(), - }, - OutputFormat: &OutputFormat{ - Value: res.Output.Options.OutputFormat.Value.String(), - }, - PrefetchConnections: res.Output.Options.PrefetchConnections.Value, - BurstSize: res.Output.Options.BurstSize, - AddressFamily: &AddressFamily{ - Value: res.Output.Options.AddressFamily.Value.String(), - }, - RequestOptions: &RequestOption{ - RequestMethod: res.Output.Options.GetRequestOptions().RequestMethod.String(), - RequestHeaders: res.Output.Options.GetRequestOptions().RequestHeaders, - }, - MaxPendingRequests: res.Output.Options.MaxPendingRequests.ProtoReflect().Descriptor().Index(), - MaxActiveRequests: res.Output.Options.MaxActiveRequests.ProtoReflect().Descriptor().Index(), - MaxRequestsPerConnection: int64(res.Output.Options.MaxRequestsPerConnection.Value), - SequencerIdleStrategy: &SequencerIdleStrategy{ - Value: res.Output.Options.SequencerIdleStrategy.Value.String(), - }, - URI: res.Output.Options.GetUri().Value, - Trace: res.Output.Options.Trace.Value, - ExperimentalH1ConnectionReuseStrategy: &ExperimentalH1ConnectionReuseStrategy{ - Value: expStrategy, - }, - ExperimentalH2UseMultipleConnections: res.Output.Options.ExperimentalH2UseMultipleConnections.Value, - FailurePredicates: &FailurePredicates{ - BenchmarkHTTP4Xx: fmt.Sprint(res.Output.Options.FailurePredicates["benchmark.http_4xx"]), - BenchmarkHTTP5Xx: fmt.Sprint(res.Output.Options.FailurePredicates["benchmark.http_5xx"]), - BenchmarkPoolConnectionFailure: fmt.Sprint(res.Output.Options.FailurePredicates["benchmark.pool_connection_failure"]), - RequestsourceUpstreamRq5Xx: fmt.Sprint(res.Output.Options.FailurePredicates["requestsource.upstream_rq_5xx"]), - }, - OpenLoop: res.Output.Options.OpenLoop.Value, - NighthawkService: res.Output.Options.NighthawkService.Value, - SimpleWarmup: res.Output.Options.SimpleWarmup.Value, - StatsFlushInterval: res.Output.Options.GetStatsFlushInterval().ProtoReflect().Descriptor().Index(), - LatencyResponseHeaderName: res.Output.Options.LatencyResponseHeaderName.Value, - }, - Results: results, - } - input, err := utils.Marshal(t) - if err != nil { - return nil, err + prevFortioCount = p.GetCount() + prevFortioEnd = value + + fortioHistogram.Data = append(fortioHistogram.Data, dataEntry) } - command := "./nighthawk_output_transform" - cmd := exec.Command(command, "--output-format", "fortio") - cmd.Stdin = strings.NewReader(input) - out, err := cmd.Output() - if err != nil { - return nil, err + fortioHistogram.Count = stat.GetCount() + + if mean := stat.GetMean(); mean != nil { + fortioHistogram.Avg = mean.AsDuration().Seconds() + } else { + fortioHistogram.Avg = stat.GetRawMean() } - // Hack due to bug in nighthawk - outputFinal, err := hackFormat(out) - if err != nil { - return nil, err + if min := stat.GetMin(); min != nil { + fortioHistogram.Min = min.AsDuration().Seconds() + } else { + fortioHistogram.Min = float64(stat.GetRawMin()) } - return outputFinal, nil -} + fortioHistogram.Sum = float64(stat.GetCount() * uint64(fortioHistogram.GetAvg())) -func constructResults(res *nighthawk_client.ExecutionResponse) ([]Result, error) { - results := make([]Result, 0) - if res == nil || res.Output == nil { - return nil, ErrResponseNil + if max := stat.GetMax(); max != nil { + fortioHistogram.Max = max.AsDuration().Seconds() + } else { + fortioHistogram.Max = float64(stat.GetRawMax()) } - for _, r := range res.Output.Results { - statistics := make([]Statistic, 0) - counters := make([]Counter, 0) - for _, c := range r.Counters { - counters = append(counters, Counter{ - Name: c.Name, - Value: strconv.Itoa(int(c.Value)), - }) - } - - for _, s := range r.Statistics { - percentiles := make([]Percentile, 0) - for _, p := range s.Percentiles { - percentiles = append(percentiles, Percentile{ - Percentile: int(p.Percentile), - Count: strconv.Itoa(int(p.Count)), - Duration: formatToNs(p.GetDuration()), - }) - } + if pstDev := stat.GetPstdev(); pstDev != nil { + fortioHistogram.StdDev = pstDev.AsDuration().Seconds() + } else { + fortioHistogram.StdDev = stat.GetRawPstdev() + } - sts := Statistic{ - Count: strconv.Itoa(int(s.Count)), - ID: s.Id, - Percentiles: percentiles, - Mean: formatToNs(s.GetMean()), - Pstdev: formatToNs(s.GetPstdev()), - Min: formatToNs(s.GetMin()), - Max: formatToNs(s.GetMax()), - } - if sts.Mean == "" { - sts.RawMean = int(s.GetRawMean()) - } - if sts.Pstdev == "" { - sts.RawPstdev = int(s.GetRawPstdev()) - } - if sts.Min == "" { - sts.RawMin = strconv.Itoa(int(s.GetRawMin())) + iteratePercentiles(fortioHistogram, stat, func (fortioHistogram *nighthawk_client.DurationHistogram, percentile *nighthawk_client.Percentile) { + if percentile.GetPercentile() > 0 && percentile.GetPercentile() < 1 { + p := &nighthawk_client.FortioPercentile{} + p.Percentile = (percentile.Percentile * 1000)/10 + if duration := percentile.GetDuration(); duration != nil { + p.Value = duration.AsDuration().Seconds() + } else { + p.Value = percentile.GetRawValue() } - if sts.Max == "" { - sts.RawMax = strconv.Itoa(int(s.GetRawMax())) - } - statistics = append(statistics, sts) + fortioHistogram.Percentiles = append(fortioHistogram.Percentiles, p) } - results = append(results, Result{ - Name: r.Name, - ExecutionStart: r.ExecutionStart.AsTime(), - ExecutionDuration: formatToNs(r.ExecutionDuration), - Statistics: statistics, - Counters: counters, - }) - } - return results, nil -} + }) -func formatToNs(s *duration.Duration) string { - ss := s.AsDuration().String() - if strings.Contains(ss, "ms") { - sep := strings.Split(ss, "m") - f, _ := strconv.ParseFloat(sep[0], 64) - f /= 1000 - st := fmt.Sprintf("%f", f) - sep[0] = st - ss = strings.Join(sep, "") - } else if strings.Contains(ss, "µs") { - sep := strings.Split(ss, "µ") - f, _ := strconv.ParseFloat(sep[0], 64) - f /= 1000000 - st := fmt.Sprintf("%f", f) - sep[0] = st - ss = strings.Join(sep, "") - } else if strings.Contains(ss, "ns") { - sep := strings.Split(ss, "n") - f, _ := strconv.ParseFloat(sep[0], 64) - f /= 10000000 - st := fmt.Sprintf("%f", f) - sep[0] = st - ss = strings.Join(sep, "") - } - return ss + return fortioHistogram } -func hackFormat(out []byte) ([]byte, error) { - m := map[string]interface{}{} - err := json.Unmarshal(out, &m) - if err != nil { - return nil, err - } +type callback func (*nighthawk_client.DurationHistogram, *nighthawk_client.Percentile) - m["RequestedQPS"] = fmt.Sprint(m["RequestedQPS"].(float64)) - - if m["DurationHistogram"] != nil { - dh, err := strconv.ParseInt(m["DurationHistogram"].(map[string]interface{})["Count"].(string), 10, 64) - if err != nil { - return nil, err - } - m["DurationHistogram"].(map[string]interface{})["Count"] = dh +func iteratePercentiles(fortioHistogram *nighthawk_client.DurationHistogram, stat *nighthawk_client.Statistic, fn callback) { + var lastPercentile float64 = -1 - for _, c := range m["DurationHistogram"].(map[string]interface{})["Data"].([]interface{}) { - h, err := strconv.ParseInt(c.(map[string]interface{})["Count"].(string), 10, 64) - if err != nil { - return nil, err + percentiles := []float64{.0, .5, .75, .8, .9, .95, .99, .999, 1} + for _, p := range percentiles { + for _, percentile := range stat.Percentiles { + if percentile.GetPercentile() >= p && lastPercentile < percentile.GetPercentile() { + lastPercentile = percentile.GetPercentile() + fn(fortioHistogram, percentile) + fmt.Println(fortioHistogram.GetPercentiles()) + break; } - c.(map[string]interface{})["Count"] = h } } - if m["HeaderSizes"] != nil { - h, err := strconv.ParseInt(m["HeaderSizes"].(map[string]interface{})["Count"].(string), 10, 64) - if err != nil { - return nil, err - } - m["HeaderSizes"].(map[string]interface{})["Count"] = h - } - - if m["RetCodes"] != nil { - temp := make(map[int]int64) - for key, val := range m["RetCodes"].(map[string]interface{}) { - k, _ := strconv.Atoi(key) - v, _ := strconv.ParseInt(val.(string), 10, 64) - temp[k] = v - } - m["RetCodes"] = temp - } - - if m["Sizes"] != nil { - h, err := strconv.ParseInt(m["Sizes"].(map[string]interface{})["Count"].(string), 10, 64) - if err != nil { - return nil, err - } - m["Sizes"].(map[string]interface{})["Count"] = h - } - return json.Marshal(m) } diff --git a/pkg/proto/fortio.pb.go b/pkg/proto/fortio.pb.go new file mode 100644 index 00000000..1357fb70 --- /dev/null +++ b/pkg/proto/fortio.pb.go @@ -0,0 +1,676 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.17.3 +// source: api/client/transform/fortio.proto + +package nighthawk_client + +import ( + _ "github.com/envoyproxy/protoc-gen-validate/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + _ "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This proto represents that output format that Fortio expects when converted to JSON. +// Nighthawk can fill in this proto, and then unmarshal to the Fortio-compatible JSON. +// Therefore, this proto may not follow conventions. aip.dev/not-precedent +type FortioResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // From https://github.com/fortio/fortio/wiki/FAQ: + // If using the command line, don't forget to use -a to auto save the json results in the current + // data directory. And to use labels -labels "x y z" so the file name and the json include some + // description of your run. You can later run fortio report to browse + // graphically your results. + // The Nighthawk equivalent of this field is structured as a repeated string, which will be + // concatenated into this field, using ' ' as a separator. + Labels string `protobuf:"bytes,1,opt,name=Labels,proto3" json:"Labels,omitempty"` + // Start time of the load test execution. + StartTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=StartTime,proto3" json:"StartTime,omitempty"` + // Configured qps + RequestedQPS uint32 `protobuf:"varint,3,opt,name=RequestedQPS,proto3" json:"RequestedQPS,omitempty"` + // Configured duration + RequestedDuration *durationpb.Duration `protobuf:"bytes,4,opt,name=RequestedDuration,proto3" json:"RequestedDuration,omitempty"` + // Effective qps + ActualQPS float64 `protobuf:"fixed64,5,opt,name=ActualQPS,proto3" json:"ActualQPS,omitempty"` + // Effective duration + ActualDuration float64 `protobuf:"fixed64,6,opt,name=ActualDuration,proto3" json:"ActualDuration,omitempty"` + // The configured number of used connections + NumThreads uint32 `protobuf:"varint,7,opt,name=NumThreads,proto3" json:"NumThreads,omitempty"` + // Latency histogram + DurationHistogram *DurationHistogram `protobuf:"bytes,8,opt,name=DurationHistogram,proto3" json:"DurationHistogram,omitempty"` + // Fortio tracks per-return-code. We group by 2xx,3xx, etc. + RetCodes map[string]uint64 `protobuf:"bytes,11,rep,name=RetCodes,proto3" json:"RetCodes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + // Effective URI. + URL string `protobuf:"bytes,12,opt,name=URL,proto3" json:"URL,omitempty"` + // (Unstructured) version. We serialize a representation of the Nighthawk version into this field. + Version string `protobuf:"bytes,13,opt,name=Version,proto3" json:"Version,omitempty"` + // Was jitter used Y/N. + Jitter bool `protobuf:"varint,14,opt,name=Jitter,proto3" json:"Jitter,omitempty"` + // Run type. Can be "HTTP", "GRPC", and an empty string has also been observed. + // We only set HTTP for now. + RunType string `protobuf:"bytes,15,opt,name=RunType,proto3" json:"RunType,omitempty"` + // Sizes and HeaderSizes seems to mean different things in Fortio depending on if the go stdclient + // or DIY fastclient was used. We populate this field with response body sizes, and HeaderSizes + // with header sizes. Both are tracked in bytes. Note: we don't use full histograms here, but + // rather rely on StreamingStatistic. This means we don't populate percentiles, and only populate + // min/mean/max/etc with respect to DurationHistogram. + Sizes *DurationHistogram `protobuf:"bytes,16,opt,name=Sizes,proto3" json:"Sizes,omitempty"` + // See the 'Sizes' field for detals. + HeaderSizes *DurationHistogram `protobuf:"bytes,17,opt,name=HeaderSizes,proto3" json:"HeaderSizes,omitempty"` + // Bytes sent should reflect the bytes sent after protocol serialization, compression, and + // encryption are applied (i.e., the size of the buffers passed to the send() system call or its + // equivalent). + BytesSent uint64 `protobuf:"varint,18,opt,name=BytesSent,proto3" json:"BytesSent,omitempty"` + // Bytes received should reflect the bytes read before decryption, de-compression, and protocol + // de-serialization are applied (i.e., the size of bytes read from the recv() system call or its + // equivalent). + BytesReceived uint64 `protobuf:"varint,19,opt,name=BytesReceived,proto3" json:"BytesReceived,omitempty"` +} + +func (x *FortioResult) Reset() { + *x = FortioResult{} + if protoimpl.UnsafeEnabled { + mi := &file_api_client_transform_fortio_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FortioResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FortioResult) ProtoMessage() {} + +func (x *FortioResult) ProtoReflect() protoreflect.Message { + mi := &file_api_client_transform_fortio_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FortioResult.ProtoReflect.Descriptor instead. +func (*FortioResult) Descriptor() ([]byte, []int) { + return file_api_client_transform_fortio_proto_rawDescGZIP(), []int{0} +} + +func (x *FortioResult) GetLabels() string { + if x != nil { + return x.Labels + } + return "" +} + +func (x *FortioResult) GetStartTime() *timestamppb.Timestamp { + if x != nil { + return x.StartTime + } + return nil +} + +func (x *FortioResult) GetRequestedQPS() uint32 { + if x != nil { + return x.RequestedQPS + } + return 0 +} + +func (x *FortioResult) GetRequestedDuration() *durationpb.Duration { + if x != nil { + return x.RequestedDuration + } + return nil +} + +func (x *FortioResult) GetActualQPS() float64 { + if x != nil { + return x.ActualQPS + } + return 0 +} + +func (x *FortioResult) GetActualDuration() float64 { + if x != nil { + return x.ActualDuration + } + return 0 +} + +func (x *FortioResult) GetNumThreads() uint32 { + if x != nil { + return x.NumThreads + } + return 0 +} + +func (x *FortioResult) GetDurationHistogram() *DurationHistogram { + if x != nil { + return x.DurationHistogram + } + return nil +} + +func (x *FortioResult) GetRetCodes() map[string]uint64 { + if x != nil { + return x.RetCodes + } + return nil +} + +func (x *FortioResult) GetURL() string { + if x != nil { + return x.URL + } + return "" +} + +func (x *FortioResult) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *FortioResult) GetJitter() bool { + if x != nil { + return x.Jitter + } + return false +} + +func (x *FortioResult) GetRunType() string { + if x != nil { + return x.RunType + } + return "" +} + +func (x *FortioResult) GetSizes() *DurationHistogram { + if x != nil { + return x.Sizes + } + return nil +} + +func (x *FortioResult) GetHeaderSizes() *DurationHistogram { + if x != nil { + return x.HeaderSizes + } + return nil +} + +func (x *FortioResult) GetBytesSent() uint64 { + if x != nil { + return x.BytesSent + } + return 0 +} + +func (x *FortioResult) GetBytesReceived() uint64 { + if x != nil { + return x.BytesReceived + } + return 0 +} + +type DurationHistogram struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Count uint64 `protobuf:"varint,1,opt,name=Count,proto3" json:"Count,omitempty"` + Data []*DataEntry `protobuf:"bytes,2,rep,name=Data,proto3" json:"Data,omitempty"` + Min float64 `protobuf:"fixed64,3,opt,name=Min,proto3" json:"Min,omitempty"` + Max float64 `protobuf:"fixed64,4,opt,name=Max,proto3" json:"Max,omitempty"` + Sum float64 `protobuf:"fixed64,5,opt,name=Sum,proto3" json:"Sum,omitempty"` + Avg float64 `protobuf:"fixed64,6,opt,name=Avg,proto3" json:"Avg,omitempty"` + StdDev float64 `protobuf:"fixed64,7,opt,name=StdDev,proto3" json:"StdDev,omitempty"` + Percentiles []*FortioPercentile `protobuf:"bytes,8,rep,name=Percentiles,proto3" json:"Percentiles,omitempty"` +} + +func (x *DurationHistogram) Reset() { + *x = DurationHistogram{} + if protoimpl.UnsafeEnabled { + mi := &file_api_client_transform_fortio_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DurationHistogram) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DurationHistogram) ProtoMessage() {} + +func (x *DurationHistogram) ProtoReflect() protoreflect.Message { + mi := &file_api_client_transform_fortio_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DurationHistogram.ProtoReflect.Descriptor instead. +func (*DurationHistogram) Descriptor() ([]byte, []int) { + return file_api_client_transform_fortio_proto_rawDescGZIP(), []int{1} +} + +func (x *DurationHistogram) GetCount() uint64 { + if x != nil { + return x.Count + } + return 0 +} + +func (x *DurationHistogram) GetData() []*DataEntry { + if x != nil { + return x.Data + } + return nil +} + +func (x *DurationHistogram) GetMin() float64 { + if x != nil { + return x.Min + } + return 0 +} + +func (x *DurationHistogram) GetMax() float64 { + if x != nil { + return x.Max + } + return 0 +} + +func (x *DurationHistogram) GetSum() float64 { + if x != nil { + return x.Sum + } + return 0 +} + +func (x *DurationHistogram) GetAvg() float64 { + if x != nil { + return x.Avg + } + return 0 +} + +func (x *DurationHistogram) GetStdDev() float64 { + if x != nil { + return x.StdDev + } + return 0 +} + +func (x *DurationHistogram) GetPercentiles() []*FortioPercentile { + if x != nil { + return x.Percentiles + } + return nil +} + +type DataEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Start float64 `protobuf:"fixed64,1,opt,name=Start,proto3" json:"Start,omitempty"` + End float64 `protobuf:"fixed64,2,opt,name=End,proto3" json:"End,omitempty"` + Percent float64 `protobuf:"fixed64,3,opt,name=Percent,proto3" json:"Percent,omitempty"` + Count uint64 `protobuf:"varint,4,opt,name=Count,proto3" json:"Count,omitempty"` +} + +func (x *DataEntry) Reset() { + *x = DataEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_api_client_transform_fortio_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DataEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataEntry) ProtoMessage() {} + +func (x *DataEntry) ProtoReflect() protoreflect.Message { + mi := &file_api_client_transform_fortio_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataEntry.ProtoReflect.Descriptor instead. +func (*DataEntry) Descriptor() ([]byte, []int) { + return file_api_client_transform_fortio_proto_rawDescGZIP(), []int{2} +} + +func (x *DataEntry) GetStart() float64 { + if x != nil { + return x.Start + } + return 0 +} + +func (x *DataEntry) GetEnd() float64 { + if x != nil { + return x.End + } + return 0 +} + +func (x *DataEntry) GetPercent() float64 { + if x != nil { + return x.Percent + } + return 0 +} + +func (x *DataEntry) GetCount() uint64 { + if x != nil { + return x.Count + } + return 0 +} + +type FortioPercentile struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Percentile float64 `protobuf:"fixed64,1,opt,name=Percentile,proto3" json:"Percentile,omitempty"` + Value float64 `protobuf:"fixed64,2,opt,name=Value,proto3" json:"Value,omitempty"` +} + +func (x *FortioPercentile) Reset() { + *x = FortioPercentile{} + if protoimpl.UnsafeEnabled { + mi := &file_api_client_transform_fortio_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FortioPercentile) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FortioPercentile) ProtoMessage() {} + +func (x *FortioPercentile) ProtoReflect() protoreflect.Message { + mi := &file_api_client_transform_fortio_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FortioPercentile.ProtoReflect.Descriptor instead. +func (*FortioPercentile) Descriptor() ([]byte, []int) { + return file_api_client_transform_fortio_proto_rawDescGZIP(), []int{3} +} + +func (x *FortioPercentile) GetPercentile() float64 { + if x != nil { + return x.Percentile + } + return 0 +} + +func (x *FortioPercentile) GetValue() float64 { + if x != nil { + return x.Value + } + return 0 +} + +var File_api_client_transform_fortio_proto protoreflect.FileDescriptor + +var file_api_client_transform_fortio_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x66, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x68, 0x61, 0x77, 0x6b, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0xb6, 0x06, 0x0a, 0x0c, 0x46, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x51, + 0x50, 0x53, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x65, 0x64, 0x51, 0x50, 0x53, 0x12, 0x47, 0x0a, 0x11, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x65, 0x64, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x1c, 0x0a, 0x09, 0x41, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x51, 0x50, 0x53, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x01, 0x52, 0x09, 0x41, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x51, 0x50, 0x53, 0x12, 0x26, 0x0a, + 0x0e, 0x41, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0e, 0x41, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x4e, 0x75, 0x6d, 0x54, 0x68, 0x72, 0x65, + 0x61, 0x64, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x4e, 0x75, 0x6d, 0x54, 0x68, + 0x72, 0x65, 0x61, 0x64, 0x73, 0x12, 0x51, 0x0a, 0x11, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x68, 0x61, 0x77, 0x6b, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, + 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x11, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, + 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x48, 0x0a, 0x08, 0x52, 0x65, 0x74, 0x43, + 0x6f, 0x64, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6e, 0x69, 0x67, + 0x68, 0x74, 0x68, 0x61, 0x77, 0x6b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x46, 0x6f, + 0x72, 0x74, 0x69, 0x6f, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x52, 0x65, 0x74, 0x43, 0x6f, + 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x52, 0x65, 0x74, 0x43, 0x6f, 0x64, + 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x52, 0x4c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x55, 0x52, 0x4c, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, + 0x0a, 0x06, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, + 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x75, 0x6e, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x52, 0x75, 0x6e, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x39, 0x0a, 0x05, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x68, 0x61, 0x77, 0x6b, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, + 0x67, 0x72, 0x61, 0x6d, 0x52, 0x05, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x0b, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x68, 0x61, 0x77, 0x6b, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, + 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x69, 0x7a, + 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x79, 0x74, 0x65, 0x73, 0x53, 0x65, 0x6e, 0x74, 0x18, + 0x12, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x42, 0x79, 0x74, 0x65, 0x73, 0x53, 0x65, 0x6e, 0x74, + 0x12, 0x24, 0x0a, 0x0d, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x65, + 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x1a, 0x3b, 0x0a, 0x0d, 0x52, 0x65, 0x74, 0x43, 0x6f, 0x64, + 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x3a, 0x03, 0xf8, 0x42, 0x01, 0x22, 0x85, 0x02, 0x0a, 0x11, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x14, + 0x0a, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x68, 0x61, 0x77, 0x6b, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x4d, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x01, 0x52, 0x03, 0x4d, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x4d, 0x61, 0x78, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x4d, 0x61, 0x78, 0x12, 0x10, 0x0a, 0x03, 0x53, 0x75, 0x6d, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x53, 0x75, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x41, + 0x76, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x41, 0x76, 0x67, 0x12, 0x16, 0x0a, + 0x06, 0x53, 0x74, 0x64, 0x44, 0x65, 0x76, 0x18, 0x07, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x53, + 0x74, 0x64, 0x44, 0x65, 0x76, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, + 0x69, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6e, 0x69, 0x67, + 0x68, 0x74, 0x68, 0x61, 0x77, 0x6b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x46, 0x6f, + 0x72, 0x74, 0x69, 0x6f, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x52, 0x0b, + 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x3a, 0x03, 0xf8, 0x42, 0x01, + 0x22, 0x68, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, + 0x52, 0x03, 0x45, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x03, 0xf8, 0x42, 0x01, 0x22, 0x4d, 0x0a, 0x10, 0x46, 0x6f, + 0x72, 0x74, 0x69, 0x6f, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x12, 0x1e, + 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x01, 0x52, 0x0a, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x03, 0xf8, 0x42, 0x01, 0x42, 0x23, 0x5a, 0x21, 0x61, 0x70, 0x69, + 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, + 0x6d, 0x2f, 0x66, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_client_transform_fortio_proto_rawDescOnce sync.Once + file_api_client_transform_fortio_proto_rawDescData = file_api_client_transform_fortio_proto_rawDesc +) + +func file_api_client_transform_fortio_proto_rawDescGZIP() []byte { + file_api_client_transform_fortio_proto_rawDescOnce.Do(func() { + file_api_client_transform_fortio_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_client_transform_fortio_proto_rawDescData) + }) + return file_api_client_transform_fortio_proto_rawDescData +} + +var file_api_client_transform_fortio_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_api_client_transform_fortio_proto_goTypes = []interface{}{ + (*FortioResult)(nil), // 0: nighthawk.client.FortioResult + (*DurationHistogram)(nil), // 1: nighthawk.client.DurationHistogram + (*DataEntry)(nil), // 2: nighthawk.client.DataEntry + (*FortioPercentile)(nil), // 3: nighthawk.client.FortioPercentile + nil, // 4: nighthawk.client.FortioResult.RetCodesEntry + (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp + (*durationpb.Duration)(nil), // 6: google.protobuf.Duration +} +var file_api_client_transform_fortio_proto_depIdxs = []int32{ + 5, // 0: nighthawk.client.FortioResult.StartTime:type_name -> google.protobuf.Timestamp + 6, // 1: nighthawk.client.FortioResult.RequestedDuration:type_name -> google.protobuf.Duration + 1, // 2: nighthawk.client.FortioResult.DurationHistogram:type_name -> nighthawk.client.DurationHistogram + 4, // 3: nighthawk.client.FortioResult.RetCodes:type_name -> nighthawk.client.FortioResult.RetCodesEntry + 1, // 4: nighthawk.client.FortioResult.Sizes:type_name -> nighthawk.client.DurationHistogram + 1, // 5: nighthawk.client.FortioResult.HeaderSizes:type_name -> nighthawk.client.DurationHistogram + 2, // 6: nighthawk.client.DurationHistogram.Data:type_name -> nighthawk.client.DataEntry + 3, // 7: nighthawk.client.DurationHistogram.Percentiles:type_name -> nighthawk.client.FortioPercentile + 8, // [8:8] is the sub-list for method output_type + 8, // [8:8] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name +} + +func init() { file_api_client_transform_fortio_proto_init() } +func file_api_client_transform_fortio_proto_init() { + if File_api_client_transform_fortio_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_client_transform_fortio_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FortioResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_client_transform_fortio_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DurationHistogram); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_client_transform_fortio_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DataEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_client_transform_fortio_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FortioPercentile); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_client_transform_fortio_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_client_transform_fortio_proto_goTypes, + DependencyIndexes: file_api_client_transform_fortio_proto_depIdxs, + MessageInfos: file_api_client_transform_fortio_proto_msgTypes, + }.Build() + File_api_client_transform_fortio_proto = out.File + file_api_client_transform_fortio_proto_rawDesc = nil + file_api_client_transform_fortio_proto_goTypes = nil + file_api_client_transform_fortio_proto_depIdxs = nil +} From cb39acccda79c86bf3c84c25f1b8da40142d6519 Mon Sep 17 00:00:00 2001 From: Rudraksh Pareek Date: Sun, 19 Sep 2021 19:58:13 +0530 Subject: [PATCH 2/3] lint Signed-off-by: Rudraksh Pareek --- pkg/client/transform.go | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/pkg/client/transform.go b/pkg/client/transform.go index 842aa878..9ca2d893 100644 --- a/pkg/client/transform.go +++ b/pkg/client/transform.go @@ -18,7 +18,7 @@ func Transform(res *nighthawk_client.ExecutionResponse) ([]byte, error) { var workers int if workers = len(res.Output.Results); workers != 1 { - workers = workers - 1 + workers-- } // TODO resFortio.Label resFortio.Version = res.Output.GetVersion().GetVersion().String() @@ -44,11 +44,11 @@ func Transform(res *nighthawk_client.ExecutionResponse) ([]byte, error) { if globalResult == nil { return nil, err } - resFortio.ActualQPS = float64(getCounterValue(globalResult, "upstream_rq_total", 0).GetValue())/resFortio.ActualDuration - resFortio.BytesReceived = getCounterValue(globalResult, "upstream_cx_rx_bytes_total", 0).GetValue() - resFortio.BytesSent = getCounterValue(globalResult, "upstream_cx_tx_bytes_total", 0).GetValue() + resFortio.ActualQPS = float64(getCounterValue(globalResult, "upstream_rq_total").GetValue()) / resFortio.ActualDuration + resFortio.BytesReceived = getCounterValue(globalResult, "upstream_cx_rx_bytes_total").GetValue() + resFortio.BytesSent = getCounterValue(globalResult, "upstream_cx_tx_bytes_total").GetValue() mRetCodes := make(map[string]uint64, 1) - mRetCodes["200"] = getCounterValue(globalResult, "benchmark.http_2xx", 0).GetValue() + mRetCodes["200"] = getCounterValue(globalResult, "benchmark.http_2xx").GetValue() resFortio.RetCodes = mRetCodes statistic := findStatistic(globalResult, "benchmark_http_client.request_to_response") if statistic != nil { @@ -77,7 +77,7 @@ func getAverageExecutionDuration(res *nighthawk_client.ExecutionResponse) (time. return 0, errors.New("no results found") } - avgExecutionDuration := res.Output.Results[resultsLen - 1].ExecutionDuration.AsDuration() + avgExecutionDuration := res.Output.Results[resultsLen-1].ExecutionDuration.AsDuration() return avgExecutionDuration, nil } @@ -90,13 +90,13 @@ func getGlobalResult(res *nighthawk_client.ExecutionResponse) *nighthawk_client. return nil } -func getCounterValue(result *nighthawk_client.Result, counterName string, zeroValue uint64) *nighthawk_client.Counter { +func getCounterValue(result *nighthawk_client.Result, counterName string) *nighthawk_client.Counter { for _, counter := range result.Counters { if counter.GetName() == counterName { return counter } } - return &nighthawk_client.Counter{Value: zeroValue} + return &nighthawk_client.Counter{Value: 0} } func findStatistic(result *nighthawk_client.Result, statID string) *nighthawk_client.Statistic { @@ -131,7 +131,8 @@ func renderFortioDurationHistogram(stat *nighthawk_client.Statistic) *nighthawk_ // fortioStart = prevFortioEnd // If this is the first entry, force the start and end time to be the same. // This prevents it from starting at 0, making it disproportionally big in the UI. - if i++; i == 0 { + i++ + if i == 0 { prevFortioEnd = value } dataEntry.Start = prevFortioEnd @@ -170,10 +171,10 @@ func renderFortioDurationHistogram(stat *nighthawk_client.Statistic) *nighthawk_ fortioHistogram.StdDev = stat.GetRawPstdev() } - iteratePercentiles(fortioHistogram, stat, func (fortioHistogram *nighthawk_client.DurationHistogram, percentile *nighthawk_client.Percentile) { + iteratePercentiles(fortioHistogram, stat, func(fortioHistogram *nighthawk_client.DurationHistogram, percentile *nighthawk_client.Percentile) { if percentile.GetPercentile() > 0 && percentile.GetPercentile() < 1 { p := &nighthawk_client.FortioPercentile{} - p.Percentile = (percentile.Percentile * 1000)/10 + p.Percentile = (percentile.Percentile * 1000) / 10 if duration := percentile.GetDuration(); duration != nil { p.Value = duration.AsDuration().Seconds() } else { @@ -186,9 +187,9 @@ func renderFortioDurationHistogram(stat *nighthawk_client.Statistic) *nighthawk_ return fortioHistogram } -type callback func (*nighthawk_client.DurationHistogram, *nighthawk_client.Percentile) +type callback func(*nighthawk_client.DurationHistogram, *nighthawk_client.Percentile) -func iteratePercentiles(fortioHistogram *nighthawk_client.DurationHistogram, stat *nighthawk_client.Statistic, fn callback) { +func iteratePercentiles(fortioHistogram *nighthawk_client.DurationHistogram, stat *nighthawk_client.Statistic, fn callback) { var lastPercentile float64 = -1 percentiles := []float64{.0, .5, .75, .8, .9, .95, .99, .999, 1} @@ -198,7 +199,7 @@ func iteratePercentiles(fortioHistogram *nighthawk_client.DurationHistogram, sta lastPercentile = percentile.GetPercentile() fn(fortioHistogram, percentile) fmt.Println(fortioHistogram.GetPercentiles()) - break; + break } } } From 4d5aa34546357e94aadf5e1e8069a9cd17fba321 Mon Sep 17 00:00:00 2001 From: Rudraksh Pareek Date: Sun, 19 Sep 2021 20:09:25 +0530 Subject: [PATCH 3/3] golangci-lint Signed-off-by: Rudraksh Pareek --- pkg/client/transform.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/client/transform.go b/pkg/client/transform.go index 9ca2d893..29bdcc1e 100644 --- a/pkg/client/transform.go +++ b/pkg/client/transform.go @@ -171,7 +171,8 @@ func renderFortioDurationHistogram(stat *nighthawk_client.Statistic) *nighthawk_ fortioHistogram.StdDev = stat.GetRawPstdev() } - iteratePercentiles(fortioHistogram, stat, func(fortioHistogram *nighthawk_client.DurationHistogram, percentile *nighthawk_client.Percentile) { + iteratePercentiles(fortioHistogram, stat, func(fortioHistogram *nighthawk_client.DurationHistogram, + percentile *nighthawk_client.Percentile) { if percentile.GetPercentile() > 0 && percentile.GetPercentile() < 1 { p := &nighthawk_client.FortioPercentile{} p.Percentile = (percentile.Percentile * 1000) / 10 @@ -203,5 +204,4 @@ func iteratePercentiles(fortioHistogram *nighthawk_client.DurationHistogram, sta } } } - }