From 371470bc0e58c4f1620c96463f598e7045939d07 Mon Sep 17 00:00:00 2001 From: Craig Peterson <192540+captncraig@users.noreply.github.com> Date: Mon, 12 Jun 2023 15:48:37 -0400 Subject: [PATCH] Release 0.34.1 (#4135) * Fix windows exporter defaults not being set correctly (#4109) * trying to find root cause * Update windows exporter to use fork and allow defaults and multiple usages. * Update windows exporter to use fork and allow defaults and multiple usages. * Revert useapi usage. * Remove unused SValue * Change some verbiage and add comments. * Update to newest version * Update go.mod * add indirect * Fix tests * Add test that checks for defaults * Fix tidy * go mod tidy * remote.http: fail early and add logs for failed requests (#4103) This updates `remote.http` to return an error if polling after Update fails. Returning an error following Update is important to make sure that background failures don't cause issues to propagate across components: If a component expects remote.http to have a non-empty body, remote.http should be unhealthy on first evaluation to prevent downstream components from evaluating. In addition to failing early, failed requests are now logged to assist with user debugging. Fixes #4084. Co-authored-by: Erik Baranowski <39704712+erikbaranowski@users.noreply.github.com> * changelog * prometheus.operator.servicemonitors: allow servicemonitors to set bearerTokenFile (#4118) * version updates for 0.34.1 --------- Co-authored-by: mattdurham Co-authored-by: Robert Fratto Co-authored-by: Erik Baranowski <39704712+erikbaranowski@users.noreply.github.com> --- CHANGELOG.md | 18 ++ .../configgen/config_gen_servicemonitor.go | 4 +- component/remote/http/http.go | 15 +- .../deploy-agent-operator-resources.md | 4 +- docs/sources/operator/getting-started.md | 2 +- .../integrations/node-exporter-config.md | 4 +- .../integrations/process-exporter-config.md | 4 +- .../static/set-up/install-agent-docker.md | 4 +- go.mod | 11 +- go.sum | 7 +- .../windows_exporter/config_windows.go | 182 +++++++++++------- .../windows_exporter/config_windows_test.go | 69 +++++++ .../windows_exporter_windows.go | 26 ++- pkg/operator/defaults.go | 2 +- production/kubernetes/agent-bare.yaml | 2 +- production/kubernetes/agent-loki.yaml | 2 +- production/kubernetes/agent-traces.yaml | 2 +- .../kubernetes/build/lib/version.libsonnet | 2 +- .../build/templates/operator/main.jsonnet | 4 +- production/kubernetes/install-bare.sh | 2 +- .../operator/templates/agent-operator.yaml | 4 +- .../tanka/grafana-agent/v1/main.libsonnet | 4 +- .../grafana-agent/v2/internal/base.libsonnet | 4 +- .../v2/internal/syncer.libsonnet | 2 +- 24 files changed, 265 insertions(+), 115 deletions(-) create mode 100644 pkg/integrations/windows_exporter/config_windows_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fc623bdf347..76d746a44688 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,24 @@ This document contains a historical list of changes between releases. Only changes that impact end-user behavior are listed; changes to documentation or internal API changes are not present. +v0.34.1 (2023-06-12) +-------------------- + +### Bugfixes + +- Fixed application of sub-collector defaults using the `windows_exporter` integration or `prometheus.exporter.windows`. (@mattdurham) + +- Fix issue where `remote.http` did not fail early if the initial request + failed. This caused failed requests to initially export empty values, which + could lead to propagating issues downstream to other components which expect + the export to be non-empty. (@rfratto) + +- Allow `bearerTokenFile` field to be used in ServiceMonitors. (@captncraig) + +### Other changes + +- Add logging to failed requests in `remote.http`. (@rfratto) + v0.34.0 (2023-06-08) -------------------- diff --git a/component/prometheus/operator/configgen/config_gen_servicemonitor.go b/component/prometheus/operator/configgen/config_gen_servicemonitor.go index bc8fa4ecdbf9..1c6efdcd9a50 100644 --- a/component/prometheus/operator/configgen/config_gen_servicemonitor.go +++ b/component/prometheus/operator/configgen/config_gen_servicemonitor.go @@ -67,7 +67,9 @@ func (cg *ConfigGenerator) GenerateServiceMonitorConfig(m *promopv1.ServiceMonit return nil, err } } - if ep.BearerTokenSecret.Name != "" { + if ep.BearerTokenFile != "" { + cfg.HTTPClientConfig.BearerTokenFile = ep.BearerTokenFile + } else if ep.BearerTokenSecret.Name != "" { val, err := cg.Secrets.GetSecretValue(m.Namespace, ep.BearerTokenSecret) if err != nil { return nil, err diff --git a/component/remote/http/http.go b/component/remote/http/http.go index aa5f392cc814..903cee193a5b 100644 --- a/component/remote/http/http.go +++ b/component/remote/http/http.go @@ -11,6 +11,7 @@ import ( "time" "github.com/go-kit/log" + "github.com/go-kit/log/level" "github.com/grafana/agent/component" common_config "github.com/grafana/agent/component/common/config" "github.com/grafana/agent/pkg/build" @@ -199,6 +200,7 @@ func (c *Component) pollError() error { req, err := http.NewRequest(c.args.Method, c.args.URL, nil) if err != nil { + level.Error(c.log).Log("msg", "failed to build request", "err", err) return fmt.Errorf("building request: %w", err) } for name, value := range c.args.Headers { @@ -208,15 +210,18 @@ func (c *Component) pollError() error { resp, err := c.cli.Do(req) if err != nil { + level.Error(c.log).Log("msg", "failed to perform request", "err", err) return fmt.Errorf("performing request: %w", err) } bb, err := io.ReadAll(resp.Body) if err != nil { + level.Error(c.log).Log("msg", "failed to read response", "err", err) return fmt.Errorf("reading response: %w", err) } if resp.StatusCode != http.StatusOK { + level.Error(c.log).Log("msg", "unexpected status code from response", "status", resp.Status) return fmt.Errorf("unexpected status code %s", resp.Status) } @@ -241,13 +246,17 @@ func (c *Component) pollError() error { // Update updates the remote.http component. After the update completes, a // poll is forced. func (c *Component) Update(args component.Arguments) (err error) { - // poll after updating. If an error occurred during Update, we don't bother - // to do anything. + // Poll after updating and propagate the error if the poll fails. If an error + // occurred during Update, we don't bother to do anything. + // + // It's important to propagate the error in update so the initial state of + // the component is calculated correctly, otherwise the exports will be empty + // and may cause unexpected errors in downstream components. defer func() { if err != nil { return } - c.poll() + err = c.pollError() }() c.mut.Lock() diff --git a/docs/sources/operator/deploy-agent-operator-resources.md b/docs/sources/operator/deploy-agent-operator-resources.md index 4319f0700aaa..88fb71c8d41f 100644 --- a/docs/sources/operator/deploy-agent-operator-resources.md +++ b/docs/sources/operator/deploy-agent-operator-resources.md @@ -53,12 +53,12 @@ To deploy the `GrafanaAgent` resource: labels: app: grafana-agent spec: - image: grafana/agent:v0.34.0 + image: grafana/agent:v0.34.1 integrations: selector: matchLabels: agent: grafana-agent-integrations - image: grafana/agent:v0.34.0 + image: grafana/agent:v0.34.1 logLevel: info serviceAccountName: grafana-agent metrics: diff --git a/docs/sources/operator/getting-started.md b/docs/sources/operator/getting-started.md index b21cdb13f03e..0154a125d6a7 100644 --- a/docs/sources/operator/getting-started.md +++ b/docs/sources/operator/getting-started.md @@ -73,7 +73,7 @@ To install Agent Operator: serviceAccountName: grafana-agent-operator containers: - name: operator - image: grafana/agent-operator:v0.34.0 + image: grafana/agent-operator:v0.34.1 args: - --kubelet-service=default/kubelet --- diff --git a/docs/sources/static/configuration/integrations/node-exporter-config.md b/docs/sources/static/configuration/integrations/node-exporter-config.md index d9a1a8dd62a5..0799ad3f39ff 100644 --- a/docs/sources/static/configuration/integrations/node-exporter-config.md +++ b/docs/sources/static/configuration/integrations/node-exporter-config.md @@ -28,7 +28,7 @@ docker run \ -v "/proc:/host/proc:ro,rslave" \ -v /tmp/agent:/etc/agent \ -v /path/to/config.yaml:/etc/agent-config/agent.yaml \ - grafana/agent:v0.34.0 \ + grafana/agent:v0.34.1 \ --config.file=/etc/agent-config/agent.yaml ``` @@ -67,7 +67,7 @@ metadata: name: agent spec: containers: - - image: grafana/agent:v0.34.0 + - image: grafana/agent:v0.34.1 name: agent args: - --config.file=/etc/agent-config/agent.yaml diff --git a/docs/sources/static/configuration/integrations/process-exporter-config.md b/docs/sources/static/configuration/integrations/process-exporter-config.md index 70693e8f2a3e..77a0c624eb85 100644 --- a/docs/sources/static/configuration/integrations/process-exporter-config.md +++ b/docs/sources/static/configuration/integrations/process-exporter-config.md @@ -20,7 +20,7 @@ docker run \ -v "/proc:/proc:ro" \ -v /tmp/agent:/etc/agent \ -v /path/to/config.yaml:/etc/agent-config/agent.yaml \ - grafana/agent:v0.34.0 \ + grafana/agent:v0.34.1 \ --config.file=/etc/agent-config/agent.yaml ``` @@ -37,7 +37,7 @@ metadata: name: agent spec: containers: - - image: grafana/agent:v0.34.0 + - image: grafana/agent:v0.34.1 name: agent args: - --config.file=/etc/agent-config/agent.yaml diff --git a/docs/sources/static/set-up/install-agent-docker.md b/docs/sources/static/set-up/install-agent-docker.md index a5164669193b..5a948201ac25 100644 --- a/docs/sources/static/set-up/install-agent-docker.md +++ b/docs/sources/static/set-up/install-agent-docker.md @@ -29,7 +29,7 @@ Grafana Agent is available as a Docker container image on the following platform docker run \ -v WAL_DATA_DIRECTORY:/etc/agent/data \ -v CONFIG_FILE_PATH:/etc/agent/agent.yaml \ - grafana/agent:v0.34.0 + grafana/agent:v0.34.1 ``` - Replace `CONFIG_FILE_PATH` with the configuration file path on your Linux host system. @@ -47,7 +47,7 @@ Grafana Agent is available as a Docker container image on the following platform docker run ^ -v WAL_DATA_DIRECTORY:c:\etc\grafana-agent\data ^ -v CONFIG_FILE_PATH:c:\etc\grafana-agent ^ - grafana/agent:v0.34.0-windows + grafana/agent:v0.34.1-windows ``` - Replace `CONFIG_FILE_PATH` with the configuration file path on your Windows host system. diff --git a/go.mod b/go.mod index ff9dfe9499d1..f7c5f19d1b68 100644 --- a/go.mod +++ b/go.mod @@ -48,6 +48,7 @@ require ( github.com/google/dnsmasq_exporter v0.0.0-00010101000000-000000000000 github.com/google/go-cmp v0.5.9 github.com/google/go-jsonnet v0.18.0 + github.com/google/pprof v0.0.0-20230111200839-76d1ae5aea2b // indirect github.com/google/renameio/v2 v2.0.0 github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.8.0 @@ -145,6 +146,7 @@ require ( github.com/shirou/gopsutil/v3 v3.22.9 github.com/sijms/go-ora/v2 v2.7.3 github.com/sirupsen/logrus v1.9.2 + github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/cobra v1.6.1 github.com/stretchr/testify v1.8.2 github.com/testcontainers/testcontainers-go v0.19.0 @@ -198,8 +200,11 @@ require ( k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 sigs.k8s.io/controller-runtime v0.14.6 sigs.k8s.io/yaml v1.3.0 + ) +require github.com/klauspost/compress v1.15.15 + require ( cloud.google.com/go v0.107.0 // indirect cloud.google.com/go/compute v1.14.0 // indirect @@ -359,7 +364,6 @@ require ( github.com/google/gnostic v0.6.9 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20230111200839-76d1ae5aea2b // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect github.com/googleapis/gax-go/v2 v2.7.0 // indirect @@ -430,7 +434,6 @@ require ( github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/karrick/godirwalk v1.16.1 // indirect github.com/kevinburke/ssh_config v1.1.0 // indirect - github.com/klauspost/compress v1.15.15 // indirect github.com/knadh/koanf v1.4.4 // indirect github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b // indirect github.com/krallistic/kazoo-go v0.0.0-20170526135507-a15279744f4e // indirect @@ -530,7 +533,6 @@ require ( github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a // indirect - github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -695,3 +697,6 @@ replace github.com/prometheus/procfs => github.com/prometheus/procfs v0.8.0 // TODO(mattdurham): this is so you can debug on windows, when PR is merged into perflib, can you use that // and eventually remove if windows_exporter shifts to it. https://github.com/leoluk/perflib_exporter/pull/43 replace github.com/leoluk/perflib_exporter => github.com/grafana/perflib_exporter v0.1.1-0.20230511173423-6166026bd090 + +// TODO(mattdurham): this is to allow defaults to propogate properly. +replace github.com/prometheus-community/windows_exporter => github.com/grafana/windows_exporter v0.15.1-0.20230609142740-b47fa97c3c47 diff --git a/go.sum b/go.sum index d276b28a92f7..0e913f6b9214 100644 --- a/go.sum +++ b/go.sum @@ -1813,6 +1813,8 @@ github.com/grafana/tail v0.0.0-20230328181249-aa6682d7843a h1:ypBalFlWhbqP+60je3 github.com/grafana/tail v0.0.0-20230328181249-aa6682d7843a/go.mod h1:7t5XR+2IA8P2qggOAHTj/GCZfoLBle3OvNSYh1VkRBU= github.com/grafana/vmware_exporter v0.0.4-beta h1:Tb8Edm/wDYh0Lvhm38HLNTlkflUrlPGB+jD+/hW4xHI= github.com/grafana/vmware_exporter v0.0.4-beta/go.mod h1:+SsUoWeCJ3nDm1gkw8xqBp4NNSUIrGVoEbnwJeeoIVU= +github.com/grafana/windows_exporter v0.15.1-0.20230609142740-b47fa97c3c47 h1:0B4dYFrny1h51kdddXbvg6yHn8LAEfoYuxeQceV6uXw= +github.com/grafana/windows_exporter v0.15.1-0.20230609142740-b47fa97c3c47/go.mod h1:VP/c/Xo6p/PRlSN5s7M2SGscCxLGFRHydjmk0WqxaHU= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grobie/gomemcache v0.0.0-20201204163352-08d7c80fcac6 h1:vqwzYov9hrRoGAmy61um8mVteOCD0bEbKgXr1mmkTlI= github.com/grobie/gomemcache v0.0.0-20201204163352-08d7c80fcac6/go.mod h1:L69/dBlPQlWkcnU76WgcppK5e4rrxzQdi6LhLnK/ytA= @@ -2651,8 +2653,6 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= -github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= @@ -2779,8 +2779,6 @@ github.com/prometheus-community/prom-label-proxy v0.5.0 h1:f9RqZ+xwznh/7XbTEr0LD github.com/prometheus-community/prom-label-proxy v0.5.0/go.mod h1:qiIPYa/ju9u4wq3LjvL3ofzd3jcyW0Rt5jkZ6QgF4nc= github.com/prometheus-community/stackdriver_exporter v0.13.0 h1:4h7v28foRJ4/RuchNZCYsoDp+CkF4Mp9nebtPzgil3g= github.com/prometheus-community/stackdriver_exporter v0.13.0/go.mod h1:ZFO015Mexz1xNHSvFjZFiIspYx6qhDg9Kre4LPUjO9s= -github.com/prometheus-community/windows_exporter v0.0.0-20230507104622-79781c6d75fc h1:5HoXejMR9fh1Sh46I/pe/Y3M1vJpm5UvCSqWdBmUZHs= -github.com/prometheus-community/windows_exporter v0.0.0-20230507104622-79781c6d75fc/go.mod h1:O3yNykuN8H0YOdVc4NEzs12Ugp4x2MgNhZvXHPkf7j8= github.com/prometheus-operator/prometheus-operator v0.62.0 h1:9pjQm5NgZrhJgLIapWxKJXeZ0hasBZ/ekWcyHnsldk0= github.com/prometheus-operator/prometheus-operator v0.62.0/go.mod h1:fyio1iC7r5NSFw/AQaNH8E+7N7embyY2W1ozINQRShw= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.63.0 h1:efsW3CfymG5bZUpeIsYfdihB33YItCn7uHBOEbnHQG8= @@ -2980,7 +2978,6 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= diff --git a/pkg/integrations/windows_exporter/config_windows.go b/pkg/integrations/windows_exporter/config_windows.go index c81b07fa75de..b88523460153 100644 --- a/pkg/integrations/windows_exporter/config_windows.go +++ b/pkg/integrations/windows_exporter/config_windows.go @@ -1,18 +1,23 @@ package windows_exporter //nolint:golint import ( + "fmt" "github.com/alecthomas/kingpin/v2" "github.com/prometheus-community/windows_exporter/collector" + "strconv" ) // Populate defaults for all collector configs. func init() { + // TODO (@mattdurham) we should look at removing this init. I think it can become + // a function call now. // Register flags from all collector configs to a fake integration and then // parse an empty command line to force defaults to be populated. app := kingpin.New("", "") // Register all flags from collector - collector.RegisterCollectorsFlags(app) + collectors := collector.CreateInitializers() + collector.RegisterCollectorsFlags(collectors, app) _, err := app.Parse([]string{}) if err != nil { @@ -20,77 +25,116 @@ func init() { } // Map the configs with defaults applied to our default config. - DefaultConfig.fromExporterConfig(app) + DefaultConfig.setDefaults(app) } -// fromExporterConfig converts windows_exporter configs into the integration Config. -func (c *Config) fromExporterConfig(app *kingpin.Application) { - c.Dfsr.SourcesEnabled = *app.GetFlag(collector.FlagDfsrEnabledCollectors).String() - c.Exchange.EnabledList = *app.GetFlag(collector.FlagExchangeCollectorsEnabled).String() - c.IIS.SiteBlackList = *app.GetFlag(collector.FlagIISSiteOldExclude).String() - c.IIS.SiteWhiteList = *app.GetFlag(collector.FlagIISSiteOldInclude).String() - c.IIS.AppBlackList = *app.GetFlag(collector.FlagIISAppOldExclude).String() - c.IIS.AppWhiteList = *app.GetFlag(collector.FlagIISAppOldInclude).String() - c.IIS.SiteExclude = *app.GetFlag(collector.FlagIISSiteExclude).String() - c.IIS.SiteInclude = *app.GetFlag(collector.FlagIISSiteInclude).String() - c.IIS.AppExclude = *app.GetFlag(collector.FlagIISAppExclude).String() - c.IIS.AppInclude = *app.GetFlag(collector.FlagIISAppInclude).String() - c.LogicalDisk.BlackList = *app.GetFlag(collector.FlagLogicalDiskVolumeOldExclude).String() - c.LogicalDisk.WhiteList = *app.GetFlag(collector.FlagLogicalDiskVolumeOldInclude).String() - c.LogicalDisk.Exclude = *app.GetFlag(collector.FlagLogicalDiskVolumeExclude).String() - c.LogicalDisk.Include = *app.GetFlag(collector.FlagLogicalDiskVolumeInclude).String() - c.MSMQ.Where = *app.GetFlag(collector.FlagMsmqWhereClause).String() - c.MSSQL.EnabledClasses = *app.GetFlag(collector.FlagMssqlEnabledCollectors).String() - c.Network.BlackList = *app.GetFlag(collector.FlagNicOldExclude).String() - c.Network.WhiteList = *app.GetFlag(collector.FlagNicOldInclude).String() - c.Network.Exclude = *app.GetFlag(collector.FlagNicExclude).String() - c.Network.Include = *app.GetFlag(collector.FlagNicInclude).String() - c.Process.BlackList = *app.GetFlag(collector.FlagProcessOldExclude).String() - c.Process.WhiteList = *app.GetFlag(collector.FlagProcessOldInclude).String() - c.Process.Exclude = *app.GetFlag(collector.FlagProcessExclude).String() - c.Process.Include = *app.GetFlag(collector.FlagProcessInclude).String() - c.ScheduledTask.Exclude = *app.GetFlag(collector.FlagScheduledTaskExclude).String() - c.ScheduledTask.Include = *app.GetFlag(collector.FlagScheduledTaskInclude).String() - c.Service.Where = *app.GetFlag(collector.FlagServiceWhereClause).String() - c.Service.UseApi = *app.GetFlag(collector.FlagServiceUseAPI).String() - c.SMTP.BlackList = *app.GetFlag(collector.FlagSmtpServerOldExclude).String() - c.SMTP.WhiteList = *app.GetFlag(collector.FlagSmtpServerOldInclude).String() - c.SMTP.Exclude = *app.GetFlag(collector.FlagSmtpServerExclude).String() - c.SMTP.Include = *app.GetFlag(collector.FlagSmtpServerInclude).String() - c.TextFile.TextFileDirectory = *app.GetFlag(collector.FlagTextFileDirectory).String() +// getDefault works by getting the Flag values after being parsed, which sets the defaults. +// The only default we differ on is the parent enabled-collectors, which we remove textfile. +func getDefault(app *kingpin.Application, name string) string { + for _, f := range app.Model().Flags { + if f.Name != name { + continue + } + // Returns default value. + return f.String() + } + return "" +} + +// setDefaults converts windows_exporter configs into the integration Config. +// This should ONLY be called from the DefaultConfig to generate the defaults. +func (c *Config) setDefaults(app *kingpin.Application) { + c.Dfsr.SourcesEnabled = getDefault(app, collector.FlagDfsrEnabledCollectors) + c.Exchange.EnabledList = getDefault(app, collector.FlagExchangeCollectorsEnabled) + c.IIS.SiteBlackList = getDefault(app, collector.FlagIISSiteOldExclude) + c.IIS.SiteWhiteList = getDefault(app, collector.FlagIISSiteOldInclude) + c.IIS.AppBlackList = getDefault(app, collector.FlagIISAppOldExclude) + c.IIS.AppWhiteList = getDefault(app, collector.FlagIISAppOldInclude) + c.IIS.SiteExclude = getDefault(app, collector.FlagIISSiteExclude) + c.IIS.SiteInclude = getDefault(app, collector.FlagIISSiteInclude) + c.IIS.AppExclude = getDefault(app, collector.FlagIISAppExclude) + c.IIS.AppInclude = getDefault(app, collector.FlagIISAppInclude) + c.LogicalDisk.BlackList = getDefault(app, collector.FlagLogicalDiskVolumeOldExclude) + c.LogicalDisk.WhiteList = getDefault(app, collector.FlagLogicalDiskVolumeOldInclude) + c.LogicalDisk.Exclude = getDefault(app, collector.FlagLogicalDiskVolumeExclude) + c.LogicalDisk.Include = getDefault(app, collector.FlagLogicalDiskVolumeInclude) + c.MSMQ.Where = getDefault(app, collector.FlagMsmqWhereClause) + c.MSSQL.EnabledClasses = getDefault(app, collector.FlagMssqlEnabledCollectors) + c.Network.BlackList = getDefault(app, collector.FlagNicOldExclude) + c.Network.WhiteList = getDefault(app, collector.FlagNicOldInclude) + c.Network.Exclude = getDefault(app, collector.FlagNicExclude) + c.Network.Include = getDefault(app, collector.FlagNicInclude) + c.Process.BlackList = getDefault(app, collector.FlagProcessOldExclude) + c.Process.WhiteList = getDefault(app, collector.FlagProcessOldInclude) + c.Process.Exclude = getDefault(app, collector.FlagProcessExclude) + c.Process.Include = getDefault(app, collector.FlagProcessInclude) + c.ScheduledTask.Exclude = getDefault(app, collector.FlagScheduledTaskExclude) + c.ScheduledTask.Include = getDefault(app, collector.FlagScheduledTaskInclude) + c.Service.Where = getDefault(app, collector.FlagServiceWhereClause) + c.Service.UseApi = getDefault(app, collector.FlagServiceUseAPI) + c.SMTP.BlackList = getDefault(app, collector.FlagSmtpServerOldExclude) + c.SMTP.WhiteList = getDefault(app, collector.FlagSmtpServerOldInclude) + c.SMTP.Exclude = getDefault(app, collector.FlagSmtpServerExclude) + c.SMTP.Include = getDefault(app, collector.FlagSmtpServerInclude) + c.TextFile.TextFileDirectory = getDefault(app, collector.FlagTextFileDirectory) } // toExporterConfig converts integration Configs into windows_exporter configs. -func (c *Config) toExporterConfig(app *kingpin.Application) { - app.GetFlag(collector.FlagDfsrEnabledCollectors).StringVar(&c.Dfsr.SourcesEnabled) - app.GetFlag(collector.FlagExchangeCollectorsEnabled).StringVar(&c.Exchange.EnabledList) - app.GetFlag(collector.FlagIISSiteOldExclude).StringVar(&c.IIS.SiteBlackList) - app.GetFlag(collector.FlagIISSiteOldInclude).StringVar(&c.IIS.SiteWhiteList) - app.GetFlag(collector.FlagIISAppOldExclude).StringVar(&c.IIS.AppBlackList) - app.GetFlag(collector.FlagIISAppOldInclude).StringVar(&c.IIS.AppWhiteList) - app.GetFlag(collector.FlagIISSiteExclude).StringVar(&c.IIS.SiteExclude) - app.GetFlag(collector.FlagIISSiteInclude).StringVar(&c.IIS.SiteInclude) - app.GetFlag(collector.FlagIISAppExclude).StringVar(&c.IIS.AppExclude) - app.GetFlag(collector.FlagIISAppInclude).StringVar(&c.IIS.AppInclude) - app.GetFlag(collector.FlagLogicalDiskVolumeOldExclude).StringVar(&c.LogicalDisk.BlackList) - app.GetFlag(collector.FlagLogicalDiskVolumeOldInclude).StringVar(&c.LogicalDisk.WhiteList) - app.GetFlag(collector.FlagLogicalDiskVolumeExclude).StringVar(&c.LogicalDisk.Exclude) - app.GetFlag(collector.FlagLogicalDiskVolumeInclude).StringVar(&c.LogicalDisk.Include) - app.GetFlag(collector.FlagMsmqWhereClause).StringVar(&c.MSMQ.Where) - app.GetFlag(collector.FlagMssqlEnabledCollectors).StringVar(&c.MSSQL.EnabledClasses) - app.GetFlag(collector.FlagNicOldExclude).StringVar(&c.Network.BlackList) - app.GetFlag(collector.FlagNicOldInclude).StringVar(&c.Network.WhiteList) - app.GetFlag(collector.FlagNicExclude).StringVar(&c.Network.Exclude) - app.GetFlag(collector.FlagNicInclude).StringVar(&c.Network.Include) - app.GetFlag(collector.FlagProcessOldExclude).StringVar(&c.Process.BlackList) - app.GetFlag(collector.FlagProcessOldInclude).StringVar(&c.Process.WhiteList) - app.GetFlag(collector.FlagProcessExclude).StringVar(&c.Process.Exclude) - app.GetFlag(collector.FlagProcessInclude).StringVar(&c.Process.Include) - app.GetFlag(collector.FlagScheduledTaskExclude).StringVar(&c.Process.Exclude) - app.GetFlag(collector.FlagScheduledTaskInclude).StringVar(&c.Process.Include) - app.GetFlag(collector.FlagServiceWhereClause).StringVar(&c.Service.Where) - app.GetFlag(collector.FlagServiceUseAPI).StringVar(&c.Service.UseApi) - app.GetFlag(collector.FlagSmtpServerExclude).StringVar(&c.SMTP.Exclude) - app.GetFlag(collector.FlagNicInclude).StringVar(&c.SMTP.Include) - app.GetFlag(collector.FlagTextFileDirectory).StringVar(&c.TextFile.TextFileDirectory) +func (c *Config) toExporterConfig(collectors map[string]*collector.Initializer) error { + for _, v := range collectors { + // Most collectors don't have settings so if its nil then pass on by. + // The windows_export functions ensure that if a setting is required it will be initialized. + if v.Settings == nil { + continue + } + switch t := v.Settings.(type) { + case *collector.DFRSSettings: + t.DFRSEnabledCollectors = &c.Dfsr.SourcesEnabled + case *collector.DiskSettings: + t.VolumeInclude = &c.LogicalDisk.Include + t.VolumeExclude = &c.LogicalDisk.Exclude + case *collector.ExchangeSettings: + t.ArgExchangeCollectorsEnabled = &c.Exchange.EnabledList + case *collector.IISSettings: + t.AppInclude = &c.IIS.AppInclude + t.AppExclude = &c.IIS.AppExclude + t.OldAppExclude = &c.IIS.AppBlackList + t.OldAppInclude = &c.IIS.AppWhiteList + t.SiteExclude = &c.IIS.SiteExclude + t.SiteInclude = &c.IIS.SiteInclude + t.OldSiteExclude = &c.IIS.SiteBlackList + t.OldSiteInclude = &c.IIS.SiteWhiteList + case *collector.MSMQSettings: + t.MSMQWhereClause = &c.MSMQ.Where + case *collector.MSSqlSettings: + t.ClassesEnabled = &c.MSSQL.EnabledClasses + case *collector.NetSettings: + t.NicInclude = &c.Network.Include + t.NicExclude = &c.Network.Exclude + t.NicOldExclude = &c.Network.BlackList + t.NicOldInclude = &c.Network.WhiteList + case *collector.ProcessSettings: + t.ProcessExclude = &c.Process.Exclude + t.ProcessInclude = &c.Process.Include + t.ProcessOldExclude = &c.Process.BlackList + t.ProcessOldInclude = &c.Process.WhiteList + case *collector.ServiceSettings: + val, _ := strconv.ParseBool(c.Service.UseApi) + t.UseAPI = &val + t.ServiceWhereClause = &c.Service.Where + case *collector.SMTPSettings: + t.ServerInclude = &c.SMTP.Include + t.ServerExclude = &c.SMTP.Exclude + t.ServerOldExclude = &c.SMTP.BlackList + t.ServerOldInclude = &c.SMTP.WhiteList + case *collector.TaskSettings: + t.TaskInclude = &c.ScheduledTask.Include + t.TaskExclude = &c.ScheduledTask.Exclude + case *collector.TextSettings: + t.TextFileDirectory = &c.TextFile.TextFileDirectory + default: + return fmt.Errorf("unknown windows exporter type %t", t) + } + } + return nil } diff --git a/pkg/integrations/windows_exporter/config_windows_test.go b/pkg/integrations/windows_exporter/config_windows_test.go new file mode 100644 index 000000000000..580e1cd3a52c --- /dev/null +++ b/pkg/integrations/windows_exporter/config_windows_test.go @@ -0,0 +1,69 @@ +//go:build windows + +package windows_exporter + +import ( + "github.com/alecthomas/kingpin/v2" + "github.com/prometheus-community/windows_exporter/collector" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v2" + "testing" +) + +func TestConfig(t *testing.T) { + built, total := testConfig(t, "") + // Default which is windows_exporter defaults minus textfile + require.Len(t, built, 7) + // Total should be 50 + require.Len(t, total, 50) +} + +func TestMultipleConfig(t *testing.T) { + cfg1 := ` +enabled_collectors: "mssql,os" +mssql: + enabled_classes: "accessmethods,availreplica" +` + cfg2 := ` +enabled_collectors: "mssql,os,cpu" +mssql: + enabled_classes: "accessmethods,availreplica,bufman" +` + cfg3 := ` +enabled_collectors: "mssql,os" +mssql: {} +` + built1, total1 := testConfig(t, cfg1) + built2, total2 := testConfig(t, cfg2) + built3, total3 := testConfig(t, cfg3) + require.Len(t, built1, 2) + require.Len(t, built2, 3) + require.Len(t, built3, 2) + total1mssql := "accessmethods,availreplica" + require.True(t, *total1["mssql"].Settings.(*collector.MSSqlSettings).ClassesEnabled == total1mssql) + total2mssql := "accessmethods,availreplica,bufman" + require.True(t, *total2["mssql"].Settings.(*collector.MSSqlSettings).ClassesEnabled == total2mssql) + total3mssql := "accessmethods,availreplica,bufman,databases,dbreplica,genstats,locks,memmgr,sqlstats,sqlerrors,transactions,waitstats" + require.True(t, *total3["mssql"].Settings.(*collector.MSSqlSettings).ClassesEnabled == total3mssql) +} + +func testConfig(t *testing.T, cfg string) (map[string]collector.Collector, map[string]*collector.Initializer) { + c := DefaultConfig + err := yaml.Unmarshal([]byte(cfg), &c) + require.NoError(t, err) + collectors := collector.CreateInitializers() + windowsExporter := kingpin.New("", "") + // We only need this to fill in the appropriate settings structs so we can override them. + collector.RegisterCollectorsFlags(collectors, windowsExporter) + // Override the settings structs with our own + err = c.toExporterConfig(collectors) + require.NoError(t, err) + // Register the performance monitors + collector.RegisterCollectors(collectors) + // Filter down to the enabled collectors + enabledCollectorNames := enabledCollectors(c.EnabledCollectors) + // Finally build the collectors that we need to run. + builtCollectors, err := buildCollectors(collectors, enabledCollectorNames) + require.NoError(t, err) + return builtCollectors, collectors +} diff --git a/pkg/integrations/windows_exporter/windows_exporter_windows.go b/pkg/integrations/windows_exporter/windows_exporter_windows.go index 0acbccff5c3f..2418acf07b6d 100644 --- a/pkg/integrations/windows_exporter/windows_exporter_windows.go +++ b/pkg/integrations/windows_exporter/windows_exporter_windows.go @@ -14,17 +14,23 @@ import ( // New creates a new windows_exporter integration. func New(logger log.Logger, c *Config) (integrations.Integration, error) { + // We need to create a list of all the possible collectors. + collectors := collector.CreateInitializers() + // We need to pass in kingpin so that the settings get created appropriately. Even though we arent going to use its output. windowsExporter := kingpin.New("", "") - collector.RegisterCollectorsFlags(windowsExporter) - c.toExporterConfig(windowsExporter) - - if _, err := windowsExporter.Parse([]string{}); err != nil { + // We only need this to fill in the appropriate settings structs so we can override them. + collector.RegisterCollectorsFlags(collectors, windowsExporter) + // Override the settings structs generated from the kingping.app switch our own. + err := c.toExporterConfig(collectors) + if err != nil { return nil, err } - - collector.RegisterCollectors() + // Register the performance monitors + collector.RegisterCollectors(collectors) + // Filter down to the enabled collectors enabledCollectorNames := enabledCollectors(c.EnabledCollectors) - collectors, err := buildCollectors(enabledCollectorNames) + // Finally build the collectors that we need to run. + builtCollectors, err := buildCollectors(collectors, enabledCollectorNames) if err != nil { return nil, err } @@ -39,7 +45,7 @@ func New(logger log.Logger, c *Config) (integrations.Integration, error) { return integrations.NewCollectorIntegration(c.Name(), integrations.WithCollectors( // Hard-coded 4m timeout to represent the time a series goes stale. // TODO: Make configurable if useful. - collector.NewPrometheus(4*time.Minute, collectors), + collector.NewPrometheus(4*time.Minute, builtCollectors), )), nil } @@ -59,11 +65,11 @@ func enabledCollectors(input string) []string { return result } -func buildCollectors(enabled []string) (map[string]collector.Collector, error) { +func buildCollectors(colls map[string]*collector.Initializer, enabled []string) (map[string]collector.Collector, error) { collectors := map[string]collector.Collector{} for _, name := range enabled { - c, err := collector.Build(name) + c, err := collector.Build(colls, name) if err != nil { return nil, err } diff --git a/pkg/operator/defaults.go b/pkg/operator/defaults.go index 30c5dd1d9f82..40cbb2430f13 100644 --- a/pkg/operator/defaults.go +++ b/pkg/operator/defaults.go @@ -2,7 +2,7 @@ package operator // Supported versions of the Grafana Agent. var ( - DefaultAgentVersion = "v0.34.0" + DefaultAgentVersion = "v0.34.1" DefaultAgentBaseImage = "grafana/agent" DefaultAgentImage = DefaultAgentBaseImage + ":" + DefaultAgentVersion ) diff --git a/production/kubernetes/agent-bare.yaml b/production/kubernetes/agent-bare.yaml index 3dfb1efdd677..1ba2cc189d8c 100644 --- a/production/kubernetes/agent-bare.yaml +++ b/production/kubernetes/agent-bare.yaml @@ -83,7 +83,7 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName - image: grafana/agent:v0.34.0 + image: grafana/agent:v0.34.1 imagePullPolicy: IfNotPresent name: grafana-agent ports: diff --git a/production/kubernetes/agent-loki.yaml b/production/kubernetes/agent-loki.yaml index d0c57c643839..f5f55fc5379c 100644 --- a/production/kubernetes/agent-loki.yaml +++ b/production/kubernetes/agent-loki.yaml @@ -65,7 +65,7 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName - image: grafana/agent:v0.34.0 + image: grafana/agent:v0.34.1 imagePullPolicy: IfNotPresent name: grafana-agent-logs ports: diff --git a/production/kubernetes/agent-traces.yaml b/production/kubernetes/agent-traces.yaml index 470e35a5cc3d..c662afda59b0 100644 --- a/production/kubernetes/agent-traces.yaml +++ b/production/kubernetes/agent-traces.yaml @@ -114,7 +114,7 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName - image: grafana/agent:v0.34.0 + image: grafana/agent:v0.34.1 imagePullPolicy: IfNotPresent name: grafana-agent-traces ports: diff --git a/production/kubernetes/build/lib/version.libsonnet b/production/kubernetes/build/lib/version.libsonnet index b514233d58eb..ff8df037ff32 100644 --- a/production/kubernetes/build/lib/version.libsonnet +++ b/production/kubernetes/build/lib/version.libsonnet @@ -1 +1 @@ -'grafana/agent:v0.34.0' +'grafana/agent:v0.34.1' diff --git a/production/kubernetes/build/templates/operator/main.jsonnet b/production/kubernetes/build/templates/operator/main.jsonnet index 6f91f2039ad6..8854bb63e457 100644 --- a/production/kubernetes/build/templates/operator/main.jsonnet +++ b/production/kubernetes/build/templates/operator/main.jsonnet @@ -23,8 +23,8 @@ local ksm = import 'kube-state-metrics/kube-state-metrics.libsonnet'; local this = self, _images:: { - agent: 'grafana/agent:v0.34.0', - agent_operator: 'grafana/agent-operator:v0.34.0', + agent: 'grafana/agent:v0.34.1', + agent_operator: 'grafana/agent-operator:v0.34.1', ksm: 'registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.5.0', }, diff --git a/production/kubernetes/install-bare.sh b/production/kubernetes/install-bare.sh index 185a2f402c7a..886a24323f62 100644 --- a/production/kubernetes/install-bare.sh +++ b/production/kubernetes/install-bare.sh @@ -25,7 +25,7 @@ check_installed() { check_installed curl check_installed envsubst -MANIFEST_BRANCH=v0.34.0 +MANIFEST_BRANCH=v0.34.1 MANIFEST_URL=${MANIFEST_URL:-https://raw.githubusercontent.com/grafana/agent/${MANIFEST_BRANCH}/production/kubernetes/agent-bare.yaml} NAMESPACE=${NAMESPACE:-default} diff --git a/production/operator/templates/agent-operator.yaml b/production/operator/templates/agent-operator.yaml index 8883c2f84b48..07e90750480c 100644 --- a/production/operator/templates/agent-operator.yaml +++ b/production/operator/templates/agent-operator.yaml @@ -372,7 +372,7 @@ spec: containers: - args: - --kubelet-service=default/kubelet - image: grafana/agent-operator:v0.34.0 + image: grafana/agent-operator:v0.34.1 imagePullPolicy: IfNotPresent name: grafana-agent-operator serviceAccount: grafana-agent-operator @@ -436,7 +436,7 @@ metadata: name: grafana-agent namespace: ${NAMESPACE} spec: - image: grafana/agent:v0.34.0 + image: grafana/agent:v0.34.1 integrations: selector: matchLabels: diff --git a/production/tanka/grafana-agent/v1/main.libsonnet b/production/tanka/grafana-agent/v1/main.libsonnet index 5705fa8519ab..81d986b90b94 100644 --- a/production/tanka/grafana-agent/v1/main.libsonnet +++ b/production/tanka/grafana-agent/v1/main.libsonnet @@ -15,8 +15,8 @@ local service = k.core.v1.service; (import './lib/traces.libsonnet') + { _images:: { - agent: 'grafana/agent:v0.34.0', - agentctl: 'grafana/agentctl:v0.34.0', + agent: 'grafana/agent:v0.34.1', + agentctl: 'grafana/agentctl:v0.34.1', }, // new creates a new DaemonSet deployment of the grafana-agent. By default, diff --git a/production/tanka/grafana-agent/v2/internal/base.libsonnet b/production/tanka/grafana-agent/v2/internal/base.libsonnet index 3e644d81192e..2b6edcf26239 100644 --- a/production/tanka/grafana-agent/v2/internal/base.libsonnet +++ b/production/tanka/grafana-agent/v2/internal/base.libsonnet @@ -11,8 +11,8 @@ function(name='grafana-agent', namespace='') { local this = self, _images:: { - agent: 'grafana/agent:v0.34.0', - agentctl: 'grafana/agentctl:v0.34.0', + agent: 'grafana/agent:v0.34.1', + agentctl: 'grafana/agentctl:v0.34.1', }, _config:: { name: name, diff --git a/production/tanka/grafana-agent/v2/internal/syncer.libsonnet b/production/tanka/grafana-agent/v2/internal/syncer.libsonnet index d0e7ab12da0e..2caa7d45ebdb 100644 --- a/production/tanka/grafana-agent/v2/internal/syncer.libsonnet +++ b/production/tanka/grafana-agent/v2/internal/syncer.libsonnet @@ -14,7 +14,7 @@ function( ) { local _config = { api: error 'api must be set', - image: 'grafana/agentctl:v0.34.0', + image: 'grafana/agentctl:v0.34.1', schedule: '*/5 * * * *', configs: [], } + config,