package main
import (
"fmt"
"log"
"net/http"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go/log"
"github.com/uber/jaeger-client-go"
"github.com/uber/jaeger-client-go/config"
)
// 数据库模拟
type Database struct {
Data map[int]string
}
func NewDatabase() *Database {
return &Database{
Data: make(map[int]string),
}
}
func (db *Database) Insert(id int, value string) {
db.Data[id] = value
}
func (db *Database) Query(id int) string {
return db.Data[id]
}
func main() {
// 初始化Jaeger配置
cfg, _ := config.FromEnv()
cfg.ServiceName = "my-goframe-app"
cfg.Sampler.Type = jaeger.SamplerTypeConst
cfg.Sampler.Param = 1
// 创建Jaeger跟踪器
tracer, closer, _ := cfg.NewTracer(config.Logger(jaeger.StdLogger))
defer closer.Close()
// 设置全局跟踪器
opentracing.SetGlobalTracer(tracer)
// 创建GoFrame应用
app := g.New()
// 模拟数据库
db := NewDatabase()
// 注册路由
app.BindHandler("/insert", func(r *ghttp.Request) {
// 从HTTP请求头中提取上下文信息
spanCtx, _ := tracer.Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(r.Request.Header))
// 创建一个新的Span,作为根Span或者子Span
span := tracer.StartSpan("http-request", ext.RPCServerOption(spanCtx))
defer span.Finish()
// 模拟业务处理:插入数据到数据库
id := r.GetInt("id")
value := r.GetString("value")
// 在Span中记录一些信息
span.SetTag("http.method", r.Method)
span.SetTag("http.url", r.URL.Path)
// 在Span中添加日志
span.LogFields(
log.String("event", "insert-start"),
log.String("message", fmt.Sprintf("Inserting data into database: %d -> %s", id, value)),
)
// 插入数据
db.Insert(id, value)
// 在Span中添加日志
span.LogFields(
log.String("event", "insert-end"),
log.String("message", "Data inserted into database."),
)
// 返回响应
r.Response.Write("Data inserted into database.")
})
app.BindHandler("/query", func(r *ghttp.Request) {
// 从HTTP请求头中提取上下文信息
spanCtx, _ := tracer.Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(r.Request.Header))
// 创建一个新的Span,作为根Span或者子Span
span := tracer.StartSpan("http-request", ext.RPCServerOption(spanCtx))
defer span.Finish()
// 模拟业务处理:从数据库查询数据
id := r.GetInt("id")
// 在Span中记录一些信息
span.SetTag("http.method", r.Method)
span.SetTag("http.url", r.URL.Path)
// 在Span中添加日志
span.LogFields(
log.String("event", "query-start"),
log.String("message", fmt.Sprintf("Querying data from database: %d", id)),
)
// 查询数据
result := db.Query(id)
// 在Span中添加日志
span.LogFields(
log.String("event", "query-end"),
log.String("message", fmt.Sprintf("Data retrieved from database: %s", result)),
)
// 返回响应
r.Response.Write("Query result: " + result)
})
// 启动Web服务器
server := &http.Server{
Addr: ":8080",
Handler: app.Serve(),
}
log.Fatal(server.ListenAndServe())
}
在这个示例中,我们模拟了一个简单的数据库操作,包括插入数据和查询数据。在每个操作中,都创建了一个新的 Span,并在 Span 中记录了相应的信息。这样,我们就能够在 Jaeger 中清晰地看到整个链路中的数据库操作。
启动应用并通过访问 http://localhost:8080/insert 和 http://localhost:8080/query 来模拟插入和查询操作。然后,查看 Jaeger UI,你应该能够看到包含数据库操作的链路信息。
转载请注明出处:http://www.zyzy.cn/article/detail/7625/GoFrame