github.com/grafana/pyroscope@v1.18.0/cmd/pyroscope/main.go (about)

     1  package main
     2  
     3  import (
     4  	_ "embed"
     5  	"flag"
     6  	"fmt"
     7  	"os"
     8  	"sort"
     9  
    10  	"github.com/grafana/dskit/flagext"
    11  	"github.com/prometheus/common/version"
    12  
    13  	_ "github.com/grafana/pyroscope-go/godeltaprof/http/pprof"
    14  
    15  	"github.com/grafana/pyroscope/pkg/cfg"
    16  	"github.com/grafana/pyroscope/pkg/pyroscope"
    17  	"github.com/grafana/pyroscope/pkg/usage"
    18  	_ "github.com/grafana/pyroscope/pkg/util/build"
    19  )
    20  
    21  type mainFlags struct {
    22  	pyroscope.Config `yaml:",inline"`
    23  
    24  	PrintVersion bool `yaml:"-"`
    25  	PrintModules bool `yaml:"-"`
    26  	PrintHelp    bool `yaml:"-"`
    27  	PrintHelpAll bool `yaml:"-"`
    28  }
    29  
    30  func (mf *mainFlags) Clone() flagext.Registerer {
    31  	return func(mf mainFlags) *mainFlags {
    32  		return &mf
    33  	}(*mf)
    34  }
    35  
    36  func (mf *mainFlags) PhlareConfig() *pyroscope.Config {
    37  	return &mf.Config
    38  }
    39  
    40  func (mf *mainFlags) RegisterFlags(fs *flag.FlagSet) {
    41  	mf.Config.RegisterFlags(fs)
    42  	fs.BoolVar(&mf.PrintVersion, "version", false, "Show the version of pyroscope and exit")
    43  	fs.BoolVar(&mf.PrintModules, "modules", false, "List available modules that can be used as target and exit.")
    44  	fs.BoolVar(&mf.PrintHelp, "h", false, "Print basic help.")
    45  	fs.BoolVar(&mf.PrintHelp, "help", false, "Print basic help.")
    46  	fs.BoolVar(&mf.PrintHelpAll, "help-all", false, "Print help, also including advanced and experimental parameters.")
    47  }
    48  func errorHandler() {
    49  	testMode := cfg.GetTestMode()
    50  	if !testMode {
    51  		os.Exit(1)
    52  	}
    53  
    54  }
    55  func main() {
    56  	var flags mainFlags
    57  
    58  	flags.V2 = os.Getenv("PYROSCOPE_V2") != "" || os.Getenv("PYROSCOPE_V2_EXPERIMENT") != ""
    59  	if err := cfg.DynamicUnmarshal(&flags, os.Args[1:], flag.CommandLine); err != nil {
    60  		fmt.Fprintf(os.Stderr, "failed parsing config: %v\n", err)
    61  		errorHandler()
    62  		return
    63  	}
    64  
    65  	if args := flag.Args(); len(args) > 0 {
    66  		switch args[0] {
    67  		// server mode is the pyroscope's only mode from 1.0
    68  		case "server":
    69  			break
    70  		case "agent", "ebpf":
    71  			fmt.Printf("%s mode is deprecated. Please use Grafana Agent instead.\n", args[0])
    72  			os.Exit(1)
    73  		case "connect", "exec":
    74  			fmt.Printf("%s mode is deprecated. Please use Pyroscope 0.37 or earlier.\n", args[0])
    75  			os.Exit(1)
    76  		default:
    77  			fmt.Printf("unknown mode: %s\n", args[0])
    78  			os.Exit(1)
    79  		}
    80  	}
    81  
    82  	f, err := pyroscope.New(flags.Config)
    83  	if err != nil {
    84  		fmt.Fprintf(os.Stderr, "failed creating pyroscope: %v\n", err)
    85  		errorHandler()
    86  		return
    87  	}
    88  
    89  	if flags.PrintVersion {
    90  		fmt.Println(version.Print("pyroscope"))
    91  		return
    92  	}
    93  
    94  	if flags.PrintModules {
    95  		allDeps := f.ModuleManager.DependenciesForModule(pyroscope.All)
    96  
    97  		for _, m := range f.ModuleManager.UserVisibleModuleNames() {
    98  			ix := sort.SearchStrings(allDeps, m)
    99  			included := ix < len(allDeps) && allDeps[ix] == m
   100  
   101  			if included {
   102  				fmt.Fprintln(os.Stdout, m, "*")
   103  			} else {
   104  				fmt.Fprintln(os.Stdout, m)
   105  			}
   106  		}
   107  
   108  		fmt.Fprintln(os.Stdout)
   109  		fmt.Fprintln(os.Stdout, "Modules marked with * are included in target All.")
   110  		return
   111  	}
   112  
   113  	if flags.PrintHelp || flags.PrintHelpAll {
   114  		// Print available parameters to stdout, so that users can grep/less them easily.
   115  		flag.CommandLine.SetOutput(os.Stdout)
   116  		if err := usage.Usage(flags.PrintHelpAll, &flags); err != nil {
   117  			fmt.Fprintf(os.Stderr, "error printing usage: %s\n", err)
   118  			errorHandler()
   119  			return
   120  		}
   121  
   122  		return
   123  	}
   124  
   125  	err = f.Run()
   126  	if err != nil {
   127  		fmt.Fprintf(os.Stderr, "failed running pyroscope: %v\n", err)
   128  		errorHandler()
   129  		return
   130  	}
   131  }