为了演示方便,我们这里简单定义一个 user 实体, user 有2个成员字段 id 和 name。
$ ent init User
packageschemaimport("entgo.io/ent""entgo.io/ent/schema/field")// User holds the schema definition for the User entity.
typeUserstruct{ent.Schema}// Fields of the User.
func(User)Fields()[]ent.Field{return[]ent.Field{field.Int("id"),field.String("name"),}}// Edges of the User.
func(User)Edges()[]ent.Edge{returnnil}
执行 go run -mod=mod entgo.io/ent/cmd/ent generate ./schema,就会生成一系列的文件。
packagemainimport("context""log"_"github.com/go-sql-driver/mysql""github.com/overstarry/ent-trace/ent")funcmain(){client,err:=ent.Open("mysql","root:a12345@tcp(127.0.0.1:3306)/trace?parseTime=True")iferr!=nil{log.Fatal(err)}deferclient.Close()// Run the auto migration tool.
iferr:=client.Schema.Create(context.Background());err!=nil{log.Fatalf("failed creating schema resources: %v",err)}createUser(context.Background(),client)}funccreateUser(ctxcontext.Context,client*ent.Client){u,err:=client.User.Create().SetName("Overstarry").SetID(1).Save(ctx)iferr!=nil{log.Fatal(err)}log.Printf("Created: %v",u)}
packagemainimport("context"_"github.com/go-sql-driver/mysql""github.com/overstarry/ent-trace/ent""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.4.0""log")functracerProvider(urlstring)(*tracesdk.TracerProvider,error){// Create the Jaeger exporter
exp,err:=jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))iferr!=nil{returnnil,err}tp:=tracesdk.NewTracerProvider(tracesdk.WithSampler(tracesdk.AlwaysSample()),tracesdk.WithBatcher(exp),tracesdk.WithResource(resource.NewWithAttributes(semconv.SchemaURL,semconv.ServiceNameKey.String("opentelemetry-ent-trace"),// 服务名
semconv.ServiceVersionKey.String("0.0.1"),attribute.String("environment","test"),)),)otel.SetTracerProvider(tp)otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{},propagation.Baggage{}))returntp,nil}funcmain(){tp,err:=tracerProvider("http://localhost:14268/api/traces")iferr!=nil{log.Fatal(err)}client,err:=ent.Open("mysql","root:a12345@tcp(127.0.0.1:3306)/trace?parseTime=True")iferr!=nil{log.Fatal(err)}deferclient.Close()// Run the auto migration tool.
iferr:=client.Schema.Create(context.Background());err!=nil{log.Fatalf("failed creating schema resources: %v",err)}createUser(context.Background(),client)}funccreateUser(ctxcontext.Context,client*ent.Client){u,err:=client.User.Create().SetName("Overstarry").SetID(1).Save(ctx)iferr!=nil{log.Fatal(err)}log.Printf("Created: %v",u)}
但由于我们使用的 sql 包不是标准库 database/sql, 而是采用了 ent, ent 缺乏了对 database/sql 的集成,导致使用上有点困难,在 ent 的 issue(#1232) 有讨论过这个事情,ent 提供了
sql.DB 的支持,使我们的工作能够顺利进行。
这时完整的代码:
packagemainimport("context""database/sql""log""net/http"entsql"entgo.io/ent/dialect/sql""github.com/XSAM/otelsql"_"github.com/go-sql-driver/mysql""github.com/overstarry/ent-trace/ent""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.4.0")functracerProvider(urlstring)(*tracesdk.TracerProvider,error){// Create the Jaeger exporter
exp,err:=jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))iferr!=nil{returnnil,err}tp:=tracesdk.NewTracerProvider(tracesdk.WithSampler(tracesdk.AlwaysSample()),tracesdk.WithBatcher(exp),tracesdk.WithResource(resource.NewWithAttributes(semconv.SchemaURL,semconv.ServiceNameKey.String("opentelemetry-ent-trace"),// 服务名
semconv.ServiceVersionKey.String("0.0.1"),attribute.String("environment","test"),)),)otel.SetTracerProvider(tp)otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{},propagation.Baggage{}))returntp,nil}funcmain(){_,err:=tracerProvider("http://localhost:14268/api/traces")iferr!=nil{log.Fatal(err)}driverName,err:=otelsql.Register("mysql",semconv.DBSystemMySQL.Value.AsString())iferr!=nil{panic(err)}// Connect to database
db,err:=sql.Open(driverName,"root:a12345@tcp(127.0.0.1:3306)/trace?parseTime=True")iferr!=nil{panic(err)}deferdb.Close()drv:=entsql.OpenDB("mysql",db)client:=ent.NewClient(ent.Driver(drv))// Run the auto migration tool.
iferr:=client.Schema.Create(context.Background());err!=nil{log.Fatalf("failed creating schema resources: %v",err)}createUser(client)http.ListenAndServe(":8080",nil)}funccreateUser(client*ent.Client){tracer:=otel.GetTracerProvider()ctx,span:=tracer.Tracer("github.com/overstarry/ent-trace/example").Start(context.Background(),"example")deferspan.End()u,err:=client.User.Create().SetName("Overstarry").Save(ctx)iferr!=nil{log.Fatal(err)}log.Printf("Created: %v",u)}