add tracing example for grpc

This commit is contained in:
jianchenma
2021-01-26 16:50:16 +08:00
parent c72c7dbe9a
commit e3be3bac92
8 changed files with 1616 additions and 12 deletions

View File

@ -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()
}

View File

@ -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()
}

View 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()
}

File diff suppressed because it is too large Load Diff

View File

@ -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 {}

View 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"

View 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
View File

@ -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
)