@@ -324,6 +324,44 @@ func (r *pyroscopeReceiver) Push(ctx context.Context, req *connect.Request[pushv
324
324
return connect .NewResponse (& pushv1.PushResponse {}), nil
325
325
}
326
326
327
+ func (r * pyroscopeReceiver ) getProfilesBuff (req * http.Request ) (* bytes.Buffer , error ) {
328
+ var err error
329
+ var buf * bytes.Buffer
330
+ defer func () {
331
+ if err != nil && buf != nil {
332
+ releaseBuf (r .uncompressedBufPool , buf )
333
+ }
334
+ }()
335
+ contentType := ""
336
+ if len (req .Header ["Content-Type" ]) > 0 {
337
+ contentType = req .Header ["Content-Type" ][0 ]
338
+ }
339
+ if strings .HasPrefix (contentType , "multipart/form-data" ) {
340
+ var f multipart.File
341
+ f , err = r .openMultipart (req )
342
+ if err != nil {
343
+ return nil , err
344
+ }
345
+ defer f .Close ()
346
+
347
+ buf = acquireBuf (r .uncompressedBufPool )
348
+ err = r .decompressor .Decompress (f , compress .Gzip , buf )
349
+ if err != nil {
350
+ return nil , fmt .Errorf ("failed to decompress body: %w" , err )
351
+ }
352
+ return buf , nil
353
+ }
354
+ if strings .HasPrefix (contentType , "binary/octet-stream" ) {
355
+ buf = acquireBuf (r .uncompressedBufPool )
356
+ _ , err = io .Copy (buf , req .Body )
357
+ if err != nil {
358
+ return buf , fmt .Errorf ("failed to read body: %w" , err )
359
+ }
360
+ return buf , nil
361
+ }
362
+ return nil , fmt .Errorf ("unsupported content type: %s" , contentType )
363
+ }
364
+
327
365
func (r * pyroscopeReceiver ) readProfiles (ctx context.Context , req * http.Request , pm params ) (plog.Logs , error ) {
328
366
var (
329
367
tmp []string
@@ -342,21 +380,14 @@ func (r *pyroscopeReceiver) readProfiles(ctx context.Context, req *http.Request,
342
380
p = pprofparser .NewPprofParser ()
343
381
}
344
382
// support only multipart/form-data
345
- f , err := r .openMultipart (req )
383
+ buf , err := r .getProfilesBuff (req )
346
384
if err != nil {
347
385
return logs , err
348
386
}
349
- defer f .Close ()
350
-
351
- buf := acquireBuf (r .uncompressedBufPool )
352
387
defer func () {
353
388
releaseBuf (r .uncompressedBufPool , buf )
354
389
}()
355
390
356
- err = r .decompressor .Decompress (f , compress .Gzip , buf )
357
- if err != nil {
358
- return logs , fmt .Errorf ("failed to decompress body: %w" , err )
359
- }
360
391
// TODO: try measure compressed size
361
392
otelcolReceiverPyroscopeRequestBodyUncompressedSizeBytes .Record (ctx , int64 (buf .Len ()), metric .WithAttributeSet (* newOtelcolAttrSetPayloadSizeBytes (pm .name , formatJfr , "" )))
362
393
resetHeaders (req )
@@ -384,15 +415,13 @@ func (r *pyroscopeReceiver) readProfiles(ctx context.Context, req *http.Request,
384
415
record := rs .AppendEmpty ()
385
416
if tmp , ok = qs ["format" ]; ok && (tmp [0 ] == "jfr" ) {
386
417
timestampNs = ns (pm .start )
387
- durationNs = pm .end - pm .start
388
- durationNs = ns (durationNs )
418
+ durationNs = ns (pm .end ) - ns (pm .start )
389
419
} else if tmp , ok = qs ["spyName" ]; ok && (tmp [0 ] == "nodespy" ) {
390
420
timestampNs = uint64 (pr .TimeStampNao )
391
421
durationNs = uint64 (pr .DurationNano )
392
422
} else {
393
- timestampNs = pm .start
394
- durationNs = pm .end - pm .start
395
- durationNs = ns (durationNs )
423
+ timestampNs = ns (pm .start )
424
+ durationNs = ns (pm .end ) - ns (pm .start )
396
425
}
397
426
record .SetTimestamp (pcommon .Timestamp (timestampNs ))
398
427
m := record .Attributes ()
@@ -409,7 +438,7 @@ func (r *pyroscopeReceiver) readProfiles(ctx context.Context, req *http.Request,
409
438
postProcessProf (pr .Profile , & m )
410
439
record .Body ().SetEmptyBytes ().FromRaw (pr .Payload .Bytes ())
411
440
sz += pr .Payload .Len ()
412
- r .logger .Debug (
441
+ r .logger .Info (
413
442
fmt .Sprintf ("parsed profile %d" , i ),
414
443
zap .Uint64 ("timestamp_ns" , timestampNs ),
415
444
zap .String ("type" , pr .Type .Type ),
@@ -427,7 +456,16 @@ func (r *pyroscopeReceiver) readProfiles(ctx context.Context, req *http.Request,
427
456
}
428
457
429
458
func ns (sec uint64 ) uint64 {
430
- return sec * 1e9
459
+ if sec < 10000000000000 {
460
+ return sec * 1e9
461
+ }
462
+ if sec < 10000000000000000 {
463
+ return sec * 1e6
464
+ }
465
+ if sec < 10000000000000000000 {
466
+ return sec * 1e3
467
+ }
468
+ return sec
431
469
}
432
470
433
471
func newOtelcolAttrSetPayloadSizeBytes (service string , typ string , encoding string ) * attribute.Set {
0 commit comments