@@ -190,20 +190,20 @@ private async Task<bool> SendOtlpRequest(IReadOnlyList<MetricPoint> metrics)
190190 {
191191 try
192192 {
193- // Serialize metrics to protobuf format
194- // For gRPC, reserve 5 bytes at the start for the frame header (added later)
195- // For HTTP, start at position 0
196- // Note: JSON serialization is not yet implemented, so we always use protobuf ATM
197- var startPosition = _protocol == Configuration . OtlpProtocol . Grpc ? 5 : 0 ;
198- var otlpPayload = _serializer . SerializeMetrics ( metrics , startPosition ) ;
199-
200- return _protocol switch
193+ // OTEL-style: serialize per protocol so we never leak the gRPC 5-byte reservation into HTTP.
194+ var task = _protocol switch
201195 {
202- Configuration . OtlpProtocol . HttpProtobuf => await SendHttpProtobufRequest ( otlpPayload ) . ConfigureAwait ( false ) ,
203- Configuration . OtlpProtocol . HttpJson => await SendHttpJsonRequest ( otlpPayload ) . ConfigureAwait ( false ) ,
204- Configuration . OtlpProtocol . Grpc => await SendGrpcRequest ( otlpPayload ) . ConfigureAwait ( false ) ,
205- _ => await SendHttpProtobufRequest ( otlpPayload ) . ConfigureAwait ( false )
196+ Configuration . OtlpProtocol . Grpc =>
197+ SendGrpcRequest ( _serializer . SerializeMetrics ( metrics , startPosition : 5 ) ) ,
198+ Configuration . OtlpProtocol . HttpProtobuf =>
199+ SendHttpProtobufRequest ( _serializer . SerializeMetrics ( metrics , startPosition : 0 ) ) ,
200+ Configuration . OtlpProtocol . HttpJson =>
201+ SendHttpJsonRequest ( _serializer . SerializeMetrics ( metrics , startPosition : 0 ) ) ,
202+ _ =>
203+ SendHttpProtobufRequest ( _serializer . SerializeMetrics ( metrics , startPosition : 0 ) )
206204 } ;
205+
206+ return await task . ConfigureAwait ( false ) ;
207207 }
208208 catch ( Exception ex )
209209 {
@@ -246,7 +246,27 @@ private async Task<bool> SendGrpcRequest(byte[] otlpPayload)
246246 if ( _grpcClient is null )
247247 {
248248 Log . Warning ( "GRPC selected but gRPC client is not initialized; falling back to HTTP/protobuf." ) ;
249- return await SendHttpProtobufRequest ( otlpPayload ) . ConfigureAwait ( false ) ;
249+ // otlpPayload was serialized with startPosition=5 => slice off the 5-byte reservation.
250+ return await SendWithRetry (
251+ otlpPayload ,
252+ ( p , endpoint , headers ) =>
253+ {
254+ var content = new ByteArrayContent ( p , 5 , p . Length - 5 ) ;
255+ content . Headers . ContentType = new MediaTypeHeaderValue ( "application/x-protobuf" ) ;
256+
257+ var httpRequest = new HttpRequestMessage ( HttpMethod . Post , endpoint )
258+ {
259+ Content = content
260+ } ;
261+
262+ foreach ( var header in headers )
263+ {
264+ httpRequest . Headers . TryAddWithoutValidation ( header . Key , header . Value ) ;
265+ }
266+
267+ return httpRequest ;
268+ } )
269+ . ConfigureAwait ( false ) ;
250270 }
251271
252272 try
0 commit comments