From 603d37b1351e727e082beb490ba940987ba529ff Mon Sep 17 00:00:00 2001 From: Di Wu Date: Wed, 26 Feb 2020 00:42:43 +0800 Subject: [PATCH] Set option and cli args to the service profile (#1259) --- config/cmd/cmd.go | 21 +++++++++++++++++++++ config/cmd/options.go | 9 +++++++++ debug/profile/profile.go | 18 ++++++++++++++++++ options.go | 9 +++++++++ service.go | 25 ++++--------------------- 5 files changed, 61 insertions(+), 21 deletions(-) diff --git a/config/cmd/cmd.go b/config/cmd/cmd.go index dc16b7e6..894cceb9 100644 --- a/config/cmd/cmd.go +++ b/config/cmd/cmd.go @@ -11,6 +11,9 @@ import ( "github.com/micro/go-micro/v2/broker" "github.com/micro/go-micro/v2/client" "github.com/micro/go-micro/v2/client/selector" + "github.com/micro/go-micro/v2/debug/profile" + "github.com/micro/go-micro/v2/debug/profile/http" + "github.com/micro/go-micro/v2/debug/profile/pprof" "github.com/micro/go-micro/v2/debug/trace" log "github.com/micro/go-micro/v2/logger" "github.com/micro/go-micro/v2/registry" @@ -25,6 +28,7 @@ import ( // servers "github.com/micro/cli/v2" + sgrpc "github.com/micro/go-micro/v2/server/grpc" smucp "github.com/micro/go-micro/v2/server/mucp" @@ -318,6 +322,11 @@ var ( "store": storeAuth.NewAuth, "jwt": jwtAuth.NewAuth, } + + DefaultProfiles = map[string]func(...profile.Option) profile.Profile{ + "http": http.NewProfile, + "pprof": pprof.NewProfile, + } ) func init() { @@ -336,6 +345,7 @@ func newCmd(opts ...Option) Cmd { Runtime: &runtime.DefaultRuntime, Store: &store.DefaultStore, Tracer: &trace.DefaultTracer, + Profile: &profile.DefaultProfile, Brokers: DefaultBrokers, Clients: DefaultClients, @@ -347,6 +357,7 @@ func newCmd(opts ...Option) Cmd { Stores: DefaultStores, Tracers: DefaultTracers, Auths: DefaultAuths, + Profiles: DefaultProfiles, } for _, o := range opts { @@ -430,6 +441,16 @@ func (c *cmd) Before(ctx *cli.Context) error { *c.opts.Auth = a() } + // Set the profile + if name := ctx.String("profile"); len(name) > 0 { + p, ok := c.opts.Profiles[name] + if !ok { + return fmt.Errorf("Unsupported profile: %s", name) + } + + *c.opts.Profile = p() + } + // Set the client if name := ctx.String("client"); len(name) > 0 { // only change if we have the client and type differs diff --git a/config/cmd/options.go b/config/cmd/options.go index cf387228..da58938f 100644 --- a/config/cmd/options.go +++ b/config/cmd/options.go @@ -7,6 +7,7 @@ import ( "github.com/micro/go-micro/v2/broker" "github.com/micro/go-micro/v2/client" "github.com/micro/go-micro/v2/client/selector" + "github.com/micro/go-micro/v2/debug/profile" "github.com/micro/go-micro/v2/debug/trace" "github.com/micro/go-micro/v2/registry" "github.com/micro/go-micro/v2/runtime" @@ -32,6 +33,7 @@ type Options struct { Store *store.Store Tracer *trace.Tracer Auth *auth.Auth + Profile *profile.Profile Brokers map[string]func(...broker.Option) broker.Broker Clients map[string]func(...client.Option) client.Client @@ -43,6 +45,7 @@ type Options struct { Stores map[string]func(...store.Option) store.Store Tracers map[string]func(...trace.Option) trace.Tracer Auths map[string]func(...auth.Option) auth.Auth + Profiles map[string]func(...profile.Option) profile.Profile // Other options for implementations of the interface // can be stored in a context @@ -118,6 +121,12 @@ func Auth(a *auth.Auth) Option { } } +func Profile(p *profile.Profile) Option { + return func(o *Options) { + o.Profile = p + } +} + // New broker func func NewBroker(name string, b func(...broker.Option) broker.Broker) Option { return func(o *Options) { diff --git a/debug/profile/profile.go b/debug/profile/profile.go index 3cc075f4..d043e524 100644 --- a/debug/profile/profile.go +++ b/debug/profile/profile.go @@ -10,6 +10,24 @@ type Profile interface { String() string } +var ( + DefaultProfile Profile = new(noop) +) + +type noop struct{} + +func (p *noop) Start() error { + return nil +} + +func (p *noop) Stop() error { + return nil +} + +func (p *noop) String() string { + return "noop" +} + type Options struct { // Name to use for the profile Name string diff --git a/options.go b/options.go index a2c32e3d..289b224b 100644 --- a/options.go +++ b/options.go @@ -10,6 +10,7 @@ import ( "github.com/micro/go-micro/v2/client" "github.com/micro/go-micro/v2/client/selector" "github.com/micro/go-micro/v2/config/cmd" + "github.com/micro/go-micro/v2/debug/profile" "github.com/micro/go-micro/v2/debug/trace" "github.com/micro/go-micro/v2/registry" "github.com/micro/go-micro/v2/server" @@ -25,6 +26,7 @@ type Options struct { Server server.Server Registry registry.Registry Transport transport.Transport + Profile profile.Profile // Before and After funcs BeforeStart []func() error @@ -99,6 +101,13 @@ func HandleSignal(b bool) Option { } } +// Profile to be used for debug profile +func Profile(p profile.Profile) Option { + return func(o *Options) { + o.Profile = p + } +} + // Server to be used for service func Server(s server.Server) Option { return func(o *Options) { diff --git a/service.go b/service.go index 90fdd8ca..d9fe2ca6 100644 --- a/service.go +++ b/service.go @@ -11,9 +11,6 @@ import ( "github.com/micro/go-micro/v2/auth" "github.com/micro/go-micro/v2/client" "github.com/micro/go-micro/v2/config/cmd" - "github.com/micro/go-micro/v2/debug/profile" - "github.com/micro/go-micro/v2/debug/profile/http" - "github.com/micro/go-micro/v2/debug/profile/pprof" "github.com/micro/go-micro/v2/debug/service/handler" "github.com/micro/go-micro/v2/debug/stats" "github.com/micro/go-micro/v2/debug/trace" @@ -101,6 +98,7 @@ func (s *service) Init(opts ...Option) { cmd.Transport(&s.opts.Transport), cmd.Client(&s.opts.Client), cmd.Server(&s.opts.Server), + cmd.Profile(&s.opts.Profile), ); err != nil { log.Fatal(err) } @@ -175,31 +173,16 @@ func (s *service) Run() error { ) // start the profiler - // TODO: set as an option to the service, don't just use pprof - if prof := os.Getenv("MICRO_DEBUG_PROFILE"); len(prof) > 0 { - var profiler profile.Profile - + if s.opts.Profile != nil { // to view mutex contention runtime.SetMutexProfileFraction(5) // to view blocking profile runtime.SetBlockProfileRate(1) - switch prof { - case "http": - profiler = http.NewProfile() - default: - service := s.opts.Server.Options().Name - version := s.opts.Server.Options().Version - id := s.opts.Server.Options().Id - profiler = pprof.NewProfile( - profile.Name(service + "." + version + "." + id), - ) - } - - if err := profiler.Start(); err != nil { + if err := s.opts.Profile.Start(); err != nil { return err } - defer profiler.Stop() + defer s.opts.Profile.Stop() } log.Infof("Starting [service] %s", s.Name())