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 中间件组合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276561.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

shell 练习3

1、编写脚本/root/bin/createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息2、编写脚本/root/bin/yesorno.sh,提示…

两个数组结果相减_学点算法(三)——数组归并排序

今天来学习归并排序算法。分而治之归并算法的核心思想是分而治之,就是将大问题转化为小问题,在解决小问题的基础上,再去解决大问题。将这句话套用到排序中,就是将一个大的待排序区间分为小的待排序区间,对小的排序区间…

ASP记数器

这两天有好几个老的ASP网站要改,其中有要求加记数器,为图简单,就用文本文件的形式存储记数。以前用ifream的形式嵌入,不能很好的控制记数器显示的风格,现在改进了一下,可以很好的与嵌入板块风格结合了。把做…

[转] DevExpress 第三方控件汉化的全部代码和使用方法

DevExpress.XtraEditors.Controls 此控件包中包含的控件最多,包括文本框,下拉列表,按钮,等等 DevExpress.XtraGrid 网格 DevExpress.XtraBars 菜单栏 和 工具栏 DevExpress.XtraNavBar 导航条 DevExpress.XtraPr…

福音!微信个人公众号可以改名了!

微信个人公众号可以改名了!!!今年,我们学校从景德镇陶瓷学院更名为景德镇陶瓷大学,但苦于微信限制,很多微信公众号无法更名。很多组织社团就放弃了原先的关注量,重新申请注册账号。当前我们的订…

js list删除指定元素_删除js数组中的指定元素,有这两步就够了

js数组是js部分非常重要的知识,有时我们有这么个需求js数组删除指定元素,先定义一个函数来获取删除指定元素索引值,然后用js数组删除的方法,来删除指定元素即可,就两步不难,很简单。1、JS的数组对象定义一个…

计算机协会丨让技能得到提升,让思维受到启迪

“ 各位2016级新生,新的学期马上就要开始了,学校的各个组织和社团你真的了解了吗?在眼花缭乱的社团里如何找到自己真正喜欢的呢?或许看完计算机协会的纳新微信你就都明白啦!关键词:计算机协会景德镇陶瓷大学…

ondestroy什么时候调用_尾调用和尾递归

尾调用1. 定义尾调用是函数式编程中一个很重要的概念,当一个函数执行时的最后一个步骤是返回另一个函数的调用,这就叫做尾调用。注意这里函数的调用方式是无所谓的,以下方式均可:函数调用: func()方法调用: obj.method()call调用:…

dhl:使用return RedirectToAction()和 return view()

一个Action&#xff1a; Code/// <summary> /// Friend好友的地 /// </summary> /// <returns></returns> public ActionResult FriendFarm(string pid) {BLL.DTOFarm farm new AppleGrange.BLL.DTOFarm(pid); …

radio切换控制div显示_JavaScript连载31图片动态切换以及关闭图片案例

一、图标切换31.1点击那两个按钮可以做到轮番显示图片二、关闭图片案例31.2点击右上角的叉&#xff0c;图片会消失。三、源码&#xff1a;D31_iconSwitch.htmlD31_2_CloseImage.html地址:https://github.com/ruigege66/JavaScript/blob/master/D31_iconSwitch.htmlhttps://gith…

工作一年后,我有些感悟(写于2017年)

时间拉回到2016年5月23日&#xff0c;当天拍毕业照&#xff0c;晚上是大学毕业酒会&#xff0c;那一晚整个酒店都弥漫着伤感的气息。那一晚大家为了找KTV拖延到很晚&#xff0c;最后一群人选择来到了操场&#xff0c;凌晨两点多一群人还在操场上玩着游戏。5月25日离校&#xff…

PHP基础学习之数组使用要点

一、什么是PHP数组&#xff1f;数组 array 是一组有序的变量&#xff0c;其中每个变量都被称为一个元素。每个元素由一个特殊的标识符来区分&#xff0c;这个标识符称之为键&#xff08;也可以称之为下标&#xff09;。数组中的每个元素都包含两项&#xff1a;键和值。可以通过…

高考七年后、工作三年后的感悟

本打算端午假期发表这文章&#xff0c;后来因为文章还需要有些调整&#xff0c;工作日又比较忙&#xff0c;就到今天周三才发。随便写了近3000字&#xff0c;文章最后有免费送书活动&#xff0c;欢迎留言参与。又一年高考结束了。转眼高考过去七年了&#xff0c;工作了三年。很…

蚂蚁金服天街:OceanBase 在大促 5 年来的技术演进

为了与金融从业者、科技从业者共同探讨金融 业务的深层次问题&#xff0c;蚂蚁金服联手 TGO 鲲鹏会&#xff0c;在 12 月 8 日举办了「走进蚂蚁金服&#xff1a;双十一背后的蚂蚁金服技术支持」活动。蚂蚁金服高级技术专家天街为大家分享了《蚂蚁双 11 大促 OceanBase 核心技术…

学习 jQuery 源码整体架构,打造属于自己的 js 类库

虽然现在基本不怎么使用 jQuery了&#xff0c;但 jQuery流行 10多年的 JS库&#xff0c;还是有必要学习它的源码的。也可以学着打造属于自己的 js类库&#xff0c;求职面试时可以增色不少。本文章学习的是 v3.4.1版本。unpkg.com源码地址&#xff1a;https://unpkg.com/jquery3…

5分钟轻松教您如果组建100-500路大型拼接监控系统!

冰山融汇百家号17-07-2700:41大型监控系统如何组网&#xff0c;分布式还是集中式&#xff1f;可靠性与性价比又如何取舍&#xff1f;什么才是最合适的视频监控存储产品&#xff1f;在不同地区、行业的项目中&#xff0c;这些疑问均成为业主、专家、系统集成商等各方面共同关注的…

(转)mssql2005生成表字典

出处不详 CodeSELECT TOP 100 PERCENT --a.id, CASE WHEN a.colorder 1 THEN d.name ELSE END AS 表名, CASE WHEN a.colorder 1 THEN isnull(f.value, ) ELSE END AS 表说明, a.colorder AS 字段序号, a.name AS 字段名, CASE WHEN COLUMNPROPERTY(a.id, a.name, IsIdenti…

表操作

2019独角兽企业重金招聘Python工程师标准>>> 字段修改 alter table TA drop partition (day<2018-12-10); ALTER TABLE TB ADD COLUMNS (userStatus String) CASCADE; ALTER TABLE TC change appversion appCommonVersion String CASCADE; ALTER TABLE TD DROP C…

学习underscore源码整体架构,打造属于自己的函数式编程类库

前言上一篇文章写了 jQuery整体架构&#xff0c;学习 jQuery 源码整体架构&#xff0c;打造属于自己的 js 类库虽然看过挺多 underscore.js分析类的文章&#xff0c;但总感觉少点什么。这也许就是纸上得来终觉浅&#xff0c;绝知此事要躬行吧。于是决定自己写一篇学习 undersco…

拓扑目的 1.Pc9通过van3访问pc10 2.Pc9通过Vlan1\Vlan2访问pc11

1拓扑图2设置路由器R12的接口的IPint g0/0/0ip address 192.168.20.254 24undo shutdown int g0/0/01ip address 192.168.1.1 24undo shutdownint g2/0/00ip address 192.168.3.1 24undo shutdown 3设置路由器R10的接口的IPint g0/0/0ip address 192.168.2.1 24undo shutdownin…