1515package main
1616
1717import (
18+ "bytes"
1819 "context"
1920 "crypto/tls"
2021 "fmt"
2122 "io"
2223 "os"
24+ "time"
2325
2426 "github.com/alecthomas/kong"
27+ "github.com/google/pprof/profile"
2528 grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
2629 grun "github.com/oklog/run"
2730 profilestorepb "github.com/parca-dev/parca/gen/proto/go/parca/profilestore/v1alpha1"
@@ -32,9 +35,10 @@ import (
3235)
3336
3437type flags struct {
35- Path string `kong:"arg,help='Path to the profile data.'"`
36- Labels map [string ]string `kong:"help='Labels to attach to the profile data. For example --labels=__name__=process_cpu --labels=node=foo',short='l'"`
37- Normalized bool `kong:"help='Whether the profile sample addresses are already normalized by the mapping offset.',default='false'"`
38+ Path string `kong:"arg,help='Path to the profile data.'"`
39+ Labels map [string ]string `kong:"help='Labels to attach to the profile data. For example --labels=__name__=process_cpu --labels=node=foo',short='l'"`
40+ Normalized bool `kong:"help='Whether the profile sample addresses are already normalized by the mapping offset.',default='false'"`
41+ OverrideTimestamp bool `kong:"help='Update the timestamp in the pprof profile to be the current time.'"`
3842
3943 RemoteStore FlagsRemoteStore `embed:"" prefix:"remote-store-"`
4044}
@@ -75,27 +79,42 @@ func run(flags flags) error {
7579 }
7680 defer conn .Close ()
7781
78- var profile []byte
82+ var profileContent []byte
7983 if flags .Path == "-" {
80- profile , err = io .ReadAll (os .Stdin )
84+ profileContent , err = io .ReadAll (os .Stdin )
8185 if err != nil {
8286 return fmt .Errorf ("read profile from stdin: %w" , err )
8387 }
8488 } else {
85- profile , err = os .ReadFile (flags .Path )
89+ profileContent , err = os .ReadFile (flags .Path )
8690 if err != nil {
8791 return fmt .Errorf ("read profile file: %w" , err )
8892 }
8993 }
9094
95+ p , err := profile .ParseData (profileContent )
96+ if err != nil {
97+ return fmt .Errorf ("parse pprof profile: %w" , err )
98+ }
99+
100+ if flags .OverrideTimestamp {
101+ now := time .Now ()
102+ p .TimeNanos = now .UnixNano ()
103+ buf := bytes .NewBuffer (nil )
104+ if err := p .Write (buf ); err != nil {
105+ return fmt .Errorf ("serialize pprof profile: %w" , err )
106+ }
107+ profileContent = buf .Bytes ()
108+ }
109+
91110 profilestoreClient := profilestorepb .NewProfileStoreServiceClient (conn )
92111 _ , err = profilestoreClient .WriteRaw (ctx , & profilestorepb.WriteRawRequest {
93112 Series : []* profilestorepb.RawProfileSeries {{
94113 Labels : & profilestorepb.LabelSet {
95114 Labels : labels ,
96115 },
97116 Samples : []* profilestorepb.RawSample {{
98- RawProfile : profile ,
117+ RawProfile : profileContent ,
99118 }},
100119 }},
101120 Normalized : flags .Normalized ,
0 commit comments