mirror of
https://github.com/hanzoai/telemetry.git
synced 2026-10-30 20:01:49 +00:00
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue.
Ex. Adding a feature - Explain what this achieves.-->
#### Description
The gRPC service handlers for all four signal types allocate the
top-level ExportXxxServiceRequest with bare new(), bypassing the
sync.Pool when pdata.useProtoPooling is enabled. This means objects
returned to the pool via Delete are never retrieved, so the pool
accumulates unreused objects.
Replace new() with the pool-aware New*() constructors so the top-level
request struct participates in the pool lifecycle.
benchstat (20 runs, pdata.useProtoPooling=true, 10k logs/request):
```
│ old (new()) │ new (New*()) │
│ sec/op │ sec/op vs base │
GRPCLogsSequentialPooling-12 3.858m ± 2% 3.811m ± 1% ~ (p=0.165 n=20)
│ B/op │ B/op vs base │
GRPCLogsSequentialPooling-12 3.551Mi ± 2% 3.523Mi ± 1% ~ (p=0.445 n=20)
│ allocs/op │ allocs/op vs base│
GRPCLogsSequentialPooling-12 75.46k ± 0% 75.46k ± 0% ~ (p=0.867 n=20)
```
No measurable perf difference (1 alloc out of 75k), but this is a
correctness fix for the pool lifecycle.
<!-- Issue number if applicable -->
#### Link to tracking issue
Fixes #
<!--Describe what testing was performed and which tests were added.-->
#### Testing
<!--Describe the documentation added.-->
#### Documentation
<!--Please delete paragraphs that you did not use before submitting.-->
---------
Co-authored-by: Pablo Baeyens <[email protected]>
89 lines
3.0 KiB
Go
89 lines
3.0 KiB
Go
// Copyright The OpenTelemetry Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package otelgrpc // import "go.opentelemetry.io/collector/pdata/internal/otelgrpc"
|
|
|
|
import (
|
|
"context"
|
|
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
|
|
"go.opentelemetry.io/collector/pdata/internal"
|
|
)
|
|
|
|
// LogsServiceClient is the client API for LogsService service.
|
|
//
|
|
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
|
type LogsServiceClient interface {
|
|
Export(context.Context, *internal.ExportLogsServiceRequest, ...grpc.CallOption) (*internal.ExportLogsServiceResponse, error)
|
|
}
|
|
|
|
type logsServiceClient struct {
|
|
cc *grpc.ClientConn
|
|
}
|
|
|
|
func NewLogsServiceClient(cc *grpc.ClientConn) LogsServiceClient {
|
|
return &logsServiceClient{cc}
|
|
}
|
|
|
|
func (c *logsServiceClient) Export(ctx context.Context, in *internal.ExportLogsServiceRequest, opts ...grpc.CallOption) (*internal.ExportLogsServiceResponse, error) {
|
|
out := new(internal.ExportLogsServiceResponse)
|
|
err := c.cc.Invoke(ctx, "/opentelemetry.proto.collector.logs.v1.LogsService/Export", in, out, opts...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
// LogsServiceServer is the server API for LogsService service.
|
|
type LogsServiceServer interface {
|
|
Export(context.Context, *internal.ExportLogsServiceRequest) (*internal.ExportLogsServiceResponse, error)
|
|
}
|
|
|
|
// UnimplementedLogsServiceServer can be embedded to have forward compatible implementations.
|
|
type UnimplementedLogsServiceServer struct{}
|
|
|
|
func (*UnimplementedLogsServiceServer) Export(context.Context, *internal.ExportLogsServiceRequest) (*internal.ExportLogsServiceResponse, error) {
|
|
return nil, status.Errorf(codes.Unimplemented, "method Export not implemented")
|
|
}
|
|
|
|
func RegisterLogsServiceServer(s *grpc.Server, srv LogsServiceServer) {
|
|
s.RegisterService(&logsServiceServiceDesc, srv)
|
|
}
|
|
|
|
// Context cannot be the first parameter of the function because gRPC definition.
|
|
//
|
|
//nolint:revive
|
|
func logsServiceExportHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
|
in := internal.NewExportLogsServiceRequest()
|
|
if err := dec(in); err != nil {
|
|
return nil, err
|
|
}
|
|
if interceptor == nil {
|
|
return srv.(LogsServiceServer).Export(ctx, in)
|
|
}
|
|
info := &grpc.UnaryServerInfo{
|
|
Server: srv,
|
|
FullMethod: "/opentelemetry.proto.collector.logs.v1.LogsService/Export",
|
|
}
|
|
handler := func(ctx context.Context, req any) (any, error) {
|
|
return srv.(LogsServiceServer).Export(ctx, req.(*internal.ExportLogsServiceRequest))
|
|
}
|
|
return interceptor(ctx, in, info, handler)
|
|
}
|
|
|
|
var logsServiceServiceDesc = grpc.ServiceDesc{
|
|
ServiceName: "opentelemetry.proto.collector.logs.v1.LogsService",
|
|
HandlerType: (*LogsServiceServer)(nil),
|
|
Methods: []grpc.MethodDesc{
|
|
{
|
|
MethodName: "Export",
|
|
Handler: logsServiceExportHandler,
|
|
},
|
|
},
|
|
Streams: []grpc.StreamDesc{},
|
|
Metadata: "opentelemetry/proto/collector/logs/v1/logs_service.proto",
|
|
}
|