diff --git a/CHANGELOG.md b/CHANGELOG.md index f2775c11d..abaefb71c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,11 @@ - GRPC version upgraded to v1.22 [GH-219] +- HTTP Metrics Implementation [GH-220] + - Support HTTP request sizes on client and server side of proxy + - Improved HTTP metrics implementation internals + - The HTTP method label is now `http_method`, and HTTP status label is now `http_status` + ## v0.1.0 ### NEW diff --git a/docs/reference/readme.md b/docs/reference/readme.md index 20e9e803e..f6374ff4f 100644 --- a/docs/reference/readme.md +++ b/docs/reference/readme.md @@ -168,9 +168,11 @@ Name | Type | Description :------------------------------ | :-------- | :-------------------------------------------- http_server_requests_total | Counter | Total HTTP server requests handled by service http_server_response_size_bytes | Histogram | HTTP server response size by service +http_server_request_size_bytes | Histogram | HTTP server request size by service http_server_request_duration_ms | Histogram | HTTP server request duration by service http_client_requests_total | Counter | Total HTTP client requests made by service http_client_response_size_bytes | Histogram | HTTP client response size by service +http_client_request_size_bytes | Histogram | HTTP client request size by service http_client_request_duration_ms | Histogram | HTTP client request duration by service grpc_client_requests_total | Counter | Total GRPC client requests made by service grpc_client_response_size_bytes | Histogram | GRPC client response size by service diff --git a/internal/metrics/helpers_test.go b/internal/metrics/helpers_test.go index 7171da858..28a2cf2fa 100644 --- a/internal/metrics/helpers_test.go +++ b/internal/metrics/helpers_test.go @@ -18,7 +18,7 @@ func testDataRetrieval(v *view.View, t *testing.T, want string) { t.Fatalf("%s: failed to retrieve data line %s", name, err) } if len(data) != 1 { - t.Errorf("%s: received too many data rows: %d", name, len(data)) + t.Fatalf("%s: received incorrect number of data rows: %d", name, len(data)) } if !strings.HasPrefix(data[0].String(), want) { diff --git a/internal/metrics/middleware.go b/internal/metrics/middleware.go index cd6b8cc9e..655e6e70a 100644 --- a/internal/metrics/middleware.go +++ b/internal/metrics/middleware.go @@ -1,99 +1,105 @@ package metrics // import "github.com/pomerium/pomerium/internal/metrics" import ( - "context" "net/http" - "strconv" - "time" + + "go.opencensus.io/plugin/ochttp" "github.com/pomerium/pomerium/internal/log" - "github.com/pomerium/pomerium/internal/middleware/responsewriter" "github.com/pomerium/pomerium/internal/tripper" - "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" ) var ( - httpServerRequestCount = stats.Int64("http_server_requests_total", "Total HTTP Requests", "1") - httpServerResponseSize = stats.Int64("http_server_response_size_bytes", "HTTP Server Response Size in bytes", "bytes") - httpServerRequestDuration = stats.Int64("http_server_request_duration_ms", "HTTP Request duration in ms", "ms") + httpSizeDistribution = view.Distribution( + 1, 256, 512, 1024, 2048, 8192, 16384, 32768, 65536, 131072, 262144, 524288, + 1048576, 2097152, 4194304, 8388608, + ) - httpClientRequestCount = stats.Int64("http_client_requests_total", "Total HTTP Client Requests", "1") - httpClientResponseSize = stats.Int64("http_client_response_size_bytes", "HTTP Client Response Size in bytes", "bytes") - httpClientRequestDuration = stats.Int64("http_client_request_duration_ms", "HTTP Client Request duration in ms", "ms") + httpLatencyDistrubtion = view.Distribution( + 1, 2, 5, 7, 10, 25, 500, 750, + 100, 250, 500, 750, + 1000, 2500, 5000, 7500, + 10000, 25000, 50000, 75000, + 100000, + ) + + // httpClientRequestCount = stats.Int64("http_client_requests_total", "Total HTTP Client Requests", "1") + // httpClientResponseSize = stats.Int64("http_client_response_size_bytes", "HTTP Client Response Size in bytes", "bytes") + // httpClientRequestDuration = stats.Int64("http_client_request_duration_ms", "HTTP Client Request duration in ms", "ms") // HTTPServerRequestCountView is an OpenCensus View that tracks HTTP server requests by pomerium service, host, method and status HTTPServerRequestCountView = &view.View{ - Name: httpServerRequestCount.Name(), - Measure: httpServerRequestCount, - Description: httpServerRequestCount.Description(), - TagKeys: []tag.Key{keyService, keyHost, keyMethod, keyStatus}, + Name: "http_server_requests_total", + Measure: ochttp.ServerLatency, + Description: "Total HTTP Requests", + TagKeys: []tag.Key{keyService, keyHost, keyHTTPMethod, ochttp.StatusCode}, Aggregation: view.Count(), } // HTTPServerRequestDurationView is an OpenCensus view that tracks HTTP server request duration by pomerium service, host, method and status HTTPServerRequestDurationView = &view.View{ - Name: httpServerRequestDuration.Name(), - Measure: httpServerRequestDuration, - Description: httpServerRequestDuration.Description(), - TagKeys: []tag.Key{keyService, keyHost, keyMethod, keyStatus}, - Aggregation: view.Distribution( - 1, 2, 5, 7, 10, 25, 500, 750, - 100, 250, 500, 750, - 1000, 2500, 5000, 7500, - 10000, 25000, 50000, 75000, - 100000, - ), + Name: "http_server_request_duration_ms", + Measure: ochttp.ServerLatency, + Description: "HTTP Request duration in ms", + TagKeys: []tag.Key{keyService, keyHost, keyHTTPMethod, ochttp.StatusCode}, + Aggregation: httpLatencyDistrubtion, } - // HTTPServerRequestSizeView is an OpenCensus view that tracks HTTP server request duration by pomerium service, host, method and status + // HTTPServerRequestSizeView is an OpenCensus view that tracks HTTP server request size by pomerium service, host and method HTTPServerRequestSizeView = &view.View{ - Name: httpServerResponseSize.Name(), - Measure: httpServerResponseSize, - Description: httpServerResponseSize.Description(), - TagKeys: []tag.Key{keyService, keyHost, keyMethod, keyStatus}, - Aggregation: view.Distribution( - 1, 256, 512, 1024, 2048, 8192, 16384, 32768, 65536, 131072, 262144, 524288, - 1048576, 2097152, 4194304, 8388608, - ), + Name: "http_server_request_size_bytes", + Measure: ochttp.ServerRequestBytes, + Description: "HTTP Server Request Size in bytes", + TagKeys: []tag.Key{keyService, keyHost, keyHTTPMethod}, + Aggregation: httpSizeDistribution, } - // HTTPClientRequestCountView is an OpenCensus View that tracks HTTP client requests by pomerium service, host, method and status + // HTTPServerResponseSizeView is an OpenCensus view that tracks HTTP server response size by pomerium service, host, method and status + HTTPServerResponseSizeView = &view.View{ + Name: "http_server_response_size_bytes", + Measure: ochttp.ServerResponseBytes, + Description: "HTTP Server Response Size in bytes", + TagKeys: []tag.Key{keyService, keyHost, keyHTTPMethod, ochttp.StatusCode}, + Aggregation: httpSizeDistribution, + } + + // HTTPClientRequestCountView is an OpenCensus View that tracks HTTP client requests by pomerium service, destination, host, method and status HTTPClientRequestCountView = &view.View{ - Name: httpClientRequestCount.Name(), - Measure: httpClientRequestCount, - Description: httpClientRequestCount.Description(), - TagKeys: []tag.Key{keyService, keyHost, keyMethod, keyStatus}, + Name: "http_client_requests_total", + Measure: ochttp.ClientLatency, + Description: "Total HTTP Client Requests", + TagKeys: []tag.Key{keyService, keyHost, keyHTTPMethod, ochttp.StatusCode, keyDestination}, Aggregation: view.Count(), } - // HTTPClientRequestDurationView is an OpenCensus view that tracks HTTP client request duration by pomerium service, host, method and status + // HTTPClientRequestDurationView is an OpenCensus view that tracks HTTP client request duration by pomerium service, destination, host, method and status HTTPClientRequestDurationView = &view.View{ - Name: httpClientRequestDuration.Name(), - Measure: httpClientRequestDuration, - Description: httpClientRequestDuration.Description(), - TagKeys: []tag.Key{keyService, keyHost, keyMethod, keyStatus}, - Aggregation: view.Distribution( - 1, 2, 5, 7, 10, 25, 500, 750, - 100, 250, 500, 750, - 1000, 2500, 5000, 7500, - 10000, 25000, 50000, 75000, - 100000, - ), + Name: "http_client_request_duration_ms", + Measure: ochttp.ClientRoundtripLatency, + Description: "HTTP Client Request duration in ms", + TagKeys: []tag.Key{keyService, keyHost, keyHTTPMethod, ochttp.StatusCode, keyDestination}, + Aggregation: httpLatencyDistrubtion, } - // HTTPClientResponseSizeView is an OpenCensus view that tracks HTTP client response size by pomerium service, host, method and status + // HTTPClientResponseSizeView is an OpenCensus view that tracks HTTP client response size by pomerium service, destination, host, method and status HTTPClientResponseSizeView = &view.View{ - Name: httpClientResponseSize.Name(), - Measure: httpClientResponseSize, - Description: httpClientResponseSize.Description(), - TagKeys: []tag.Key{keyService, keyHost, keyMethod, keyStatus}, - Aggregation: view.Distribution( - 1, 256, 512, 1024, 2048, 8192, 16384, 32768, 65536, 131072, 262144, 524288, - 1048576, 2097152, 4194304, 8388608, - ), + Name: "http_client_response_size_bytes", + Measure: ochttp.ClientReceivedBytes, + Description: "HTTP Client Response Size in bytes", + TagKeys: []tag.Key{keyService, keyHost, keyHTTPMethod, ochttp.StatusCode, keyDestination}, + Aggregation: httpSizeDistribution, + } + + // HTTPClientRequestSizeView is an OpenCensus view that tracks HTTP client request size by pomerium service, destination, host and method + HTTPClientRequestSizeView = &view.View{ + Name: "http_client_response_size_bytes", + Measure: ochttp.ClientSentBytes, + Description: "HTTP Client Response Size in bytes", + TagKeys: []tag.Key{keyService, keyHost, keyHTTPMethod, keyDestination}, + Aggregation: httpSizeDistribution, } ) @@ -102,61 +108,44 @@ func HTTPMetricsHandler(service string) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - startTime := time.Now() - m := responsewriter.NewWrapResponseWriter(w, 1) - - next.ServeHTTP(m, r) - ctx, tagErr := tag.New( - context.Background(), + r.Context(), tag.Insert(keyService, service), tag.Insert(keyHost, r.Host), - tag.Insert(keyMethod, r.Method), - tag.Insert(keyStatus, strconv.Itoa(m.Status())), + tag.Insert(keyHTTPMethod, r.Method), ) - if tagErr != nil { - log.Warn().Err(tagErr).Str("context", "HTTPMetricsHandler").Msg("Failed to create metrics context tag") - } else { - stats.Record(ctx, - httpServerRequestCount.M(1), - httpServerRequestDuration.M(time.Since(startTime).Nanoseconds()/int64(time.Millisecond)), - httpServerResponseSize.M(int64(m.BytesWritten())), - ) + log.Warn().Err(tagErr).Str("context", "HTTPMetricsHandler").Msg("internal/metrics: Failed to create metrics context tag") + next.ServeHTTP(w, r) + return } + + ocHandler := ochttp.Handler{Handler: next} + ocHandler.ServeHTTP(w, r.WithContext(ctx)) }) } } // HTTPMetricsRoundTripper creates a metrics tracking tripper for outbound HTTP Requests -func HTTPMetricsRoundTripper(service string) func(next http.RoundTripper) http.RoundTripper { - +func HTTPMetricsRoundTripper(service string, destination string) func(next http.RoundTripper) http.RoundTripper { return func(next http.RoundTripper) http.RoundTripper { return tripper.RoundTripperFunc(func(r *http.Request) (*http.Response, error) { - startTime := time.Now() - resp, err := next.RoundTrip(r) + ctx, tagErr := tag.New( + r.Context(), + tag.Insert(keyService, service), + tag.Insert(keyHost, r.Host), + tag.Insert(keyHTTPMethod, r.Method), + tag.Insert(keyDestination, destination), + ) - if resp != nil && err == nil { - ctx, tagErr := tag.New( - context.Background(), - tag.Insert(keyService, service), - tag.Insert(keyHost, r.Host), - tag.Insert(keyMethod, r.Method), - tag.Insert(keyStatus, strconv.Itoa(resp.StatusCode)), - ) - - if tagErr != nil { - log.Warn().Err(tagErr).Str("context", "HTTPMetricsRoundTripper").Msg("Failed to create context tag") - } else { - stats.Record(ctx, - httpClientRequestCount.M(1), - httpClientRequestDuration.M(time.Since(startTime).Nanoseconds()/int64(time.Millisecond)), - httpClientResponseSize.M(resp.ContentLength), - ) - } + if tagErr != nil { + log.Warn().Err(tagErr).Str("context", "HTTPMetricsRoundTripper").Msg("internal/metrics: Failed to create context tag") + return next.RoundTrip(r) } - return resp, err + + ocTransport := ochttp.Transport{Base: next} + return ocTransport.RoundTrip(r.WithContext(ctx)) }) } } diff --git a/internal/metrics/middleware_test.go b/internal/metrics/middleware_test.go index 1454d953d..e13e9eca9 100644 --- a/internal/metrics/middleware_test.go +++ b/internal/metrics/middleware_test.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "fmt" + "io/ioutil" "net/http" "net/http/httptest" "testing" @@ -32,6 +33,7 @@ func Test_HTTPMetricsHandler(t *testing.T) { name string url string verb string + wanthttpServerRequestSize string wanthttpServerResponseSize string wanthttpServerRequestDuration string wanthttpServerRequestCount string @@ -40,37 +42,41 @@ func Test_HTTPMetricsHandler(t *testing.T) { name: "good get", url: "http://test.local/good", verb: "GET", - wanthttpServerResponseSize: "{ { {host test.local}{method GET}{service test_service}{status 200} }&{1 5 5 5 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", - wanthttpServerRequestDuration: "{ { {host test.local}{method GET}{service test_service}{status 200} }&{1", - wanthttpServerRequestCount: "{ { {host test.local}{method GET}{service test_service}{status 200} }&{1", + wanthttpServerRequestSize: "{ { {host test.local}{http_method GET}{service test_service} }&{1 0 5e-324 0 0 [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", + wanthttpServerResponseSize: "{ { {host test.local}{http.status 200}{http_method GET}{service test_service} }&{1 5 5 5 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", + wanthttpServerRequestDuration: "{ { {host test.local}{http.status 200}{http_method GET}{service test_service} }&{1", + wanthttpServerRequestCount: "{ { {host test.local}{http.status 200}{http_method GET}{service test_service} }&{1", }, { name: "good post", url: "http://test.local/good", verb: "POST", - wanthttpServerResponseSize: "{ { {host test.local}{method POST}{service test_service}{status 200} }&{1 5 5 5 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", - wanthttpServerRequestDuration: "{ { {host test.local}{method POST}{service test_service}{status 200} }&{1", - wanthttpServerRequestCount: "{ { {host test.local}{method POST}{service test_service}{status 200} }&{1", + wanthttpServerRequestSize: "{ { {host test.local}{http_method POST}{service test_service} }&{1 0 5e-324 0 0 [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", + wanthttpServerResponseSize: "{ { {host test.local}{http.status 200}{http_method POST}{service test_service} }&{1 5 5 5 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", + wanthttpServerRequestDuration: "{ { {host test.local}{http.status 200}{http_method POST}{service test_service} }&{1", + wanthttpServerRequestCount: "{ { {host test.local}{http.status 200}{http_method POST}{service test_service} }&{1", }, { name: "bad post", url: "http://test.local/bad", verb: "POST", - wanthttpServerResponseSize: "{ { {host test.local}{method POST}{service test_service}{status 404} }&{1 19 19 19 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", - wanthttpServerRequestDuration: "{ { {host test.local}{method POST}{service test_service}{status 404} }&{1", - wanthttpServerRequestCount: "{ { {host test.local}{method POST}{service test_service}{status 404} }&{1", + wanthttpServerRequestSize: "{ { {host test.local}{http_method POST}{service test_service} }&{1 0 5e-324 0 0 [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", + wanthttpServerResponseSize: "{ { {host test.local}{http.status 404}{http_method POST}{service test_service} }&{1 19 19 19 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", + wanthttpServerRequestDuration: "{ { {host test.local}{http.status 404}{http_method POST}{service test_service} }&{1", + wanthttpServerRequestCount: "{ { {host test.local}{http.status 404}{http_method POST}{service test_service} }&{1", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - view.Unregister(HTTPServerRequestCountView, HTTPServerRequestDurationView, HTTPServerRequestSizeView) - view.Register(HTTPServerRequestCountView, HTTPServerRequestDurationView, HTTPServerRequestSizeView) + view.Unregister(HTTPServerRequestCountView, HTTPServerRequestDurationView, HTTPServerRequestSizeView, HTTPServerResponseSizeView) + view.Register(HTTPServerRequestCountView, HTTPServerRequestDurationView, HTTPServerRequestSizeView, HTTPServerResponseSizeView) req := httptest.NewRequest(tt.verb, tt.url, new(bytes.Buffer)) rec := httptest.NewRecorder() chainHandler.ServeHTTP(rec, req) - testDataRetrieval(HTTPServerRequestSizeView, t, tt.wanthttpServerResponseSize) + testDataRetrieval(HTTPServerRequestSizeView, t, tt.wanthttpServerRequestSize) + testDataRetrieval(HTTPServerResponseSizeView, t, tt.wanthttpServerResponseSize) testDataRetrieval(HTTPServerRequestDurationView, t, tt.wanthttpServerRequestDuration) testDataRetrieval(HTTPServerRequestCountView, t, tt.wanthttpServerRequestCount) }) @@ -98,7 +104,7 @@ func newFailingTestTransport() http.RoundTripper { } func Test_HTTPMetricsRoundTripper(t *testing.T) { - chain := tripper.NewChain(HTTPMetricsRoundTripper("test_service")) + chain := tripper.NewChain(HTTPMetricsRoundTripper("test_service", "test_destination")) rt := chain.Then(newTestTransport()) client := http.Client{Transport: rt} @@ -106,6 +112,7 @@ func Test_HTTPMetricsRoundTripper(t *testing.T) { name string url string verb string + wanthttpClientRequestSize string wanthttpClientResponseSize string wanthttpClientRequestDuration string wanthttpClientRequestCount string @@ -114,36 +121,42 @@ func Test_HTTPMetricsRoundTripper(t *testing.T) { name: "good get", url: "http://test.local/good", verb: "GET", - wanthttpClientResponseSize: "{ { {host test.local}{method GET}{service test_service}{status 200} }&{1 5 5 5 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", - wanthttpClientRequestDuration: "{ { {host test.local}{method GET}{service test_service}{status 200} }&{1", - wanthttpClientRequestCount: "{ { {host test.local}{method GET}{service test_service}{status 200} }&{1", + wanthttpClientRequestSize: "{ { {destination test_destination}{host test.local}{http.status 200}{http_method GET}{service test_service} }&{1 5 5 5 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", + wanthttpClientResponseSize: "{ { {destination test_destination}{host test.local}{http.status 200}{http_method GET}{service test_service} }&{1 5 5 5 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", + wanthttpClientRequestDuration: "{ { {destination test_destination}{host test.local}{http.status 200}{http_method GET}{service test_service} }&{1", + wanthttpClientRequestCount: "{ { {destination test_destination}{host test.local}{http.status 200}{http_method GET}{service test_service} }&{1", }, { name: "good post", url: "http://test.local/good", verb: "POST", - wanthttpClientResponseSize: "{ { {host test.local}{method POST}{service test_service}{status 200} }&{1 5 5 5 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", - wanthttpClientRequestDuration: "{ { {host test.local}{method POST}{service test_service}{status 200} }&{1", - wanthttpClientRequestCount: "{ { {host test.local}{method POST}{service test_service}{status 200} }&{1", + wanthttpClientRequestSize: "{ { {destination test_destination}{host test.local}{http.status 200}{http_method POST}{service test_service} }&{1 5 5 5 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", + wanthttpClientResponseSize: "{ { {destination test_destination}{host test.local}{http.status 200}{http_method POST}{service test_service} }&{1 5 5 5 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", + wanthttpClientRequestDuration: "{ { {destination test_destination}{host test.local}{http.status 200}{http_method POST}{service test_service} }&{1", + wanthttpClientRequestCount: "{ { {destination test_destination}{host test.local}{http.status 200}{http_method POST}{service test_service} }&{1", }, { name: "bad post", url: "http://test.local/bad", verb: "POST", - wanthttpClientResponseSize: "{ { {host test.local}{method POST}{service test_service}{status 404} }&{1 19 19 19 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", - wanthttpClientRequestDuration: "{ { {host test.local}{method POST}{service test_service}{status 404} }&{1", - wanthttpClientRequestCount: "{ { {host test.local}{method POST}{service test_service}{status 404} }&{1", + wanthttpClientRequestSize: "{ { {destination test_destination}{host test.local}{http.status 404}{http_method POST}{service test_service} }&{1 19 19 19 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", + wanthttpClientResponseSize: "{ { {destination test_destination}{host test.local}{http.status 404}{http_method POST}{service test_service} }&{1 19 19 19 0 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]", + wanthttpClientRequestDuration: "{ { {destination test_destination}{host test.local}{http.status 404}{http_method POST}{service test_service} }&{1", + wanthttpClientRequestCount: "{ { {destination test_destination}{host test.local}{http.status 404}{http_method POST}{service test_service} }&{1", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - view.Unregister(HTTPClientRequestCountView, HTTPClientRequestDurationView, HTTPClientResponseSizeView) - view.Register(HTTPClientRequestCountView, HTTPClientRequestDurationView, HTTPClientResponseSizeView) + view.Unregister(HTTPClientRequestCountView, HTTPClientRequestDurationView, HTTPClientResponseSizeView, HTTPClientRequestSizeView) + view.Register(HTTPClientRequestCountView, HTTPClientRequestDurationView, HTTPClientResponseSizeView, HTTPClientRequestSizeView) req, _ := http.NewRequest(tt.verb, tt.url, new(bytes.Buffer)) resp, err := client.Do(req) + // must be done to record() + ioutil.ReadAll(resp.Body) - t.Logf("response: %#v, %#v", resp, err) + t.Logf("response: %#v, %#v\n\n", resp, err) + testDataRetrieval(HTTPClientRequestSizeView, t, tt.wanthttpClientRequestSize) testDataRetrieval(HTTPClientResponseSizeView, t, tt.wanthttpClientResponseSize) testDataRetrieval(HTTPClientRequestDurationView, t, tt.wanthttpClientRequestDuration) testDataRetrieval(HTTPClientRequestCountView, t, tt.wanthttpClientRequestCount) diff --git a/internal/metrics/tags.go b/internal/metrics/tags.go index e68f1fa58..bd4ffae55 100644 --- a/internal/metrics/tags.go +++ b/internal/metrics/tags.go @@ -5,10 +5,11 @@ import ( ) var ( - keyMethod tag.Key = tag.MustNewKey("method") + keyHTTPMethod tag.Key = tag.MustNewKey("http_method") keyStatus tag.Key = tag.MustNewKey("status") keyService tag.Key = tag.MustNewKey("service") keyGRPCService tag.Key = tag.MustNewKey("grpc_service") keyGRPCMethod tag.Key = tag.MustNewKey("grpc_method") keyHost tag.Key = tag.MustNewKey("host") + keyDestination tag.Key = tag.MustNewKey("destination") ) diff --git a/internal/metrics/view.go b/internal/metrics/view.go index 23914eab3..24d26fc1f 100644 --- a/internal/metrics/view.go +++ b/internal/metrics/view.go @@ -9,7 +9,7 @@ var ( // HTTPClientViews contains opencensus views for HTTP Client metrics HTTPClientViews = []*view.View{HTTPClientRequestCountView, HTTPClientRequestDurationView, HTTPClientResponseSizeView} // HTTPServerViews contains opencensus views for HTTP Server metrics - HTTPServerViews = []*view.View{HTTPServerRequestCountView, HTTPServerRequestDurationView, HTTPServerRequestSizeView} + HTTPServerViews = []*view.View{HTTPServerRequestCountView, HTTPServerRequestDurationView, HTTPServerRequestSizeView, HTTPServerResponseSizeView} // GRPCClientViews contains opencensus views for GRPC Client metrics GRPCClientViews = []*view.View{GRPCClientRequestCountView, GRPCClientRequestDurationView, GRPCClientResponseSizeView, GRPCClientRequestSizeView} // GRPCServerViews contains opencensus views for GRPC Server metrics diff --git a/proxy/proxy.go b/proxy/proxy.go index 75ed590e2..cadd85c22 100755 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -200,7 +200,7 @@ func (p *Proxy) UpdatePolicies(opts *config.Options) error { // https://github.com/golang/go/issues/26013#issuecomment-399481302 transport := *(http.DefaultTransport.(*http.Transport)) c := tripper.NewChain() - c = c.Append(metrics.HTTPMetricsRoundTripper("proxy")) + c = c.Append(metrics.HTTPMetricsRoundTripper("proxy", policy.Destination.Host)) if policy.TLSSkipVerify { transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} }