github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/exec/cli.go (about) 1 package exec 2 3 import ( 4 "fmt" 5 "os" 6 "path" 7 "strings" 8 9 "github.com/fatih/color" 10 "github.com/sirupsen/logrus" 11 12 "github.com/pyroscope-io/pyroscope/pkg/agent/spy" 13 "github.com/pyroscope-io/pyroscope/pkg/agent/types" 14 "github.com/pyroscope-io/pyroscope/pkg/util/names" 15 ) 16 17 // used in tests 18 var ( 19 disableMacOSChecks bool 20 disableLinuxChecks bool 21 ) 22 23 type UnsupportedSpyError struct { 24 Args []string 25 Subcommand string 26 } 27 28 func (e UnsupportedSpyError) Error() string { 29 supportedSpies := spy.SupportedExecSpies() 30 suggestedCommand := fmt.Sprintf("pyroscope %s -spy-name %s %s", e.Subcommand, supportedSpies[0], strings.Join(e.Args, " ")) 31 return fmt.Sprintf( 32 "could not automatically find a spy for program \"%s\". Pass spy name via %s argument, for example: \n"+ 33 " %s\n\nAvailable spies are: %s\nIf you believe this is a mistake, please submit an issue at %s", 34 path.Base(e.Args[0]), 35 color.YellowString("-spy-name"), 36 color.YellowString(suggestedCommand), 37 strings.Join(supportedSpies, ","), 38 color.GreenString("https://github.com/pyroscope-io/pyroscope/issues"), 39 ) 40 } 41 42 func NewLogger(logLevel string, noLogging bool) *logrus.Logger { 43 level := logrus.PanicLevel 44 if l, err := logrus.ParseLevel(logLevel); err == nil && !noLogging { 45 level = l 46 } 47 logger := logrus.StandardLogger() 48 logger.SetLevel(level) 49 if level != logrus.PanicLevel { 50 logger.Info("to disable logging from pyroscope, specify " + color.YellowString("-no-logging") + " flag") 51 } 52 return logger 53 } 54 55 func CheckApplicationName(logger *logrus.Logger, applicationName string, spyName string, args []string) string { 56 if applicationName == "" { 57 logger.Infof("we recommend specifying application name via %s flag or env variable %s", 58 color.YellowString("-application-name"), color.YellowString("PYROSCOPE_APPLICATION_NAME")) 59 applicationName = spyName + "." + names.GetRandomName(generateSeed(args)) 60 logger.Infof("for now we chose the name for you and it's \"%s\"", color.GreenString(applicationName)) 61 } 62 return applicationName 63 } 64 65 func PerformChecks(spyName string) error { 66 if spyName == types.GoSpy { 67 return fmt.Errorf("gospy can not profile other processes. See our documentation on using gospy: %s", color.GreenString("https://pyroscope.io/docs/")) 68 } 69 70 err := performOSChecks(spyName) 71 if err != nil { 72 return err 73 } 74 75 if !stringsContains(spy.SupportedSpies, spyName) { 76 supportedSpies := spy.SupportedExecSpies() 77 return fmt.Errorf( 78 "spy \"%s\" is not supported. Available spies are: %s", 79 color.GreenString(spyName), 80 strings.Join(supportedSpies, ","), 81 ) 82 } 83 84 return nil 85 } 86 87 func stringsContains(arr []string, element string) bool { 88 for _, v := range arr { 89 if v == element { 90 return true 91 } 92 } 93 return false 94 } 95 96 func generateSeed(args []string) string { 97 cwd, err := os.Getwd() 98 if err != nil { 99 cwd = "<unknown>" 100 } 101 return cwd + "|" + strings.Join(args, "&") 102 }