ZBLOG

golang基于grpc的微服务开发脚手架分布式日志链路追踪设计

在Golang基于gRPC的微服务开发中,常常需要对分布式系统进行日志和链路追踪,以便更好地进行监控和调试。下面是一个简单的设计示例:

  1. 安装依赖:
  1. $ go get google.golang.org/grpc
  2. $ go get github.com/golang/protobuf/proto
  3. $ go get github.com/golang/protobuf/protoc-gen-go
  4. # 安装logrus和logrus的json格式输出插件。
  5. $ go get github.com/sirupsen/logrus
  6. $ go get github.com/mattn/go-isatty
  7. # 安装opentracing相关库。
  8. $ go get github.com/opentracing/opentracing-go
  9. $ go get github.com/uber/jaeger-client-go/config
  1. 在main函数中初始化Logrus、Jaeger等组件并设置日志级别、输出格式等参数:
  1. import (
  2. "log"
  3. "os"
  4. "github.com/sirupsen/logrus"
  5. "github.com/mattn/go-isatty"
  6. "github.com/opentracing/opentracing-go"
  7. "github.com/uber/jaeger-client-go/config"
  8. )
  9. func main() {
  10. // 初始化Logrus,并设置日志级别、输出格式等参数。
  11. logrus.SetFormatter(&logrus.JSONFormatter{})
  12. if isatty.IsTerminal(os.Stdout.Fd()) {
  13. logrus.SetLevel(logrus.DebugLevel)
  14. } else {
  15. logrus.SetLevel(logrus.InfoLevel)
  16. }
  17. logrus.SetOutput(os.Stdout)
  18. // 初始化Jaeger Tracer。
  19. cfg, err := config.FromEnv()
  20. if err != nil {
  21. log.Fatalf("Failed to read Jaeger config from env: %v", err)
  22. }
  23. tracer, closer, err := cfg.NewTracer()
  24. if err != nil {
  25. log.Fatalf("Failed to create Jaeger tracer: %v", err)
  26. }
  27. defer closer.Close()
  28. opentracing.SetGlobalTracer(tracer)
  29. // ...
  30. }
  1. 封装Logrus和Jaeger,以便在Golang基于gRPC的微服务开发中进行使用:
  1. import (
  2. "github.com/sirupsen/logrus"
  3. "github.com/opentracing/opentracing-go"
  4. "github.com/opentracing/opentracing-go/ext"
  5. "github.com/uber/jaeger-client-go"
  6. jaegercfg "github.com/uber/jaeger-client-go/config"
  7. )
  8. var log *logrus.Entry
  9. func init() {
  10. log = logrus.WithFields(logrus.Fields{
  11. "app": "myapp",
  12. "env": "production",
  13. })
  14. }
  15. func doSomething(ctx context.Context) {
  16. // 创建Span。
  17. span, ctx := opentracing.StartSpanFromContext(ctx, "doSomething")
  18. defer span.Finish()
  19. // 记录日志。
  20. log.WithFields(logrus.Fields{
  21. "operation": span.OperationName(),
  22. "trace_id": span.Context().(jaeger.SpanContext).TraceID().String(),
  23. "span_id": span.Context().(jaeger.SpanContext).SpanID().String(),
  24. }).Infof("doing something")
  25. // 发起下游调用,将当前Span传递给下游服务。
  26. req := &pb.Request{...}
  27. resp, err := client.Call(ctx, req)
  28. if err != nil {...}
  29. // 记录返回结果,并设置相关标签。
  30. ext.HTTPStatusCode.Set(span, uint16(resp.StatusCode))
  31. log.WithFields(logrus.Fields{
  32. "operation": span.OperationName(),
  33. "trace_id": span.Context().(jaeger.SpanContext).TraceID().String(),
  34. "span_id": span.Context().(jaeger.SpanContext).SpanID().String(),
  35. "response_code": resp.StatusCode,
  36. }).Infof("got response")
  37. // ...
  38. }

在这个设计中,我们使用了Logrus作为日志组件,并使用Jaeger作为分布式链路追踪组件。在main函数中初始化Logrus和Jaeger,并设置日志级别、输出格式等参数。封装Logrus和Jaeger时,可以在init函数中创建全局log实例和tracer实例,并设置一些默认的字段值,然后在需要打印日志或者记录Span的地方调用对应的方法即可。注意,在记录日志和记录Span时都要将当前上下文ctx传递给相关方法,以便进行跨服务间的信息传递。同时,在发起下游调用时也需要将当前Span传递给下游服务,以便进行链路追踪。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=7029

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?