服务端代码:
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()
}