@@ -53,6 +53,21 @@ func (p *prwTelemetryOtel) recordTranslatedTimeSeries(ctx context.Context, numTS
53
53
p .telemetryBuilder .ExporterPrometheusremotewriteTranslatedTimeSeries .Add (ctx , int64 (numTS ), metric .WithAttributes (p .otelAttrs ... ))
54
54
}
55
55
56
+ type buffer struct {
57
+ protobuf * proto.Buffer
58
+ snappy []byte
59
+ }
60
+
61
+ // A reusable buffer pool for serializing protobufs and compressing them with Snappy.
62
+ var bufferPool = sync.Pool {
63
+ New : func () any {
64
+ return & buffer {
65
+ protobuf : proto .NewBuffer (nil ),
66
+ snappy : nil ,
67
+ }
68
+ },
69
+ }
70
+
56
71
// prwExporter converts OTLP metrics to Prometheus remote write TimeSeries and sends them to a remote endpoint.
57
72
type prwExporter struct {
58
73
endpointURL * url.URL
@@ -271,14 +286,26 @@ func (prwe *prwExporter) export(ctx context.Context, requests []*prompb.WriteReq
271
286
}
272
287
273
288
func (prwe * prwExporter ) execute (ctx context.Context , writeReq * prompb.WriteRequest ) error {
289
+ buf := bufferPool .Get ().(* buffer )
290
+ buf .protobuf .Reset ()
291
+ defer bufferPool .Put (buf )
292
+
274
293
// Uses proto.Marshal to convert the WriteRequest into bytes array
275
- data , errMarshal := proto .Marshal (writeReq )
294
+ errMarshal := buf . protobuf .Marshal (writeReq )
276
295
if errMarshal != nil {
277
296
return consumererror .NewPermanent (errMarshal )
278
297
}
279
298
// If we don't pass a buffer large enough, Snappy Encode function will not use it and instead will allocate a new buffer.
280
- // Therefore we always let Snappy decide the size of the buffer.
281
- compressedData := snappy .Encode (nil , data )
299
+ // Manually grow the buffer to make sure Snappy uses it and we can re-use it afterwards.
300
+ maxCompressedLen := snappy .MaxEncodedLen (len (buf .protobuf .Bytes ()))
301
+ if maxCompressedLen > len (buf .snappy ) {
302
+ if cap (buf .snappy ) < maxCompressedLen {
303
+ buf .snappy = make ([]byte , maxCompressedLen )
304
+ } else {
305
+ buf .snappy = buf .snappy [:maxCompressedLen ]
306
+ }
307
+ }
308
+ compressedData := snappy .Encode (buf .snappy , buf .protobuf .Bytes ())
282
309
283
310
// executeFunc can be used for backoff and non backoff scenarios.
284
311
executeFunc := func () error {
0 commit comments