mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-10 07:37:33 +02:00
telemetry: add tracing
- telemetry/tace: add traces throughout code - telemetry/metrics: nest metrics and trace under telemetry - telemetry/tace: add service name span to HTTPMetricsHandler. - telemetry/metrics: removed chain dependency middleware_tests. - telemetry/metrics: wrap and encapsulate variatic view registration. - telemetry/tace: add jaeger support for tracing. - cmd/pomerium: move `parseOptions` to internal/config. - cmd/pomerium: offload server handling to httputil and sub pkgs. - httputil: standardize creation/shutdown of http listeners. - httputil: prefer curve X25519 to P256 when negotiating TLS. - fileutil: use standardized Getw Signed-off-by: Bobby DeSimone <bobbydesimone@gmail.com>
This commit is contained in:
parent
6b61a48fce
commit
5edfa7b03f
49 changed files with 1524 additions and 758 deletions
184
internal/telemetry/metrics/grpc_test.go
Normal file
184
internal/telemetry/metrics/grpc_test.go
Normal file
|
@ -0,0 +1,184 @@
|
|||
package metrics // import "github.com/pomerium/pomerium/internal/telemetry/metrics"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"go.opencensus.io/plugin/ocgrpc"
|
||||
"go.opencensus.io/stats/view"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/stats"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type testProto struct {
|
||||
message string
|
||||
}
|
||||
|
||||
func (t testProto) Reset() {}
|
||||
func (t testProto) ProtoMessage() {}
|
||||
func (t testProto) String() string {
|
||||
return t.message
|
||||
}
|
||||
|
||||
func (t testProto) XXX_Size() int {
|
||||
return len([]byte(t.message))
|
||||
}
|
||||
|
||||
func (t testProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return []byte(t.message), nil
|
||||
}
|
||||
|
||||
type testInvoker struct {
|
||||
invokeResult error
|
||||
statsHandler stats.Handler
|
||||
}
|
||||
|
||||
func (t testInvoker) UnaryInvoke(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, opts ...grpc.CallOption) error {
|
||||
r := reply.(*testProto)
|
||||
r.message = "hello"
|
||||
|
||||
ctx = t.statsHandler.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: method})
|
||||
t.statsHandler.HandleRPC(ctx, &stats.InPayload{Client: true, Length: len(r.message)})
|
||||
t.statsHandler.HandleRPC(ctx, &stats.OutPayload{Client: true, Length: len(r.message)})
|
||||
t.statsHandler.HandleRPC(ctx, &stats.End{Client: true, Error: t.invokeResult})
|
||||
|
||||
return t.invokeResult
|
||||
}
|
||||
|
||||
func newTestCC(t *testing.T) *grpc.ClientConn {
|
||||
testCC, err := grpc.Dial("dns:localhost:9999", grpc.WithInsecure())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create testCC: %s", err)
|
||||
}
|
||||
return testCC
|
||||
}
|
||||
func Test_GRPCClientInterceptor(t *testing.T) {
|
||||
|
||||
interceptor := GRPCClientInterceptor("test_service")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
method string
|
||||
errorCode error
|
||||
wantgrpcClientResponseSize string
|
||||
wantgrpcClientRequestDuration string
|
||||
wantgrpcClientRequestCount string
|
||||
wantgrpcClientRequestSize string
|
||||
}{
|
||||
{
|
||||
name: "ok authorize",
|
||||
method: "/authorize.Authorizer/Authorize",
|
||||
errorCode: nil,
|
||||
wantgrpcClientResponseSize: "{ { {grpc_client_status OK}{grpc_method Authorize}{grpc_service authorize.Authorizer}{host dns:localhost:9999}{service test_service} }&{1 5 5 5 0 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]",
|
||||
wantgrpcClientRequestDuration: "{ { {grpc_client_status OK}{grpc_method Authorize}{grpc_service authorize.Authorizer}{host dns:localhost:9999}{service test_service} }&{1",
|
||||
wantgrpcClientRequestCount: "{ { {grpc_client_status OK}{grpc_method Authorize}{grpc_service authorize.Authorizer}{host dns:localhost:9999}{service test_service} }&{1",
|
||||
wantgrpcClientRequestSize: "{ { {grpc_client_status OK}{grpc_method Authorize}{grpc_service authorize.Authorizer}{host dns:localhost:9999}{service test_service} }&{1 5 5 5 0 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]",
|
||||
},
|
||||
{
|
||||
name: "unknown validate",
|
||||
method: "/authenticate.Authenticator/Validate",
|
||||
errorCode: status.Error(14, ""),
|
||||
wantgrpcClientResponseSize: "{ { {grpc_client_status UNAVAILABLE}{grpc_method Validate}{grpc_service authenticate.Authenticator}{host dns:localhost:9999}{service test_service} }&{1 5 5 5 0 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]",
|
||||
wantgrpcClientRequestDuration: "{ { {grpc_client_status UNAVAILABLE}{grpc_method Validate}{grpc_service authenticate.Authenticator}{host dns:localhost:9999}{service test_service} }&{1",
|
||||
wantgrpcClientRequestCount: "{ { {grpc_client_status UNAVAILABLE}{grpc_method Validate}{grpc_service authenticate.Authenticator}{host dns:localhost:9999}{service test_service} }&{1",
|
||||
wantgrpcClientRequestSize: "{ { {grpc_client_status UNAVAILABLE}{grpc_method Validate}{grpc_service authenticate.Authenticator}{host dns:localhost:9999}{service test_service} }&{1 5 5 5 0 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]",
|
||||
},
|
||||
{
|
||||
name: "broken method parsing",
|
||||
method: "f",
|
||||
errorCode: status.Error(14, ""),
|
||||
wantgrpcClientResponseSize: "{ { {grpc_client_status UNAVAILABLE}{host dns:localhost:9999}{service test_service} }&{1 5 5 5 0 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]",
|
||||
wantgrpcClientRequestDuration: "{ { {grpc_client_status UNAVAILABLE}{host dns:localhost:9999}{service test_service} }&{1",
|
||||
wantgrpcClientRequestCount: "{ { {grpc_client_status UNAVAILABLE}{host dns:localhost:9999}{service test_service} }&{1",
|
||||
wantgrpcClientRequestSize: "{ { {grpc_client_status UNAVAILABLE}{host dns:localhost:9999}{service test_service} }&{1 5 5 5 0 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
view.Unregister(GRPCClientViews...)
|
||||
view.Register(GRPCClientViews...)
|
||||
|
||||
invoker := testInvoker{
|
||||
invokeResult: tt.errorCode,
|
||||
statsHandler: &ocgrpc.ClientHandler{},
|
||||
}
|
||||
var reply testProto
|
||||
|
||||
interceptor(context.Background(), tt.method, nil, &reply, newTestCC(t), invoker.UnaryInvoke)
|
||||
|
||||
testDataRetrieval(GRPCClientResponseSizeView, t, tt.wantgrpcClientResponseSize)
|
||||
testDataRetrieval(GRPCClientRequestDurationView, t, tt.wantgrpcClientRequestDuration)
|
||||
testDataRetrieval(GRPCClientRequestCountView, t, tt.wantgrpcClientRequestCount)
|
||||
testDataRetrieval(GRPCClientRequestSizeView, t, tt.wantgrpcClientRequestSize)
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func mockServerRPCHandle(statsHandler stats.Handler, method string, errorCode error) {
|
||||
message := "hello"
|
||||
ctx := statsHandler.TagRPC(context.Background(), &stats.RPCTagInfo{FullMethodName: method})
|
||||
statsHandler.HandleRPC(ctx, &stats.InPayload{Client: false, Length: len(message)})
|
||||
statsHandler.HandleRPC(ctx, &stats.OutPayload{Client: false, Length: len(message)})
|
||||
statsHandler.HandleRPC(ctx, &stats.End{Client: false, Error: errorCode})
|
||||
|
||||
}
|
||||
func Test_GRPCServerStatsHandler(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
method string
|
||||
errorCode error
|
||||
wantgrpcServerResponseSize string
|
||||
wantgrpcServerRequestDuration string
|
||||
wantgrpcServerRequestCount string
|
||||
wantgrpcServerRequestSizeView string
|
||||
}{
|
||||
{
|
||||
name: "ok authorize",
|
||||
method: "/authorize.Authorizer/Authorize",
|
||||
errorCode: nil,
|
||||
wantgrpcServerResponseSize: "{ { {grpc_method Authorize}{grpc_server_status OK}{grpc_service authorize.Authorizer}{service test_service} }&{1 5 5 5 0 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]",
|
||||
wantgrpcServerRequestDuration: "{ { {grpc_method Authorize}{grpc_server_status OK}{grpc_service authorize.Authorizer}{service test_service} }&{1",
|
||||
wantgrpcServerRequestCount: "{ { {grpc_method Authorize}{grpc_server_status OK}{grpc_service authorize.Authorizer}{service test_service} }&{1",
|
||||
wantgrpcServerRequestSizeView: "{ { {grpc_method Authorize}{grpc_server_status OK}{grpc_service authorize.Authorizer}{service test_service} }&{1 5 5 5 0 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]",
|
||||
},
|
||||
{
|
||||
name: "unknown validate",
|
||||
method: "/authenticate.Authenticator/Validate",
|
||||
errorCode: status.Error(14, ""),
|
||||
wantgrpcServerResponseSize: "{ { {grpc_method Validate}{grpc_server_status UNAVAILABLE}{grpc_service authenticate.Authenticator}{service test_service} }&{1 5 5 5 0 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]",
|
||||
wantgrpcServerRequestDuration: "{ { {grpc_method Validate}{grpc_server_status UNAVAILABLE}{grpc_service authenticate.Authenticator}{service test_service} }&{1",
|
||||
wantgrpcServerRequestCount: "{ { {grpc_method Validate}{grpc_server_status UNAVAILABLE}{grpc_service authenticate.Authenticator}{service test_service} }&{1",
|
||||
wantgrpcServerRequestSizeView: "{ { {grpc_method Validate}{grpc_server_status UNAVAILABLE}{grpc_service authenticate.Authenticator}{service test_service} }&{1 5 5 5 0 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]",
|
||||
},
|
||||
{
|
||||
name: "broken method parsing",
|
||||
method: "f",
|
||||
errorCode: status.Error(14, ""),
|
||||
wantgrpcServerResponseSize: "{ { {grpc_server_status UNAVAILABLE}{service test_service} }&{1 5 5 5 0 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]",
|
||||
wantgrpcServerRequestDuration: "{ { {grpc_server_status UNAVAILABLE}{service test_service} }&{1",
|
||||
wantgrpcServerRequestCount: "{ { {grpc_server_status UNAVAILABLE}{service test_service} }&{1",
|
||||
wantgrpcServerRequestSizeView: "{ { {grpc_server_status UNAVAILABLE}{service test_service} }&{1 5 5 5 0 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
view.Unregister(GRPCServerViews...)
|
||||
view.Register(GRPCServerViews...)
|
||||
|
||||
statsHandler := NewGRPCServerStatsHandler("test_service")
|
||||
mockServerRPCHandle(statsHandler, tt.method, tt.errorCode)
|
||||
|
||||
testDataRetrieval(GRPCServerResponseSizeView, t, tt.wantgrpcServerResponseSize)
|
||||
testDataRetrieval(GRPCServerRequestDurationView, t, tt.wantgrpcServerRequestDuration)
|
||||
testDataRetrieval(GRPCServerRequestCountView, t, tt.wantgrpcServerRequestCount)
|
||||
testDataRetrieval(GRPCServerRequestSizeView, t, tt.wantgrpcServerRequestSizeView)
|
||||
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue