Merge pull request 'add client tracing' (#341) from traceclient into v3

Reviewed-on: #341
This commit is contained in:
Василий Толстов 2024-04-22 23:44:54 +03:00
commit 54a55c83e2
2 changed files with 66 additions and 8 deletions

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"os" "os"
"strconv"
"time" "time"
"go.unistack.org/micro/v3/broker" "go.unistack.org/micro/v3/broker"
@ -12,6 +13,8 @@ import (
"go.unistack.org/micro/v3/metadata" "go.unistack.org/micro/v3/metadata"
"go.unistack.org/micro/v3/options" "go.unistack.org/micro/v3/options"
"go.unistack.org/micro/v3/selector" "go.unistack.org/micro/v3/selector"
"go.unistack.org/micro/v3/semconv"
"go.unistack.org/micro/v3/tracer"
) )
// DefaultCodecs will be used to encode/decode data // DefaultCodecs will be used to encode/decode data
@ -104,10 +107,13 @@ func (n *noopResponse) Read() ([]byte, error) {
return nil, nil return nil, nil
} }
type noopStream struct{} type noopStream struct {
err error
ctx context.Context
}
func (n *noopStream) Context() context.Context { func (n *noopStream) Context() context.Context {
return context.Background() return n.ctx
} }
func (n *noopStream) Request() Request { func (n *noopStream) Request() Request {
@ -135,15 +141,21 @@ func (n *noopStream) RecvMsg(interface{}) error {
} }
func (n *noopStream) Error() error { func (n *noopStream) Error() error {
return nil return n.err
} }
func (n *noopStream) Close() error { func (n *noopStream) Close() error {
return nil if sp, ok := tracer.SpanFromContext(n.ctx); ok && sp != nil {
if n.err != nil {
sp.SetStatus(tracer.SpanStatusError, n.err.Error())
}
sp.Finish()
}
return n.err
} }
func (n *noopStream) CloseSend() error { func (n *noopStream) CloseSend() error {
return nil return n.err
} }
func (n *noopMessage) Topic() string { func (n *noopMessage) Topic() string {
@ -207,7 +219,28 @@ func (n *noopClient) String() string {
} }
func (n *noopClient) Call(ctx context.Context, req Request, rsp interface{}, opts ...CallOption) error { func (n *noopClient) Call(ctx context.Context, req Request, rsp interface{}, opts ...CallOption) error {
return n.funcCall(ctx, req, rsp, opts...) ts := time.Now()
n.opts.Meter.Counter(semconv.ClientRequestInflight, "endpoint", req.Endpoint()).Inc()
var sp tracer.Span
ctx, sp = n.opts.Tracer.Start(ctx, req.Endpoint()+" rpc-client",
tracer.WithSpanKind(tracer.SpanKindClient),
tracer.WithSpanLabels("endpoint", req.Endpoint()),
)
err := n.funcCall(ctx, req, rsp, opts...)
n.opts.Meter.Counter(semconv.ClientRequestInflight, "endpoint", req.Endpoint()).Dec()
te := time.Since(ts)
n.opts.Meter.Summary(semconv.ClientRequestLatencyMicroseconds, "endpoint", req.Endpoint()).Update(te.Seconds())
n.opts.Meter.Histogram(semconv.ClientRequestDurationSeconds, "endpoint", req.Endpoint()).Update(te.Seconds())
if me := errors.FromError(err); me == nil {
sp.Finish()
n.opts.Meter.Counter(semconv.ClientRequestTotal, "endpoint", req.Endpoint(), "status", "success", "code", strconv.Itoa(int(200))).Inc()
} else {
sp.SetStatus(tracer.SpanStatusError, err.Error())
n.opts.Meter.Counter(semconv.ClientRequestTotal, "endpoint", req.Endpoint(), "status", "failure", "code", strconv.Itoa(int(me.Code))).Inc()
}
return err
} }
func (n *noopClient) fnCall(ctx context.Context, req Request, rsp interface{}, opts ...CallOption) error { func (n *noopClient) fnCall(ctx context.Context, req Request, rsp interface{}, opts ...CallOption) error {
@ -349,7 +382,28 @@ func (n *noopClient) NewMessage(topic string, msg interface{}, opts ...MessageOp
} }
func (n *noopClient) Stream(ctx context.Context, req Request, opts ...CallOption) (Stream, error) { func (n *noopClient) Stream(ctx context.Context, req Request, opts ...CallOption) (Stream, error) {
return n.funcStream(ctx, req, opts...) ts := time.Now()
n.opts.Meter.Counter(semconv.ClientRequestInflight, "endpoint", req.Endpoint()).Inc()
var sp tracer.Span
ctx, sp = n.opts.Tracer.Start(ctx, req.Endpoint()+" rpc-client",
tracer.WithSpanKind(tracer.SpanKindClient),
tracer.WithSpanLabels("endpoint", req.Endpoint()),
)
stream, err := n.funcStream(ctx, req, opts...)
n.opts.Meter.Counter(semconv.ClientRequestInflight, "endpoint", req.Endpoint()).Dec()
te := time.Since(ts)
n.opts.Meter.Summary(semconv.ClientRequestLatencyMicroseconds, "endpoint", req.Endpoint()).Update(te.Seconds())
n.opts.Meter.Histogram(semconv.ClientRequestDurationSeconds, "endpoint", req.Endpoint()).Update(te.Seconds())
if me := errors.FromError(err); me == nil {
sp.Finish()
n.opts.Meter.Counter(semconv.ClientRequestTotal, "endpoint", req.Endpoint(), "status", "success", "code", strconv.Itoa(int(200))).Inc()
} else {
sp.SetStatus(tracer.SpanStatusError, err.Error())
n.opts.Meter.Counter(semconv.ClientRequestTotal, "endpoint", req.Endpoint(), "status", "failure", "code", strconv.Itoa(int(me.Code))).Inc()
}
return stream, err
} }
func (n *noopClient) fnStream(ctx context.Context, req Request, opts ...CallOption) (Stream, error) { func (n *noopClient) fnStream(ctx context.Context, req Request, opts ...CallOption) (Stream, error) {
@ -493,7 +547,7 @@ func (n *noopClient) fnStream(ctx context.Context, req Request, opts ...CallOpti
} }
func (n *noopClient) stream(ctx context.Context, addr string, req Request, opts CallOptions) (Stream, error) { func (n *noopClient) stream(ctx context.Context, addr string, req Request, opts CallOptions) (Stream, error) {
return &noopStream{}, nil return &noopStream{ctx: ctx}, nil
} }
func (n *noopClient) BatchPublish(ctx context.Context, ps []Message, opts ...PublishOption) error { func (n *noopClient) BatchPublish(ctx context.Context, ps []Message, opts ...PublishOption) error {

View File

@ -262,6 +262,10 @@ func CodeIn(err interface{}, codes ...int32) bool {
// FromError try to convert go error to *Error // FromError try to convert go error to *Error
func FromError(err error) *Error { func FromError(err error) *Error {
if err == nil {
return nil
}
if verr, ok := err.(*Error); ok && verr != nil { if verr, ok := err.(*Error); ok && verr != nil {
return verr return verr
} }