Skip to content

Commit

Permalink
added heap profile
Browse files Browse the repository at this point in the history
  • Loading branch information
dvovk committed Aug 19, 2024
1 parent 08da1ce commit 6b25e22
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
24 changes: 24 additions & 0 deletions api/api_handler.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package api

import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
Expand Down Expand Up @@ -271,6 +273,27 @@ func (h *APIHandler) UniversalRequest(w http.ResponseWriter, r *http.Request) {
w.Write(jsonData)
}

func (h *APIHandler) HeapProfile(w http.ResponseWriter, r *http.Request) {
client, err := h.findNodeClient(r)

if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

heap, err := client.FindHeapProfile(r.Context())

if err != nil {
http.Error(w, fmt.Sprintf("Unable to fetch sync stage progress: %v", err), http.StatusInternalServerError)
return
}

encoded := base64.StdEncoding.EncodeToString(heap)

//w.Header().Set("Content-Type", "text/plain")
w.Write(bytes.NewBufferString(encoded).Bytes())
}

func NewAPIHandler(
sessions sessions.CacheService,
erigonNode erigon_node.Client,
Expand All @@ -291,6 +314,7 @@ func NewAPIHandler(
r.Get("/sessions/{sessionId}/nodes/{nodeId}/headers/download-summary", r.HeadersDownload)
r.Get("/sessions/{sessionId}/nodes/{nodeId}/sync-stages", r.SyncStages)
r.Get("/v2/sessions/{sessionId}/nodes/{nodeId}/*", r.UniversalRequest)
r.Get("/sessions/{sessionId}/nodes/{nodeId}/profile/heap", r.HeapProfile)

return r
}
Expand Down
2 changes: 2 additions & 0 deletions internal/erigon_node/erigon_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,7 @@ type Client interface {
BodiesDownload(ctx context.Context, w http.ResponseWriter)
HeadersDownload(ctx context.Context, w http.ResponseWriter)

FindHeapProfile(ctx context.Context) ([]byte, error)

fetch(ctx context.Context, method string, params url.Values) (*NodeRequest, error)
}
62 changes: 62 additions & 0 deletions internal/erigon_node/profile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package erigon_node

import (
"context"
"encoding/json"
"fmt"
"os"
"os/exec"
)

type ProfileContent struct {
Chunk []byte `json:"chunk"`
}

func (c *NodeClient) FindHeapProfile(ctx context.Context) ([]byte, error) {
request, err := c.fetch(ctx, "heap-profile", nil)

if err != nil {
return nil, err
}

_, result, err := request.nextResult(ctx)

if err != nil {
return nil, err
}

var content ProfileContent

if err := json.Unmarshal(result, &content); err != nil {
return nil, err
}

//result is a file content so I need to save it to file and return the file path
tempFile, err := os.CreateTemp("", "heap-profile-*.pprof")
if err != nil {
return nil, err
}

defer func() {
if err := tempFile.Close(); err != nil {
fmt.Printf("Error closing temporary file: %v\n", err)
}

// Remove the file after closing it
if err := os.Remove(tempFile.Name()); err != nil {
fmt.Printf("Error removing temporary file: %v\n", err)
}
}()

if _, err := tempFile.Write(content.Chunk); err != nil {
return nil, err
}

cmd := exec.Command("go", "tool", "pprof", "-png", tempFile.Name())
svgOutput, err := cmd.Output()
if err != nil {
return nil, err
}

return svgOutput, nil
}

0 comments on commit 6b25e22

Please sign in to comment.