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  }