mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
add tracing example for grpc
This commit is contained in:
@ -32,15 +32,20 @@ func initTracer() func() {
|
||||
return flush
|
||||
}
|
||||
|
||||
func main() {
|
||||
flush := initTracer()
|
||||
defer flush()
|
||||
|
||||
ctx, span := gtrace.Tracer().Start(context.Background(), "test")
|
||||
func StartRequests() {
|
||||
ctx, span := gtrace.Tracer().Start(context.Background(), "StartRequests")
|
||||
defer span.End()
|
||||
|
||||
ctx = baggage.ContextWithValues(ctx, label.String("name", "john"))
|
||||
client := g.Client().Use(ghttp.MiddlewareClientTracing)
|
||||
|
||||
content := client.Ctx(ctx).GetContent("http://127.0.0.1:8199/hello")
|
||||
g.Log().Print(content)
|
||||
g.Log().Ctx(ctx).Print(content)
|
||||
}
|
||||
|
||||
func main() {
|
||||
flush := initTracer()
|
||||
defer flush()
|
||||
|
||||
StartRequests()
|
||||
}
|
||||
|
||||
@ -30,15 +30,11 @@ func initTracer() func() {
|
||||
return flush
|
||||
}
|
||||
|
||||
func main() {
|
||||
flush := initTracer()
|
||||
defer flush()
|
||||
|
||||
ctx, span := gtrace.Tracer().Start(context.Background(), "root")
|
||||
func StartRequests() {
|
||||
ctx, span := gtrace.Tracer().Start(context.Background(), "StartRequests")
|
||||
defer span.End()
|
||||
|
||||
client := g.Client().Use(ghttp.MiddlewareClientTracing)
|
||||
//client := g.Client()
|
||||
// Add user info.
|
||||
idStr := client.Ctx(ctx).PostContent(
|
||||
"http://127.0.0.1:8199/user/insert",
|
||||
@ -69,3 +65,10 @@ func main() {
|
||||
)
|
||||
g.Log().Ctx(ctx).Print("delete:", idStr, deleteResult)
|
||||
}
|
||||
|
||||
func main() {
|
||||
flush := initTracer()
|
||||
defer flush()
|
||||
|
||||
StartRequests()
|
||||
}
|
||||
|
||||
80
.example/net/gtrace/5.grpc+db+redis+log/client/main.go
Normal file
80
.example/net/gtrace/5.grpc+db+redis+log/client/main.go
Normal file
@ -0,0 +1,80 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/.example/net/gtrace/5.grpc+db+redis+log/protobuf/user"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/net/gtrace"
|
||||
"go.opentelemetry.io/otel/exporters/trace/jaeger"
|
||||
sdkTrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
const (
|
||||
JaegerEndpoint = "http://localhost:14268/api/traces"
|
||||
ServiceName = "tracing-grpc-client"
|
||||
)
|
||||
|
||||
// initTracer creates a new trace provider instance and registers it as global trace provider.
|
||||
func initTracer() func() {
|
||||
// Create and install Jaeger export pipeline.
|
||||
flush, err := jaeger.InstallNewPipeline(
|
||||
jaeger.WithCollectorEndpoint(JaegerEndpoint),
|
||||
jaeger.WithProcess(jaeger.Process{
|
||||
ServiceName: ServiceName,
|
||||
}),
|
||||
jaeger.WithSDK(&sdkTrace.Config{DefaultSampler: sdkTrace.AlwaysSample()}),
|
||||
)
|
||||
if err != nil {
|
||||
g.Log().Fatal(err)
|
||||
}
|
||||
return flush
|
||||
}
|
||||
|
||||
func StartRequests() {
|
||||
ctx, span := gtrace.Tracer().Start(context.Background(), "StartRequests")
|
||||
defer span.End()
|
||||
|
||||
conn, err := grpc.Dial(":8000", grpc.WithInsecure(), grpc.WithBlock())
|
||||
if err != nil {
|
||||
g.Log().Fatalf("did not connect: %v", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
client := user.NewUserClient(conn)
|
||||
|
||||
// Insert.
|
||||
insertRes, err := client.Insert(ctx, &user.InsertReq{
|
||||
Name: "john",
|
||||
})
|
||||
if err != nil {
|
||||
g.Log().Ctx(ctx).Fatalf(`%+v`, err)
|
||||
}
|
||||
g.Log().Ctx(ctx).Println("insert:", insertRes.Id)
|
||||
|
||||
// Query.
|
||||
queryRes, err := client.Query(ctx, &user.QueryReq{
|
||||
Id: insertRes.Id,
|
||||
})
|
||||
if err != nil {
|
||||
g.Log().Ctx(ctx).Fatalf(`%+v`, err)
|
||||
}
|
||||
g.Log().Ctx(ctx).Println("query:", queryRes)
|
||||
|
||||
// Delete.
|
||||
_, err = client.Delete(ctx, &user.DeleteReq{
|
||||
Id: insertRes.Id,
|
||||
})
|
||||
if err != nil {
|
||||
g.Log().Ctx(ctx).Fatalf(`%+v`, err)
|
||||
}
|
||||
g.Log().Ctx(ctx).Println("delete:", "ok")
|
||||
|
||||
}
|
||||
|
||||
func main() {
|
||||
flush := initTracer()
|
||||
defer flush()
|
||||
|
||||
StartRequests()
|
||||
}
|
||||
1336
.example/net/gtrace/5.grpc+db+redis+log/protobuf/user/user.pb.go
Normal file
1336
.example/net/gtrace/5.grpc+db+redis+log/protobuf/user/user.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,39 @@
|
||||
// protoc --gofast_out=plugins=grpc:. protocol/*.proto -I/Users/john/Workspace/Go/GOPATH/src
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package demos;
|
||||
|
||||
option go_package = "protobuf/user";
|
||||
|
||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||
|
||||
// User service for tracing demo.
|
||||
service User {
|
||||
rpc Insert(InsertReq) returns (InsertRes) {}
|
||||
rpc Query(QueryReq) returns (QueryRes) {}
|
||||
rpc Delete(DeleteReq) returns (DeleteRes) {}
|
||||
}
|
||||
|
||||
message InsertReq {
|
||||
string Name = 1 [(gogoproto.moretags) = 'v:"required#Please input user name."'];
|
||||
}
|
||||
|
||||
message InsertRes {
|
||||
int32 Id = 1;
|
||||
}
|
||||
|
||||
message QueryReq {
|
||||
int32 Id = 1 [(gogoproto.moretags) = 'v:"min:1#User id is required for querying."'];
|
||||
}
|
||||
|
||||
message QueryRes {
|
||||
int32 Id = 1;
|
||||
string Name = 2;
|
||||
}
|
||||
|
||||
message DeleteReq {
|
||||
int32 Id = 1 [(gogoproto.moretags) = 'v:"required#User id is required for deleting."'];
|
||||
}
|
||||
|
||||
message DeleteRes {}
|
||||
19
.example/net/gtrace/5.grpc+db+redis+log/server/config.toml
Normal file
19
.example/net/gtrace/5.grpc+db+redis+log/server/config.toml
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
# MySQL.
|
||||
[database]
|
||||
[database.logger]
|
||||
level = "all"
|
||||
stdout = true
|
||||
[database.default]
|
||||
link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
|
||||
debug = true
|
||||
|
||||
# Redis.
|
||||
[redis]
|
||||
default = "127.0.0.1:6379,0"
|
||||
cache = "127.0.0.1:6379,1"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
118
.example/net/gtrace/5.grpc+db+redis+log/server/main.go
Normal file
118
.example/net/gtrace/5.grpc+db+redis+log/server/main.go
Normal file
@ -0,0 +1,118 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gcache-adapter/adapter"
|
||||
"github.com/gogf/gf/.example/net/gtrace/5.grpc+db+redis+log/protobuf/user"
|
||||
"github.com/gogf/gf/errors/gerror"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/util/gvalid"
|
||||
"go.opentelemetry.io/otel/exporters/trace/jaeger"
|
||||
sdkTrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
type server struct{}
|
||||
|
||||
const (
|
||||
JaegerEndpoint = "http://localhost:14268/s/traces"
|
||||
ServiceName = "tracing-grpc-server"
|
||||
)
|
||||
|
||||
// initTracer creates a new trace provider instance and registers it as global trace provider.
|
||||
func initTracer() func() {
|
||||
// Create and install Jaeger export pipeline.
|
||||
flush, err := jaeger.InstallNewPipeline(
|
||||
jaeger.WithCollectorEndpoint(JaegerEndpoint),
|
||||
jaeger.WithProcess(jaeger.Process{
|
||||
ServiceName: ServiceName,
|
||||
}),
|
||||
jaeger.WithSDK(&sdkTrace.Config{DefaultSampler: sdkTrace.AlwaysSample()}),
|
||||
)
|
||||
if err != nil {
|
||||
g.Log().Fatal(err)
|
||||
}
|
||||
return flush
|
||||
}
|
||||
|
||||
// Common validation unary interpreter.
|
||||
func UnaryValidate(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
// It does nothing if there's no validation tag in the struct definition.
|
||||
if err := gvalid.CheckStruct(req, nil); err != nil {
|
||||
return nil, gerror.NewCode(
|
||||
int(codes.InvalidArgument),
|
||||
gerror.Current(err).Error(),
|
||||
)
|
||||
}
|
||||
return handler(ctx, req)
|
||||
}
|
||||
|
||||
// Insert is a route handler for inserting user info into dtabase.
|
||||
func (s *server) Insert(ctx context.Context, req *user.InsertReq) (*user.InsertRes, error) {
|
||||
res := user.InsertRes{}
|
||||
result, err := g.Table("user").Ctx(ctx).Insert(g.Map{
|
||||
"name": req.Name,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
id, _ := result.LastInsertId()
|
||||
res.Id = int32(id)
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// Query is a route handler for querying user info. It firstly retrieves the info from redis,
|
||||
// if there's nothing in the redis, it then does db select.
|
||||
func (s *server) Query(ctx context.Context, req *user.QueryReq) (*user.QueryRes, error) {
|
||||
res := user.QueryRes{}
|
||||
err := g.Table("user").
|
||||
Ctx(ctx).
|
||||
Cache(5*time.Second, s.userCacheKey(req.Id)).
|
||||
WherePri(req.Id).
|
||||
Scan(&res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// Delete is a route handler for deleting specified user info.
|
||||
func (s *server) Delete(ctx context.Context, req *user.DeleteReq) (*user.DeleteRes, error) {
|
||||
res := user.DeleteRes{}
|
||||
_, err := g.Table("user").
|
||||
Ctx(ctx).
|
||||
Cache(-1, s.userCacheKey(req.Id)).
|
||||
WherePri(req.Id).
|
||||
Delete()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (s *server) userCacheKey(id int32) string {
|
||||
return fmt.Sprintf(`userInfo:%d`, id)
|
||||
}
|
||||
|
||||
func main() {
|
||||
flush := initTracer()
|
||||
defer flush()
|
||||
|
||||
g.DB().GetCache().SetAdapter(adapter.NewRedis(g.Redis()))
|
||||
|
||||
listen, err := net.Listen("tcp", ":8000")
|
||||
if err != nil {
|
||||
g.Log().Fatalf("failed to listen: %v", err)
|
||||
}
|
||||
s := grpc.NewServer(
|
||||
grpc.ChainUnaryInterceptor(UnaryValidate),
|
||||
)
|
||||
user.RegisterUserServer(s, &server{})
|
||||
if err := s.Serve(listen); err != nil {
|
||||
g.Log().Fatalf("failed to serve: %v", err)
|
||||
}
|
||||
}
|
||||
4
go.mod
4
go.mod
@ -5,9 +5,12 @@ go 1.11
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/gogf/gcache-adapter v0.0.4-0.20210126062229-c84b9cefa528
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang/protobuf v1.4.3
|
||||
github.com/gomodule/redigo v2.0.0+incompatible
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/grokify/html-strip-tags-go v0.0.0-20190921062105-daaa06bf1aaf
|
||||
@ -21,6 +24,7 @@ require (
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 // indirect
|
||||
golang.org/x/text v0.3.4
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/grpc v1.35.0
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user