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

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

一、日志库如何集成opentelemetry?

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

二、简单demo演示

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

log.go

package pkg

import (
	`context`
	`log`
	`os`
	
	`go.opentelemetry.io/otel/attribute`
	`go.opentelemetry.io/otel/trace`
)

//封装一下日志
type Logger struct {
	log *log.Logger
}

var Log *Logger

func 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 main

import (
	"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 span
	ctx, span := tracer.Start(req.Context(), "root service")
	defer span.End()
	
	pkg.Log.Debug(ctx, "this is root service")
	
	//访问服务A
	callServiceA(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只是一个演示,我们也可以依照这个思路封装我们自己项目中的日志库

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

设计模式-创建型模式-工厂方法模式

一、什么是工厂方法模式 工厂模式又称工厂方法模式,是一种创建型设计模式,其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。工厂方法模式是目标是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。…

美创联合浙江省农业农村厅斩获“IDC中国20大杰出安全项目”!

11月23日,由IDC主办,以“安全风险管控:新形势下的数据安全保护”为主题的2023全球CSO网络安全峰会(中国站)隆重召开。 会上,IDC “中国20大杰出安全项目(CSO20)” 重磅揭晓&#xff…

Linux中df命令使用

在Linux中,df命令用于显示磁盘空间的使用情况。它的基本语法如下: df [选项] [文件或目录]这个命令可以用来查看当前系统上各个磁盘分区的使用情况。如果没有指定文件或目录,则所有当前被挂载的文件系统的可用空间将被显示。 df命令的一些常…

手把手用GPT开发小程序全流程!就是这么easy~

大家好,我是五竹。 前段时间用GPT开发了一款小程序:GPT真牛批!三天开发一个小程序,三天积累了2000的用户,上周末抽空又接入了流量主,感兴趣的同学可以围观一下。 今天就来带大家走一遍用GPT开发一款小程序的全过程&a…

手把手webpack搭建前端架子

这里以react为例> (一)初始化package.json package name: 你的项目名字叫啥 version: 版本号 description: 对项目的描述 entry point: 项目的入口文件(一般你要用那…

【回眸】Tessy单元测试软件使用指南(一)安装篇

安装 在官网上下载安装包,安装完成后打开进入这个界面 注册申请license:在作为服务端的电脑上安装Tessy。安装完成后,启动Tessy会自动生成license服务器的注册码。(注册码用于申请试用或永久的license文件)这个对于我…

树莓派上使用Nginx通过内网穿透实现无公网IP访问内网本地站点

前言 安装 Nginx(发音为“engine-x”)可以将您的树莓派变成一个强大的 Web 服务器,可以用于托管网站或 Web 应用程序。相比其他 Web 服务器,Nginx 的内存占用率非常低,可以在树莓派等资源受限的设备上运行。同时结合c…

NX二次开发UF_CSYS_set_wcs 函数介绍

文章作者:里海 来源网站:https://blog.csdn.net/WangPaiFeiXingYuan UF_CSYS_set_wcs Defined in: uf_csys.h int UF_CSYS_set_wcs(tag_t csys_id ) overview 概述 Sets the work coordinate system to the prototype coordinate system whose tag y…

竞赛选题 题目:基于FP-Growth的新闻挖掘算法系统的设计与实现

文章目录 0 前言1 项目背景2 算法架构3 FP-Growth算法原理3.1 FP树3.2 算法过程3.3 算法实现3.3.1 构建FP树 3.4 从FP树中挖掘频繁项集 4 系统设计展示5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于FP-Growth的新闻挖掘算法系统的设计与实现…

【PDF.js】2023 最新 PDF.js 在 Vue3 中的使用

因为自己写业务要定制各种 pdf 预览情况(可能),所以采用了 pdf.js 而不是各种第三方封装库,主要还是为了更好的自由度。 一、PDF.js 介绍 官方地址 中文文档 PDF.js 是一个使用 HTML5 构建的便携式文档格式查看器。 pdf.js 是社区…

【HuggingFace Transformer库学习笔记】基础组件学习:pipeline

一、Transformer基础知识 pip install transformers datasets evaluate peft accelerate gradio optimum sentencepiece pip install jupyterlab scikit-learn pandas matplotlib tensorboard nltk rouge在host文件里添加途中信息,可以避免运行代码下载模型时候报错…

vue中下载文件后无法打开的坑

今天在项目开发的时候临时要添加个导出功能我就写了一份请求加导出得代码, 代码: //导出按钮放开exportDutySummarizing (dataRangeInfo) {const params {departmentName: dataRangeInfo.name,departmentQode: dataRangeInfo.qode}//拼接所需得urlcons…

Tomcat注册为服务后,如何配置Tomcat内存大小

前提条件:tomcat已经注册为服务。 1.winR,输入regedit打开注册表 2.找到Tomcat注册表路径: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Apache Software Foundation\Procrun 2.0\Tomcat80603.找到jvm内存配置路径: HKEY_LOCAL_MACHINE\SOFTW…

Redis高可用之主从复制及哨兵模式

一、Redis的主从复制 1.1 Redis主从复制定义 主从复制是redis实现高可用的基础,哨兵模式和集群都是在主从复制的基础之上实现高可用; 主从复制实现数据的多级备份,以及读写分离(主服务器负责写,从服务器只能读) 1.2 主从复制流…

Windows从源码构建tensorflow

由一开始的在线编译,到后面的离线编译,一路踩坑无数。在此记录一下参考过的文章,有时间整理一下踩坑记录。 一、环境配置 在tensorflow官网上有版本对应关系 win10 bazel 3.1.0 msys2 tensorflow2.3.0 python3.5-3.8 MSVC2019 protobuf3.9.…

羊大师:强健身体是成功的关键

健康是一项无价的财富,拥有强健的身体是实现人生目标的关键。而如何保持健康并拥有一个强健的身体呢?下面就为大家分享一些有效的健身方法和建议,帮助您达到健美身材的目标。 良好的饮食习惯是形成强健身体的基石。我们要摄入足够的营养物质…

Java二级医院区域HIS信息管理系统源码(SaaS服务)

一个好的HIS系统,要具有开放性,便于扩展升级,增加新的功能模块,支撑好医院的业务的拓展,而且可以反过来给医院赋能,最终向更多的患者提供更好的服务。 系统采用前后端分离架构,前端由Angular、J…

首先啊骚年们我们必须先了解网络安全这个行业究竟是干啥的。

导 读 近年来,人工智能、5G、量子信息技术、工业互联网、大数据、云计算、物联网、虚拟现实、区块链等具有颠覆性的战略性新技术突飞猛进,但伴随着互联网技术的发展,网络安全问题也日趋多样化,甚至严重威胁到国家、企业&#xff…

【正点原子STM32连载】 第六十章 串口IAP实验(Julia分形)实验 摘自【正点原子】APM32F407最小系统板使用指南

1)实验平台:正点原子APM32F407最小系统板 2)平台购买地址:https://detail.tmall.com/item.htm?id609294757420 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html## 第六十…

AD9528学习笔记

前言 AD9528是ADI的一款时钟芯片,由2-stage PLL组成,并且集成JESD204B/JESD204C SYSREF信号发生器,SYSREF发生器输出单次、N次或连续信号,并与PLL1和PLL2输出同步,从而可以实现多器件之间的同步。 AD9528总共有14路输…