首页 > 其他分享 >go使用opentelemetry+jaeger---gin+gprc

go使用opentelemetry+jaeger---gin+gprc

时间:2024-06-18 16:22:54浏览次数:14  
标签:opentelemetry otel err grpc jaeger --- io go

api-1

package main

import (
	"context"
	"fmt"
	"github.com/gin-gonic/gin"
	"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/codes"
	"go.opentelemetry.io/otel/exporters/jaeger"
	"go.opentelemetry.io/otel/propagation"
	"go.opentelemetry.io/otel/sdk/resource"
	tracesdk "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
	oteltrace "go.opentelemetry.io/otel/trace"
	"log"
	"net/http"

	modahttp "github.com/webws/go-moda/transport/http"
)

const (
	service     = "api1"
	environment = "dev"
	id          = 3
)

var tracer = otel.Tracer(service)

func tracerProvider() (*tracesdk.TracerProvider, error) {
	// Create the Jaeger exporter
	exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint("http://192.168.252.128:14268/api/traces")))
	if err != nil {
		return nil, err
	}
	tp := tracesdk.NewTracerProvider(
		// Always be sure to batch in production.
		tracesdk.WithSampler(tracesdk.AlwaysSample()),
		tracesdk.WithBatcher(exp),
		tracesdk.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceName(service),
			attribute.String("environment", environment),
			attribute.Int64("ID", id),
		),
		),
	)

	otel.SetTracerProvider(tp)
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))

	return tp, nil
}

func main() {
	tp, err := tracerProvider()
	if err != nil {
		log.Fatal(err)
	}

	defer func() {
		if err := tp.Shutdown(context.Background()); err != nil {
			log.Fatal(err)
		}
	}()

	r := gin.New()
	r.Use(otelgin.Middleware("gin-api1"))
	loadRoutes(r)

	fmt.Println("api1 start 8081")
	r.Run(":8081")
}

func loadRoutes(r *gin.Engine) {
	r.GET("/ping", pingFunc)
}

func pingFunc(c *gin.Context) {
	tracerCtx, span := tracer.Start(c.Request.Context(), "pingFunc",
		oteltrace.WithAttributes(attribute.String("key-pingFunc", "val-pingFunc")))
	defer span.End()

	callApi2(tracerCtx)

	c.JSON(http.StatusOK, gin.H{
		"message": "pong",
	})
}

func callApi2(ctx context.Context) {
	// tracer
	fmt.Println("on callApi2")
	tracerCtx, span := tracer.Start(ctx, "callApi2")
	span.AddEvent("starting callApi2")
	span.SetAttributes(attribute.Key("key_callApi2").String("value_callApi2"))
	defer span.End()
	// 打印TraceID SpanID
	spanCtx := oteltrace.SpanContextFromContext(ctx)
	fmt.Println(spanCtx.TraceID())
	fmt.Println(spanCtx.SpanID())

	// 调用api2
	url := fmt.Sprintf("http://localhost:8082/ping")
	defer span.End()

	_, err := modahttp.CallAPI(tracerCtx, url, "GET", nil)
	if err != nil {
		fmt.Printf("call api2 error: %v", err)
		span.SetStatus(codes.Error, err.Error())
	}
}

api-2

package main

import (
	"context"
	"fmt"
	"github.com/gin-gonic/gin"
	"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
	"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/exporters/jaeger"
	"go.opentelemetry.io/otel/propagation"
	"go.opentelemetry.io/otel/sdk/resource"
	tracesdk "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
	oteltrace "go.opentelemetry.io/otel/trace"
	"go_otel/3gin_http/grpc/grpc_proto/hello_grpc"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"log"
	"net/http"
)

const (
	service     = "api2"
	environment = "dev"
	id          = 2
)

var tracer = otel.Tracer(service)

func tracerProvider() (*tracesdk.TracerProvider, error) {
	// Create the Jaeger exporter
	exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint("http://192.168.252.128:14268/api/traces")))
	if err != nil {
		return nil, err
	}
	tp := tracesdk.NewTracerProvider(
		// Always be sure to batch in production.
		tracesdk.WithSampler(tracesdk.AlwaysSample()),
		tracesdk.WithBatcher(exp),
		tracesdk.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceName(service),
			attribute.String("environment", environment),
			attribute.Int64("ID", id),
		),
		),
	)

	// Register our TracerProvider as the global so any imported
	// instrumentation in the future will default to using it.
	otel.SetTracerProvider(tp)
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))

	return tp, nil
}

func main() {
	tp, err := tracerProvider()
	if err != nil {
		log.Fatal(err)
	}

	// Cleanly shutdown and flush telemetry when the application exits.
	defer func() {
		if err := tp.Shutdown(context.Background()); err != nil {
			log.Fatal(err)
		}
	}()

	r := gin.New()
	r.Use(otelgin.Middleware("gin-api2"))
	loadRoutes(r)

	fmt.Println("api2 start 8082")
	r.Run(":8082")
}

func loadRoutes(r *gin.Engine) {
	r.GET("/ping", pingFunc)
}

func pingFunc(c *gin.Context) {
	fmt.Println("on pingFunc")
	ctx, span := tracer.Start(c.Request.Context(), "pingFunc")
	defer span.End()

	callGrpc(ctx)

	c.JSON(http.StatusOK, gin.H{
		"message": "pong",
	})
}

func callGrpc(ctx context.Context) {
	fmt.Println("on callGrpc")
	ctx, span := tracer.Start(ctx, "callGrpc")
	defer span.End()
	// 打印TraceID SpanID
	spanCtx := oteltrace.SpanContextFromContext(ctx)
	fmt.Println(spanCtx.TraceID())
	fmt.Println(spanCtx.SpanID())

	// 连接服务器
	options := make([]grpc.DialOption, 0)
	options = append(options, grpc.WithTransportCredentials(insecure.NewCredentials()),
		grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
		grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()))
	conn, err := grpc.DialContext(ctx, "localhost:8083", options...)
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	// 初始化客户端
	client := hello_grpc.NewHelloServiceClient(conn)
	result, err := client.SayHello(ctx, &hello_grpc.HelloRequest{
		Name:    "client",
		Message: "hello",
	})
	fmt.Println(result, err)
}


grpc-server

package main

import (
	"context"
	"fmt"
	"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/exporters/jaeger"
	"go.opentelemetry.io/otel/propagation"
	"go.opentelemetry.io/otel/sdk/resource"
	tracesdk "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
	oteltrace "go.opentelemetry.io/otel/trace"
	"go_otel/3gin_http/grpc/grpc_proto/hello_grpc"
	"google.golang.org/grpc"
	"google.golang.org/grpc/grpclog"
	"log"
	"net"
)

const (
	service     = "remote-grpc"
	environment = "dev"
	id          = 3
)

var tracer = otel.Tracer(service)

// HelloServer 得有一个结构体,需要实现这个服务的全部方法,叫什么名字不重要
type HelloServer struct {
}

func (HelloServer) SayHello(ctx context.Context, request *hello_grpc.HelloRequest) (*hello_grpc.HelloResponse, error) {

	fmt.Println("on grpc SayHello")
	_, span := tracer.Start(ctx, "SayHello",
		oteltrace.WithAttributes(attribute.String("key-pingFunc", "val-pingFunc")))
	defer span.End()
	spanCtx := oteltrace.SpanContextFromContext(ctx)
	fmt.Println(spanCtx.SpanID())
	fmt.Println(spanCtx.TraceID())

	fmt.Println("入参:", request.Name, request.Message)
	return &hello_grpc.HelloResponse{
		Name:    "server",
		Message: "hello " + request.Name,
	}, nil
}

func tracerProvider() (*tracesdk.TracerProvider, error) {
	// Create the Jaeger exporter
	exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint("http://10.128.175.196:14268/api/traces")))
	if err != nil {
		return nil, err
	}
	tp := tracesdk.NewTracerProvider(
		// Always be sure to batch in production.
		tracesdk.WithSampler(tracesdk.AlwaysSample()),
		tracesdk.WithBatcher(exp),
		tracesdk.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceName(service),
			attribute.String("environment", environment),
			attribute.Int64("ID", id),
		),
		),
	)

	// Register our TracerProvider as the global so any imported
	// instrumentation in the future will default to using it.
	otel.SetTracerProvider(tp)
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))

	return tp, nil
}

func main() {

	tp, err := tracerProvider()
	if err != nil {
		log.Fatal(err)
	}

	// Cleanly shutdown and flush telemetry when the application exits.
	defer func() {
		if err := tp.Shutdown(context.Background()); err != nil {
			log.Fatal(err)
		}
	}()

	// grpc
	fmt.Println("grpc start 8083")
	listen, err := net.Listen("tcp", ":8083")
	if err != nil {
		grpclog.Fatalf("Failed to listen: %v", err)
	}

	// 创建一个gRPC服务器实例。
	// 添加拦截器(grpc集成OpenTelemetry主要是调用(otelgrpc.UnaryServerInterceptor())
	s := grpc.NewServer(grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor()))
	server := HelloServer{}
	// 将server结构体注册为gRPC服务。
	hello_grpc.RegisterHelloServiceServer(s, &server)
	// 开始处理客户端请求。
	err = s.Serve(listen)
}

hello.proto

syntax = "proto3"; // 指定proto版本
package hello_grpc;     // 指定默认包名

// 指定golang包名
option go_package = "/hello_grpc";

//定义rpc服务
service HelloService {
  // 定义函数
  rpc SayHello (HelloRequest) returns (HelloResponse) {}
}

// HelloRequest 请求内容
message HelloRequest {
  string name = 1;
  string message = 2;
}

// HelloResponse 响应内容
message HelloResponse{
  string name = 1;
  string message = 2;
}

protoc -I . --go_out=plugins=grpc:.\grpc_proto .\grpc_proto\hello.proto

标签:opentelemetry,otel,err,grpc,jaeger,---,io,go
From: https://www.cnblogs.com/qcy-blog/p/18254589

相关文章

  • spring-boot 热部署
    1.引入依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope></dependency>2.修改pom文件中插件 3.setting设置 4.crtl+shift+alt+......
  • k8s的python客户端库--kubernetes
    简介Kubernetes是什么Kubernetes是一个全新的基于容器技术的分布式架构解决方案,是Google开源的一个容器集群管理系统,Kubernetes简称K8S。Kubernetes是一个一站式的完备的分布式系统开发和支撑平台,更是一个开放平台,对现有的编程语言、编程框架、中间件没有任何侵入性。K......
  • <转载>使用inotify-tools监控文件夹或文件的变动
    版权声明:本文为博主原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接和本声明。原文链接:https://blog.csdn.net/ywd1992/article/details/106251339文章目录一、前言什么是inotify和inotify-tools检查系统是否支持inotify二、安装使用inotify-tools获取安装包......
  • U盘量产经历二——phisonPS2251-70(PS2270)
    写在前面:量产相关的BBS看了挺多,phison群联的芯片PS2251-70(PS2270)的量产工具比较少,而且很难下载。这里我访问了国外的网站下载来了,也贴出来给童鞋们取用。以下是记录的量产过程:https://www.usbdev.ru工具:STTOOL_V381_12_SZ_20210618_forHG2309PS2270下载地址:https://d......
  • 港股OMD-C原始数据接口知识拓展
    OMD-C包括SS、SP、SF三个级别。简单来说,就是通过三种级别推送不同的数据,具体使用哪一档由企业自行选择。OMD-C数据服务分为实时服务、刷新服务、重传服务三部分来完成所有数据的处理。OMD-C包括约20个消息类型的数据,每天约产生3亿条数据。港交所数据持有HKEx(香港交易所)数据......
  • 前端面试题-基础篇(一)
    最近在准备面试,搜集了一些偏基础的面试题,简单记录一下。1、列举一些常用的ES6新特性1、const、let(块级作用域{})不存在变量提升,不能在变量声明之前使用,且只在当前作用域有效,避免了全局命名冲突let用来声明变量,const用来声明常量,const声明的值不能被修改(对于引用类型,指的是......
  • 02-Excel初阶操作-学习笔记
    数据透视表专题续利用筛选字段切换数据场景:在数据透视表中显示各个所属地区每个月筛选出宠物用品类别,销售部门为三科的发生额,并在会议时展示,样例如下所示。具体操作step1:制作数据透视表点击任意单元格——插入选项卡——数据透视表——将“订购日期”拖拽到行字段,“所......
  • 基于google f1的schema-change
    异步schema变更为什么在分布式系统中异步变更schema比较困难F1中的schema变更是在线的、异步的,schema变更的过程中所有数据保持可用,保持数据一致性,并最大限度的减小对性能的影响。最大的难点在于所有F1服务器的schema变更是无法同步的,也就是说不同的F1服务器会在......
  • schema-change-implement
    TiDB的异步schema变更实现背景现在一般数据库在进行DDL操作时都会锁表,导致线上对此表的DML操作全部进入等待状态(有些数据支持读操作,但是也以消耗大量内存为代价),即很多涉及此表的业务都处于阻塞状态,表越大,影响时间越久。这使得DBA在做此类操作前要做足准备,然后挑个天时......
  • 使用docx-preview打印文档时,页数超出和页面元素样式问题
    #在打印时调整内容边距及隐藏Header的问题和解决方案##问题描述在使用JavaScript代码唤起打印窗口时,生成的文档中`<section>`标签自带`padding`样式,这导致内容无法铺满整个A4页面。此外,页面中还有一个`header`元素会占据头部的一部分高度,需要在打印时去掉......