Skip to content

Commit b357120

Browse files
committed
feat: add logging support to generated clients
1 parent 7e64160 commit b357120

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+526
-191
lines changed

internal/gengapic/client_init_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ func TestClientInit(t *testing.T) {
414414
{Name: "iampb", Path: "cloud.google.com/go/iam/apiv1/iampb"}: true,
415415
{Name: "locationpb", Path: "google.golang.org/genproto/googleapis/cloud/location"}: true,
416416
{Name: "mypackagepb", Path: "github.com/googleapis/mypackage"}: true,
417+
{Path: "log/slog"}: true,
417418
},
418419
wantNumSnps: 6,
419420
},
@@ -436,6 +437,7 @@ func TestClientInit(t *testing.T) {
436437
{Name: "iampb", Path: "cloud.google.com/go/iam/apiv1/iampb"}: true,
437438
{Name: "locationpb", Path: "google.golang.org/genproto/googleapis/cloud/location"}: true,
438439
{Name: "mypackagepb", Path: "github.com/googleapis/mypackage"}: true,
440+
{Path: "log/slog"}: true,
439441
},
440442
wantNumSnps: 6,
441443
},
@@ -453,6 +455,7 @@ func TestClientInit(t *testing.T) {
453455
{Name: "gtransport", Path: "google.golang.org/api/transport/grpc"}: true,
454456
{Name: "mypackagepb", Path: "github.com/googleapis/mypackage"}: true,
455457
{Name: "httptransport", Path: "google.golang.org/api/transport/http"}: true,
458+
{Path: "log/slog"}: true,
456459
},
457460
wantNumSnps: 1,
458461
},
@@ -472,6 +475,7 @@ func TestClientInit(t *testing.T) {
472475
{Path: "context"}: true,
473476
{Path: "google.golang.org/api/option"}: true,
474477
{Path: "google.golang.org/grpc"}: true,
478+
{Path: "log/slog"}: true,
475479
},
476480
wantNumSnps: 6,
477481
},
@@ -489,6 +493,7 @@ func TestClientInit(t *testing.T) {
489493
{Path: "google.golang.org/api/option/internaloption"}: true,
490494
{Path: "google.golang.org/grpc"}: true,
491495
{Path: "net/http"}: true,
496+
{Path: "log/slog"}: true,
492497
},
493498
wantNumSnps: 1,
494499
},
@@ -506,6 +511,7 @@ func TestClientInit(t *testing.T) {
506511
{Path: "net/http"}: true,
507512
{Name: "httptransport", Path: "google.golang.org/api/transport/http"}: true,
508513
{Name: "mypackagepb", Path: "github.com/googleapis/mypackage"}: true,
514+
{Path: "log/slog"}: true,
509515
},
510516
wantNumSnps: 1,
511517
setExt: func() (protoreflect.ExtensionType, interface{}) {

internal/gengapic/doc_file.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,19 @@ func (g *generator) genDocFile(year int, scopes []string, serv *descriptorpb.Ser
128128

129129
p("import (")
130130
p("%s%q", "\t", "context")
131+
p("%s%q", "\t", "io")
132+
p("%s%q", "\t", "log/slog")
133+
p("%s%q", "\t", "net/http")
131134
p("")
135+
p("%s%q", "\t", "github.com/googleapis/gax-go/v2/internallog")
136+
p("%s%q", "\t", "github.com/googleapis/gax-go/v2/internallog/grpclog")
137+
p("%s%q", "\t", "google.golang.org/api/googleapi")
132138
p("%s%q", "\t", "google.golang.org/api/option")
139+
p("%s%q", "\t", "google.golang.org/grpc")
140+
p("%s%q", "\t", "google.golang.org/protobuf/proto")
133141
p(")")
134142
p("")
143+
p("const serviceName = %q", g.serviceConfig.GetName())
135144

136145
p("// For more information on implementing a client constructor hook, see")
137146
p("// https://github.com/googleapis/google-cloud-go/wiki/Customizing-constructors.")
@@ -157,6 +166,52 @@ func (g *generator) genDocFile(year int, scopes []string, serv *descriptorpb.Ser
157166
}
158167
p(" }")
159168
p("}")
169+
p("")
170+
171+
p("func executeHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) ([]byte, error) {")
172+
p(` logger.DebugContext(ctx, "api request", "serviceName", serviceName, "rpcName", rpc, "request", internallog.HTTPRequest(req, body))`)
173+
p(" resp, err := client.Do(req)")
174+
p(" if err != nil{")
175+
p(" return nil, err")
176+
p(" }")
177+
p(" defer resp.Body.Close()")
178+
p(" buf, err := io.ReadAll(resp.Body)")
179+
p(" if err != nil {")
180+
p(" return nil, err")
181+
p(" }")
182+
p(` logger.DebugContext(ctx, "api response", "serviceName", serviceName, "rpcName", rpc, "response", internallog.HTTPResponse(resp, buf))`)
183+
p(" if err = googleapi.CheckResponse(resp); err != nil {")
184+
p(" return nil, err")
185+
p(" }")
186+
p(" return buf, nil")
187+
p("}")
188+
p("")
189+
190+
p("func executeStreamingHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) (*http.Response, error) {")
191+
p(` logger.DebugContext(ctx, "api request", "serviceName", serviceName, "rpcName", rpc, "request", internallog.HTTPRequest(req, body))`)
192+
p(" resp, err := client.Do(req)")
193+
p(" if err != nil{")
194+
p(" return nil, err")
195+
p(" }")
196+
p(` logger.DebugContext(ctx, "api response", "serviceName", serviceName, "rpcName", rpc, "response", internallog.HTTPResponse(resp, nil))`)
197+
p(" if err = googleapi.CheckResponse(resp); err != nil {")
198+
p(" return nil, err")
199+
p(" }")
200+
p(" return resp, nil")
201+
p("}")
202+
p("")
203+
204+
p("func executeRPC[I proto.Message, O proto.Message](ctx context.Context, fn func(context.Context, I, ...grpc.CallOption) (O, error), req I, opts []grpc.CallOption, logger *slog.Logger, rpc string) (O, error) {")
205+
p(" var zero O")
206+
p(` logger.DebugContext(ctx, "api request", "serviceName", serviceName, "rpcName", rpc, "request", grpclog.ProtoMessageRequest(ctx, req))`)
207+
p(" resp, err := fn(ctx, req, opts...)")
208+
p(" if err != nil {")
209+
p(" return zero, err")
210+
p(" }")
211+
p(` logger.DebugContext(ctx, "api response", "serviceName", serviceName, "rpcName", rpc, "response", grpclog.ProtoMessageResponse(resp))`)
212+
p(" return resp, err")
213+
p("}")
214+
p("")
160215
}
161216

162217
func collectScopes(servs []*descriptorpb.ServiceDescriptorProto) []string {

internal/gengapic/gengapic_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,12 +1127,12 @@ func TestGRPCStubCall(t *testing.T) {
11271127
}{
11281128
{
11291129
name: "foo.FooService.GetFoo",
1130-
want: "c.client.GetFoo(ctx, req, settings.GRPC...)",
1130+
want: `executeRPC(ctx, c.client.GetFoo, req, settings.GRPC, c.logger, "GetFoo")`,
11311131
in: getFoo,
11321132
},
11331133
{
11341134
name: "foo.BarService.GetBar",
1135-
want: "c.barClient.GetBar(ctx, req, settings.GRPC...)",
1135+
want: `executeRPC(ctx, c.barClient.GetBar, req, settings.GRPC, c.logger, "GetBar")`,
11361136
in: getBar,
11371137
},
11381138
} {

internal/gengapic/gengrpc.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ func (g *generator) emptyUnaryGRPCCall(servName string, m *descriptorpb.MethodDe
162162
func (g *generator) grpcStubCall(method *descriptorpb.MethodDescriptorProto) string {
163163
service := g.descInfo.ParentElement[method]
164164
stub := pbinfo.ReduceServName(service.GetName(), g.opts.pkgName)
165-
return fmt.Sprintf("c.%s.%s(ctx, req, settings.GRPC...)", grpcClientField(stub), method.GetName())
165+
return fmt.Sprintf("executeRPC(ctx, c.%s.%s, req, settings.GRPC, c.logger, %q)", grpcClientField(stub), method.GetName(), method.GetName())
166166
}
167167

168168
func (g *generator) grpcClientOptions(serv *descriptorpb.ServiceDescriptorProto, servName string) error {
@@ -295,6 +295,8 @@ func (g *generator) grpcClientInit(serv *descriptorpb.ServiceDescriptorProto, se
295295

296296
p("// The x-goog-* metadata to be sent with each request.")
297297
p("xGoogHeaders []string")
298+
p("")
299+
p("logger *slog.Logger")
298300

299301
p("}")
300302
p("")
@@ -303,6 +305,7 @@ func (g *generator) grpcClientInit(serv *descriptorpb.ServiceDescriptorProto, se
303305
g.imports[imp] = true
304306

305307
g.grpcClientUtilities(serv, servName, imp, hasRPCForLRO)
308+
g.imports[pbinfo.ImportSpec{Path: "log/slog"}] = true
306309
}
307310

308311
func (g *generator) grpcClientUtilities(serv *descriptorpb.ServiceDescriptorProto, servName string, imp pbinfo.ImportSpec, hasRPCForLRO bool) {
@@ -337,6 +340,7 @@ func (g *generator) grpcClientUtilities(serv *descriptorpb.ServiceDescriptorProt
337340
p(" connPool: connPool,")
338341
p(" %s: %s.New%sClient(connPool),", grpcClientField(servName), imp.Name, serv.GetName())
339342
p(" CallOptions: &client.CallOptions,")
343+
p(" logger: internaloption.GetLogger(opts),")
340344
g.mixinStubsInit()
341345
p("")
342346
p(" }")

0 commit comments

Comments
 (0)