github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/config/config.go (about)

     1  package config
     2  
     3  //revive:disable:line-length-limit Most of line length is documentation
     4  //revive:disable:max-public-structs Config structs
     5  
     6  // TODO(abeaumont): spy and remote configurations could be grouped,
     7  // but using squash seems to keep the prefix in the CLI.
     8  
     9  import (
    10  	"fmt"
    11  	"net/http"
    12  	"time"
    13  
    14  	scrape "github.com/pyroscope-io/pyroscope/pkg/scrape/config"
    15  	"github.com/pyroscope-io/pyroscope/pkg/util/bytesize"
    16  )
    17  
    18  type Config struct {
    19  	Version bool `mapstructure:"version"`
    20  
    21  	Agent     Agent     `skip:"true" mapstructure:",squash"`
    22  	Server    Server    `skip:"true" mapstructure:",squash"`
    23  	Convert   Convert   `skip:"true" mapstructure:",squash"`
    24  	Exec      Exec      `skip:"true" mapstructure:",squash"`
    25  	Connect   Connect   `skip:"true" mapstructure:",squash"`
    26  	EBPF      EBPF      `skip:"true" mapstructure:",squash"`
    27  	DbManager DbManager `skip:"true" mapstructure:",squash"`
    28  	Admin     Admin     `skip:"true" mapstructure:",squash"`
    29  	Adhoc     Adhoc     `skip:"true" mapstructure:",squash"`
    30  	CI        CI        `skip:"true" mapstructure:",squash"`
    31  }
    32  
    33  type Adhoc struct {
    34  	AnalyticsOptOut bool `def:"false" desc:"disables analytics" mapstructure:"analytics-opt-out"`
    35  
    36  	LogLevel  string `def:"info" desc:"log level: debug|info|warn|error" mapstructure:"log-level"`
    37  	NoLogging bool   `def:"false" desc:"disables logging from pyroscope" mapstructure:"no-logging"`
    38  
    39  	MaxNodesSerialization int           `def:"2048" desc:"max number of nodes used when saving profiles to disk" mapstructure:"max-nodes-serialization"`
    40  	Duration              time.Duration `def:"0" desc:"duration of the profiling session, which is the whole execution of the profield process by default" mapstructure:"duration"`
    41  
    42  	// Output configuration
    43  	MaxNodesRender int    `def:"8192" desc:"max number of nodes used to display data on the frontend" mapstructure:"max-nodes-render"`
    44  	OutputFormat   string `def:"html" desc:"format to export profiling data, supported formats are: html, pprof, collapsed, none" mapstructure:"output-format"`
    45  	NoJSONOutput   bool   `def:"false" desc:"disables generating native JSON file(s) in pyroscope data directory" mapstructure:"no-joson-output"`
    46  	DataPath       string `def:"<defaultAdhocDataPath>" desc:"directory where pyroscope stores adhoc profiles" mapstructure:"data-path"`
    47  
    48  	// Spy configuration
    49  	ApplicationName    string `def:"" desc:"application name used when uploading profiling data" mapstructure:"application-name"`
    50  	SampleRate         uint   `def:"100" desc:"sample rate for the profiler in Hz. 100 means reading 100 times per second" mapstructure:"sample-rate"`
    51  	SpyName            string `def:"auto" desc:"name of the profiler you want to use. Supported ones are: <supportedProfilers>" mapstructure:"spy-name"`
    52  	DetectSubprocesses bool   `def:"true" desc:"makes pyroscope keep track of and profile subprocesses of the main process" mapstructure:"detect-subprocesses"`
    53  	PHPSpyArgs         string `def:"" desc:"comma separated list of phpspy's argument. direct_mem=true/false,php_awk_pattern=libphp'" mapstructure:"php-spy-args"`
    54  
    55  	// Connect mode configuration
    56  	Pid int `def:"0" desc:"PID of the process you want to profile. Pass -1 to profile the whole system (only supported by ebpfspy)" mapstructure:"pid"`
    57  
    58  	// Push mode configuration
    59  	Push bool `def:"false" desc:"Use push mode, exposing an ingestion endpoint for the profiled program to use" mapstructure:"push"`
    60  
    61  	// Pull mode configuration
    62  	URL string `def:"" desc:"URL to gather profiling data from" mapstructure:"url"`
    63  
    64  	StripTimestamp bool `def:"false" desc:"whether to strip the timestamp in the filename" mapstructure:"strip-timestamp"`
    65  }
    66  
    67  type Agent struct {
    68  	Config string `def:"<defaultAgentConfigPath>" desc:"location of config file" mapstructure:"config"`
    69  
    70  	LogFilePath string `def:"<defaultAgentLogFilePath>" desc:"log file path" mapstructure:"log-file-path"`
    71  	LogLevel    string `def:"info" desc:"log level: debug|info|warn|error" mapstructure:"log-level"`
    72  	NoLogging   bool   `def:"false" desc:"disables logging from pyroscope" mapstructure:"no-logging"`
    73  
    74  	ServerAddress          string            `def:"http://localhost:4040" desc:"address of the pyroscope server" mapstructure:"server-address"`
    75  	AuthToken              string            `json:"-" def:"" desc:"authorization token used to upload profiling data" mapstructure:"auth-token"`
    76  	BasicAuthUser          string            `json:"-" def:"" desc:"HTTP Basic authentication username" mapstructure:"basic-auth-user"`
    77  	BasicAuthPassword      string            `json:"-" def:"" desc:"HTTP Basic authentication password" mapstructure:"basic-auth-password"`
    78  	TenantID               string            `def:"" desc:"Phlare tenant ID passed as X-Scope-OrgID http header" mapstructure:"tenant-id"`
    79  	Headers                map[string]string `name:"header" desc:"extra http header. The flag may be specified multiple times" mapstructure:"headers"`
    80  	UpstreamThreads        int               `def:"4" desc:"number of upload threads" mapstructure:"upstream-threads"`
    81  	UpstreamRequestTimeout time.Duration     `def:"10s" desc:"profile upload timeout" mapstructure:"upstream-request-timeout"`
    82  
    83  	Targets []Target `yaml:"targets" desc:"list of targets to be profiled" mapstructure:"-"`
    84  
    85  	// Note that in YAML the key is 'tags' but the flag is 'tag'.
    86  	Tags map[string]string `yaml:"tags" name:"tag" def:"" desc:"tag key value pairs" mapstructure:"-"`
    87  }
    88  
    89  type Target struct {
    90  	ServiceName string `yaml:"service-name" mapstructure:"service-name" desc:"name of the system service to be profiled"`
    91  
    92  	SpyName            string `yaml:"spy-name" mapstructure:"spy-name" def:"" desc:"name of the profiler you want to use. Supported ones are: <supportedProfilers>"`
    93  	ApplicationName    string `yaml:"application-name" mapstructure:"application-name" def:"" desc:"application name used when uploading profiling data"`
    94  	SampleRate         uint   `yaml:"sample-rate" mapstructure:"sample-rate" def:"100" desc:"sample rate for the profiler in Hz. 100 means reading 100 times per second"`
    95  	DetectSubprocesses bool   `yaml:"detect-subprocesses" mapstructure:"detect-subprocesses" def:"true" desc:"makes pyroscope keep track of and profile subprocesses of the main process"`
    96  
    97  	// Tags are inherited from the agent level. At some point we may need
    98  	// specifying tags at the target level (override).
    99  	Tags map[string]string `yaml:"-"`
   100  }
   101  
   102  type Server struct {
   103  	AnalyticsOptOut bool `def:"false" desc:"disables analytics" mapstructure:"analytics-opt-out"`
   104  
   105  	Config         string `def:"<installPrefix>/etc/pyroscope/server.yml" desc:"location of config file" mapstructure:"config"`
   106  	LogLevel       string `def:"info" desc:"log level: debug|info|warn|error" mapstructure:"log-level"`
   107  	BadgerLogLevel string `def:"error" desc:"log level: debug|info|warn|error" mapstructure:"badger-log-level"`
   108  
   109  	StoragePath            string  `def:"<installPrefix>/var/lib/pyroscope" desc:"directory where pyroscope stores profiling data" mapstructure:"storage-path"`
   110  	StorageQueueSize       int     `desc:"storage queue size" mapstructure:"storage-queue-size"`
   111  	StorageQueueWorkers    int     `desc:"number of workers handling internal storage queue" mapstructure:"storage-queue-workers"`
   112  	MinFreeSpacePercentage float64 `def:"5" desc:"percentage of available disk space at which ingestion requests are discarded. Defaults to 5% but not less than 1GB. Set 0 to disable" mapstructure:"min-free-space-percentage"`
   113  
   114  	ExemplarsBatchQueueSize int           `deprecated:"true" mapstructure:"exemplars-batch-queue-size"`
   115  	ExemplarsBatchDuration  time.Duration `deprecated:"true" mapstructure:"exemplars-batch-duration"`
   116  	ExemplarsBatchSize      int           `deprecated:"true" mapstructure:"exemplars-batch-size"`
   117  
   118  	APIBindAddr     string `def:":4040" desc:"port for the HTTP(S) server used for data ingestion and web UI" mapstructure:"api-bind-addr"`
   119  	BaseURL         string `def:"" desc:"base URL for when the server is behind a reverse proxy with a different path" mapstructure:"base-url"`
   120  	BaseURLBindAddr string `def:"" deprecated:"true" desc:"server for debugging base url" mapstructure:"base-url-bind-addr"`
   121  
   122  	CacheEvictThreshold float64 `def:"0.25" desc:"percentage of memory at which cache evictions start" mapstructure:"cache-evict-threshold"`
   123  	CacheEvictVolume    float64 `def:"0.33" desc:"percentage of cache that is evicted per eviction run" mapstructure:"cache-evict-volume"`
   124  
   125  	Database Database `mapstructure:"database"`
   126  
   127  	// TODO: I don't think a lot of people will change these values.
   128  	//   I think these should just be constants.
   129  	BadgerNoTruncate     bool `def:"false" desc:"indicates whether value log files should be truncated to delete corrupt data, if any" mapstructure:"badger-no-truncate"`
   130  	DisablePprofEndpoint bool `def:"false" desc:"disables /debug/pprof route" mapstructure:"disable-pprof-endpoint"`
   131  
   132  	MaxNodesSerialization int `def:"2048" desc:"max number of nodes used when saving profiles to disk" mapstructure:"max-nodes-serialization"`
   133  	MaxNodesRender        int `def:"8192" desc:"max number of nodes used to display data on the frontend" mapstructure:"max-nodes-render"`
   134  
   135  	// currently only used in our demo app
   136  	HideApplications []string `def:"" desc:"please don't use, this will soon be deprecated" mapstructure:"hide-applications"`
   137  
   138  	Retention          time.Duration   `def:"" desc:"sets the maximum amount of time the profiling data is stored for. Data before this threshold is deleted. Disabled by default" mapstructure:"retention"`
   139  	ExemplarsRetention time.Duration   `def:"" desc:"sets the maximum amount of time profile exemplars are stored for. Data before this threshold is deleted. Disabled by default" mapstructure:"exemplars-retention"`
   140  	RetentionLevels    RetentionLevels `def:"" desc:"specifies how long the profiling data stored per aggregation level. Disabled by default" mapstructure:"retention-levels"`
   141  
   142  	// Deprecated fields. They can be set (for backwards compatibility) but have no effect
   143  	// TODO: we should print some warning messages when people try to use these
   144  	SampleRate          uint              `deprecated:"true" mapstructure:"sample-rate"`
   145  	OutOfSpaceThreshold bytesize.ByteSize `deprecated:"true" mapstructure:"out-of-space-threshold"`
   146  	CacheDimensionSize  int               `deprecated:"true" mapstructure:"cache-dimensions-size"`
   147  	CacheDictionarySize int               `deprecated:"true" mapstructure:"cache-dictonary-size"`
   148  	CacheSegmentSize    int               `deprecated:"true" mapstructure:"cache-segment-size"`
   149  	CacheTreeSize       int               `deprecated:"true" mapstructure:"cache-tree-size"`
   150  
   151  	CORS CORSConfig `mapstructure:"cors"`
   152  
   153  	Auth Auth `mapstructure:"auth"`
   154  
   155  	MetricsExportRules MetricsExportRules `yaml:"metrics-export-rules" def:"" desc:"metrics export rules" mapstructure:"metrics-export-rules"`
   156  
   157  	TLSCertificateFile string `def:"" desc:"location of TLS Certificate file (.crt)" mapstructure:"tls-certificate-file"`
   158  	TLSKeyFile         string `def:"" desc:"location of TLS Private key file (.key)" mapstructure:"tls-key-file"`
   159  
   160  	AdminSocketPath         string `def:"/tmp/pyroscope.sock" desc:"path where the admin server socket will be created." mapstructure:"admin-socket-path"`
   161  	EnableExperimentalAdmin bool   `def:"true" deprecated:"true" desc:"whether to enable the experimental admin interface" mapstructure:"enable-experimental-admin"`
   162  
   163  	NoAdhocUI        bool   `def:"false" desc:"disable the adhoc ui interface" mapstructure:"no-adhoc-ui"`
   164  	AdhocDataPath    string `def:"<defaultAdhocDataPath>" desc:"directory where pyroscope stores adhoc profiles" mapstructure:"adhoc-data-path"`
   165  	AdhocMaxFileSize int    `def:"52428800" desc:"maximum size of adhoc profile file. To remove any size limitations, set the value to -1" mapstructure:"adhoc-max-file-size"`
   166  
   167  	ScrapeConfigs []*scrape.Config `yaml:"scrape-configs" mapstructure:"-"`
   168  
   169  	NoSelfProfiling   bool              `def:"false" desc:"disable profiling of pyroscope itself" mapstructure:"no-self-profiling"`
   170  	SelfProfilingTags map[string]string `name:"self-profiling-tag" def:"" desc:"tag in key=value form. The flag may be specified multiple times" mapstructure:"self-profiling-tags" yaml:"self-profiling-tags"`
   171  
   172  	RemoteWrite RemoteWrite `yaml:"remote-write" mapstructure:"remote-write"`
   173  	RemoteRead  RemoteRead  `yaml:"remote-read" mapstructure:"remote-read"`
   174  
   175  	DisableExportToFlamegraphDotCom bool `def:"false" desc:"disable exporting to flamegraph.com in the UI" mapstructure:"disable-export-to-flamegraph-dot-com"`
   176  
   177  	EnableExperimentalExemplarsPage bool `def:"false" desc:"whether to enable the experimental exemplars page" mapstructure:"enable-experimental-exemplars-page"`
   178  }
   179  
   180  type MetricsExportRules map[string]MetricsExportRule
   181  
   182  type MetricsExportRule struct {
   183  	Expr    string   `def:"" desc:"expression in FlameQL syntax to be evaluated against samples" mapstructure:"expr"`
   184  	Node    string   `def:"total" desc:"tree node filter expression. Should be either 'total' or a valid regexp" mapstructure:"node"`
   185  	GroupBy []string `def:"" desc:"list of tags to be used for aggregation. The tags are exported as prometheus labels" mapstructure:"group_by"`
   186  }
   187  
   188  type RetentionLevels struct {
   189  	Zero time.Duration `name:"0" deprecated:"true" mapstructure:"0"`
   190  	One  time.Duration `name:"1" deprecated:"true" mapstructure:"1"`
   191  	Two  time.Duration `name:"2" deprecated:"true" mapstructure:"2"`
   192  }
   193  
   194  type Auth struct {
   195  	SignupDefaultRole string `json:"-" deprecated:"true" def:"ReadOnly" desc:"specifies which role will be granted to a newly signed up user. Supported roles: Admin, ReadOnly. Defaults to ReadOnly" mapstructure:"signup-default-role"`
   196  
   197  	Internal InternalAuth `mapstructure:"internal"`
   198  	Google   GoogleOauth  `mapstructure:"google"`
   199  	Gitlab   GitlabOauth  `mapstructure:"gitlab"`
   200  	Github   GithubOauth  `mapstructure:"github"`
   201  
   202  	Ingestion IngestionAuth `mapstructure:"ingestion"`
   203  
   204  	CookieSameSite           http.SameSite `json:"-" deprecated:"true" def:"Lax" desc:"specifies SameSite attribute for JWT token cookie" mapstructure:"cookie-same-site"`
   205  	CookieSecure             bool          `json:"-" deprecated:"true" def:"false" desc:"specifies Secure attribute for JWT token cookie" mapstructure:"cookie-secure"`
   206  	JWTSecret                string        `json:"-" deprecated:"true" def:"" desc:"secret used to secure your JWT tokens" mapstructure:"jwt-secret"`
   207  	LoginMaximumLifetimeDays int           `json:"-" deprecated:"true" def:"0" desc:"amount of days after which user will be logged out. 0 means non-expiring." mapstructure:"login-maximum-lifetime-days"`
   208  	APIKeyBcryptCost         int           `json:"-" deprecated:"true" def:"10" mapstructure:"api-key-bcrypt-cost"`
   209  }
   210  
   211  type InternalAuth struct {
   212  	Enabled       bool      `json:"-" deprecated:"true" def:"false" desc:"enables login-password authentication" mapstructure:"enabled"`
   213  	SignupEnabled bool      `json:"-" deprecated:"true" def:"false" desc:"indicates whether users are allowed to create accounts" mapstructure:"signup-enabled"`
   214  	AdminUser     AdminUser `json:"-" deprecated:"true" def:"false" mapstructure:"admin"`
   215  }
   216  
   217  type IngestionAuth struct {
   218  	Enabled   bool          `json:"-" deprecated:"true" def:"false" desc:"require authentication for ingestion endpoint" mapstructure:"enabled"`
   219  	CacheTTL  time.Duration `json:"-" deprecated:"true" def:"1m" mapstructure:"cache-ttl"`
   220  	CacheSize int           `json:"-" deprecated:"true" def:"1024" mapstructure:"cache-size"`
   221  }
   222  
   223  type AdminUser struct {
   224  	Create   bool   `json:"-" deprecated:"true" def:"true" desc:"" mapstructure:"create"`
   225  	Name     string `json:"-" deprecated:"true" def:"admin" desc:"" mapstructure:"name"`
   226  	Email    string `json:"-" deprecated:"true" def:"admin@localhost.local" desc:"" mapstructure:"email"`
   227  	Password string `json:"-" deprecated:"true" def:"admin" desc:"" mapstructure:"password"`
   228  }
   229  
   230  type CORSConfig struct {
   231  	AllowedOrigins   []string `json:"-" deprecated:"true" def:"" desc:"" mapstructure:"allowed-origins"`
   232  	AllowedHeaders   []string `json:"-" deprecated:"true" def:"" desc:"" mapstructure:"allowed-headers"`
   233  	AllowedMethods   []string `json:"-" deprecated:"true" def:"" desc:"" mapstructure:"allowed-methods"`
   234  	AllowCredentials bool     `json:"-" deprecated:"true" def:"" desc:"" mapstructure:"allow-credentials"`
   235  	MaxAge           int      `json:"-" deprecated:"true" def:"" desc:"" mapstructure:"max-age"`
   236  }
   237  
   238  // TODO: Maybe merge Oauth structs into one (would have to move def and desc tags somewhere else in code)
   239  type GoogleOauth struct {
   240  	// TODO: remove deprecated: true when we enable these back
   241  	Enabled        bool     `json:"-" deprecated:"true" def:"false" desc:"enables Google Oauth" mapstructure:"enabled"`
   242  	ClientID       string   `json:"-" deprecated:"true" def:"" desc:"client ID generated for Google API" mapstructure:"client-id"`
   243  	ClientSecret   string   `json:"-" deprecated:"true" def:"" desc:"client secret generated for Google API" mapstructure:"client-secret"`
   244  	RedirectURL    string   `json:"-" deprecated:"true" def:"" desc:"url that google will redirect to after logging in. Has to be in form <pathToPyroscopeServer/auth/google/callback>" mapstructure:"redirect-url"`
   245  	AuthURL        string   `json:"-" deprecated:"true" def:"https://accounts.google.com/o/oauth2/auth" desc:"auth url for Google API (usually present in credentials.json file)" mapstructure:"auth-url"`
   246  	TokenURL       string   `json:"-" deprecated:"true" def:"https://accounts.google.com/o/oauth2/token" desc:"token url for Google API (usually present in credentials.json file)" mapstructure:"token-url"`
   247  	AllowedDomains []string `json:"-" deprecated:"true" def:"" desc:"list of domains that are allowed to login through google" mapstructure:"allowed-domains"`
   248  }
   249  
   250  type GitlabOauth struct {
   251  	Enabled bool `json:"-" deprecated:"true" def:"false" desc:"enables Gitlab Oauth" mapstructure:"enabled"`
   252  	// TODO: I changed this to ClientID to fit others, but in Gitlab docs it's Application ID so it might get someone confused?
   253  	ClientID      string   `json:"-" deprecated:"true" def:"" desc:"client ID generated for GitLab API" mapstructure:"client-id"`
   254  	ClientSecret  string   `json:"-" deprecated:"true" def:"" desc:"client secret generated for GitLab API" mapstructure:"client-secret"`
   255  	RedirectURL   string   `json:"-" deprecated:"true" def:"" desc:"url that gitlab will redirect to after logging in. Has to be in form <pathToPyroscopeServer/auth/gitlab/callback>" mapstructure:"redirect-url"`
   256  	AuthURL       string   `json:"-" deprecated:"true" def:"https://gitlab.com/oauth/authorize" desc:"auth url for GitLab API (keep default for cloud, usually https://gitlab.mycompany.com/oauth/authorize for on-premise)" mapstructure:"auth-url"`
   257  	TokenURL      string   `json:"-" deprecated:"true" def:"https://gitlab.com/oauth/token" desc:"token url for GitLab API (keep default for cloud, usually https://gitlab.mycompany.com/oauth/token for on-premise)" mapstructure:"token-url"`
   258  	APIURL        string   `json:"-" deprecated:"true" def:"https://gitlab.com/api/v4" desc:"URL to gitlab API (keep default for cloud, usually https://gitlab.mycompany.com/api/v4/user for on-premise)" mapstructure:"api-url"`
   259  	AllowedGroups []string `json:"-" deprecated:"true" def:"" desc:"list of groups (unique names of the group as listed in URL) that are allowed to login through gitlab" mapstructure:"allowed-groups"`
   260  }
   261  
   262  type GithubOauth struct {
   263  	Enabled              bool     `json:"-" deprecated:"true" def:"false" desc:"enables Github Oauth" mapstructure:"enabled"`
   264  	ClientID             string   `json:"-" deprecated:"true" def:"" desc:"client ID generated for Github API" mapstructure:"client-id"`
   265  	ClientSecret         string   `json:"-" deprecated:"true" def:"" desc:"client secret generated for Github API" mapstructure:"client-secret"`
   266  	RedirectURL          string   `json:"-" deprecated:"true" def:"" desc:"url that Github will redirect to after logging in. Has to be in form <pathToPyroscopeServer/auth/github/callback>" mapstructure:"redirect-url"`
   267  	AuthURL              string   `json:"-" deprecated:"true" def:"https://github.com/login/oauth/authorize" desc:"auth url for Github API" mapstructure:"auth-url"`
   268  	TokenURL             string   `json:"-" deprecated:"true" def:"https://github.com/login/oauth/access_token" desc:"token url for Github API" mapstructure:"token-url"`
   269  	AllowedOrganizations []string `json:"-" deprecated:"true" def:"" desc:"list of organizations that are allowed to login through github" mapstructure:"allowed-organizations"`
   270  }
   271  
   272  type Convert struct {
   273  	Format string `def:"tree" mapstructure:"format"`
   274  }
   275  
   276  type CombinedDbManager struct {
   277  	*DbManager `mapstructure:",squash"`
   278  	*Server    `mapstructure:",squash"`
   279  }
   280  
   281  type DbManager struct {
   282  	LogLevel        string `def:"error" desc:"log level: debug|info|warn|error" mapstructure:"log-level"`
   283  	StoragePath     string `def:"<installPrefix>/var/lib/pyroscope" desc:"directory where pyroscope stores profiling data" mapstructure:"storage-path"`
   284  	DstStartTime    time.Time
   285  	DstEndTime      time.Time
   286  	SrcStartTime    time.Time
   287  	ApplicationName string
   288  
   289  	EnableProfiling bool `def:"false" desc:"enables profiling of dbmanager" mapstructure:"enable-profiling"`
   290  }
   291  
   292  type Exec struct {
   293  	LogLevel  string `def:"info" desc:"log level: debug|info|warn|error" mapstructure:"log-level"`
   294  	NoLogging bool   `def:"false" desc:"disables logging from pyroscope" mapstructure:"no-logging"`
   295  
   296  	// Spy configuration
   297  	ApplicationName    string `def:"" desc:"application name used when uploading profiling data" mapstructure:"application-name"`
   298  	SampleRate         uint   `def:"100" desc:"sample rate for the profiler in Hz. 100 means reading 100 times per second" mapstructure:"sample-rate"`
   299  	SpyName            string `def:"auto" desc:"name of the profiler you want to use. Supported ones are: <supportedProfilers>" mapstructure:"spy-name"`
   300  	DetectSubprocesses bool   `def:"true" desc:"makes pyroscope keep track of and profile subprocesses of the main process" mapstructure:"detect-subprocesses"`
   301  	PHPSpyArgs         string `def:"" desc:"comma separated list of phpspy's argument. direct_mem=true/false,php_awk_pattern=libphp'" mapstructure:"php-spy-args"`
   302  
   303  	// Remote upstream configuration
   304  	ServerAddress          string            `def:"http://localhost:4040" desc:"address of the pyroscope server" mapstructure:"server-address"`
   305  	AuthToken              string            `json:"-" def:"" desc:"authorization token used to upload profiling data" mapstructure:"auth-token"`
   306  	BasicAuthUser          string            `json:"-" def:"" desc:"HTTP Basic authentication username" mapstructure:"basic-auth-user"`
   307  	BasicAuthPassword      string            `json:"-" def:"" desc:"HTTP Basic authentication password" mapstructure:"basic-auth-password"`
   308  	TenantID               string            `def:"" desc:"Phlare tenant ID passed as X-Scope-OrgID http header" mapstructure:"tenant-id"`
   309  	Headers                map[string]string `name:"header" desc:"extra http header. The flag may be specified multiple times" mapstructure:"headers"`
   310  	UpstreamThreads        int               `def:"4" desc:"number of upload threads" mapstructure:"upstream-threads"`
   311  	UpstreamRequestTimeout time.Duration     `def:"10s" desc:"profile upload timeout" mapstructure:"upstream-request-timeout"`
   312  
   313  	Tags map[string]string `name:"tag" def:"" desc:"tag in key=value form. The flag may be specified multiple times" mapstructure:"tags"`
   314  
   315  	NoRootDrop bool   `def:"false" desc:"disables permissions drop when ran under root. use this one if you want to run your command as root" mapstructure:"no-root-drop"`
   316  	UserName   string `def:"" desc:"starts process under specified user name" mapstructure:"user-name"`
   317  	GroupName  string `def:"" desc:"starts process under specified group name" mapstructure:"group-name"`
   318  }
   319  
   320  type Connect struct {
   321  	LogLevel  string `def:"info" desc:"log level: debug|info|warn|error" mapstructure:"log-level"`
   322  	NoLogging bool   `def:"false" desc:"disables logging from pyroscope" mapstructure:"no-logging"`
   323  
   324  	// Spy configuration
   325  	ApplicationName    string `def:"" desc:"application name used when uploading profiling data" mapstructure:"application-name"`
   326  	SampleRate         uint   `def:"100" desc:"sample rate for the profiler in Hz. 100 means reading 100 times per second" mapstructure:"sample-rate"`
   327  	SpyName            string `def:"" desc:"name of the profiler you want to use. Supported ones are: <supportedProfilers>" mapstructure:"spy-name"`
   328  	DetectSubprocesses bool   `def:"true" desc:"makes pyroscope keep track of and profile subprocesses of the main process" mapstructure:"detect-subprocesses"`
   329  	PHPSpyArgs         string `def:"" desc:"comma separated list of phpspy's argument. direct_mem=true/false,php_awk_pattern=libphp'" mapstructure:"php-spy-args"`
   330  
   331  	// Remote upstream configuration
   332  	ServerAddress          string            `def:"http://localhost:4040" desc:"address of the pyroscope server" mapstructure:"server-address"`
   333  	AuthToken              string            `json:"-" def:"" desc:"authorization token used to upload profiling data" mapstructure:"auth-token"`
   334  	BasicAuthUser          string            `json:"-" def:"" desc:"HTTP Basic authentication username" mapstructure:"basic-auth-user"`
   335  	BasicAuthPassword      string            `json:"-" def:"" desc:"HTTP Basic authentication password" mapstructure:"basic-auth-password"`
   336  	TenantID               string            `def:"" desc:"Phlare tenant ID passed as X-Scope-OrgID http header" mapstructure:"tenant-id"`
   337  	Headers                map[string]string `name:"header" desc:"extra http header. The flag may be specified multiple times" mapstructure:"headers"`
   338  	UpstreamThreads        int               `def:"4" desc:"number of upload threads" mapstructure:"upstream-threads"`
   339  	UpstreamRequestTimeout time.Duration     `def:"10s" desc:"profile upload timeout" mapstructure:"upstream-request-timeout"`
   340  
   341  	Tags map[string]string `name:"tag" def:"" desc:"tag in key=value form. The flag may be specified multiple times" mapstructure:"tags"`
   342  
   343  	Pid int `def:"0" desc:"PID of the process you want to profile. Pass -1 to profile the whole system (only supported by ebpfspy)" mapstructure:"pid"`
   344  }
   345  
   346  type EBPF struct {
   347  	LogLevel  string `def:"info" desc:"log level: debug|info|warn|error" mapstructure:"log-level"`
   348  	NoLogging bool   `def:"false" desc:"disables logging from pyroscope" mapstructure:"no-logging"`
   349  
   350  	// Spy configuration
   351  	ApplicationName string `def:"" desc:"application name used when uploading profiling data" mapstructure:"application-name"`
   352  	SampleRate      uint   `def:"100" desc:"sample rate for the profiler in Hz. 100 means reading 100 times per second" mapstructure:"sample-rate"`
   353  
   354  	// Remote upstream configuration
   355  	ServerAddress          string            `def:"http://localhost:4040" desc:"address of the pyroscope server" mapstructure:"server-address"`
   356  	AuthToken              string            `json:"-" def:"" desc:"authorization token used to upload profiling data" mapstructure:"auth-token"`
   357  	BasicAuthUser          string            `json:"-" def:"" desc:"HTTP Basic authentication username" mapstructure:"basic-auth-user"`
   358  	BasicAuthPassword      string            `json:"-" def:"" desc:"HTTP Basic authentication password" mapstructure:"basic-auth-password"`
   359  	TenantID               string            `def:"" desc:"Phlare tenant ID passed as X-Scope-OrgID http header" mapstructure:"tenant-id"`
   360  	Headers                map[string]string `name:"header" desc:"extra http header. The flag may be specified multiple times" mapstructure:"headers"`
   361  	UpstreamThreads        int               `def:"4" desc:"number of upload threads" mapstructure:"upstream-threads"`
   362  	UpstreamRequestTimeout time.Duration     `def:"10s" desc:"profile upload timeout" mapstructure:"upstream-request-timeout"`
   363  
   364  	Tags map[string]string `name:"tag" def:"" desc:"tag in key=value form. The flag may be specified multiple times" mapstructure:"tags"`
   365  
   366  	Pid                int    `def:"-1" desc:"PID of the process you want to profile. Pass -1 to profile the whole system" mapstructure:"pid"`
   367  	DetectSubprocesses bool   `def:"false" desc:"makes pyroscope keep track of and profile subprocesses of the main process" mapstructure:"detect-subprocesses"`
   368  	SymbolCacheSize    int    `def:"256" desc:"max size of symbols cache (1 entry per process)" mapstructure:"symbol-cache-size"`
   369  	KubernetesNode     string `def:"" desc:"Set to current k8s Node.nodeName for service discovery and labeling" mapstructure:"kubernetes-node"`
   370  	OnlyServices       bool   `def:"false" desc:"Ignore processes unknown to service discovery" mapstructure:"only-services"`
   371  }
   372  
   373  // TODO how to abstract this better?
   374  type Admin struct {
   375  	AdminAppDelete         AdminAppDelete         `skip:"true" mapstructure:",squash"`
   376  	AdminAppGet            AdminAppGet            `skip:"true" mapstructure:",squash"`
   377  	AdminUserPasswordReset AdminUserPasswordReset `skip:"true" mapstructure:",squash"`
   378  	AdminStorageCleanup    AdminStorageCleanup    `skip:"true" mapstructure:",squash"`
   379  }
   380  
   381  type AdminAppGet struct {
   382  	SocketPath string        `def:"/tmp/pyroscope.sock" desc:"path where the admin server socket was created." mapstructure:"socket-path"`
   383  	Timeout    time.Duration `def:"30m" desc:"timeout for the server to respond" mapstructure:"timeout"`
   384  }
   385  
   386  type AdminAppDelete struct {
   387  	SocketPath string        `def:"/tmp/pyroscope.sock" desc:"path where the admin server socket was created." mapstructure:"socket-path"`
   388  	Force      bool          `def:"false" desc:"don't prompt for confirmation of dangerous actions" mapstructure:"force"`
   389  	Timeout    time.Duration `def:"30m" desc:"timeout for the server to respond" mapstructure:"timeout"`
   390  }
   391  
   392  type AdminUserPasswordReset struct {
   393  	SocketPath string        `def:"/tmp/pyroscope.sock" desc:"path where the admin server socket was created." mapstructure:"socket-path"`
   394  	Timeout    time.Duration `def:"30m" desc:"timeout for the server to respond" mapstructure:"timeout"`
   395  
   396  	Username string `desc:"user name (login)" mapstructure:"username"`
   397  	Password string `desc:"new password" mapstructure:"password"`
   398  	Enable   bool   `desc:"enable user" mapstructure:"enable"`
   399  }
   400  
   401  type AdminStorageCleanup struct {
   402  	SocketPath string        `def:"/tmp/pyroscope.sock" desc:"path where the admin server socket was created." mapstructure:"socket-path"`
   403  	Timeout    time.Duration `def:"30m" desc:"timeout for the server to respond" mapstructure:"timeout"`
   404  }
   405  
   406  type Database struct {
   407  	Type string `def:"sqlite3" desc:"" mapstructure:"type"`
   408  	URL  string `def:"" desc:"" mapstructure:"url"`
   409  }
   410  
   411  type RemoteWrite struct {
   412  	Enabled            bool `def:"false" desc:"EXPERIMENTAL! the API will change, use at your own risk. whether to enable remote write or not"`
   413  	DisableLocalWrites bool `def:"false" desc:"EXPERIMENTAL! the API will change, use at your own risk. whether to enable remote write or not" mapstructure:"disable-local-writes"`
   414  
   415  	// see loadRemoteWriteTargetConfigsFromFile in server.go
   416  	Targets map[string]RemoteWriteTarget `yaml:"scrape-configs" mapstructure:"-"`
   417  }
   418  
   419  type RemoteRead struct {
   420  	Enabled   bool   `def:"false" desc:"EXPERIMENTAL! the API will change, use at your own risk. whether to enable remote write or not"`
   421  	Address   string `desc:"server that implements the pyroscope /render endpoint" mapstructure:"address"`
   422  	AuthToken string `json:"-" desc:"authorization token used to read profiling data" yaml:"auth-token" mapstructure:"auth-token"`
   423  }
   424  
   425  type RemoteWriteTarget struct {
   426  	Address string `desc:"server that implements the pyroscope /ingest endpoint" mapstructure:"address"`
   427  	// TODO(eh-am): use a custom type here to not accidentaly leak the AuthToken?
   428  	AuthToken         string            `json:"-" desc:"authorization token used to upload profiling data" yaml:"auth-token"`
   429  	BasicAuthUser     string            `json:"-" def:"" desc:"HTTP Basic authentication username" mapstructure:"basic-auth-user" yaml:"basic-auth-user"`
   430  	BasicAuthPassword string            `json:"-" def:"" desc:"HTTP Basic authentication password" mapstructure:"basic-auth-password" yaml:"basic-auth-password"`
   431  	TenantID          string            `def:"" desc:"Phlare tenant ID passed as X-Scope-OrgID http header" mapstructure:"tenant-id" yaml:"tenant-id"`
   432  	Tags              map[string]string `name:"tag" desc:"tag in key=value form. The flag may be specified multiple times" mapstructure:"tags"`
   433  	Headers           map[string]string `name:"header" desc:"extra http header. The flag may be specified multiple times" mapstructure:"headers"`
   434  	Timeout           time.Duration     `desc:"profile upload timeout" mapstructure:"timeout" yaml:"timeout"`
   435  	QueueSize         int               `desc:"number of items in the queue" yaml:"queue-size"`
   436  	QueueWorkers      int               `desc:"number of queue workers" yaml:"queue-workers"`
   437  }
   438  
   439  func (r RemoteWriteTarget) String() string {
   440  	tags := ""
   441  	for key, value := range r.Tags {
   442  		tags = tags + fmt.Sprintf("%s=%s ", key, value)
   443  	}
   444  
   445  	// it's useful to distinguish between set/not set when debugging
   446  	authToken := "[redacted]"
   447  	if r.AuthToken == "" {
   448  		authToken = "[not set]"
   449  	}
   450  
   451  	return fmt.Sprintf("Address: %s\nAuthToken: %s\nTags: %s\nTimeout: %s\nQueueSize: %d\nQueueWorkers %d", r.Address, authToken, tags, r.Timeout.String(), r.QueueSize, r.QueueWorkers)
   452  }
   453  
   454  type CI struct {
   455  	ApplicationName string `def:"ci" desc:"application name used when uploading profiling data" mapstructure:"application-name"`
   456  }