Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: log jitter during best-fit template loading #2920

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ clean: ## Cleanup the project binary (bin) folders
fi

test: ## run tests
@echo "Running tests"
# The ldflags force the old Apple linker to suppress ld warning messages on MacOS
# See https://github.com/golang/go/issues/61229#issuecomment-1988965927
go test -ldflags=-extldflags=-Wl,-ld_classic -race -shuffle=on ./...
@echo "Testing"
@# The ldflags force the old Apple linker to suppress ld warning messages on MacOS
@# See https://github.com/golang/go/issues/61229#issuecomment-1988965927
@go test -ldflags=-extldflags=-Wl,-ld_classic -race -shuffle=on ./...

fmt: ## format the go source files
@echo "Formatting"
Expand Down
3 changes: 2 additions & 1 deletion cmd/collectors/rest/templating.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import (

func (r *Rest) LoadTemplate() (string, error) {

template, path, err := r.ImportSubTemplate("", TemplateFn(r.Params, r.Object), r.Client.Cluster().Version)
jitter := r.Params.GetChildContentS("jitter")
template, path, err := r.ImportSubTemplate("", TemplateFn(r.Params, r.Object), jitter, r.Client.Cluster().Version)
if err != nil {
return "", err
}
Expand Down
6 changes: 4 additions & 2 deletions cmd/collectors/storagegrid/storagegrid.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (s *StorageGrid) Init(a *collector.AbstractCollector) error {
return err
}

s.Logger.Info().Msg("initialized")
s.Logger.Debug().Msg("initialized")
return nil
}

Expand Down Expand Up @@ -472,7 +472,9 @@ func (s *StorageGrid) LoadTemplate() (string, error) {
err error
)

template, path, err = s.ImportSubTemplate("", rest.TemplateFn(s.Params, s.Object), s.client.Cluster.Version)
jitter := s.Params.GetChildContentS("jitter")

template, path, err = s.ImportSubTemplate("", rest.TemplateFn(s.Params, s.Object), jitter, s.client.Cluster.Version)
if err != nil {
return "", err
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/collectors/zapi/collector/zapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,12 @@ func (z *Zapi) Init(a *collector.AbstractCollector) error {
}

func (z *Zapi) InitVars() error {
jitter := z.Params.GetChildContentS("jitter")
// It's used for unit tests only
if z.Options.IsTest {
z.Client = client.NewTestClient()
templateName := z.Params.GetChildS("objects").GetChildContentS(z.Object)
template, path, err := z.ImportSubTemplate("cdot", templateName, [3]int{9, 8, 0})
template, path, err := z.ImportSubTemplate("cdot", templateName, jitter, [3]int{9, 8, 0})
if err != nil {
return err
}
Expand Down Expand Up @@ -123,7 +124,7 @@ func (z *Zapi) InitVars() error {
z.HostModel = model
templateName := z.Params.GetChildS("objects").GetChildContentS(z.Object)

template, path, err := z.ImportSubTemplate(model, templateName, z.Client.Version())
template, path, err := z.ImportSubTemplate(model, templateName, jitter, z.Client.Version())
if err != nil {
return err
}
Expand Down
12 changes: 10 additions & 2 deletions cmd/poller/collector/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ var versionRegex = regexp.MustCompile(`\d+\.\d+\.\d+`)
// are sorted, and we try to return the subtemplate that most closely matches the ONTAP version.
// Model is cdot or 7mode, filename is the name of the subtemplate, and ver is the
// ONTAP version triple (generation, major, minor)
func (c *AbstractCollector) ImportSubTemplate(model, filename string, ver [3]int) (*node.Node, string, error) {
func (c *AbstractCollector) ImportSubTemplate(model, filename, jitter string, ver [3]int) (*node.Node, string, error) {

var (
selectedVersion, templatePath string
Expand Down Expand Up @@ -85,7 +85,15 @@ nextFile:
}

templatePath = filepath.Join(selectedVersion, f)
c.Logger.Info().Str("path", templatePath).Str("v", verWithDots).Msg("best-fit template")
if jitter == "" {
jitter = "none"
}

c.Logger.Info().
Str("path", templatePath).
Str("v", verWithDots).
Str("jitter", jitter).
Msg("best-fit template")
if finalTemplate == nil {
finalTemplate, err = tree.ImportYaml(templatePath)
if err == nil {
Expand Down
11 changes: 6 additions & 5 deletions docs/configure-rest.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,12 @@ explained in the next section).
Additionally, this file contains the parameters that are applied as defaults to all objects. As mentioned before, any
of these parameters can be defined in the Harvest or object configuration files as well.

| parameter | type | description | default |
|------------------|----------------------|-------------------------------------------------------------------------|-----------|
| `client_timeout` | duration (Go-syntax) | how long to wait for server responses | 30s |
| `schedule` | list, **required** | how frequently to retrieve metrics from ONTAP | |
| - `data` | duration (Go-syntax) | how frequently this collector/object should retrieve metrics from ONTAP | 3 minutes |
| parameter | type | description | default |
|------------------|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
| `client_timeout` | duration (Go-syntax) | how long to wait for server responses | 30s |
| `jitter` | duration (Go-syntax), optional | Each Harvest collector runs independently, which means that at startup, each collector may send its REST queries at nearly the same time. To spread out the collector startup times over a broader period, you can use `jitter` to randomly distribute collector startup across a specified duration. For example, a `jitter` of `1m` starts each collector after a random delay between 0 and 60 seconds. For more details, refer to [this discussion](https://github.com/NetApp/harvest/discussions/2856). | |
| `schedule` | list, **required** | how frequently to retrieve metrics from ONTAP | |
| - `data` | duration (Go-syntax) | how frequently this collector/object should retrieve metrics from ONTAP | 3 minutes |

The template should define objects in the `objects` section. Example:

Expand Down
13 changes: 7 additions & 6 deletions docs/configure-zapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,13 @@ The full set of parameters are described [below](#collector-configuration-file).
The parameters are similar to those of the [ZapiPerf collector](#zapiperf-collector).
Parameters different from ZapiPerf:

| parameter | type | description | default |
|-------------------------|----------------|--------------------------------------------------------------------------------------------------------------|---------|
| `schedule` | required | same as for ZapiPerf, but only two elements: `instance` and `data` (collector does not run a `counter` poll) | |
| `no_max_records` | bool, optional | don't add `max-records` to the ZAPI request | |
| `collect_only_labels` | bool, optional | don't look for numeric metrics, only submit labels (suppresses the `ErrNoMetrics` error) | |
| `only_cluster_instance` | bool, optional | don't look for instance keys and assume only instance is the cluster itself | |
| parameter | type | description | default |
|-------------------------|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|
| `jitter` | duration (Go-syntax), optional | Each Harvest collector runs independently, which means that at startup, each collector may send its ZAPI queries at nearly the same time. To spread out the collector startup times over a broader period, you can use `jitter` to randomly distribute collector startup across a specified duration. For example, a `jitter` of `1m` starts each collector after a random delay between 0 and 60 seconds. For more details, refer to [this discussion](https://github.com/NetApp/harvest/discussions/2856). | |
| `schedule` | required | same as for ZapiPerf, but only two elements: `instance` and `data` (collector does not run a `counter` poll) | |
| `no_max_records` | bool, optional | don't add `max-records` to the ZAPI request | |
| `collect_only_labels` | bool, optional | don't look for numeric metrics, only submit labels (suppresses the `ErrNoMetrics` error) | |
| `only_cluster_instance` | bool, optional | don't look for instance keys and assume only instance is the cluster itself | |

#### Object configuration file

Expand Down