78 lines
1.6 KiB
Go
78 lines
1.6 KiB
Go
package profiling
|
|
|
|
import (
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"runtime/pprof"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"code.icb4dc0.de/buildr/buildr/internal/config"
|
|
)
|
|
|
|
type Config struct {
|
|
OutFile string
|
|
ProfileName string
|
|
CPUProfile bool
|
|
}
|
|
|
|
func (c *Config) IsConfigured() bool {
|
|
return (c.ProfileName != "" || c.CPUProfile) && c.OutFile != ""
|
|
}
|
|
|
|
func (c *Config) Setup() (*Recorder, error) {
|
|
if !c.IsConfigured() {
|
|
//nolint:nilnil // correct from a domain perspective
|
|
return nil, nil
|
|
}
|
|
|
|
f, err := os.Create(c.OutFile)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if c.CPUProfile {
|
|
if err := pprof.StartCPUProfile(f); err != nil {
|
|
return nil, errors.Join(err, f.Close())
|
|
}
|
|
|
|
return &Recorder{outFile: f, cpuProfile: true}, nil
|
|
}
|
|
|
|
return &Recorder{outFile: f, profile: pprof.Lookup(c.ProfileName)}, nil
|
|
}
|
|
|
|
func (c *Config) AddFlags(fs *flag.FlagSet) {
|
|
fs.StringVar(
|
|
&c.OutFile,
|
|
"pprof.out-file",
|
|
config.StringEnvOr("BUILDR_PPROF_OUT_FILE", ""),
|
|
"Output file for PPROF profiling data.",
|
|
)
|
|
|
|
fs.BoolVar(
|
|
&c.CPUProfile,
|
|
"pprof.cpu-profile",
|
|
config.EnvOr("BUILDR_PPROF_CPU_PROFILE", strconv.ParseBool, false),
|
|
"Enable CPU profiling. If enabled, any profile name will be ignored and a CPU profile will be generated at the specified path.",
|
|
)
|
|
|
|
fs.StringVar(
|
|
&c.ProfileName,
|
|
"pprof.profile-name",
|
|
config.StringEnvOr("BUILDR_PPROF_PROFILE_NAME", ""),
|
|
fmt.Sprintf("Name of the PPROF profile to use [%s]", strings.Join(profileNames(), ", ")),
|
|
)
|
|
}
|
|
|
|
func profileNames() []string {
|
|
names := make([]string, 0)
|
|
for _, profile := range pprof.Profiles() {
|
|
names = append(names, profile.Name())
|
|
}
|
|
|
|
return names
|
|
}
|