diff --git a/diagnostics/profile.go b/diagnostics/profile.go new file mode 100644 index 00000000000..4a9a16e3bfd --- /dev/null +++ b/diagnostics/profile.go @@ -0,0 +1,53 @@ +// Copyright 2024 The Erigon Authors +// This file is part of Erigon. +// +// Erigon is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Erigon is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with Erigon. If not, see . + +package diagnostics + +import ( + "fmt" + "net/http" + "runtime/pprof" + "strings" + + diaglib "github.com/erigontech/erigon-lib/diagnostics" +) + +func SetupProfileAccess(metricsMux *http.ServeMux, diag *diaglib.DiagnosticClient) { + if metricsMux == nil { + return + } + + //handle all pprof, supported: goroutine, threadcreate, heap, allocs, block, mutex + metricsMux.HandleFunc("/pprof/", func(w http.ResponseWriter, r *http.Request) { + profile := strings.TrimPrefix(r.URL.Path, "/pprof/") + writePprofProfile(w, profile) + }) +} + +func writePprofProfile(w http.ResponseWriter, profile string) { + p := pprof.Lookup(profile) + if p == nil { + http.Error(w, "Unknown profile: "+profile, http.StatusNotFound) + return + } + + w.Header().Set("Content-Type", "aplication/profile") + err := p.WriteTo(w, 0) + if err != nil { + http.Error(w, fmt.Sprintf("Failed to write profile: %v", err), http.StatusInternalServerError) + return + } +} diff --git a/diagnostics/setup.go b/diagnostics/setup.go index 38ee64d1cf6..241afb03301 100644 --- a/diagnostics/setup.go +++ b/diagnostics/setup.go @@ -134,4 +134,5 @@ func SetupEndpoints(ctx *cli.Context, node *node.ErigonNode, diagMux *http.Serve SetupHeadersAccess(diagMux, diagnostic) SetupBodiesAccess(diagMux, diagnostic) SetupSysInfoAccess(diagMux, diagnostic) + SetupProfileAccess(diagMux, diagnostic) } diff --git a/diagnostics/sysinfo.go b/diagnostics/sysinfo.go index aae54428ed7..4dd9c8c41e2 100644 --- a/diagnostics/sysinfo.go +++ b/diagnostics/sysinfo.go @@ -18,9 +18,7 @@ package diagnostics import ( "encoding/json" - "fmt" "net/http" - "runtime/pprof" diaglib "github.com/ledgerwatch/erigon-lib/diagnostics" "github.com/ledgerwatch/erigon-lib/sysutils" @@ -54,6 +52,7 @@ func SetupSysInfoAccess(metricsMux *http.ServeMux, diag *diaglib.DiagnosticClien w.Header().Set("Content-Type", "application/json") writeMemoryInfo(w) }) +<<<<<<< HEAD metricsMux.HandleFunc("/heap-profile", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") @@ -68,6 +67,8 @@ func writeHeapProfile(w http.ResponseWriter) { http.Error(w, fmt.Sprintf("Failed to write profile: %v", err), http.StatusInternalServerError) return } +======= +>>>>>>> a899646eed (diagnostics: all pprofs (#11891)) } func writeHardwareInfo(w http.ResponseWriter, diag *diaglib.DiagnosticClient) {