Skip to content
This repository has been archived by the owner on Apr 18, 2023. It is now read-only.

Support Namespace and Subsytem for ServerMetrics #29

Open
saurcery opened this issue Dec 15, 2017 · 3 comments
Open

Support Namespace and Subsytem for ServerMetrics #29

saurcery opened this issue Dec 15, 2017 · 3 comments

Comments

@saurcery
Copy link

After poking around with ServerMetrics type I was unable to modify the behavior ofNewServerMetrics() function under server_metrics.go.
Can someone help me understand how can one add Namespace/Subsystem CounterOpts to e.g. ServerMetrics.serverStartedCounter?

@cstockton
Copy link

Looks like this issue is a bit old, but it took me a few minutes of digging to figure out how to do this properly so figured I would share:

package grpcutil

import (
	"context"

	"acme/pkg/metrics"

	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
	grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
	grpctag "github.com/grpc-ecosystem/go-grpc-middleware/tags"
	grpcot "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
	grpcprom "github.com/grpc-ecosystem/go-grpc-prometheus"
	prom "github.com/prometheus/client_golang/prometheus"
	grpc "google.golang.org/grpc"

	"go.uber.org/zap"
)

var sbprom = grpcprom.NewServerMetrics(
	grpcprom.CounterOption(func(o *prom.CounterOpts) {
		o.Namespace = metrics.Namespace
	}),
)

func init() {
	prom.MustRegister(sbprom) // sbprom is a collector
}

// Dial adds the default dial options to opts before calling
// grpc.DialContext.
func Dial(ctx context.Context, target string, opts ...grpc.DialOption) (conn *grpc.ClientConn, err error) {
	return grpc.DialContext(ctx, target, append(DialOptions(), opts...)...)
}

// DialOptions returns the default grpc dial options.
func DialOptions() []grpc.DialOption {
	return []grpc.DialOption{
		grpc.WithUnaryInterceptor(grpcprom.UnaryClientInterceptor),
		grpc.WithStreamInterceptor(grpcprom.StreamClientInterceptor),
		grpc.WithUnaryInterceptor(grpcot.UnaryClientInterceptor()),
		grpc.WithStreamInterceptor(grpcot.StreamClientInterceptor()),
	}
}

// NewServer adds the default server options to opts before calling
// grpc.NewServer.
func NewServer(l *zap.Logger, opts ...grpc.ServerOption) *grpc.Server {
	srv := grpc.NewServer(append(ServerOptions(l), opts...)...)

	sbprom.InitializeMetrics(srv)
	return srv
}

// ServerOptions returns the default grpc server options.
func ServerOptions(l *zap.Logger) []grpc.ServerOption {
	return []grpc.ServerOption{
		grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
			grpctag.StreamServerInterceptor(),
			grpcot.StreamServerInterceptor(),
			sbprom.StreamServerInterceptor(),
			grpczap.StreamServerInterceptor(l),
		)),
		grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
			grpctag.UnaryServerInterceptor(),
			grpcot.UnaryServerInterceptor(),
			sbprom.UnaryServerInterceptor(),
			grpczap.UnaryServerInterceptor(l),
		)),
	}
}

@yspanchal
Copy link

@cstockton if i want to use 'sbprom' counter metrics in one of my grpc demo service like this one 'pb.RegisterDemoServiceServer(grpcServer, demoServer)' and i want to increment counter based on certain condition in demo service is it possible ? can you provide small example for this ?

@cstockton
Copy link

@yspanchal You would want to wrap the grpc.StreamServerInterceptor - it's just an ordinary function so you can wrap the call to the sbprom interceptors.

func certainConditionWrapper(
	maybe grpc.StreamServerInterceptor,
) grpc.StreamServerInterceptor {
	return grpc.StreamServerInterceptor(func(
		srv interface{},
		ss grpc.ServerStream,
		info *grpc.StreamServerInfo,
		handler grpc.StreamHandler,
	) error {
		if true {
			return maybe(srv, ss, info, handler)
		}
		return handler(srv, ss)
	})
}

// ServerOptions returns the default grpc server options.
func ServerOptions(l *zap.Logger) []grpc.ServerOption {
	return []grpc.ServerOption{
		grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
			grpctag.StreamServerInterceptor(),
			grpcot.StreamServerInterceptor(),
			certainConditionWrapper(sbSrvProm.StreamServerInterceptor()),
			grpczap.StreamServerInterceptor(l),
		)),
		grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
			grpctag.UnaryServerInterceptor(),
			grpcot.UnaryServerInterceptor(),
			sbSrvProm.UnaryServerInterceptor(),
			grpczap.UnaryServerInterceptor(l),
		)),
	}
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants