66 "encoding/json"
77 "fmt"
88 "github.com/google/pprof/driver"
9+ "github.com/google/pprof/profile"
910 "github.com/spf13/cobra"
1011 "io"
1112 "io/ioutil"
@@ -38,12 +39,21 @@ func exportLogic() func(cmd *cobra.Command, args []string) {
3839 log .Fatalf ("Exactly one profile file is required" )
3940 }
4041 if local {
42+ err , finalTree := generateFlameGraph (args [0 ])
43+ if err != nil {
44+ log .Fatalf ("An Error Occured %v" , err )
45+ }
46+ postBody , err := json .Marshal (finalTree )
47+ if err != nil {
48+ log .Fatalf ("An Error Occured %v" , err )
49+ }
50+ fmt .Println (string (postBody ))
51+
4152 for _ , granularity := range granularityOptions {
4253 err , report := generateTextReports (granularity , args [0 ])
4354 if err == nil {
4455 var w io.Writer
4556 // open output file
46- fmt .Println ()
4757 localExportLogic (w , report )
4858 } else {
4959 log .Fatal (err )
@@ -53,16 +63,45 @@ func exportLogic() func(cmd *cobra.Command, args []string) {
5363 for _ , granularity := range granularityOptions {
5464 err , report := generateTextReports (granularity , args [0 ])
5565 if err == nil {
56- fmt .Println ()
5766 remoteExportLogic (report , granularity )
5867 } else {
5968 log .Fatal (err )
6069 }
6170 }
62- log .Printf ("Successfully published profile data. Check it at: %s/gh/%s/%s/commit/%s/bench/%s/cpu" , codeperfUrl , gitOrg , gitRepo , gitCommit , bench )
71+ err , finalTree := generateFlameGraph (args [0 ])
72+ if err != nil {
73+ log .Fatalf ("An Error Occured %v" , err )
74+ }
75+ remoteFlameGraphExport (finalTree )
76+ log .Printf ("Successfully published profile data" )
77+ log .Printf ("Check it at: %s/gh/%s/%s/commit/%s/bench/%s/cpu" , codeperfUrl , gitOrg , gitRepo , gitCommit , bench )
6378 }
79+ }
80+ }
81+
82+ func remoteFlameGraphExport (tree treeNodeSlice ) {
83+ postBody , err := json .Marshal (tree )
84+ if err != nil {
85+ log .Fatalf ("An Error Occured %v" , err )
86+ }
87+ responseBody := bytes .NewBuffer (postBody )
88+ endPoint := fmt .Sprintf ("%s/v1/gh/%s/%s/commit/%s/bench/%s/cpu/flamegraph" , codeperfApiUrl , gitOrg , gitRepo , gitCommit , bench )
89+ resp , err := http .Post (endPoint , "application/json" , responseBody )
90+ //Handle Error
91+ if err != nil {
92+ log .Fatalf ("An Error Occured %v" , err )
93+ }
94+ defer resp .Body .Close ()
6495
96+ //Read the response body
97+ reply , err := ioutil .ReadAll (resp .Body )
98+ if err != nil {
99+ log .Fatalln (err )
65100 }
101+ if resp .StatusCode != 200 {
102+ log .Fatalf ("An error ocurred while phusing data to remote %s. Status code %d. Reply: %s" , codeperfApiUrl , resp .StatusCode , string (reply ))
103+ }
104+
66105}
67106
68107func remoteExportLogic (report TextReport , granularity string ) {
@@ -111,6 +150,48 @@ func localExportLogic(w io.Writer, report TextReport) {
111150 }
112151}
113152
153+ func generateFlameGraph (input string ) (err error , tree treeNodeSlice ) {
154+ f := baseFlags ()
155+
156+ // Read the profile from the encoded protobuf
157+ outputTempFile , err := ioutil .TempFile ("" , "profile_output" )
158+ if err != nil {
159+ log .Fatalf ("cannot create tempfile: %v" , err )
160+ }
161+ log .Printf ("Generating temp file %s" , outputTempFile .Name ())
162+ //defer os.Remove(outputTempFile.Name())
163+ defer outputTempFile .Close ()
164+ f .strings ["output" ] = outputTempFile .Name ()
165+ f .bools ["proto" ] = true
166+ f .bools ["text" ] = false
167+ f .args = []string {
168+ input ,
169+ }
170+ reader := bufio .NewReader (os .Stdin )
171+ options := & driver.Options {
172+ Flagset : f ,
173+ UI : & UI {r : reader },
174+ }
175+
176+ if err = driver .PProf (options ); err != nil {
177+ log .Fatalf ("cannot read pprof profile from %s. Error: %v" , input , err )
178+ return
179+ }
180+
181+ file , err := os .Open (outputTempFile .Name ())
182+ if err != nil {
183+ log .Fatal (err )
184+ }
185+ defer file .Close ()
186+ r := bufio .NewReader (file )
187+ profile , err := profile .Parse (r )
188+ if err != nil {
189+ log .Fatal (err )
190+ }
191+ tree = profileToFolded (profile )
192+ return
193+ }
194+
114195func generateTextReports (granularity string , input string ) (err error , report TextReport ) {
115196 f := baseFlags ()
116197
0 commit comments