日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Golang 微服务系列 go-kit(Log,Metrics,Tracing)

發布時間:2023/12/9 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Golang 微服务系列 go-kit(Log,Metrics,Tracing) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

go-kit Log & Metrics & Tracing

微服務監控3大核心 Log & Metrics & Tracing

Log

Log 模塊源碼有待分析(分析完再補上)

Metrics

主要是封裝 Metrics 接口,及各個 Metrics(Prometheus,InfluxDB,StatsD,expvar) 中間件的封裝。

// Counter describes a metric that accumulates values monotonically. // An example of a counter is the number of received HTTP requests. type Counter interface {With(labelValues ...string) CounterAdd(delta float64) }// Gauge describes a metric that takes specific values over time. // An example of a gauge is the current depth of a job queue. type Gauge interface {With(labelValues ...string) GaugeSet(value float64)Add(delta float64) }// Histogram describes a metric that takes repeated observations of the same // kind of thing, and produces a statistical summary of those observations, // typically expressed as quantiles or buckets. An example of a histogram is // HTTP request latencies. type Histogram interface {With(labelValues ...string) HistogramObserve(value float64) }

Tracing

Tracing 主要是對 Zipkin, OpenTracing, OpenCensus 的封裝。

Zipkin

func TraceEndpoint(tracer *zipkin.Tracer, name string) endpoint.Middleware {return func(next endpoint.Endpoint) endpoint.Endpoint {return func(ctx context.Context, request interface{}) (interface{}, error) {var sc model.SpanContextif parentSpan := zipkin.SpanFromContext(ctx); parentSpan != nil {sc = parentSpan.Context()}sp := tracer.StartSpan(name, zipkin.Parent(sc))defer sp.Finish()ctx = zipkin.NewContext(ctx, sp)return next(ctx, request)}} }

OpenTracing

// TraceServer returns a Middleware that wraps the `next` Endpoint in an // OpenTracing Span called `operationName`. // // If `ctx` already has a Span, it is re-used and the operation name is // overwritten. If `ctx` does not yet have a Span, one is created here. func TraceServer(tracer opentracing.Tracer, operationName string) endpoint.Middleware {return func(next endpoint.Endpoint) endpoint.Endpoint {return func(ctx context.Context, request interface{}) (interface{}, error) {serverSpan := opentracing.SpanFromContext(ctx)if serverSpan == nil {// All we can do is create a new root span.serverSpan = tracer.StartSpan(operationName)} else {serverSpan.SetOperationName(operationName)}defer serverSpan.Finish()otext.SpanKindRPCServer.Set(serverSpan)ctx = opentracing.ContextWithSpan(ctx, serverSpan)return next(ctx, request)}} }// TraceClient returns a Middleware that wraps the `next` Endpoint in an // OpenTracing Span called `operationName`. func TraceClient(tracer opentracing.Tracer, operationName string) endpoint.Middleware {return func(next endpoint.Endpoint) endpoint.Endpoint {return func(ctx context.Context, request interface{}) (interface{}, error) {var clientSpan opentracing.Spanif parentSpan := opentracing.SpanFromContext(ctx); parentSpan != nil {clientSpan = tracer.StartSpan(operationName,opentracing.ChildOf(parentSpan.Context()),)} else {clientSpan = tracer.StartSpan(operationName)}defer clientSpan.Finish()otext.SpanKindRPCClient.Set(clientSpan)ctx = opentracing.ContextWithSpan(ctx, clientSpan)return next(ctx, request)}} }

OpenCensus

func TraceEndpoint(name string, options ...EndpointOption) endpoint.Middleware {if name == "" {name = TraceEndpointDefaultName}cfg := &EndpointOptions{}for _, o := range options {o(cfg)}return func(next endpoint.Endpoint) endpoint.Endpoint {return func(ctx context.Context, request interface{}) (response interface{}, err error) {ctx, span := trace.StartSpan(ctx, name)if len(cfg.Attributes) > 0 {span.AddAttributes(cfg.Attributes...)}defer span.End()defer func() {if err != nil {if lberr, ok := err.(lb.RetryError); ok {// handle errors originating from lb.Retryattrs := make([]trace.Attribute, 0, len(lberr.RawErrors))for idx, rawErr := range lberr.RawErrors {attrs = append(attrs, trace.StringAttribute("gokit.retry.error."+strconv.Itoa(idx+1), rawErr.Error(),))}span.AddAttributes(attrs...)span.SetStatus(trace.Status{Code: trace.StatusCodeUnknown,Message: lberr.Final.Error(),})return}// generic errorspan.SetStatus(trace.Status{Code: trace.StatusCodeUnknown,Message: err.Error(),})return}// test for business errorif res, ok := response.(endpoint.Failer); ok && res.Failed() != nil {span.AddAttributes(trace.StringAttribute("gokit.business.error", res.Failed().Error()),)if cfg.IgnoreBusinessError {span.SetStatus(trace.Status{Code: trace.StatusCodeOK})return}// treating business error as real error in span.span.SetStatus(trace.Status{Code: trace.StatusCodeUnknown,Message: res.Failed().Error(),})return}// no errors identifiedspan.SetStatus(trace.Status{Code: trace.StatusCodeOK})}()response, err = next(ctx, request)return}} }

使用

參考 examples/set.go

var concatEndpoint endpoint.EndpointconcatEndpoint = MakeConcatEndpoint(svc) concatEndpoint = opentracing.TraceServer(otTracer, "Concat")(concatEndpoint) concatEndpoint = zipkin.TraceEndpoint(zipkinTracer, "Concat")(concatEndpoint) concatEndpoint = LoggingMiddleware(log.With(logger, "method", "Concat"))(concatEndpoint) concatEndpoint = InstrumentingMiddleware(duration.With("method", "Concat"))(concatEndpoint)

小結

通過把第三方中間件封裝成 endpoint.Middleware, 可以與其它 go-kit 中間件組合。

總結

以上是生活随笔為你收集整理的Golang 微服务系列 go-kit(Log,Metrics,Tracing)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。