gorm 集成opentelemetry

服务端代码:

package main

import (
   "GoStart/telemetry/ch03/server/model"
   "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/exporters/jaeger"
   "go.opentelemetry.io/otel/propagation"
   "go.opentelemetry.io/otel/sdk/resource"
   "go.opentelemetry.io/otel/sdk/trace"
   semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
   "gorm.io/driver/mysql"
   "gorm.io/gorm"
   "gorm.io/gorm/logger"
   "gorm.io/gorm/schema"
   "gorm.io/plugin/opentelemetry/tracing"
   "log"
   "os"
   "time"
)

var tp *trace.TracerProvider

const (
   TRACE_NAME = "mxshop-otel"
)

func tracerProvider() error {
   url := "http://192.168.66.130:14268/api/traces"
   jexp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
   if err != nil {
      panic(err)
   }
   tp = trace.NewTracerProvider(
      trace.WithBatcher(jexp),
      trace.WithResource(
         resource.NewWithAttributes(
            semconv.SchemaURL,
            semconv.ServiceNameKey.String("mxshop-user"),
            attribute.String("environment", "dev"),
            attribute.Int("ID", 1),
         ),
      ),
   )
   otel.SetTracerProvider(tp)
   otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
   return nil
}
func Server(c *gin.Context) {
	dsn := "root:123456@tcp(127.0.0.1:3306)/mxshop_user_srv?charset=utf8mb4&parseTime=True&loc=Local"

	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
		logger.Config{
			LogLevel: logger.Info, // Log level
			Colorful: true,        // Disable color
		},
	)
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			SingularTable: true,
		},
		Logger: newLogger,
	})
	if err != nil {
		panic(err)
	}

	if err := db.Use(tracing.NewPlugin()); err != nil {
		panic(err)
	}

	if err := db.WithContext(c.Request.Context()).Model(model.User{}).Where("id = ?", 1).First(&model.User{}).Error; err != nil {
		panic(err)
	}
	time.Sleep(500 * time.Millisecond)
	//span.End()
	c.JSON(200, gin.H{})
}

func main() {
	_ = tracerProvider()
	r := gin.Default()
	r.Use(otelgin.Middleware("my-server"))
	r.GET("/", func(c *gin.Context) {

	})
	r.GET("/server", Server)
	r.Run(":8090")
}

客户端代码:

package main

import (
   "context"
   "encoding/json"
   "fmt"
   "github.com/valyala/fasthttp"
   "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"
   "go.opentelemetry.io/otel/sdk/trace"
   semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
   "sync"
   "time"
)

const (
   TRACE_NAME = "mxshop-otel"
)

var tp *trace.TracerProvider

func tracerProvider() error {
   url := "http://192.168.66.130:14268/api/traces"
   jexp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
   if err != nil {
      panic(err)
   }

   tp = trace.NewTracerProvider(
      trace.WithBatcher(jexp),
      trace.WithResource(
         resource.NewWithAttributes(
            semconv.SchemaURL,
            semconv.ServiceNameKey.String("mxshop-user"),
            attribute.String("environment", "dev"),
            attribute.Int("ID", 1),
         ),
      ),
   )
   otel.SetTracerProvider(tp)
   otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
   return nil
}

func funcA(ctx context.Context, wg *sync.WaitGroup) {
   defer wg.Done()
   tr := otel.Tracer(TRACE_NAME)
   _, span := tr.Start(ctx, "func-a")
   span.SetAttributes(attribute.String("name", "funA"))

   type _LogStruct struct {
      CurrentTime time.Time `json:"current_time"`
      PassWho     string    `json:"pass_who"`
      Name        string    `json:"name"`
   }
   logTest := _LogStruct{
      CurrentTime: time.Now(),
      PassWho:     "bobby",
      Name:        "func-a",
   }
   b, _ := json.Marshal(logTest)
   span.SetAttributes(attribute.Key("这是测试日志的key").String(string(b)))
   time.Sleep(time.Second)
   span.End()
}

func funcB(ctx context.Context, wg *sync.WaitGroup) {
   defer wg.Done()
   tr := otel.Tracer("traceName")
   spanCtx, span := tr.Start(ctx, "func-b")
   fmt.Println("trace:", span.SpanContext().TraceID(), span.SpanContext().SpanID())
   time.Sleep(time.Second)

   req := fasthttp.AcquireRequest()
   req.SetRequestURI("http://192.168.0.4:8090/server")
   req.Header.SetMethod("GET")

   //拿起传播器
   p := otel.GetTextMapPropagator()
   //包裹
   headers := make(map[string]string)
   p.Inject(spanCtx, propagation.MapCarrier(headers))

   for key, value := range headers {
      req.Header.Set(key, value)
   }
   //req.Header.Set("trace-id", span.SpanContext().TraceID().String())
   //req.Header.Set("span-id", span.SpanContext().SpanID().String())

   fclient := fasthttp.Client{}
   fres := fasthttp.Response{}
   _ = fclient.Do(req, &fres)

   span.End()
}

func main() {
   _ = tracerProvider()
   ctx, cancel := context.WithCancel(context.Background())
   defer func(ctx context.Context) {
      ctx, cancel = context.WithTimeout(ctx, time.Second*5)
      defer cancel()
      if err := tp.Shutdown(ctx); err != nil {
         panic(err)
      }
   }(ctx)

   tr := otel.Tracer(TRACE_NAME)
   spanCtx, span := tr.Start(ctx, "func-main")

   wg := &sync.WaitGroup{}
   wg.Add(2)
   go funcA(spanCtx, wg)
   go funcB(spanCtx, wg)

   span.AddEvent("this is an event")

   time.Sleep(time.Second)
   wg.Wait()
   span.End()
}

你可能感兴趣的:(GO开发工程师系列,golang)