分布式链路追踪实战篇-日志库集成opentelemetry的思路

本文主要是介绍分布式链路追踪实战篇-日志库集成opentelemetry的思路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

由上文分布式链路追踪入门篇-基础原理与快速应用可以知道分布式链路追踪的作用,但是距离应用到项目中,我们还需要对项目中一些关键组件进行opentelemetry的集成,例如日志库,ORM、http框架、rpc框架等。

一、日志库如何集成opentelemetry?

其实对日志库的集成无非就是调用日志库的方法进行日志打印时,可以把日志信息也被记录下来,推送到可视化的后端(eg:jaeger)。而由上文分布式链路追踪入门篇-基础原理与快速应用可以知道,通过span可以关联上相关的操作信息

二、简单demo演示

例如就对我们go原生的log库进行封装:

log.go

package pkgimport (`context``log``os``go.opentelemetry.io/otel/attribute``go.opentelemetry.io/otel/trace`
)//封装一下日志
type Logger struct {log *log.Logger
}var Log *Loggerfunc init()  {Log = &Logger{log: log.New(os.Stderr, "", log.LstdFlags),}
}func (l *Logger) Debug(ctx context.Context, msg string) {span := trace.SpanFromContext(ctx)span.AddEvent("", trace.WithAttributes(attribute.String("log", msg)))l.log.Println(msg)
}//todo 原生日志库只有Print方法,没有INFO、WARNd等分级
func (l *Logger) Info(ctx context.Context, msg string) {}
//todo
func (l *Logger) Warn(ctx context.Context, msg string) {}
//todo
func (l *Logger) Error(ctx context.Context, msg string) {}
//todo
func (l *Logger) Fatal(ctx context.Context, msg string) {}

main.go

package mainimport ("context""fmt""log""net/http""go.opentelemetry.io/otel""go.opentelemetry.io/otel/exporters/trace/jaeger"`go.opentelemetry.io/otel/sdk/resource`sdktrace "go.opentelemetry.io/otel/sdk/trace"`go.opentelemetry.io/otel/semconv``otel/log/pkg`
)// 初始化 OpenTelemetry
func initTracer() *sdktrace.TracerProvider {exporter, err := jaeger.NewRawExporter(jaeger.WithAgentEndpoint(func(options *jaeger.AgentEndpointOptions) {options.Host = "localhost"options.Port = "6831"}),)if err != nil {log.Fatalf("Error creating Jaeger exporter: %v", err)}tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter),sdktrace.WithSampler(sdktrace.AlwaysSample()),sdktrace.WithResource(resource.NewWithAttributes(semconv.ServiceNameKey.String("demo_service"), // 服务名)),)otel.SetTracerProvider(tp)return tp
}func main() {tp := initTracer()defer func() {if cerr := tp.Shutdown(context.Background()); cerr != nil {log.Fatalf("Error shutting down tracer provider: %v", cerr)}}()//启动http服务器http.HandleFunc("/log/demo", handleRequest)go func() {if err := http.ListenAndServe(":8080", nil); err != nil {log.Fatalf("Error starting Service A server: %v", err)}}()//模拟请求SimulateRequest()
}func SimulateRequest()  {req, err := http.NewRequest("GET", "http://localhost:8080/log/demo", nil)if err != nil {log.Fatalf("Creating request fail: %v", err)}resp, err := http.DefaultClient.Do(req)if err != nil {log.Fatalf("Request failed: %v", err)}defer resp.Body.Close()fmt.Println("Response received from Root Service")
}func handleRequest(w http.ResponseWriter, req *http.Request) {tracer := otel.Tracer("root")//开始创建root spanctx, span := tracer.Start(req.Context(), "root service")defer span.End()pkg.Log.Debug(ctx, "this is root service")//访问服务AcallServiceA(ctx)w.WriteHeader(http.StatusOK)fmt.Fprintf(w, "Response from Service Root")
}// Service A
func callServiceA(ctx context.Context) {tracer := otel.Tracer("service A")ctx, span := tracer.Start(ctx, "ServiceA")defer span.End()pkg.Log.Debug(ctx, "this is A service")fmt.Println("Service A")
}

运行程序后,访问jeager:
在这里插入图片描述

三、总结

1. 其实日志库的集成就是对原先的日志库进行一层封装,日志打印方法传入上下文,通过上下文获取到操作单元span,然后给span关联上日志信息
2. 上面demo只是一个演示,我们也可以依照这个思路封装我们自己项目中的日志库

这篇关于分布式链路追踪实战篇-日志库集成opentelemetry的思路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/424121

相关文章

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

Java 线程池+分布式实现代码

《Java线程池+分布式实现代码》在Java开发中,池通过预先创建并管理一定数量的资源,避免频繁创建和销毁资源带来的性能开销,从而提高系统效率,:本文主要介绍Java线程池+分布式实现代码,需要... 目录1. 线程池1.1 自定义线程池实现1.1.1 线程池核心1.1.2 代码示例1.2 总结流程2. J

SpringBoot集成WebService(wsdl)实践

《SpringBoot集成WebService(wsdl)实践》文章介绍了SpringBoot项目中通过缓存IWebService接口实现类的泛型入参类型,减少反射调用提升性能的实现方案,包含依赖配置... 目录pom.XML创建入口ApplicationContextUtils.JavaJacksonUt

Java 日志中 Marker 的使用示例详解

《Java日志中Marker的使用示例详解》Marker是SLF4J(以及Logback、Log4j2)提供的一个接口,它本质上是一个命名对象,你可以把它想象成一个可以附加到日志语句上的标签或戳... 目录什么是Marker?为什么使用Markejavascriptr?1. 精细化的过滤2. 触发特定操作3

linux查找java项目日志查找报错信息方式

《linux查找java项目日志查找报错信息方式》日志查找定位步骤:进入项目,用tail-f实时跟踪日志,tail-n1000查看末尾1000行,grep搜索关键词或时间,vim内精准查找并高亮定位,... 目录日志查找定位在当前文件里找到报错消息总结日志查找定位1.cd 进入项目2.正常日志 和错误日

springboot集成easypoi导出word换行处理过程

《springboot集成easypoi导出word换行处理过程》SpringBoot集成Easypoi导出Word时,换行符n失效显示为空格,解决方法包括生成段落或替换模板中n为回车,同时需确... 目录项目场景问题描述解决方案第一种:生成段落的方式第二种:替换模板的情况,换行符替换成回车总结项目场景s

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

SpringBoot集成XXL-JOB实现任务管理全流程

《SpringBoot集成XXL-JOB实现任务管理全流程》XXL-JOB是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展,本文介绍如何通过SpringBoot项目,使用RestTempl... 目录一、前言二、项目结构简述三、Maven 依赖四、Controller 代码详解五、Service

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”