@@ -13,6 +13,7 @@ import (
1313 "path/filepath"
1414 "slices"
1515 "strconv"
16+ "strings"
1617 "sync"
1718 "syscall"
1819 "time"
@@ -28,10 +29,11 @@ import (
2829)
2930
3031const (
31- binaryName = "conmonrs"
32- socketName = "conmon.sock"
33- pidFileName = "pidfile"
34- defaultTimeout = 10 * time .Second
32+ binaryName = "conmonrs"
33+ socketName = "conmon.sock"
34+ pidFileName = "pidfile"
35+ defaultTimeout = 10 * time .Second
36+ heaptrackBinaryName = "heaptrack"
3537)
3638
3739var (
@@ -97,6 +99,9 @@ type ConmonServerConfig struct {
9799
98100 // Tracing can be used to enable OpenTelemetry tracing.
99101 Tracing * Tracing
102+
103+ // Heaptrack can be used to memory profile the server.
104+ Heaptrack * Heaptrack
100105}
101106
102107// Tracing is the structure for managing server-side OpenTelemetry tracing.
@@ -112,6 +117,20 @@ type Tracing struct {
112117 Tracer trace.Tracer
113118}
114119
120+ // Heaptrack is the structure for configuring the memory profiling.
121+ type Heaptrack struct {
122+ // Enabled tells the server to run with heaptrack enabled.
123+ Enabled bool
124+
125+ // BinaryPath is the path to the heaptrack binary. Can be empty to lookup
126+ // the local $PATH variable.
127+ BinaryPath string
128+
129+ // OutputPath is the storage path for the memory profile. Can be empty to
130+ // use the current directory for storing the profile.
131+ OutputPath string
132+ }
133+
115134// NewConmonServerConfig creates a new ConmonServerConfig instance for the
116135// required arguments. Optional arguments are pointing to their corresponding
117136// default values.
@@ -191,6 +210,10 @@ func New(config *ConmonServerConfig) (client *ConmonClient, retErr error) {
191210
192211 cl .serverPID = pid
193212
213+ if config .Heaptrack != nil && config .Heaptrack .Enabled {
214+ go cl .attachHeaptrack (config , pid )
215+ }
216+
194217 // Cleanup the background server process
195218 // if we fail any of the next steps
196219 defer func () {
@@ -1642,3 +1665,34 @@ func (c *ConmonClient) ServePortForwardContainer(
16421665
16431666 return & ServePortForwardContainerResult {URL : url }, nil
16441667}
1668+
1669+ func (c * ConmonClient ) attachHeaptrack (config * ConmonServerConfig , pid uint32 ) {
1670+ c .logger .Infof ("Attaching heaptrack to PID %d" , pid )
1671+
1672+ args := []string {"--record-only" }
1673+
1674+ if config .Heaptrack .OutputPath != "" {
1675+ args = append (args , "-o" , config .Heaptrack .OutputPath )
1676+ }
1677+
1678+ args = append (args , "-p" , strconv .FormatUint (uint64 (pid ), 10 ))
1679+
1680+ entrypoint := config .Heaptrack .BinaryPath
1681+ if entrypoint == "" {
1682+ path , err := exec .LookPath (heaptrackBinaryName )
1683+ if err != nil {
1684+ c .logger .Errorf ("Unable to find heaptrack path: %v" , err )
1685+
1686+ return
1687+ }
1688+
1689+ entrypoint = path
1690+ }
1691+
1692+ c .logger .Debugf ("Running heaptrack via: %s %s" , entrypoint , strings .Join (args , " " ))
1693+
1694+ cmd := exec .Command (entrypoint , args ... )
1695+ if err := cmd .Run (); err != nil {
1696+ c .logger .Errorf ("Unable to run heaptrack: %v" , err )
1697+ }
1698+ }
0 commit comments