Skip to content

Commit

Permalink
Heap (#88)
Browse files Browse the repository at this point in the history
* added heap profile

* added support to query all pprofs
  • Loading branch information
dvovk authored Sep 5, 2024
1 parent d9be114 commit 90d809c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 29 deletions.
51 changes: 26 additions & 25 deletions api/api_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package api

import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"path"
"strconv"
"strings"

"github.com/go-chi/chi/v5"

Expand Down Expand Up @@ -247,51 +249,51 @@ func (h *APIHandler) findNodeClient(r *http.Request) (erigon_node.Client, error)
}

func (h *APIHandler) UniversalRequest(w http.ResponseWriter, r *http.Request) {
apiStr := chi.URLParam(r, "*")

client, err := h.findNodeClient(r)

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

response, err := client.GetResponse(r.Context(), apiStr)
pprof, data, err := GetResponseData(r.Context(), client, chi.URLParam(r, "*"))

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

jsonData, err := json.Marshal(response)

if err != nil {
api_internal.EncodeError(w, r, err)
if pprof {
encoded := base64.StdEncoding.EncodeToString(data)
data = bytes.NewBufferString(encoded).Bytes()
} else {
w.Header().Set("Content-Type", "application/json")
}

w.Header().Set("Content-Type", "application/json")
w.Write(jsonData)
w.Write(data)
}

func (h *APIHandler) HeapProfile(w http.ResponseWriter, r *http.Request) {
client, err := h.findNodeClient(r)
func GetResponseData(ctx context.Context, client erigon_node.Client, request string) (bool, []byte, error) {
if strings.Contains(request, "pprof") {
data, err := client.FindProfile(ctx, request)
if err != nil {
return true, nil, err
}

if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
return true, data, nil
} else {
response, err := client.GetResponse(ctx, request)
if err != nil {
return false, nil, err
}

heap, err := client.FindHeapProfile(r.Context())
jsonData, err := json.Marshal(response)
if err != nil {
return false, nil, err
}

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

encoded := base64.StdEncoding.EncodeToString(heap)

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

func NewAPIHandler(
Expand All @@ -314,7 +316,6 @@ 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: 1 addition & 1 deletion internal/erigon_node/erigon_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +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)
FindProfile(ctx context.Context, profile string) ([]byte, error)

fetch(ctx context.Context, method string, params url.Values) (*NodeRequest, error)
}
6 changes: 3 additions & 3 deletions internal/erigon_node/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ type ProfileContent struct {
Chunk []byte `json:"chunk"`
}

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

if err != nil {
return nil, err
Expand All @@ -32,7 +32,7 @@ func (c *NodeClient) FindHeapProfile(ctx context.Context) ([]byte, error) {
}

//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")
tempFile, err := os.CreateTemp("", "profile-*.pprof")
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 90d809c

Please sign in to comment.