diff --git a/codec.go b/codec.go index 7111807..6181259 100644 --- a/codec.go +++ b/codec.go @@ -1,7 +1,7 @@ package grpc import ( - "go.unistack.org/micro/v3/codec" + "go.unistack.org/micro/v4/codec" "google.golang.org/grpc" "google.golang.org/grpc/encoding" ) diff --git a/codec_test.go b/codec_test.go index 54b9e90..d08644f 100644 --- a/codec_test.go +++ b/codec_test.go @@ -2,9 +2,10 @@ package grpc import ( "context" - "go.unistack.org/micro/v3/codec" - gmetadata "google.golang.org/grpc/metadata" "testing" + + "go.unistack.org/micro/v4/codec" + gmetadata "google.golang.org/grpc/metadata" ) type mockStream struct { diff --git a/go.mod b/go.mod index fd2d73a..a6fc461 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module go.unistack.org/micro-client-grpc/v4 go 1.23.0 +toolchain go1.23.3 + require ( go.unistack.org/micro/v4 v4.1.2 google.golang.org/grpc v1.70.0 diff --git a/grpc.go b/grpc.go index a5aa9e5..b0fd4c3 100644 --- a/grpc.go +++ b/grpc.go @@ -5,11 +5,6 @@ import ( "context" "crypto/tls" "fmt" - "go.unistack.org/micro/v4/options" - "go.unistack.org/micro/v4/semconv" - "go.unistack.org/micro/v4/tracer" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "net" "reflect" "strconv" @@ -21,12 +16,17 @@ import ( "go.unistack.org/micro/v4/codec" "go.unistack.org/micro/v4/errors" "go.unistack.org/micro/v4/metadata" + "go.unistack.org/micro/v4/options" "go.unistack.org/micro/v4/selector" + "go.unistack.org/micro/v4/semconv" + "go.unistack.org/micro/v4/tracer" "google.golang.org/grpc" + "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/encoding" gmetadata "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" ) const ( @@ -428,6 +428,37 @@ func (g *grpcClient) NewRequest(service, method string, req interface{}, reqOpts return newGRPCRequest(service, method, req, g.opts.ContentType, reqOpts...) } +func (g *grpcClient) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { + if req == nil { + return errors.InternalServerError("go.micro.client", "req is nil") + } else if rsp == nil { + return errors.InternalServerError("go.micro.client", "rsp is nil") + } + + ts := time.Now() + g.opts.Meter.Counter(semconv.ClientRequestInflight, "endpoint", req.Endpoint()).Inc() + var sp tracer.Span + ctx, sp = g.opts.Tracer.Start(ctx, req.Endpoint()+" rpc-client", + tracer.WithSpanKind(tracer.SpanKindClient), + tracer.WithSpanLabels("endpoint", req.Endpoint()), + ) + err := g.funcCall(ctx, req, rsp, opts...) + g.opts.Meter.Counter(semconv.ClientRequestInflight, "endpoint", req.Endpoint()).Dec() + te := time.Since(ts) + g.opts.Meter.Summary(semconv.ClientRequestLatencyMicroseconds, "endpoint", req.Endpoint()).Update(te.Seconds()) + g.opts.Meter.Histogram(semconv.ClientRequestDurationSeconds, "endpoint", req.Endpoint()).Update(te.Seconds()) + + if me := errors.FromError(err); me == nil { + sp.Finish() + g.opts.Meter.Counter(semconv.ClientRequestTotal, "endpoint", req.Endpoint(), "status", "success", "code", strconv.Itoa(int(200))).Inc() + } else { + sp.SetStatus(tracer.SpanStatusError, err.Error()) + g.opts.Meter.Counter(semconv.ClientRequestTotal, "endpoint", req.Endpoint(), "status", "failure", "code", strconv.Itoa(int(me.Code))).Inc() + } + + return err +} + func (g *grpcClient) fnCall(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { // make a copy of call opts callOpts := g.opts.CallOptions @@ -558,13 +589,7 @@ func (g *grpcClient) fnCall(ctx context.Context, req client.Request, rsp interfa return gerr } -func (g *grpcClient) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { - if req == nil { - return errors.InternalServerError("go.micro.client", "req is nil") - } else if rsp == nil { - return errors.InternalServerError("go.micro.client", "rsp is nil") - } - +func (g *grpcClient) Stream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) { ts := time.Now() g.opts.Meter.Counter(semconv.ClientRequestInflight, "endpoint", req.Endpoint()).Inc() var sp tracer.Span @@ -572,21 +597,21 @@ func (g *grpcClient) Call(ctx context.Context, req client.Request, rsp interface tracer.WithSpanKind(tracer.SpanKindClient), tracer.WithSpanLabels("endpoint", req.Endpoint()), ) - err := g.funcCall(ctx, req, rsp, opts...) + stream, err := g.funcStream(ctx, req, opts...) g.opts.Meter.Counter(semconv.ClientRequestInflight, "endpoint", req.Endpoint()).Dec() te := time.Since(ts) g.opts.Meter.Summary(semconv.ClientRequestLatencyMicroseconds, "endpoint", req.Endpoint()).Update(te.Seconds()) g.opts.Meter.Histogram(semconv.ClientRequestDurationSeconds, "endpoint", req.Endpoint()).Update(te.Seconds()) - if me := errors.FromError(err); me == nil { + if me := status.Convert(err); me == nil { sp.Finish() - g.opts.Meter.Counter(semconv.ClientRequestTotal, "endpoint", req.Endpoint(), "status", "success", "code", strconv.Itoa(int(200))).Inc() + g.opts.Meter.Counter(semconv.ClientRequestTotal, "endpoint", req.Endpoint(), "status", "success", "code", strconv.Itoa(int(codes.OK))).Inc() } else { sp.SetStatus(tracer.SpanStatusError, err.Error()) - g.opts.Meter.Counter(semconv.ClientRequestTotal, "endpoint", req.Endpoint(), "status", "failure", "code", strconv.Itoa(int(me.Code))).Inc() + g.opts.Meter.Counter(semconv.ClientRequestTotal, "endpoint", req.Endpoint(), "status", "failure", "code", strconv.Itoa(int(me.Code()))).Inc() } - return err + return stream, err } func (g *grpcClient) fnStream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) { @@ -717,31 +742,6 @@ func (g *grpcClient) fnStream(ctx context.Context, req client.Request, opts ...c return nil, grr } -func (g *grpcClient) Stream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) { - ts := time.Now() - g.opts.Meter.Counter(semconv.ClientRequestInflight, "endpoint", req.Endpoint()).Inc() - var sp tracer.Span - ctx, sp = g.opts.Tracer.Start(ctx, req.Endpoint()+" rpc-client", - tracer.WithSpanKind(tracer.SpanKindClient), - tracer.WithSpanLabels("endpoint", req.Endpoint()), - ) - stream, err := g.funcStream(ctx, req, opts...) - g.opts.Meter.Counter(semconv.ClientRequestInflight, "endpoint", req.Endpoint()).Dec() - te := time.Since(ts) - g.opts.Meter.Summary(semconv.ClientRequestLatencyMicroseconds, "endpoint", req.Endpoint()).Update(te.Seconds()) - g.opts.Meter.Histogram(semconv.ClientRequestDurationSeconds, "endpoint", req.Endpoint()).Update(te.Seconds()) - - if me := status.Convert(err); me == nil { - sp.Finish() - g.opts.Meter.Counter(semconv.ClientRequestTotal, "endpoint", req.Endpoint(), "status", "success", "code", strconv.Itoa(int(codes.OK))).Inc() - } else { - sp.SetStatus(tracer.SpanStatusError, err.Error()) - g.opts.Meter.Counter(semconv.ClientRequestTotal, "endpoint", req.Endpoint(), "status", "failure", "code", strconv.Itoa(int(me.Code()))).Inc() - } - - return stream, err -} - func (g *grpcClient) String() string { return "grpc" } diff --git a/stream.go b/stream.go index 445a8f7..b591017 100644 --- a/stream.go +++ b/stream.go @@ -6,6 +6,7 @@ import ( "sync" "go.unistack.org/micro/v4/client" + "go.unistack.org/micro/v4/tracer" "google.golang.org/grpc" )