当前位置: 首页 > news >正文

golang学习笔记(二):链路追踪

自定义http连接的服务端

package serverimport ("github.com/gin-gonic/gin""go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin""net/http"
)type MyServer struct {Server *http.Server
}func GetServer() *MyServer {gin.SetMode(gin.ReleaseMode)engine := gin.New()s := &http.Server{Handler: engine,}return &MyServer{Server: s,}
}func (s *MyServer) GetEngine() *gin.Engine {return s.Server.Handler.(*gin.Engine)
}func (s *MyServer) Start(addr string) error {e := s.GetEngine()err2 := e.Run(addr)if err2 != nil {return err2}err := s.Server.ListenAndServe()if err != nil {return err}return nil
}func (s *MyServer) EnableTracing() {s.GetEngine().Use(otelgin.Middleware("go20230923"))
}

初始化链路追踪

package tracingimport ("context""fmt""go.opentelemetry.io/contrib/propagators/b3""go.opentelemetry.io/otel""go.opentelemetry.io/otel/exporters/jaeger""go.opentelemetry.io/otel/exporters/stdout/stdouttrace""go.opentelemetry.io/otel/propagation""go.opentelemetry.io/otel/sdk/resource""go.opentelemetry.io/otel/sdk/trace"semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)var tracer = otel.Tracer("go20230923")func InitStdoutProvider(serviceName string) (func(ctx context.Context) error, error) {tracer = otel.Tracer(serviceName)// stdout as exporterexporter, err := stdouttrace.New(stdouttrace.WithPrettyPrint())if err != nil {return nil, err}tp := trace.NewTracerProvider(trace.WithSampler(trace.AlwaysSample()),trace.WithBatcher(exporter),)otel.SetTracerProvider(tp)otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))return tp.Shutdown, nil
}

注册路由

package routerimport ("fmt""github.com/gin-gonic/gin""go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp""go.opentelemetry.io/otel/trace""go20230923/pkg/server""log""net/http"
)func InitRouter(s *server.MyServer) {engine := s.GetEngine()group := engine.Group("/v1")group.GET("/hello", Hello)group.GET("/world", World)
}func Hello(c *gin.Context) {if trace.SpanFromContext(c.Request.Context()).SpanContext().IsValid() {spanCtx := trace.SpanFromContext(c.Request.Context()).SpanContext()traceId := spanCtx.TraceID()spanId := spanCtx.SpanID()fmt.Printf("traceId : %s\n", traceId)fmt.Printf("spanId : %s\n", spanId)}fmt.Println("hello world")request, err := http.NewRequestWithContext(c.Request.Context(), "GET", "http://localhost:8080/v1/world", nil)if err != nil {log.Fatal(err)}client := http.Client{Transport: otelhttp.NewTransport(http.DefaultTransport)}client.Do(request)
}func World(c *gin.Context) {if trace.SpanFromContext(c.Request.Context()).SpanContext().IsValid() {spanCtx := trace.SpanFromContext(c.Request.Context()).SpanContext()traceId := spanCtx.TraceID()spanId := spanCtx.SpanID()fmt.Printf("traceId : %s\n", traceId)fmt.Printf("spanId : %s\n", spanId)}fmt.Println("hello world")
}

启动入口

package mainimport ("fmt""go20230923/pkg/server""go20230923/pkg/tracing""go20230923/router"
)func main() {s := server.GetServer()s.EnableTracing()tracing.InitStdoutProvider("go20230923")router.InitRouter(s)err := s.Start(":8080")if err != nil {fmt.Println(err)}
}

GET http://localhost:8080/v1/hello 输出:

traceId : 302c3e67a16bd20ce35b9220a4297d08
spanId : f80dd7189261ed84
hello world
traceId : 302c3e67a16bd20ce35b9220a4297d08
spanId : 7826014d750cf1c5
hello world
{"Name": "/v1/world","SpanContext": {"TraceID": "302c3e67a16bd20ce35b9220a4297d08","SpanID": "7826014d750cf1c5","TraceFlags": "01","TraceState": "","Remote": false},"Parent": {"TraceID": "302c3e67a16bd20ce35b9220a4297d08","SpanID": "aaa69798fdc0e90c","TraceFlags": "01","TraceState": "","Remote": true},"SpanKind": 2,"StartTime": "2023-09-29T11:32:41.5265746+08:00","EndTime": "2023-09-29T11:32:41.5271363+08:00","Attributes": [{"Key": "http.method","Value": {"Type": "STRING","Value": "GET"}},{"Key": "http.scheme","Value": {"Type": "STRING","Value": "http"}},{"Key": "http.flavor","Value": {"Type": "STRING","Value": "1.1"}},{"Key": "net.host.name","Value": {"Type": "STRING","Value": "go20230923"}},{"Key": "net.host.port","Value": {"Type": "INT64","Value": 8080}},{"Key": "net.sock.peer.addr","Value": {"Type": "STRING","Value": "::1"}},{"Key": "net.sock.peer.port","Value": {"Type": "INT64","Value": 62471}},{"Key": "http.user_agent","Value": {"Type": "STRING","Value": "Go-http-client/1.1"}},{"Key": "http.route","Value": {"Type": "STRING","Value": "/v1/world"}},{"Key": "http.status_code","Value": {"Type": "INT64","Value": 200}}],"Events": null,"Links": null,"Status": {"Code": "Unset","Description": ""},"DroppedAttributes": 0,"DroppedEvents": 0,"DroppedLinks": 0,"ChildSpanCount": 0,"Resource": [{"Key": "service.name","Value": {"Type": "STRING","Value": "unknown_service:___go_build_go20230923.exe"}},{"Key": "telemetry.sdk.language","Value": {"Type": "STRING","Value": "go"}},{"Key": "telemetry.sdk.name","Value": {"Type": "STRING","Value": "opentelemetry"}},{"Key": "telemetry.sdk.version","Value": {"Type": "STRING","Value": "1.18.0"}}],"InstrumentationLibrary": {"Name": "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin","Version": "0.44.0","SchemaURL": ""}
}
{"Name": "/v1/hello","SpanContext": {"TraceID": "302c3e67a16bd20ce35b9220a4297d08","SpanID": "f80dd7189261ed84","TraceFlags": "01","TraceState": "","Remote": false},"Parent": {"TraceID": "00000000000000000000000000000000","SpanID": "0000000000000000","TraceFlags": "00","TraceState": "","Remote": false},"SpanKind": 2,"StartTime": "2023-09-29T11:32:41.5252493+08:00","EndTime": "2023-09-29T11:32:41.5271363+08:00","Attributes": [{"Key": "http.method","Value": {"Type": "STRING","Value": "GET"}},{"Key": "http.scheme","Value": {"Type": "STRING","Value": "http"}},{"Key": "http.flavor","Value": {"Type": "STRING","Value": "1.1"}},{"Key": "net.host.name","Value": {"Type": "STRING","Value": "go20230923"}},{"Key": "net.host.port","Value": {"Type": "INT64","Value": 8080}},{"Key": "net.sock.peer.addr","Value": {"Type": "STRING","Value": "::1"}},{"Key": "net.sock.peer.port","Value": {"Type": "INT64","Value": 64585}},{"Key": "http.user_agent","Value": {"Type": "STRING","Value": "PostmanRuntime/7.28.0"}},{"Key": "http.route","Value": {"Type": "STRING","Value": "/v1/hello"}},{"Key": "http.status_code","Value": {"Type": "INT64","Value": 200}}],"Events": null,"Links": null,"Status": {"Code": "Unset","Description": ""},"DroppedAttributes": 0,"DroppedEvents": 0,"DroppedLinks": 0,"ChildSpanCount": 1,"Resource": [{"Key": "service.name","Value": {"Type": "STRING","Value": "unknown_service:___go_build_go20230923.exe"}},{"Key": "telemetry.sdk.language","Value": {"Type": "STRING","Value": "go"}},{"Key": "telemetry.sdk.name","Value": {"Type": "STRING","Value": "opentelemetry"}},{"Key": "telemetry.sdk.version","Value": {"Type": "STRING","Value": "1.18.0"}}],"InstrumentationLibrary": {"Name": "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin","Version": "0.44.0","SchemaURL": ""}
}
参考

Go语言 如何获取有关 *gin.Context.Request.Context()的详细信息
golang 使用 OpenTelemetry 实现跨服务全链路追踪
github go-moda项目

相关文章:

golang学习笔记(二):链路追踪

自定义http连接的服务端 package serverimport ("github.com/gin-gonic/gin""go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin""net/http" )type MyServer struct {Server *http.Server }func GetServer() *MyS…...

git提交代码实际操作

1.仓库的代码 2.克隆代码下存在的分支 git clobe https://gitee.com/sadsadasad/big-event-11.git 3.查看当下存在的分支 git branch -a 在很多情况下,我们是要围绕着dev分支进行开发,所以我们可以在开发之前问明白围绕那个分支进行开发。 4.直接拉去dev分支代码 5.如果没在…...

TF坐标变换

ROS小乌龟跟随 5.1 TF坐标变换 Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 tf模块:在 ROS 中用于实现不同坐标系之间的点或向量的转换。 在ROS中坐标变换最初对应的是tf,不过在 hydro 版本开始, tf 被弃用,迁移到 tf2,后者更…...

如何进行网络编程和套接字操作?

网络编程是计算机编程中重要的领域之一,它使程序能够在网络上进行数据传输和通信。C语言是一种强大的编程语言,也可以用于网络编程。网络编程通常涉及套接字(Socket)操作,套接字是一种用于网络通信的抽象接口。本文将详…...

在Spark中集成和使用Hudi

本文介绍了在Spark中集成和使用Hudi的功能。使用Spark数据源API(scala和python)和Spark SQL,插入、更新、删除和查询Hudi表的代码片段。 1.安装 Hudi适用于Spark-2.4.3+和Spark 3.x版本。 1.1 Spark 3支持矩阵 Hudi...

力扣第226翻转二叉数 c++三种方法 +注释

题目 226. 翻转二叉树 简单 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2: 输入:root [2,1,3] 输出&am…...

React项目部署 - Nginx配置

写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成…...

【Vue3】定义全局变量和全局函数

// main.ts import { createApp } from vue import App from ./App.vue const app createApp(App)// 解决 ts 报错 type Filter {format<T>(str: T): string } declare module vue {export interface ComponentCustomProperties {$filters: Filter,$myArgs: string} }a…...

【Pandas】Apply自定义行数

文章目录 1. Series的apply方法2. DataFrame的apply方法2.1 针对列使用apply2.2 针对行使用apply Pandas提供了很多数据处理的API,但当提供的API不能满足需求的时候,需要自己编写数据处理函数, 这个时候可以使用apply函数apply函数可以接收一个自定义函数, 可以将DataFrame的行…...

C#,数值计算——完全VEGAS编码的蒙特·卡洛计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Complete VEGAS Code /// adaptive/recursive Monte Carlo /// </summary> public abstract class VEGAS { const int NDMX 50; const int …...

纯css实现3D鼠标跟随倾斜

老规矩先上图 为什么今天会想起来整这个呢?这是因为和我朋友吵架, 就是关于这个效果的,就是这个 卡片懸停毛玻璃效果, 我朋友认为纯css也能写, 我则坦言他就是在放狗屁,这种跟随鼠标的3D效果要怎么可能能用纯css写, 然后吵着吵着发现,欸,好像真能用css写哦,我以前还写过这种…...

Pandas数据结构

文章目录 1. Series数据结构1.1 Series数据类型创建1.2 Series的常用属性valuesindex/keys()shapeTloc/iloc 1.3 Series的常用方法mean()max()/min()var()/std()value_counts()describe() 1.4 Series运算加/减法乘法 2. DataFrame数据结构2.1 DataFrame数据类型创建2.2 布尔索引…...

systemverilog function的一点小case

关于function的应用无论是在systemverilog还是verilog中都有很广泛的应用&#xff0c;但是一直有一个模糊的概念困扰着我&#xff0c;今天刚好有时间来搞清楚并记录下来。 关于fucntion的返回值的问题&#xff1a; function integer clog2( input logic[255:0] value);for(cl…...

微服务的初步使用

环境说明 jdk1.8 maven3.6.3 mysql8 idea2022 spring cloud2022.0.8 微服务案例的搭建 新建父工程 打开IDEA&#xff0c;File->New ->Project&#xff0c;填写Name&#xff08;工程名称&#xff09;和Location&#xff08;工程存储位置&#xff09;&#xff0c;选…...

【2023年11月第四版教材】第18章《项目绩效域》(合集篇)

第18章《项目绩效域》&#xff08;合集篇&#xff09; 1 章节内容2 干系人绩效域2.1 绩效要点2.2 执行效果检查2.3 与其他绩效域的相互作用 3 团队绩效域3.1 绩效要点3.2 与其他绩效域的相互作用3.3 执行效果检查3.4 开发方法和生命周期绩效域 4 绩效要点4.1 与其他绩效域的相互…...

Android 11.0 mt6771新增分区功能实现三

1.前言 在11.0的系统开发中,在对某些特殊模块中关于数据的存储方面等需要新增分区来保存, 所以就需要在系统分区新增分区,接下来就来实现这个功能,看系列三的实现过程 2.mt6771新增分区功能实现三的核心类 build/make/tools/releasetools/common.py device/mediatek/mt6…...

计算机网络——计算机网络的性能指标(上)-速率、带宽、吞吐量、时延

目录 速率 比特 速率 例1 带宽 带宽在模拟信号系统中的意义 带宽在计算机网络中的意义 吞吐量 时延 发送时延 传播时延 处理时延 例2 例3 速率 了解速率之前&#xff0c;先详细了解一下比特&#xff1a; 比特 计算机中数据量的单位&#xff0c;也是信息论中信…...

每日一题 518零钱兑换2(完全背包)

题目 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带符号整…...

Linux shell编程学习笔记8:使用字符串

一、前言 字符串是大多数编程语言中最常用最有用的数据类型&#xff0c;这在Linux shell编程中也不例外。 本文讨论了Linux Shell编程中的字符串的三种定义方式的差别&#xff0c;以及字符串拼接、取字符串长度、提取字符串、查找子字符串等常用字符串操作,&#xff0c;以及反…...

【Spring笔记03】Spring依赖注入各种数据类型

这篇文章&#xff0c;详细介绍一下Spring框架中如何注入各种数据类型&#xff0c;包含&#xff1a;注入基本数据类型、数组、集合、Map映射、Property属性、注入空字符串、注入null值、注入特殊字符等内容&#xff0c;以及如何使用命名空间进行依赖注入。 目录 一、注入各种数据…...

2023计算机保研——双非上岸酒吧舞

我大概是从22年10月份开始写博客的&#xff0c;当时因为本校专业的培养方案的原因&#xff0c;课程很多&#xff0c;有些知识纸质记录很不方便&#xff0c;于是选择了打破了自己的成见使用博客来记录学习生活。对于我个人而言&#xff0c;保研生活在前一大半过程中都比较艰难&a…...

《计算机视觉中的多视图几何》笔记(13)

13 Scene planes and homographies 本章主要讲述两个摄像机和一个世界平面之间的射影几何关系。 我们假设空间有一平面 π \pi π&#xff0c;平面上的一点为 x π x_{\pi} xπ​。 x π x_{\pi} xπ​分别在两幅图像 P , P ′ P, P P,P′上形成了 x , x ′ x, x x,x′。 那…...

H5移动端购物商城系统源码 小型商城全新简洁风格全新UI 支持易支付接口

一款比较简单的 H5 移动端购物商城系统源码&#xff0c;比较适合单品商城、小型商城使用。带有易支付接口。 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/88391704 源码下载2&#xff1a;评论留言或私信留言...

全志ARM926 Melis2.0系统的开发指引⑤

全志ARM926 Melis2.0系统的开发指引⑤ 编写目的8. 固件修改工具(ImageModify)使用8.1.界面说明8.2.操作步骤8.2.1. 配置平台8.2.2. 选择固件8.2.3. 选择要替换的文件8.2.4. 替换文件8.2.5. 保存固件 8.3.注意事项8.4.增加固件修改权限设置8.4.1. 概述8.4.2. 操作说明8.4.2.1.打…...

【AI视野·今日Robot 机器人论文速览 第四十七期】Wed, 4 Oct 2023

AI视野今日CS.Robotics 机器人学论文速览 Wed, 4 Oct 2023 Totally 40 papers &#x1f449;上期速览✈更多精彩请移步主页 Interesting: &#x1f4da;基于神经网络的多模态触觉感知, classification, position, posture, and force of the grasped object多模态形象的解耦(f…...

GPX可视化工具 GPX航迹预览工具

背景 当我们收到别人分享的航迹文档&#xff0c;即gpx文档时&#xff0c;如何快速的进行浏览呢&#xff1f;我们可以使用GIS软件来打开gpx文档并显示gpx中所记录的航迹&#xff0c;例如常用的GIS软件有googleEarth&#xff0c; Basecamp&#xff0c; GPXsee&#xff0c; GPX E…...

学信息系统项目管理师第4版系列18_采购管理

1. 协议 1.1. 合同 1.1.1. 国际合作的项目经理应牢记&#xff0c;无论合同规定如何详尽&#xff0c;文化和当地法律对合同及其可执行性均有影响 1.2. 服务水平协议&#xff08;SLA&#xff09; 1.3. 谅解备忘录 1.4. 协议备忘录&#xff08;MOA&#xff09; 1.5. 订购单 …...

标准化数据模型

标准化数据模型 标准化被定义为减少或消除数据集中冗余的过程。 它已成为关系数据库中数据建模的事实上的方法&#xff0c;很大程度上是由于这些系统最初设计时所围绕的底层资源限制&#xff1a;缓慢的磁盘和昂贵的 RAM。更少的数据冗余/重复意味着更有效地从磁盘读取数据并占…...

linux平台源码编译ffmpeg

目录 编译平台 编译步骤 编译平台 中标麒麟 编译步骤 1 从Download FFmpeg 下载源码&#xff0c;我选中了4.2.9版 2 解压 3 在解压后的目录下输入 ./configure --enable-shared --prefix/usr/local/ffmpeg 4 make 5 sudo make install 6 ffmpeg的头文件、可执行程…...

Vue中如何进行拖拽与排序功能实现

在Vue中实现拖拽与排序功能 在Web应用程序中&#xff0c;实现拖拽和排序功能是非常常见的需求&#xff0c;特别是在管理界面、任务列表和图形用户界面等方面。Vue.js作为一个流行的JavaScript框架&#xff0c;提供了许多工具和库来简化拖拽和排序功能的实现。本文将介绍如何使…...

网站建设的步骤图/中国最新消息今天

这篇文章也是基于知乎的一个答案。因为前天蛋疼写了个99行蛋疼版2048&#xff0c;所以一时兴起在知乎上搜了搜2048&#xff0c;结果发现了这个问题。看了看&#xff0c;票数最高的两个答案都是错的&#xff0c;所以自己推导了一下。2048的玩法就不赘述了&#xff0c;先来看看相…...

网站开发常见毕业设计题目/百度快速收录seo工具软件

# 本练习是模拟登陆及验证码处理&#xff08;把验证码下载到本地后手动输入&#xff09;# 1 通过分析页面获得form表单的登陆接口为 action"https://www.douban.com/accounts/login" # 2 通过抓包发现登陆除了发送账户密码和验证码外&#xff0c;还发送了另一个值&am…...

好的交互设计网站/免费手机优化大师下载安装

题目&#xff1a; 我是超链接 题解&#xff1a; 能够看出来这道题目是网络流&#xff0c;但并不清楚这个图怎么建 这种有交换次数限制的要考虑分成两半&#xff1a;最多流入的数量&#xff0c;最多流出的数量 作为流量限制 我们对于每个节点拆成三个点&#xff1a;x1&…...

做网站买什么香港服务器吗/代写稿子的平台

迄今为止我们已经讨论过了领域以及创建表现领域的模型的重要性了。 我们给出了一些可以用来创建有效模型的技术指南。模型现在已经跟它所源自的领域紧密关联了。 我们也已经说过代码设计应该围绕模型展开&#xff0c;模型自身也会基于设计决定而有所增进。 脱离了模型的设计会导…...

wordpress指定文章标题/seo系统源码出售

PDF文件转换格式&#xff0c;需要用到PDF转换器&#xff0c;我们以奥凯丰 PDF转换大师为例&#xff0c;PDF转换成其他格式。 【PDF转换大师】转为word_excel_ppt_txt_jpg等格式-奥凯丰okfonePDF转换大师是奥凯丰推出的一款可以把pdf文件格式转换成word&#xff0c;excel&#…...

wordpress整站https/杭州专业seo公司

使用的是API方式&#xff0c;使用Mysql的数据库资源&#xff0c;所以需要包含头文件、连接Lib和获取相应的dll文件。一 vc的设置这里使用的是vs2010&#xff0c;所以附上vs2010的设置(1)打开VC6.0 工具栏Tools菜单下的Options选项&#xff0c;在Directories的标签页中右边的“S…...