mirror of
https://github.com/prometheus/prometheus.git
synced 2025-01-12 22:37:27 -08:00
Gate agent behind a feature flag, valide mode flags (#9620)
Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>
This commit is contained in:
parent
6e1d6edb33
commit
807f46a1ed
|
@ -132,7 +132,7 @@ func extractFlagName(pc *kingpin.ParseContext) string {
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return fc.Model().Name
|
return "--" + fc.Model().Name
|
||||||
}
|
}
|
||||||
panic("extractFlagName not called from a kingpin PreAction. This is a bug, please report to Prometheus.")
|
panic("extractFlagName not called from a kingpin PreAction. This is a bug, please report to Prometheus.")
|
||||||
}
|
}
|
||||||
|
@ -200,6 +200,9 @@ func (c *flagConfig) setFeatureListOptions(logger log.Logger) error {
|
||||||
case "new-service-discovery-manager":
|
case "new-service-discovery-manager":
|
||||||
c.enableNewSDManager = true
|
c.enableNewSDManager = true
|
||||||
level.Info(logger).Log("msg", "Experimental service discovery manager")
|
level.Info(logger).Log("msg", "Experimental service discovery manager")
|
||||||
|
case "agent":
|
||||||
|
agentMode = true
|
||||||
|
level.Info(logger).Log("msg", "Experimental agent mode enabled.")
|
||||||
case "":
|
case "":
|
||||||
continue
|
continue
|
||||||
default:
|
default:
|
||||||
|
@ -238,8 +241,6 @@ func main() {
|
||||||
|
|
||||||
a.HelpFlag.Short('h')
|
a.HelpFlag.Short('h')
|
||||||
|
|
||||||
a.Flag("agent", "Agent mode.").BoolVar(&agentMode)
|
|
||||||
|
|
||||||
a.Flag("config.file", "Prometheus configuration file path.").
|
a.Flag("config.file", "Prometheus configuration file path.").
|
||||||
Default("prometheus.yml").StringVar(&cfg.configFile)
|
Default("prometheus.yml").StringVar(&cfg.configFile)
|
||||||
|
|
||||||
|
@ -335,16 +336,16 @@ func main() {
|
||||||
PreAction(agentOnlySetting()).
|
PreAction(agentOnlySetting()).
|
||||||
Default("data-agent/").StringVar(&cfg.localStoragePath)
|
Default("data-agent/").StringVar(&cfg.localStoragePath)
|
||||||
|
|
||||||
a.Flag("storage.agent.segment-size",
|
a.Flag("storage.agent.wal-segment-size",
|
||||||
"Size at which to split WAL segment files. Example: 100MB").
|
"Size at which to split WAL segment files. Example: 100MB").
|
||||||
PreAction(agentOnlySetting()).
|
PreAction(agentOnlySetting()).
|
||||||
Hidden().PlaceHolder("<bytes>").BytesVar(&cfg.agent.WALSegmentSize)
|
Hidden().PlaceHolder("<bytes>").BytesVar(&cfg.agent.WALSegmentSize)
|
||||||
|
|
||||||
a.Flag("storage.agent.compression", "Compress the agent WAL.").
|
a.Flag("storage.agent.wal-compression", "Compress the agent WAL.").
|
||||||
PreAction(agentOnlySetting()).
|
PreAction(agentOnlySetting()).
|
||||||
Default("true").BoolVar(&cfg.agent.WALCompression)
|
Default("true").BoolVar(&cfg.agent.WALCompression)
|
||||||
|
|
||||||
a.Flag("storage.agent.truncate-frequency",
|
a.Flag("storage.agent.wal-truncate-frequency",
|
||||||
"The frequency at which to truncate the WAL and remove old data.").
|
"The frequency at which to truncate the WAL and remove old data.").
|
||||||
PreAction(agentOnlySetting()).
|
PreAction(agentOnlySetting()).
|
||||||
Hidden().PlaceHolder("<duration>").SetValue(&cfg.agent.TruncateFrequency)
|
Hidden().PlaceHolder("<duration>").SetValue(&cfg.agent.TruncateFrequency)
|
||||||
|
@ -434,6 +435,16 @@ func main() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if agentMode && len(serverOnlyFlags) > 0 {
|
||||||
|
fmt.Fprintf(os.Stderr, "The following flag(s) can not be used in agent mode: %q", serverOnlyFlags)
|
||||||
|
os.Exit(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !agentMode && len(agentOnlyFlags) > 0 {
|
||||||
|
fmt.Fprintf(os.Stderr, "The following flag(s) can only be used in agent mode: %q", agentOnlyFlags)
|
||||||
|
os.Exit(3)
|
||||||
|
}
|
||||||
|
|
||||||
cfg.web.ExternalURL, err = computeExternalURL(cfg.prometheusURL, cfg.web.ListenAddress)
|
cfg.web.ExternalURL, err = computeExternalURL(cfg.prometheusURL, cfg.web.ListenAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, errors.Wrapf(err, "parse external URL %q", cfg.prometheusURL))
|
fmt.Fprintln(os.Stderr, errors.Wrapf(err, "parse external URL %q", cfg.prometheusURL))
|
||||||
|
@ -1006,7 +1017,7 @@ func main() {
|
||||||
level.Info(logger).Log("msg", "Starting WAL storage ...")
|
level.Info(logger).Log("msg", "Starting WAL storage ...")
|
||||||
if cfg.agent.WALSegmentSize != 0 {
|
if cfg.agent.WALSegmentSize != 0 {
|
||||||
if cfg.agent.WALSegmentSize < 10*1024*1024 || cfg.agent.WALSegmentSize > 256*1024*1024 {
|
if cfg.agent.WALSegmentSize < 10*1024*1024 || cfg.agent.WALSegmentSize > 256*1024*1024 {
|
||||||
return errors.New("flag 'storage.agent.segment-size' must be set between 10MB and 256MB")
|
return errors.New("flag 'storage.agent.wal-segment-size' must be set between 10MB and 256MB")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db, err := agent.Open(
|
db, err := agent.Open(
|
||||||
|
|
|
@ -350,7 +350,7 @@ func getCurrentGaugeValuesFor(t *testing.T, reg prometheus.Gatherer, metricNames
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAgentSuccessfulStartup(t *testing.T) {
|
func TestAgentSuccessfulStartup(t *testing.T) {
|
||||||
prom := exec.Command(promPath, "-test.main", "--agent", "--config.file="+agentConfig)
|
prom := exec.Command(promPath, "-test.main", "--enable-feature=agent", "--config.file="+agentConfig)
|
||||||
err := prom.Start()
|
err := prom.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -370,7 +370,7 @@ func TestAgentSuccessfulStartup(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAgentStartupWithInvalidConfig(t *testing.T) {
|
func TestAgentStartupWithInvalidConfig(t *testing.T) {
|
||||||
prom := exec.Command(promPath, "-test.main", "--agent", "--config.file="+promConfig)
|
prom := exec.Command(promPath, "-test.main", "--enable-feature=agent", "--config.file="+promConfig)
|
||||||
err := prom.Start()
|
err := prom.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -388,3 +388,66 @@ func TestAgentStartupWithInvalidConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
require.Equal(t, expectedExitStatus, actualExitStatus)
|
require.Equal(t, expectedExitStatus, actualExitStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestModeSpecificFlags(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("skipping test in short mode.")
|
||||||
|
}
|
||||||
|
|
||||||
|
testcases := []struct {
|
||||||
|
mode string
|
||||||
|
arg string
|
||||||
|
exitStatus int
|
||||||
|
}{
|
||||||
|
{"agent", "--storage.agent.path", 0},
|
||||||
|
{"server", "--storage.tsdb.path", 0},
|
||||||
|
{"server", "--storage.agent.path", 3},
|
||||||
|
{"agent", "--storage.tsdb.path", 3},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testcases {
|
||||||
|
t.Run(fmt.Sprintf("%s mode with option %s", tc.mode, tc.arg), func(t *testing.T) {
|
||||||
|
args := []string{"-test.main", tc.arg, t.TempDir()}
|
||||||
|
|
||||||
|
if tc.mode == "agent" {
|
||||||
|
args = append(args, "--enable-feature=agent", "--config.file="+agentConfig)
|
||||||
|
} else {
|
||||||
|
args = append(args, "--config.file="+promConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
prom := exec.Command(promPath, args...)
|
||||||
|
|
||||||
|
// Log stderr in case of failure.
|
||||||
|
stderr, err := prom.StderrPipe()
|
||||||
|
require.NoError(t, err)
|
||||||
|
go func() {
|
||||||
|
slurp, _ := ioutil.ReadAll(stderr)
|
||||||
|
t.Log(string(slurp))
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = prom.Start()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if tc.exitStatus == 0 {
|
||||||
|
done := make(chan error, 1)
|
||||||
|
go func() { done <- prom.Wait() }()
|
||||||
|
select {
|
||||||
|
case err := <-done:
|
||||||
|
t.Errorf("prometheus should be still running: %v", err)
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
prom.Process.Kill()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = prom.Wait()
|
||||||
|
require.Error(t, err)
|
||||||
|
if exitError, ok := err.(*exec.ExitError); ok {
|
||||||
|
status := exitError.Sys().(syscall.WaitStatus)
|
||||||
|
require.Equal(t, tc.exitStatus, status.ExitStatus())
|
||||||
|
} else {
|
||||||
|
t.Errorf("unable to retrieve the exit status for prometheus: %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -86,3 +86,13 @@ issues upstream.
|
||||||
|
|
||||||
In future releases, this new service discovery manager will become the default and
|
In future releases, this new service discovery manager will become the default and
|
||||||
this feature flag will be ignored.
|
this feature flag will be ignored.
|
||||||
|
|
||||||
|
## Prometheus agent
|
||||||
|
|
||||||
|
`--enable-feature=agent`
|
||||||
|
|
||||||
|
When enabled, Prometheus runs in agent mode. The agent mode is limited to
|
||||||
|
discovery, scrape and remote write.
|
||||||
|
|
||||||
|
This is useful when you do not need to query the Prometheus data locally, but
|
||||||
|
only from a central [remote endpoint](https://prometheus.io/docs/operating/integrations/#remote-endpoints-and-storage).
|
||||||
|
|
Loading…
Reference in a new issue