@@ -128,9 +128,13 @@ func (h *clientStatsHandler) streamInterceptor(ctx context.Context, desc *grpc.S
128128}
129129
130130func (h * clientStatsHandler ) perCallMetrics (ctx context.Context , err error , startTime time.Time , ci * callInfo ) {
131- s := status .Convert (err )
132- callLatency := float64 (time .Since (startTime )) / float64 (time .Second )
133- h .clientMetrics .callDuration .Record (ctx , callLatency , otelmetric .WithAttributes (otelattribute .String ("grpc.method" , ci .method ), otelattribute .String ("grpc.target" , ci .target ), otelattribute .String ("grpc.status" , canonicalString (s .Code ()))))
131+ callLatency := float64 (time .Since (startTime )) / float64 (time .Second ) // calculate ASAP
132+ attrs := otelmetric .WithAttributeSet (otelattribute .NewSet (
133+ otelattribute .String ("grpc.method" , ci .method ),
134+ otelattribute .String ("grpc.target" , ci .target ),
135+ otelattribute .String ("grpc.status" , canonicalString (status .Code (err ))),
136+ ))
137+ h .clientMetrics .callDuration .Record (ctx , callLatency , attrs )
134138}
135139
136140// TagConn exists to satisfy stats.Handler.
@@ -188,7 +192,11 @@ func (h *clientStatsHandler) processRPCEvent(ctx context.Context, s stats.RPCSta
188192 return
189193 }
190194
191- h .clientMetrics .attemptStarted .Add (ctx , 1 , otelmetric .WithAttributes (otelattribute .String ("grpc.method" , ci .method ), otelattribute .String ("grpc.target" , ci .target )))
195+ attrs := otelmetric .WithAttributeSet (otelattribute .NewSet (
196+ otelattribute .String ("grpc.method" , ci .method ),
197+ otelattribute .String ("grpc.target" , ci .target ),
198+ ))
199+ h .clientMetrics .attemptStarted .Add (ctx , 1 , attrs )
192200 case * stats.OutPayload :
193201 atomic .AddInt64 (& ai .sentCompressedBytes , int64 (st .CompressedLength ))
194202 case * stats.InPayload :
@@ -244,10 +252,11 @@ func (h *clientStatsHandler) processRPCEnd(ctx context.Context, ai *attemptInfo,
244252 }
245253 }
246254
247- clientAttributeOption := otelmetric .WithAttributes (attributes ... )
248- h .clientMetrics .attemptDuration .Record (ctx , latency , clientAttributeOption )
249- h .clientMetrics .attemptSentTotalCompressedMessageSize .Record (ctx , atomic .LoadInt64 (& ai .sentCompressedBytes ), clientAttributeOption )
250- h .clientMetrics .attemptRcvdTotalCompressedMessageSize .Record (ctx , atomic .LoadInt64 (& ai .recvCompressedBytes ), clientAttributeOption )
255+ // Allocate vararg slice once.
256+ opts := []otelmetric.RecordOption {otelmetric .WithAttributeSet (otelattribute .NewSet (attributes ... ))}
257+ h .clientMetrics .attemptDuration .Record (ctx , latency , opts ... )
258+ h .clientMetrics .attemptSentTotalCompressedMessageSize .Record (ctx , atomic .LoadInt64 (& ai .sentCompressedBytes ), opts ... )
259+ h .clientMetrics .attemptRcvdTotalCompressedMessageSize .Record (ctx , atomic .LoadInt64 (& ai .recvCompressedBytes ), opts ... )
251260}
252261
253262const (
0 commit comments