diff --git a/agent/input/discord/discord.go b/agent/input/discord/discord.go index 05eb816a..39ff21f3 100644 --- a/agent/input/discord/discord.go +++ b/agent/input/discord/discord.go @@ -8,8 +8,8 @@ import ( "strings" "github.com/bwmarrin/discordgo" - "github.com/micro/cli" "github.com/micro/go-micro/agent/input" + "github.com/micro/cli/v2" ) func init() { @@ -36,21 +36,21 @@ type discordInput struct { func (d *discordInput) Flags() []cli.Flag { return []cli.Flag{ - cli.StringFlag{ - Name: "discord_token", - EnvVar: "MICRO_DISCORD_TOKEN", - Usage: "Discord token (prefix with Bot if it's for bot account)", + &cli.StringFlag{ + Name: "discord_token", + EnvVars: []string{"MICRO_DISCORD_TOKEN"}, + Usage: "Discord token (prefix with Bot if it's for bot account)", }, - cli.StringFlag{ - Name: "discord_whitelist", - EnvVar: "MICRO_DISCORD_WHITELIST", - Usage: "Discord Whitelist (seperated by ,)", + &cli.StringFlag{ + Name: "discord_whitelist", + EnvVars: []string{"MICRO_DISCORD_WHITELIST"}, + Usage: "Discord Whitelist (seperated by ,)", }, - cli.StringFlag{ - Name: "discord_prefix", - Usage: "Discord Prefix", - EnvVar: "MICRO_DISCORD_PREFIX", - Value: "Micro ", + &cli.StringFlag{ + Name: "discord_prefix", + Usage: "Discord Prefix", + EnvVars: []string{"MICRO_DISCORD_PREFIX"}, + Value: "Micro ", }, } } diff --git a/agent/input/input.go b/agent/input/input.go index 2b1d9aab..58a2ba10 100644 --- a/agent/input/input.go +++ b/agent/input/input.go @@ -2,7 +2,7 @@ package input import ( - "github.com/micro/cli" + "github.com/micro/cli/v2" ) type EventType string diff --git a/agent/input/slack/slack.go b/agent/input/slack/slack.go index 9e67b2ed..8336b1d8 100644 --- a/agent/input/slack/slack.go +++ b/agent/input/slack/slack.go @@ -4,9 +4,9 @@ import ( "errors" "sync" - "github.com/micro/cli" "github.com/micro/go-micro/agent/input" "github.com/nlopes/slack" + "github.com/micro/cli/v2" ) type slackInput struct { @@ -26,15 +26,15 @@ func init() { func (p *slackInput) Flags() []cli.Flag { return []cli.Flag{ - cli.BoolFlag{ - Name: "slack_debug", - Usage: "Slack debug output", - EnvVar: "MICRO_SLACK_DEBUG", + &cli.BoolFlag{ + Name: "slack_debug", + Usage: "Slack debug output", + EnvVars: []string{"MICRO_SLACK_DEBUG"}, }, - cli.StringFlag{ - Name: "slack_token", - Usage: "Slack token", - EnvVar: "MICRO_SLACK_TOKEN", + &cli.StringFlag{ + Name: "slack_token", + Usage: "Slack token", + EnvVars: []string{"MICRO_SLACK_TOKEN"}, }, } } diff --git a/agent/input/telegram/telegram.go b/agent/input/telegram/telegram.go index a1510527..eced5d5a 100644 --- a/agent/input/telegram/telegram.go +++ b/agent/input/telegram/telegram.go @@ -5,8 +5,8 @@ import ( "strings" "sync" - "github.com/micro/cli" "github.com/micro/go-micro/agent/input" + "github.com/micro/cli/v2" tgbotapi "gopkg.in/telegram-bot-api.v4" ) @@ -34,20 +34,20 @@ func init() { func (ti *telegramInput) Flags() []cli.Flag { return []cli.Flag{ - cli.BoolFlag{ - Name: "telegram_debug", - EnvVar: "MICRO_TELEGRAM_DEBUG", - Usage: "Telegram debug output", + &cli.BoolFlag{ + Name: "telegram_debug", + EnvVars: []string{"MICRO_TELEGRAM_DEBUG"}, + Usage: "Telegram debug output", }, - cli.StringFlag{ - Name: "telegram_token", - EnvVar: "MICRO_TELEGRAM_TOKEN", - Usage: "Telegram token", + &cli.StringFlag{ + Name: "telegram_token", + EnvVars: []string{"MICRO_TELEGRAM_TOKEN"}, + Usage: "Telegram token", }, - cli.StringFlag{ - Name: "telegram_whitelist", - EnvVar: "MICRO_TELEGRAM_WHITELIST", - Usage: "Telegram bot's users (comma-separated values)", + &cli.StringFlag{ + Name: "telegram_whitelist", + EnvVars: []string{"MICRO_TELEGRAM_WHITELIST"}, + Usage: "Telegram bot's users (comma-separated values)", }, } } diff --git a/broker/options.go b/broker/options.go index f0877a27..348857f3 100644 --- a/broker/options.go +++ b/broker/options.go @@ -46,10 +46,6 @@ type PublishOption func(*PublishOptions) type SubscribeOption func(*SubscribeOptions) -var ( - registryKey = "github.com/micro/go-micro/registry" -) - func NewSubscribeOptions(opts ...SubscribeOption) SubscribeOptions { opt := SubscribeOptions{ AutoAck: true, diff --git a/client/rpc_client.go b/client/rpc_client.go index d8f24f1c..63d20d7b 100644 --- a/client/rpc_client.go +++ b/client/rpc_client.go @@ -10,7 +10,6 @@ import ( "github.com/google/uuid" "github.com/micro/go-micro/broker" - "github.com/micro/go-micro/util/pool" "github.com/micro/go-micro/client/selector" "github.com/micro/go-micro/codec" raw "github.com/micro/go-micro/codec/bytes" @@ -19,6 +18,7 @@ import ( "github.com/micro/go-micro/registry" "github.com/micro/go-micro/transport" "github.com/micro/go-micro/util/buf" + "github.com/micro/go-micro/util/pool" ) type rpcClient struct { diff --git a/config/cmd/cmd.go b/config/cmd/cmd.go index ad3fa35a..72117a18 100644 --- a/config/cmd/cmd.go +++ b/config/cmd/cmd.go @@ -7,7 +7,6 @@ import ( "strings" "time" - "github.com/micro/cli" "github.com/micro/go-micro/broker" "github.com/micro/go-micro/client" "github.com/micro/go-micro/client/selector" @@ -25,6 +24,7 @@ import ( // servers sgrpc "github.com/micro/go-micro/server/grpc" smucp "github.com/micro/go-micro/server/mucp" + "github.com/micro/cli/v2" // brokers "github.com/micro/go-micro/broker/memory" @@ -73,140 +73,140 @@ var ( DefaultCmd = newCmd() DefaultFlags = []cli.Flag{ - cli.StringFlag{ - Name: "client", - EnvVar: "MICRO_CLIENT", - Usage: "Client for go-micro; rpc", + &cli.StringFlag{ + Name: "client", + EnvVars: []string{"MICRO_CLIENT"}, + Usage: "Client for go-micro; rpc", }, - cli.StringFlag{ - Name: "client_request_timeout", - EnvVar: "MICRO_CLIENT_REQUEST_TIMEOUT", - Usage: "Sets the client request timeout. e.g 500ms, 5s, 1m. Default: 5s", + &cli.StringFlag{ + Name: "client_request_timeout", + EnvVars: []string{"MICRO_CLIENT_REQUEST_TIMEOUT"}, + Usage: "Sets the client request timeout. e.g 500ms, 5s, 1m. Default: 5s", }, - cli.IntFlag{ - Name: "client_retries", - EnvVar: "MICRO_CLIENT_RETRIES", - Value: client.DefaultRetries, - Usage: "Sets the client retries. Default: 1", + &cli.IntFlag{ + Name: "client_retries", + EnvVars: []string{"MICRO_CLIENT_RETRIES"}, + Value: client.DefaultRetries, + Usage: "Sets the client retries. Default: 1", }, - cli.IntFlag{ - Name: "client_pool_size", - EnvVar: "MICRO_CLIENT_POOL_SIZE", - Usage: "Sets the client connection pool size. Default: 1", + &cli.IntFlag{ + Name: "client_pool_size", + EnvVars: []string{"MICRO_CLIENT_POOL_SIZE"}, + Usage: "Sets the client connection pool size. Default: 1", }, - cli.StringFlag{ - Name: "client_pool_ttl", - EnvVar: "MICRO_CLIENT_POOL_TTL", - Usage: "Sets the client connection pool ttl. e.g 500ms, 5s, 1m. Default: 1m", + &cli.StringFlag{ + Name: "client_pool_ttl", + EnvVars: []string{"MICRO_CLIENT_POOL_TTL"}, + Usage: "Sets the client connection pool ttl. e.g 500ms, 5s, 1m. Default: 1m", }, - cli.IntFlag{ - Name: "register_ttl", - EnvVar: "MICRO_REGISTER_TTL", - Value: 60, - Usage: "Register TTL in seconds", + &cli.IntFlag{ + Name: "register_ttl", + EnvVars: []string{"MICRO_REGISTER_TTL"}, + Value: 60, + Usage: "Register TTL in seconds", }, - cli.IntFlag{ - Name: "register_interval", - EnvVar: "MICRO_REGISTER_INTERVAL", - Value: 30, - Usage: "Register interval in seconds", + &cli.IntFlag{ + Name: "register_interval", + EnvVars: []string{"MICRO_REGISTER_INTERVAL"}, + Value: 30, + Usage: "Register interval in seconds", }, - cli.StringFlag{ - Name: "server", - EnvVar: "MICRO_SERVER", - Usage: "Server for go-micro; rpc", + &cli.StringFlag{ + Name: "server", + EnvVars: []string{"MICRO_SERVER"}, + Usage: "Server for go-micro; rpc", }, - cli.StringFlag{ - Name: "server_name", - EnvVar: "MICRO_SERVER_NAME", - Usage: "Name of the server. go.micro.srv.example", + &cli.StringFlag{ + Name: "server_name", + EnvVars: []string{"MICRO_SERVER_NAME"}, + Usage: "Name of the server. go.micro.srv.example", }, - cli.StringFlag{ - Name: "server_version", - EnvVar: "MICRO_SERVER_VERSION", - Usage: "Version of the server. 1.1.0", + &cli.StringFlag{ + Name: "server_version", + EnvVars: []string{"MICRO_SERVER_VERSION"}, + Usage: "Version of the server. 1.1.0", }, - cli.StringFlag{ - Name: "server_id", - EnvVar: "MICRO_SERVER_ID", - Usage: "Id of the server. Auto-generated if not specified", + &cli.StringFlag{ + Name: "server_id", + EnvVars: []string{"MICRO_SERVER_ID"}, + Usage: "Id of the server. Auto-generated if not specified", }, - cli.StringFlag{ - Name: "server_address", - EnvVar: "MICRO_SERVER_ADDRESS", - Usage: "Bind address for the server. 127.0.0.1:8080", + &cli.StringFlag{ + Name: "server_address", + EnvVars: []string{"MICRO_SERVER_ADDRESS"}, + Usage: "Bind address for the server. 127.0.0.1:8080", }, - cli.StringFlag{ - Name: "server_advertise", - EnvVar: "MICRO_SERVER_ADVERTISE", - Usage: "Used instead of the server_address when registering with discovery. 127.0.0.1:8080", + &cli.StringFlag{ + Name: "server_advertise", + EnvVars: []string{"MICRO_SERVER_ADVERTISE"}, + Usage: "Used instead of the server_address when registering with discovery. 127.0.0.1:8080", }, - cli.StringSliceFlag{ - Name: "server_metadata", - EnvVar: "MICRO_SERVER_METADATA", - Value: &cli.StringSlice{}, - Usage: "A list of key-value pairs defining metadata. version=1.0.0", + &cli.StringSliceFlag{ + Name: "server_metadata", + EnvVars: []string{"MICRO_SERVER_METADATA"}, + Value: &cli.StringSlice{}, + Usage: "A list of key-value pairs defining metadata. version=1.0.0", }, - cli.StringFlag{ - Name: "broker", - EnvVar: "MICRO_BROKER", - Usage: "Broker for pub/sub. http, nats, rabbitmq", + &cli.StringFlag{ + Name: "broker", + EnvVars: []string{"MICRO_BROKER"}, + Usage: "Broker for pub/sub. http, nats, rabbitmq", }, - cli.StringFlag{ - Name: "broker_address", - EnvVar: "MICRO_BROKER_ADDRESS", - Usage: "Comma-separated list of broker addresses", + &cli.StringFlag{ + Name: "broker_address", + EnvVars: []string{"MICRO_BROKER_ADDRESS"}, + Usage: "Comma-separated list of broker addresses", }, - cli.StringFlag{ - Name: "profile", - Usage: "Debug profiler for cpu and memory stats", - EnvVar: "MICRO_DEBUG_PROFILE", + &cli.StringFlag{ + Name: "profile", + Usage: "Debug profiler for cpu and memory stats", + EnvVars: []string{"MICRO_DEBUG_PROFILE"}, }, - cli.StringFlag{ - Name: "registry", - EnvVar: "MICRO_REGISTRY", - Usage: "Registry for discovery. etcd, mdns", + &cli.StringFlag{ + Name: "registry", + EnvVars: []string{"MICRO_REGISTRY"}, + Usage: "Registry for discovery. etcd, mdns", }, - cli.StringFlag{ - Name: "registry_address", - EnvVar: "MICRO_REGISTRY_ADDRESS", - Usage: "Comma-separated list of registry addresses", + &cli.StringFlag{ + Name: "registry_address", + EnvVars: []string{"MICRO_REGISTRY_ADDRESS"}, + Usage: "Comma-separated list of registry addresses", }, - cli.StringFlag{ - Name: "runtime", - Usage: "Runtime for building and running services e.g local, kubernetes", - EnvVar: "MICRO_RUNTIME", - Value: "local", + &cli.StringFlag{ + Name: "runtime", + Usage: "Runtime for building and running services e.g local, kubernetes", + EnvVars: []string{"MICRO_RUNTIME"}, + Value: "local", }, - cli.StringFlag{ - Name: "selector", - EnvVar: "MICRO_SELECTOR", - Usage: "Selector used to pick nodes for querying", + &cli.StringFlag{ + Name: "selector", + EnvVars: []string{"MICRO_SELECTOR"}, + Usage: "Selector used to pick nodes for querying", }, - cli.StringFlag{ - Name: "store", - EnvVar: "MICRO_STORE", - Usage: "Store used for key-value storage", + &cli.StringFlag{ + Name: "store", + EnvVars: []string{"MICRO_STORE"}, + Usage: "Store used for key-value storage", }, - cli.StringFlag{ - Name: "store_address", - EnvVar: "MICRO_STORE_ADDRESS", - Usage: "Comma-separated list of store addresses", + &cli.StringFlag{ + Name: "store_address", + EnvVars: []string{"MICRO_STORE_ADDRESS"}, + Usage: "Comma-separated list of store addresses", }, - cli.StringFlag{ - Name: "store_namespace", - EnvVar: "MICRO_STORE_NAMESPACE", - Usage: "Namespace for store data", + &cli.StringFlag{ + Name: "store_namespace", + EnvVars: []string{"MICRO_STORE_NAMESPACE"}, + Usage: "Namespace for store data", }, - cli.StringFlag{ - Name: "transport", - EnvVar: "MICRO_TRANSPORT", - Usage: "Transport mechanism used; http", + &cli.StringFlag{ + Name: "transport", + EnvVars: []string{"MICRO_TRANSPORT"}, + Usage: "Transport mechanism used; http", }, - cli.StringFlag{ - Name: "transport_address", - EnvVar: "MICRO_TRANSPORT_ADDRESS", - Usage: "Comma-separated list of transport addresses", + &cli.StringFlag{ + Name: "transport_address", + EnvVars: []string{"MICRO_TRANSPORT_ADDRESS"}, + Usage: "Comma-separated list of transport addresses", }, } @@ -246,12 +246,12 @@ var ( } DefaultRuntimes = map[string]func(...runtime.Option) runtime.Runtime{ - "local": runtime.NewRuntime, + "local": runtime.NewRuntime, } DefaultStores = map[string]func(...store.Option) store.Store{ - "memory": memStore.NewStore, - "service": svcStore.NewStore, + "memory": memStore.NewStore, + "service": svcStore.NewStore, } // used for default selection as the fall back @@ -306,7 +306,9 @@ func newCmd(opts ...Option) Cmd { cmd.app.Usage = cmd.opts.Description cmd.app.Before = cmd.Before cmd.app.Flags = DefaultFlags - cmd.app.Action = func(c *cli.Context) {} + cmd.app.Action = func(c *cli.Context) error { + return nil + } if len(options.Version) == 0 { cmd.app.HideVersion = true @@ -489,11 +491,11 @@ func (c *cmd) Before(ctx *cli.Context) error { serverOpts = append(serverOpts, server.Advertise(ctx.String("server_advertise"))) } - if ttl := time.Duration(ctx.GlobalInt("register_ttl")); ttl >= 0 { + if ttl := time.Duration(ctx.Int("register_ttl")); ttl >= 0 { serverOpts = append(serverOpts, server.RegisterTTL(ttl*time.Second)) } - if val := time.Duration(ctx.GlobalInt("register_interval")); val >= 0 { + if val := time.Duration(ctx.Int("register_interval")); val >= 0 { serverOpts = append(serverOpts, server.RegisterInterval(val*time.Second)) } diff --git a/config/source/cli/cli.go b/config/source/cli/cli.go index 6d6a8fbb..ea9a3048 100644 --- a/config/source/cli/cli.go +++ b/config/source/cli/cli.go @@ -8,9 +8,9 @@ import ( "time" "github.com/imdario/mergo" - "github.com/micro/cli" "github.com/micro/go-micro/config/cmd" "github.com/micro/go-micro/config/source" + "github.com/micro/cli/v2" ) type cliSource struct { @@ -21,11 +21,6 @@ type cliSource struct { func (c *cliSource) Read() (*source.ChangeSet, error) { var changes map[string]interface{} - for _, name := range c.ctx.GlobalFlagNames() { - tmp := toEntry(name, c.ctx.GlobalGeneric(name)) - mergo.Map(&changes, tmp) // need to sort error handling - } - for _, name := range c.ctx.FlagNames() { tmp := toEntry(name, c.ctx.Generic(name)) mergo.Map(&changes, tmp) // need to sort error handling diff --git a/config/source/cli/cli_test.go b/config/source/cli/cli_test.go index 8e1b743c..a460befa 100644 --- a/config/source/cli/cli_test.go +++ b/config/source/cli/cli_test.go @@ -5,9 +5,9 @@ import ( "os" "testing" - "github.com/micro/cli" "github.com/micro/go-micro/config/cmd" "github.com/micro/go-micro/config/source" + "github.com/micro/cli/v2" ) func test(t *testing.T, withContext bool) { @@ -17,14 +17,15 @@ func test(t *testing.T, withContext bool) { app := cmd.App() app.Name = "testapp" app.Flags = []cli.Flag{ - cli.StringFlag{Name: "db-host"}, + &cli.StringFlag{Name: "db-host"}, } // with context if withContext { // set action - app.Action = func(c *cli.Context) { + app.Action = func(c *cli.Context) error { src = WithContext(c) + return nil } // run app diff --git a/config/source/cli/options.go b/config/source/cli/options.go index 0ee463c7..274d9760 100644 --- a/config/source/cli/options.go +++ b/config/source/cli/options.go @@ -3,7 +3,7 @@ package cli import ( "context" - "github.com/micro/cli" + "github.com/micro/cli/v2" "github.com/micro/go-micro/config/source" ) diff --git a/config/source/cli/util.go b/config/source/cli/util.go index c6274068..1eb9a8b0 100644 --- a/config/source/cli/util.go +++ b/config/source/cli/util.go @@ -5,7 +5,7 @@ import ( "flag" "strings" - "github.com/micro/cli" + "github.com/micro/cli/v2" ) func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { @@ -22,7 +22,7 @@ func normalizeFlags(flags []cli.Flag, set *flag.FlagSet) error { visited[f.Name] = true }) for _, f := range flags { - parts := strings.Split(f.GetName(), ",") + parts := f.Names() if len(parts) == 1 { continue } diff --git a/debug/service/handler/debug.go b/debug/service/handler/debug.go index 7fd42632..ad0a7cbe 100644 --- a/debug/service/handler/debug.go +++ b/debug/service/handler/debug.go @@ -8,6 +8,7 @@ import ( "github.com/micro/go-micro/debug/log" proto "github.com/micro/go-micro/debug/service/proto" "github.com/micro/go-micro/debug/stats" + "github.com/micro/go-micro/debug/trace" "github.com/micro/go-micro/server" ) @@ -23,12 +24,15 @@ type Debug struct { log log.Log // the stats collector stats stats.Stats + // the tracer + trace trace.Trace } func newDebug() *Debug { return &Debug{ log: log.DefaultLog, stats: stats.DefaultStats, + trace: trace.DefaultTrace, } } @@ -60,6 +64,27 @@ func (d *Debug) Stats(ctx context.Context, req *proto.StatsRequest, rsp *proto.S return nil } +func (d *Debug) Trace(ctx context.Context, req *proto.TraceRequest, rsp *proto.TraceResponse) error { + traces, err := d.trace.Read(trace.ReadTrace(req.Id)) + if err != nil { + return err + } + + for _, trace := range traces { + rsp.Spans = append(rsp.Spans, &proto.Span{ + Trace: trace.Trace, + Id: trace.Id, + Parent: trace.Parent, + Name: trace.Name, + Started: uint64(trace.Started.UnixNano()), + Duration: uint64(trace.Duration.Nanoseconds()), + Metadata: trace.Metadata, + }) + } + + return nil +} + func (d *Debug) Log(ctx context.Context, stream server.Stream) error { req := new(proto.LogRequest) if err := stream.Recv(req); err != nil { diff --git a/debug/service/proto/debug.pb.go b/debug/service/proto/debug.pb.go index 263f21ec..6e513462 100644 --- a/debug/service/proto/debug.pb.go +++ b/debug/service/proto/debug.pb.go @@ -372,6 +372,179 @@ func (m *Record) GetMessage() string { return "" } +type TraceRequest struct { + // trace id to retrieve + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TraceRequest) Reset() { *m = TraceRequest{} } +func (m *TraceRequest) String() string { return proto.CompactTextString(m) } +func (*TraceRequest) ProtoMessage() {} +func (*TraceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_dea322649cde1ef2, []int{6} +} + +func (m *TraceRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TraceRequest.Unmarshal(m, b) +} +func (m *TraceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TraceRequest.Marshal(b, m, deterministic) +} +func (m *TraceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_TraceRequest.Merge(m, src) +} +func (m *TraceRequest) XXX_Size() int { + return xxx_messageInfo_TraceRequest.Size(m) +} +func (m *TraceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_TraceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_TraceRequest proto.InternalMessageInfo + +func (m *TraceRequest) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +type TraceResponse struct { + Spans []*Span `protobuf:"bytes,1,rep,name=spans,proto3" json:"spans,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TraceResponse) Reset() { *m = TraceResponse{} } +func (m *TraceResponse) String() string { return proto.CompactTextString(m) } +func (*TraceResponse) ProtoMessage() {} +func (*TraceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_dea322649cde1ef2, []int{7} +} + +func (m *TraceResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TraceResponse.Unmarshal(m, b) +} +func (m *TraceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TraceResponse.Marshal(b, m, deterministic) +} +func (m *TraceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TraceResponse.Merge(m, src) +} +func (m *TraceResponse) XXX_Size() int { + return xxx_messageInfo_TraceResponse.Size(m) +} +func (m *TraceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_TraceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_TraceResponse proto.InternalMessageInfo + +func (m *TraceResponse) GetSpans() []*Span { + if m != nil { + return m.Spans + } + return nil +} + +type Span struct { + // the trace id + Trace string `protobuf:"bytes,1,opt,name=trace,proto3" json:"trace,omitempty"` + // id of the span + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // parent span + Parent string `protobuf:"bytes,3,opt,name=parent,proto3" json:"parent,omitempty"` + // name of the resource + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + // time of start in nanoseconds + Started uint64 `protobuf:"varint,5,opt,name=started,proto3" json:"started,omitempty"` + // duration of the execution in nanoseconds + Duration uint64 `protobuf:"varint,6,opt,name=duration,proto3" json:"duration,omitempty"` + // associated metadata + Metadata map[string]string `protobuf:"bytes,7,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Span) Reset() { *m = Span{} } +func (m *Span) String() string { return proto.CompactTextString(m) } +func (*Span) ProtoMessage() {} +func (*Span) Descriptor() ([]byte, []int) { + return fileDescriptor_dea322649cde1ef2, []int{8} +} + +func (m *Span) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Span.Unmarshal(m, b) +} +func (m *Span) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Span.Marshal(b, m, deterministic) +} +func (m *Span) XXX_Merge(src proto.Message) { + xxx_messageInfo_Span.Merge(m, src) +} +func (m *Span) XXX_Size() int { + return xxx_messageInfo_Span.Size(m) +} +func (m *Span) XXX_DiscardUnknown() { + xxx_messageInfo_Span.DiscardUnknown(m) +} + +var xxx_messageInfo_Span proto.InternalMessageInfo + +func (m *Span) GetTrace() string { + if m != nil { + return m.Trace + } + return "" +} + +func (m *Span) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +func (m *Span) GetParent() string { + if m != nil { + return m.Parent + } + return "" +} + +func (m *Span) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Span) GetStarted() uint64 { + if m != nil { + return m.Started + } + return 0 +} + +func (m *Span) GetDuration() uint64 { + if m != nil { + return m.Duration + } + return 0 +} + +func (m *Span) GetMetadata() map[string]string { + if m != nil { + return m.Metadata + } + return nil +} + func init() { proto.RegisterType((*HealthRequest)(nil), "HealthRequest") proto.RegisterType((*HealthResponse)(nil), "HealthResponse") @@ -380,6 +553,10 @@ func init() { proto.RegisterType((*LogRequest)(nil), "LogRequest") proto.RegisterType((*Record)(nil), "Record") proto.RegisterMapType((map[string]string)(nil), "Record.MetadataEntry") + proto.RegisterType((*TraceRequest)(nil), "TraceRequest") + proto.RegisterType((*TraceResponse)(nil), "TraceResponse") + proto.RegisterType((*Span)(nil), "Span") + proto.RegisterMapType((map[string]string)(nil), "Span.MetadataEntry") } func init() { @@ -387,32 +564,40 @@ func init() { } var fileDescriptor_dea322649cde1ef2 = []byte{ - // 427 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xcd, 0x6e, 0x13, 0x31, - 0x14, 0x85, 0x33, 0x33, 0xcd, 0x24, 0xb9, 0x25, 0x01, 0x59, 0x80, 0xac, 0x11, 0x12, 0x95, 0x57, - 0x83, 0x10, 0x0e, 0x94, 0x0d, 0x82, 0x2d, 0x48, 0x2c, 0xca, 0xc6, 0x3c, 0x81, 0x3b, 0x73, 0x35, - 0x0d, 0xd4, 0x71, 0xb0, 0xef, 0x54, 0xca, 0x8a, 0x57, 0xe2, 0x65, 0x78, 0x1f, 0xe4, 0x9f, 0xb4, - 0x8d, 0x58, 0x74, 0xe7, 0xef, 0xcc, 0xf5, 0x91, 0xcf, 0x9d, 0x03, 0xd2, 0x6c, 0x3a, 0x67, 0xd7, - 0x83, 0x7d, 0x93, 0x0e, 0x3d, 0x5e, 0x8e, 0xc3, 0xda, 0xa3, 0xbb, 0xd9, 0x74, 0xb8, 0xde, 0x39, - 0x4b, 0x59, 0x93, 0xf1, 0x2c, 0x5e, 0xc1, 0xf2, 0x2b, 0xea, 0x6b, 0xba, 0x52, 0xf8, 0x6b, 0x44, - 0x4f, 0x8c, 0xc3, 0x2c, 0x4f, 0xf3, 0xe2, 0xac, 0x68, 0x17, 0xea, 0x80, 0xa2, 0x85, 0xd5, 0x61, - 0xd4, 0xef, 0xec, 0xd6, 0x23, 0x7b, 0x0e, 0xb5, 0x27, 0x4d, 0xa3, 0xcf, 0xa3, 0x99, 0x44, 0x0b, - 0x8f, 0xbe, 0x93, 0x26, 0xff, 0xb0, 0xe7, 0xdf, 0x02, 0x96, 0x79, 0x34, 0x7b, 0xbe, 0x80, 0x05, - 0x6d, 0x0c, 0x7a, 0xd2, 0x66, 0x17, 0xa7, 0x4f, 0xd4, 0x9d, 0x10, 0x9d, 0x48, 0x3b, 0xc2, 0x9e, - 0x97, 0xf1, 0xdb, 0x01, 0xc3, 0x5b, 0xc6, 0x5d, 0x18, 0xe4, 0x55, 0xfc, 0x90, 0x29, 0xe8, 0x06, - 0x8d, 0x75, 0x7b, 0x7e, 0x92, 0xf4, 0x44, 0xc1, 0x89, 0xae, 0x1c, 0xea, 0xde, 0xf3, 0x69, 0x72, - 0xca, 0xc8, 0x56, 0x50, 0x0e, 0x1d, 0xaf, 0xa3, 0x58, 0x0e, 0x1d, 0x6b, 0x60, 0xee, 0x52, 0x10, - 0xcf, 0x67, 0x51, 0xbd, 0xe5, 0xe0, 0x8e, 0xce, 0x59, 0xe7, 0xf9, 0x3c, 0xb9, 0x27, 0x12, 0x3f, - 0x00, 0x2e, 0xec, 0xf0, 0x60, 0xfe, 0xb4, 0x41, 0x87, 0xda, 0xc4, 0x38, 0x73, 0x95, 0x89, 0x3d, - 0x85, 0x69, 0x67, 0xc7, 0x2d, 0xc5, 0x30, 0x95, 0x4a, 0x10, 0x54, 0xbf, 0xd9, 0x76, 0x18, 0xa3, - 0x54, 0x2a, 0x81, 0xf8, 0x53, 0x40, 0xad, 0xb0, 0xb3, 0xae, 0xff, 0x7f, 0x79, 0xd5, 0xfd, 0xe5, - 0xbd, 0x83, 0xb9, 0x41, 0xd2, 0xbd, 0x26, 0xcd, 0xcb, 0xb3, 0xaa, 0x3d, 0x3d, 0x7f, 0x26, 0xd3, - 0x45, 0xf9, 0x2d, 0xeb, 0x5f, 0xb6, 0xe4, 0xf6, 0xea, 0x76, 0x2c, 0xbc, 0xdc, 0xa0, 0xf7, 0x7a, - 0x48, 0x6b, 0x5d, 0xa8, 0x03, 0x36, 0x9f, 0x60, 0x79, 0x74, 0x89, 0x3d, 0x81, 0xea, 0x27, 0xee, - 0x73, 0xc0, 0x70, 0x0c, 0xcf, 0xbd, 0xd1, 0xd7, 0x23, 0xc6, 0x6c, 0x0b, 0x95, 0xe0, 0x63, 0xf9, - 0xa1, 0x38, 0xff, 0x0d, 0xd3, 0xcf, 0xa1, 0x84, 0xec, 0x35, 0xd4, 0xa9, 0x53, 0x6c, 0x25, 0x8f, - 0x7a, 0xd8, 0x3c, 0x96, 0xc7, 0x65, 0x13, 0x13, 0xd6, 0xc2, 0x34, 0x76, 0x85, 0x2d, 0xe5, 0xfd, - 0x7a, 0x35, 0x2b, 0x79, 0x54, 0x21, 0x31, 0x61, 0x2f, 0xa1, 0xba, 0xb0, 0x03, 0x3b, 0x95, 0x77, - 0x3f, 0xa1, 0x99, 0xe5, 0xac, 0x62, 0xf2, 0xb6, 0xb8, 0xac, 0x63, 0xfb, 0xdf, 0xff, 0x0b, 0x00, - 0x00, 0xff, 0xff, 0x69, 0xc0, 0x33, 0x21, 0x2f, 0x03, 0x00, 0x00, + // 554 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xcd, 0x6e, 0xd4, 0x30, + 0x10, 0xde, 0x24, 0x9b, 0xdd, 0xcd, 0xb4, 0x09, 0xc8, 0xfc, 0x28, 0x0a, 0x08, 0x2a, 0x9f, 0x16, + 0x01, 0x5e, 0x28, 0x17, 0x04, 0x57, 0x90, 0x38, 0x94, 0x8b, 0xcb, 0x0b, 0xb8, 0x89, 0x95, 0x06, + 0x9a, 0x38, 0xd8, 0x4e, 0xa5, 0x7d, 0x24, 0x6e, 0xbc, 0x0c, 0x6f, 0xc3, 0x01, 0xf9, 0x27, 0xdb, + 0x44, 0x08, 0xf5, 0xc0, 0xcd, 0xdf, 0xe7, 0x99, 0x2f, 0x33, 0x9f, 0x67, 0x02, 0xa4, 0x6d, 0x4a, + 0x29, 0x76, 0xb5, 0x78, 0xe9, 0x0e, 0x15, 0xbf, 0x18, 0xea, 0x9d, 0xe2, 0xf2, 0xba, 0x29, 0xf9, + 0xae, 0x97, 0x42, 0x7b, 0x8e, 0xd8, 0x33, 0x7e, 0x06, 0xe9, 0x27, 0xce, 0xae, 0xf4, 0x25, 0xe5, + 0xdf, 0x07, 0xae, 0x34, 0xca, 0x61, 0xed, 0xa3, 0xf3, 0xe0, 0x24, 0xd8, 0x26, 0x74, 0x84, 0x78, + 0x0b, 0xd9, 0x18, 0xaa, 0x7a, 0xd1, 0x29, 0x8e, 0x1e, 0xc2, 0x4a, 0x69, 0xa6, 0x07, 0xe5, 0x43, + 0x3d, 0xc2, 0x5b, 0x38, 0x3e, 0xd7, 0x4c, 0xab, 0xdb, 0x35, 0x7f, 0x05, 0x90, 0xfa, 0x50, 0xaf, + 0xf9, 0x18, 0x12, 0xdd, 0xb4, 0x5c, 0x69, 0xd6, 0xf6, 0x36, 0x7a, 0x49, 0x6f, 0x08, 0xab, 0xa4, + 0x99, 0xd4, 0xbc, 0xca, 0x43, 0x7b, 0x37, 0x42, 0x53, 0xcb, 0xd0, 0x9b, 0xc0, 0x3c, 0xb2, 0x17, + 0x1e, 0x19, 0xbe, 0xe5, 0xad, 0x90, 0xfb, 0x7c, 0xe9, 0x78, 0x87, 0x8c, 0x92, 0xbe, 0x94, 0x9c, + 0x55, 0x2a, 0x8f, 0x9d, 0x92, 0x87, 0x28, 0x83, 0xb0, 0x2e, 0xf3, 0x95, 0x25, 0xc3, 0xba, 0x44, + 0x05, 0x6c, 0xa4, 0x6b, 0x44, 0xe5, 0x6b, 0xcb, 0x1e, 0xb0, 0x51, 0xe7, 0x52, 0x0a, 0xa9, 0xf2, + 0x8d, 0x53, 0x77, 0x08, 0x7f, 0x05, 0x38, 0x13, 0xf5, 0xad, 0xfd, 0x3b, 0x07, 0x25, 0x67, 0xad, + 0x6d, 0x67, 0x43, 0x3d, 0x42, 0xf7, 0x21, 0x2e, 0xc5, 0xd0, 0x69, 0xdb, 0x4c, 0x44, 0x1d, 0x30, + 0xac, 0x6a, 0xba, 0x92, 0xdb, 0x56, 0x22, 0xea, 0x00, 0xfe, 0x19, 0xc0, 0x8a, 0xf2, 0x52, 0xc8, + 0xea, 0x6f, 0xf3, 0xa2, 0xa9, 0x79, 0xaf, 0x61, 0xd3, 0x72, 0xcd, 0x2a, 0xa6, 0x59, 0x1e, 0x9e, + 0x44, 0xdb, 0xa3, 0xd3, 0x07, 0xc4, 0x25, 0x92, 0xcf, 0x9e, 0xff, 0xd8, 0x69, 0xb9, 0xa7, 0x87, + 0x30, 0x53, 0x79, 0xcb, 0x95, 0x62, 0xb5, 0xb3, 0x35, 0xa1, 0x23, 0x2c, 0xde, 0x43, 0x3a, 0x4b, + 0x42, 0x77, 0x21, 0xfa, 0xc6, 0xf7, 0xbe, 0x41, 0x73, 0x34, 0xe5, 0x5e, 0xb3, 0xab, 0x81, 0xdb, + 0xde, 0x12, 0xea, 0xc0, 0xbb, 0xf0, 0x6d, 0x80, 0x9f, 0xc0, 0xf1, 0x17, 0xc9, 0x4a, 0x3e, 0x1a, + 0x94, 0x41, 0xd8, 0x54, 0x3e, 0x35, 0x6c, 0x2a, 0xfc, 0x02, 0x52, 0x7f, 0xef, 0xa7, 0xe2, 0x11, + 0xc4, 0xaa, 0x67, 0x9d, 0x19, 0x34, 0x53, 0x77, 0x4c, 0xce, 0x7b, 0xd6, 0x51, 0xc7, 0xe1, 0xdf, + 0x01, 0x2c, 0x0d, 0x36, 0x1f, 0xd4, 0x26, 0xcd, 0x2b, 0x39, 0xe0, 0xc5, 0xc3, 0x51, 0xdc, 0x78, + 0xde, 0x33, 0xc9, 0xbd, 0xb9, 0x09, 0xf5, 0x08, 0x21, 0x58, 0x76, 0xac, 0x75, 0xe6, 0x26, 0xd4, + 0x9e, 0xa7, 0xf3, 0x16, 0xcf, 0xe7, 0xad, 0x80, 0x4d, 0x35, 0x48, 0xa6, 0x1b, 0xd1, 0xf9, 0x59, + 0x39, 0x60, 0xb4, 0x9b, 0x18, 0xbd, 0xb6, 0x05, 0xdf, 0xb3, 0x05, 0xff, 0xcb, 0xe6, 0xff, 0x32, + 0xf3, 0xf4, 0x47, 0x00, 0xf1, 0x07, 0xb3, 0xd2, 0xe8, 0x39, 0xac, 0xdc, 0x86, 0xa2, 0x8c, 0xcc, + 0xb6, 0xba, 0xb8, 0x43, 0xe6, 0xab, 0x8b, 0x17, 0x68, 0x0b, 0xb1, 0xdd, 0x3c, 0x94, 0x92, 0xe9, + 0xb2, 0x16, 0x19, 0x99, 0x2d, 0x24, 0x5e, 0xa0, 0xa7, 0x10, 0x9d, 0x89, 0x1a, 0x1d, 0x91, 0x9b, + 0x91, 0x2e, 0xd6, 0x7e, 0x72, 0xf0, 0xe2, 0x55, 0x60, 0xa4, 0xec, 0x73, 0xa1, 0x94, 0x4c, 0x9f, + 0xb5, 0xc8, 0xc8, 0xec, 0x15, 0xf1, 0xe2, 0x62, 0x65, 0xff, 0x3a, 0x6f, 0xfe, 0x04, 0x00, 0x00, + 0xff, 0xff, 0x02, 0xa2, 0x4d, 0xc9, 0xa7, 0x04, 0x00, 0x00, } diff --git a/debug/service/proto/debug.pb.micro.go b/debug/service/proto/debug.pb.micro.go index 45a26bac..2144f1b4 100644 --- a/debug/service/proto/debug.pb.micro.go +++ b/debug/service/proto/debug.pb.micro.go @@ -37,6 +37,7 @@ type DebugService interface { Health(ctx context.Context, in *HealthRequest, opts ...client.CallOption) (*HealthResponse, error) Stats(ctx context.Context, in *StatsRequest, opts ...client.CallOption) (*StatsResponse, error) Log(ctx context.Context, in *LogRequest, opts ...client.CallOption) (Debug_LogService, error) + Trace(ctx context.Context, in *TraceRequest, opts ...client.CallOption) (*TraceResponse, error) } type debugService struct { @@ -121,12 +122,23 @@ func (x *debugServiceLog) Recv() (*Record, error) { return m, nil } +func (c *debugService) Trace(ctx context.Context, in *TraceRequest, opts ...client.CallOption) (*TraceResponse, error) { + req := c.c.NewRequest(c.name, "Debug.Trace", in) + out := new(TraceResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for Debug service type DebugHandler interface { Health(context.Context, *HealthRequest, *HealthResponse) error Stats(context.Context, *StatsRequest, *StatsResponse) error Log(context.Context, *LogRequest, Debug_LogStream) error + Trace(context.Context, *TraceRequest, *TraceResponse) error } func RegisterDebugHandler(s server.Server, hdlr DebugHandler, opts ...server.HandlerOption) error { @@ -134,6 +146,7 @@ func RegisterDebugHandler(s server.Server, hdlr DebugHandler, opts ...server.Han Health(ctx context.Context, in *HealthRequest, out *HealthResponse) error Stats(ctx context.Context, in *StatsRequest, out *StatsResponse) error Log(ctx context.Context, stream server.Stream) error + Trace(ctx context.Context, in *TraceRequest, out *TraceResponse) error } type Debug struct { debug @@ -188,3 +201,7 @@ func (x *debugLogStream) RecvMsg(m interface{}) error { func (x *debugLogStream) Send(m *Record) error { return x.stream.Send(m) } + +func (h *debugHandler) Trace(ctx context.Context, in *TraceRequest, out *TraceResponse) error { + return h.DebugHandler.Trace(ctx, in, out) +} diff --git a/debug/service/proto/debug.proto b/debug/service/proto/debug.proto index 54358608..140b2d91 100644 --- a/debug/service/proto/debug.proto +++ b/debug/service/proto/debug.proto @@ -4,6 +4,7 @@ service Debug { rpc Health(HealthRequest) returns (HealthResponse) {}; rpc Stats(StatsRequest) returns (StatsResponse) {}; rpc Log(LogRequest) returns (stream Record) {}; + rpc Trace(TraceRequest) returns (TraceResponse) {}; } message HealthRequest { @@ -63,3 +64,30 @@ message Record { // message string message = 3; } + +message TraceRequest { + // trace id to retrieve + string id = 1; +} + +message TraceResponse { + repeated Span spans = 1; +} + + +message Span { + // the trace id + string trace = 1; + // id of the span + string id = 2; + // parent span + string parent = 3; + // name of the resource + string name = 4; + // time of start in nanoseconds + uint64 started = 5; + // duration of the execution in nanoseconds + uint64 duration = 6; + // associated metadata + map metadata = 7; +} diff --git a/debug/trace/default.go b/debug/trace/default.go index abbf1c15..65e3aa84 100644 --- a/debug/trace/default.go +++ b/debug/trace/default.go @@ -16,10 +16,28 @@ type trace struct { } func (t *trace) Read(opts ...ReadOption) ([]*Span, error) { - return []*Span{}, nil + var options ReadOptions + for _, o := range opts { + o(&options) + } + + sp := t.buffer.Get(t.buffer.Size()) + + var spans []*Span + + for _, span := range sp { + val := span.Value.(*Span) + // skip if trace id is specified and doesn't match + if len(options.Trace) > 0 && val.Trace != options.Trace { + continue + } + spans = append(spans, val) + } + + return spans, nil } -func (t *trace) Start(ctx context.Context, name string) *Span { +func (t *trace) Start(ctx context.Context, name string) (context.Context, *Span) { span := &Span{ Name: name, Trace: uuid.New().String(), @@ -30,12 +48,12 @@ func (t *trace) Start(ctx context.Context, name string) *Span { // return span if no context if ctx == nil { - return span + return context.Background(), span } s, ok := FromContext(ctx) if !ok { - return span + return ctx, span } // set trace id @@ -44,12 +62,12 @@ func (t *trace) Start(ctx context.Context, name string) *Span { span.Parent = s.Id // return the sapn - return span + return ctx, span } func (t *trace) Finish(s *Span) error { // set finished time - s.Finished = time.Now() + s.Duration = time.Since(s.Started) // save the span t.buffer.Put(s) diff --git a/debug/trace/options.go b/debug/trace/options.go index d92abad9..7a0af631 100644 --- a/debug/trace/options.go +++ b/debug/trace/options.go @@ -10,3 +10,10 @@ type ReadOptions struct { } type ReadOption func(o *ReadOptions) + +// Read the given trace +func ReadTrace(t string) ReadOption { + return func(o *ReadOptions) { + o.Trace = t + } +} diff --git a/debug/trace/trace.go b/debug/trace/trace.go index 4a4471c3..a4287213 100644 --- a/debug/trace/trace.go +++ b/debug/trace/trace.go @@ -9,7 +9,7 @@ import ( // Trace is an interface for distributed tracing type Trace interface { // Start a trace - Start(ctx context.Context, name string) *Span + Start(ctx context.Context, name string) (context.Context, *Span) // Finish the trace Finish(*Span) error // Read the traces @@ -28,14 +28,19 @@ type Span struct { Parent string // Start time Started time.Time - // Finish time - Finished time.Time + // Duration in nano seconds + Duration time.Duration // associated data Metadata map[string]string } type spanKey struct{} +var ( + // Default tracer + DefaultTrace = NewTrace() +) + // FromContext returns a span from context func FromContext(ctx context.Context) (*Span, bool) { s, ok := ctx.Value(spanKey{}).(*Span) diff --git a/go.mod b/go.mod index 35d8ea72..8dfa1e41 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/go-acme/lego/v3 v3.3.0 github.com/go-playground/universal-translator v0.17.0 // indirect github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible // indirect - github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/golang/protobuf v1.3.2 github.com/google/uuid v1.1.1 github.com/gorilla/handlers v1.4.2 @@ -36,7 +36,7 @@ require ( github.com/lib/pq v1.3.0 github.com/lucas-clemente/quic-go v0.14.1 github.com/mholt/certmagic v0.9.1 - github.com/micro/cli v0.2.0 + github.com/micro/cli/v2 v2.1.1 github.com/micro/mdns v0.3.0 github.com/miekg/dns v1.1.27 github.com/mitchellh/hashstructure v1.0.0 @@ -48,7 +48,7 @@ require ( github.com/soheilhy/cmux v0.1.4 // indirect github.com/stretchr/testify v1.4.0 github.com/technoweenie/multipartstreamer v1.0.1 // indirect - github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect + github.com/tmc/grpc-websocket-proxy v0.0.0-20200122045848-3419fae592fc // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect go.etcd.io/bbolt v1.3.3 // indirect go.uber.org/zap v1.13.0 diff --git a/go.sum b/go.sum index aaadbeae..27172711 100644 --- a/go.sum +++ b/go.sum @@ -97,6 +97,7 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpu/goacmedns v0.0.1/go.mod h1:sesf/pNnCYwUevQEQfEwY0Y3DydlQWSGZbaMElOWxok= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -161,9 +162,10 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -173,6 +175,7 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -276,8 +279,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mholt/certmagic v0.9.1 h1:wPzyouOyE+30NIQETJuhTB5ZQWz+0Hy038vaR5WWQDE= github.com/mholt/certmagic v0.9.1/go.mod h1:nu8jbsbtwK4205EDH/ZUMTKsfYpJA1Q7MKXHfgTihNw= -github.com/micro/cli v0.2.0 h1:ut3rV5JWqZjsXIa2MvGF+qMUP8DAUTvHX9Br5gO4afA= -github.com/micro/cli v0.2.0/go.mod h1:jRT9gmfVKWSS6pkKcXQ8YhUyj6bzwxK8Fp5b0Y7qNnk= +github.com/micro/cli/v2 v2.1.1 h1:uFw0SMIKmGuyHIm8lXns/NOn7V62bM5y7DnlxUM+BEQ= +github.com/micro/cli/v2 v2.1.1/go.mod h1:EguNh6DAoWKm9nmk+k/Rg0H3lQnDxqzu5x5srOtGtYg= github.com/micro/mdns v0.3.0 h1:bYycYe+98AXR3s8Nq5qvt6C573uFTDPIYzJemWON0QE= github.com/micro/mdns v0.3.0/go.mod h1:KJ0dW7KmicXU2BV++qkLlmHYcVv7/hHnbtguSWt9Aoc= github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -373,11 +376,13 @@ github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKc github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sacloud/libsacloud v1.26.1/go.mod h1:79ZwATmHLIFZIMd7sxA3LwzVy/B77uj3LDoToVTxDoQ= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 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= @@ -401,8 +406,8 @@ github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM= github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog= github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20200122045848-3419fae592fc h1:yUaosFVTJwnltaHbSNC3i82I92quFs+OFPRl8kNMVwo= +github.com/tmc/grpc-websocket-proxy v0.0.0-20200122045848-3419fae592fc/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f/go.mod h1:i0f4R4o2HM0m3DZYQWsj6/MEowD57VzoH0v3d7igeFY= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= @@ -464,6 +469,7 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= @@ -559,6 +565,7 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= diff --git a/options.go b/options.go index 673d1bfd..f73a3a45 100644 --- a/options.go +++ b/options.go @@ -4,7 +4,6 @@ import ( "context" "time" - "github.com/micro/cli" "github.com/micro/go-micro/broker" "github.com/micro/go-micro/client" "github.com/micro/go-micro/client/selector" @@ -12,6 +11,7 @@ import ( "github.com/micro/go-micro/registry" "github.com/micro/go-micro/server" "github.com/micro/go-micro/transport" + "github.com/micro/cli/v2" ) type Options struct { @@ -166,7 +166,7 @@ func Flags(flags ...cli.Flag) Option { } } -func Action(a func(*cli.Context)) Option { +func Action(a func(*cli.Context) error) Option { return func(o *Options) { o.Cmd.App().Action = a } diff --git a/service.go b/service.go index abbf23c5..521135e7 100644 --- a/service.go +++ b/service.go @@ -15,6 +15,7 @@ import ( "github.com/micro/go-micro/debug/profile/pprof" "github.com/micro/go-micro/debug/service/handler" "github.com/micro/go-micro/debug/stats" + "github.com/micro/go-micro/debug/trace" "github.com/micro/go-micro/plugin" "github.com/micro/go-micro/server" "github.com/micro/go-micro/util/log" @@ -36,8 +37,15 @@ func newService(opts ...Option) Service { // wrap client to inject From-Service header on any calls options.Client = wrapper.FromService(serviceName, options.Client) + // wrap client to inject From-Service header on any calls + options.Client = wrapper.TraceCall(serviceName, trace.DefaultTrace, options.Client) + // wrap the server to provide handler stats - options.Server.Init(server.WrapHandler(wrapper.HandlerStats(stats.DefaultStats))) + options.Server.Init( + server.WrapHandler(wrapper.HandlerStats(stats.DefaultStats)), + server.WrapHandler(wrapper.TraceHandler(trace.DefaultTrace)), + ) + return &service{ opts: options, diff --git a/tunnel/default.go b/tunnel/default.go index 798bc886..d146cb34 100644 --- a/tunnel/default.go +++ b/tunnel/default.go @@ -433,7 +433,7 @@ func (t *tun) process() { } // send the message - t.sendTo(sendTo, msg) + go t.sendTo(sendTo, msg) case <-t.closed: return } diff --git a/util/wrapper/wrapper.go b/util/wrapper/wrapper.go index 371bcb66..17d985c4 100644 --- a/util/wrapper/wrapper.go +++ b/util/wrapper/wrapper.go @@ -5,6 +5,7 @@ import ( "github.com/micro/go-micro/client" "github.com/micro/go-micro/debug/stats" + "github.com/micro/go-micro/debug/trace" "github.com/micro/go-micro/metadata" "github.com/micro/go-micro/server" ) @@ -14,6 +15,13 @@ type clientWrapper struct { headers metadata.Metadata } +type traceWrapper struct { + client.Client + + name string + trace trace.Trace +} + var ( HeaderPrefix = "Micro-" ) @@ -48,6 +56,20 @@ func (c *clientWrapper) Publish(ctx context.Context, p client.Message, opts ...c return c.Client.Publish(ctx, p, opts...) } +func (c *traceWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { + newCtx, s := c.trace.Start(ctx, req.Service()+"."+req.Endpoint()) + + err := c.Client.Call(newCtx, req, rsp, opts...) + if err != nil { + s.Metadata["error"] = err.Error() + } + + // finish the trace + c.trace.Finish(s) + + return err +} + // FromService wraps a client to inject From-Service header into metadata func FromService(name string, c client.Client) client.Client { return &clientWrapper{ @@ -73,3 +95,34 @@ func HandlerStats(stats stats.Stats) server.HandlerWrapper { } } } + +// TraceCall is a call tracing wrapper +func TraceCall(name string, t trace.Trace, c client.Client) client.Client { + return &traceWrapper{ + name: name, + trace: t, + Client: c, + } +} + +// TraceHandler wraps a server handler to perform tracing +func TraceHandler(t trace.Trace) server.HandlerWrapper { + // return a handler wrapper + return func(h server.HandlerFunc) server.HandlerFunc { + // return a function that returns a function + return func(ctx context.Context, req server.Request, rsp interface{}) error { + // get the span + newCtx, s := t.Start(ctx, req.Service()+"."+req.Endpoint()) + + err := h(newCtx, req, rsp) + if err != nil { + s.Metadata["error"] = err.Error() + } + + // finish + t.Finish(s) + + return err + } + } +} diff --git a/web/options.go b/web/options.go index 0570f7ba..ec4e1a6b 100644 --- a/web/options.go +++ b/web/options.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/micro/cli" + "github.com/micro/cli/v2" "github.com/micro/go-micro" "github.com/micro/go-micro/registry" ) diff --git a/web/service.go b/web/service.go index b76b13b9..46936b9c 100644 --- a/web/service.go +++ b/web/service.go @@ -14,7 +14,6 @@ import ( "syscall" "time" - "github.com/micro/cli" "github.com/micro/go-micro" "github.com/micro/go-micro/registry" maddr "github.com/micro/go-micro/util/addr" @@ -22,6 +21,7 @@ import ( "github.com/micro/go-micro/util/log" mnet "github.com/micro/go-micro/util/net" mls "github.com/micro/go-micro/util/tls" + "github.com/micro/cli/v2" ) type service struct { @@ -327,7 +327,7 @@ func (s *service) Init(opts ...Option) error { serviceOpts = append(serviceOpts, micro.Registry(s.opts.Registry)) } - serviceOpts = append(serviceOpts, micro.Action(func(ctx *cli.Context) { + serviceOpts = append(serviceOpts, micro.Action(func(ctx *cli.Context) error { if ttl := ctx.Int("register_ttl"); ttl > 0 { s.opts.RegisterTTL = time.Duration(ttl) * time.Second } @@ -359,6 +359,8 @@ func (s *service) Init(opts ...Option) error { if s.opts.Action != nil { s.opts.Action(ctx) } + + return nil })) s.opts.Service.Init(serviceOpts...)