Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/prometheus/prometheus v1.7.2-0.20170814170113-3101606756c5
github.com/rs/cors v1.7.0
github.com/stretchr/testify v1.8.4
github.com/stretchr/testify v1.10.0
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
golang.org/x/crypto v0.42.0
golang.org/x/sync v0.17.0
Expand All @@ -45,6 +45,7 @@ require (
github.com/golang-jwt/jwt/v4 v4.5.2
github.com/google/gofuzz v1.2.0
github.com/google/uuid v1.6.0
github.com/grafana/pyroscope-go v1.2.7
github.com/influxdata/influxdb-client-go/v2 v2.4.0
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c
github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52
Expand Down Expand Up @@ -75,14 +76,16 @@ require (
github.com/go-ole/go-ole v1.2.5 // indirect
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
github.com/grafana/pyroscope-go/godeltaprof v0.1.9 // indirect
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
github.com/kilic/bls12-381 v0.1.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/naoina/go-stringutil v0.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
Expand Down
13 changes: 10 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grafana/pyroscope-go v1.2.7 h1:VWBBlqxjyR0Cwk2W6UrE8CdcdD80GOFNutj0Kb1T8ac=
github.com/grafana/pyroscope-go v1.2.7/go.mod h1:o/bpSLiJYYP6HQtvcoVKiE9s5RiNgjYTj1DhiddP2Pc=
github.com/grafana/pyroscope-go/godeltaprof v0.1.9 h1:c1Us8i6eSmkW+Ez05d3co8kasnuOY813tbMN8i/a3Og=
github.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU=
github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA=
github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
Expand All @@ -124,6 +128,8 @@ github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 h1:msKODTL1m0wigzta
github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52/go.mod h1:qk1sX/IBgppQNcGCRoj90u6EGC056EBoIc1oEjCWla8=
github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4=
github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig=
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
Expand Down Expand Up @@ -179,7 +185,6 @@ github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM=
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand All @@ -203,11 +208,13 @@ github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go
github.com/status-im/keycard-go v0.3.3 h1:qk/JHSkT9sMka+lVXrTOIVSgHIY7lDm46wrUqTsNa4s=
github.com/status-im/keycard-go v0.3.3/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=
Expand Down
13 changes: 13 additions & 0 deletions internal/debug/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ var Flags = []cli.Flag{
//traceFlag,
periodicProfilingFlag,
debugDataDirFlag,
pyroscopeFlag,
pyroscopeServerFlag,
pyroscopeAuthUsernameFlag,
pyroscopeAuthPasswordFlag,
pyroscopeTagsFlag,
}

var (
Expand Down Expand Up @@ -323,6 +328,13 @@ func Setup(ctx *cli.Context) error {
StartPProf(address, !ctx.IsSet("metrics-addr") && !ctx.IsSet("metrics.addr"))
}

// Pyroscope profiling
if ctx.Bool(pyroscopeFlag.Name) {
if err := startPyroscope(ctx); err != nil {
return err
}
}

if len(logFile) > 0 || rotation {
log.Info("Logging configured", context...)
}
Expand All @@ -347,6 +359,7 @@ func StartPProf(address string, withMetrics bool) {
// Exit stops all running profiles, flushing their output to the
// respective file.
func Exit() {
stopPyroscope()
Handler.StopCPUProfile()
Handler.StopGoTrace()
if logOutputFile != nil {
Expand Down
139 changes: 139 additions & 0 deletions internal/debug/pyroscope.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// Copyright 2026 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library 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.
//
// The go-ethereum library 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 the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package debug

import (
"fmt"
"strings"

"github.com/XinFinOrg/XDPoSChain/internal/flags"
"github.com/XinFinOrg/XDPoSChain/log"
"github.com/grafana/pyroscope-go"
"github.com/urfave/cli/v2"
)

var (
pyroscopeFlag = &cli.BoolFlag{
Name: "pyroscope",
Usage: "Enable Pyroscope profiling",
Value: false,
Category: flags.LoggingCategory,
}
pyroscopeServerFlag = &cli.StringFlag{
Name: "pyroscope-server",
Usage: "Pyroscope server URL to push profiling data to",
Value: "http://localhost:4040",
Category: flags.LoggingCategory,
}
pyroscopeAuthUsernameFlag = &cli.StringFlag{
Name: "pyroscope-username",
Usage: "Pyroscope basic authentication username",
Value: "",
Category: flags.LoggingCategory,
}
pyroscopeAuthPasswordFlag = &cli.StringFlag{
Name: "pyroscope-password",
Usage: "Pyroscope basic authentication password (prefer setting PYROSCOPE_PASSWORD env var instead of CLI flag)",
Value: "",
Comment thread
gzliudan marked this conversation as resolved.
EnvVars: []string{"PYROSCOPE_PASSWORD"},
Category: flags.LoggingCategory,
}
pyroscopeTagsFlag = &cli.StringFlag{
Name: "pyroscope-tags",
Usage: "Comma separated list of key=value tags to add to profiling data",
Value: "",
Category: flags.LoggingCategory,
}
)

// This holds the globally-configured Pyroscope instance.
var pyroscopeProfiler *pyroscope.Profiler

func startPyroscope(ctx *cli.Context) error {
server := ctx.String(pyroscopeServerFlag.Name)
authUsername := ctx.String(pyroscopeAuthUsernameFlag.Name)
authPassword := ctx.String(pyroscopeAuthPasswordFlag.Name)

rawTags := ctx.String(pyroscopeTagsFlag.Name)
tags := make(map[string]string)
for tag := range strings.SplitSeq(rawTags, ",") {
tag = strings.TrimSpace(tag)
if tag == "" {
continue
}
k, v, ok := strings.Cut(tag, "=")
if !ok || k == "" {
// Skip tags that do not conform to the expected key=value format
continue
}
tags[k] = v
}

config := pyroscope.Config{
ApplicationName: " XDC",
ServerAddress: server,
BasicAuthUser: authUsername,
BasicAuthPassword: authPassword,
Logger: &pyroscopeLogger{Logger: log.Root()},
Tags: tags,
ProfileTypes: []pyroscope.ProfileType{
// Enabling all profile types
pyroscope.ProfileCPU,
pyroscope.ProfileAllocObjects,
pyroscope.ProfileAllocSpace,
pyroscope.ProfileInuseObjects,
pyroscope.ProfileInuseSpace,
pyroscope.ProfileGoroutines,
pyroscope.ProfileMutexCount,
pyroscope.ProfileMutexDuration,
pyroscope.ProfileBlockCount,
pyroscope.ProfileBlockDuration,
},
}

profiler, err := pyroscope.Start(config)
if err != nil {
return err
}
pyroscopeProfiler = profiler
log.Info("Enabled Pyroscope", "server", server)
return nil
}

func stopPyroscope() {
if pyroscopeProfiler != nil {
pyroscopeProfiler.Stop()
pyroscopeProfiler = nil
}
}

// Small wrapper for log.Logger to satisfy pyroscope.Logger interface
type pyroscopeLogger struct {
Logger log.Logger
}

func (l *pyroscopeLogger) Infof(format string, v ...any) {
l.Logger.Info(fmt.Sprintf("Pyroscope: "+format, v...))
}

func (l *pyroscopeLogger) Debugf(format string, v ...any) {
l.Logger.Debug(fmt.Sprintf("Pyroscope: "+format, v...))
}

func (l *pyroscopeLogger) Errorf(format string, v ...any) {
l.Logger.Error(fmt.Sprintf("Pyroscope: "+format, v...))
}