mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
docs/CHANGELOG.md: support empty command-line flag values in short array notation
For example, -fooDuration=',10s,' is now supported - it sets three command-line flag values: - the first and the last one are set to the default value for `-fooDuration` - the second one is set to 10s
This commit is contained in:
parent
05f0b707d1
commit
e78e5ccfaa
7 changed files with 36 additions and 2 deletions
|
@ -31,6 +31,7 @@ The sandbox cluster installation is running under the constant load generated by
|
||||||
* SECURITY: upgrade Go builder from Go1.21.6 to Go1.21.7. See [the list of issues addressed in Go1.21.7](https://github.com/golang/go/issues?q=milestone%3AGo1.21.7+label%3ACherryPickApproved).
|
* SECURITY: upgrade Go builder from Go1.21.6 to Go1.21.7. See [the list of issues addressed in Go1.21.7](https://github.com/golang/go/issues?q=milestone%3AGo1.21.7+label%3ACherryPickApproved).
|
||||||
|
|
||||||
* FEATURE: all VictoriaMetrics components: add support for TLS client certificate verification at `-httpListenAddr` (aka [mTLS](https://en.wikipedia.org/wiki/Mutual_authentication)). See [these docs](https://docs.victoriametrics.com/#mtls-protection). See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5458).
|
* FEATURE: all VictoriaMetrics components: add support for TLS client certificate verification at `-httpListenAddr` (aka [mTLS](https://en.wikipedia.org/wiki/Mutual_authentication)). See [these docs](https://docs.victoriametrics.com/#mtls-protection). See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5458).
|
||||||
|
* FEATURE: all VictoriaMetrics components: add support for empty command flag values in short array notation. For example, `-remoteWrite.sendTimeout=',20s,'` specifies three `-remoteWrite.sendTimeout` values - the first and the last ones are default values (`30s` in this case), while the second one is `20s`.
|
||||||
* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html) and [single-node VictoriaMetrics](https://docs.victoriametrics.com): add support for data ingestion via [DataDog lambda extension](https://docs.datadoghq.com/serverless/libraries_integrations/extension/) aka `/api/beta/sketches` endpoint. See [these docs](https://docs.victoriametrics.com/#how-to-send-data-from-datadog-agent) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3091). Thanks to @AndrewChubatiuk for [the pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5584).
|
* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html) and [single-node VictoriaMetrics](https://docs.victoriametrics.com): add support for data ingestion via [DataDog lambda extension](https://docs.datadoghq.com/serverless/libraries_integrations/extension/) aka `/api/beta/sketches` endpoint. See [these docs](https://docs.victoriametrics.com/#how-to-send-data-from-datadog-agent) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3091). Thanks to @AndrewChubatiuk for [the pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5584).
|
||||||
* FEATURE: [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): add `-disableReroutingOnUnavailable` command-line flag, which can be used for reducing resource usage spikes at `vmstorage` nodes during rolling restart. Thanks to @Muxa1L for [the pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5713).
|
* FEATURE: [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): add `-disableReroutingOnUnavailable` command-line flag, which can be used for reducing resource usage spikes at `vmstorage` nodes during rolling restart. Thanks to @Muxa1L for [the pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5713).
|
||||||
* FEATURE: [dashboards/vmagent](https://grafana.com/grafana/dashboards/12683): add `Targets scraped/s` stat panel showing the number of targets scraped by the vmagent per-second.
|
* FEATURE: [dashboards/vmagent](https://grafana.com/grafana/dashboards/12683): add `Targets scraped/s` stat panel showing the number of targets scraped by the vmagent per-second.
|
||||||
|
|
|
@ -21,6 +21,7 @@ func NewArrayString(name, description string) *ArrayString {
|
||||||
func NewArrayDuration(name string, defaultValue time.Duration, description string) *ArrayDuration {
|
func NewArrayDuration(name string, defaultValue time.Duration, description string) *ArrayDuration {
|
||||||
description += fmt.Sprintf(" (default %s)", defaultValue)
|
description += fmt.Sprintf(" (default %s)", defaultValue)
|
||||||
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
||||||
|
description += "\nEmpty values are set to default value."
|
||||||
a := &ArrayDuration{
|
a := &ArrayDuration{
|
||||||
defaultValue: defaultValue,
|
defaultValue: defaultValue,
|
||||||
}
|
}
|
||||||
|
@ -31,6 +32,7 @@ func NewArrayDuration(name string, defaultValue time.Duration, description strin
|
||||||
// NewArrayBool returns new ArrayBool with the given name and description.
|
// NewArrayBool returns new ArrayBool with the given name and description.
|
||||||
func NewArrayBool(name, description string) *ArrayBool {
|
func NewArrayBool(name, description string) *ArrayBool {
|
||||||
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
||||||
|
description += "\nEmpty values are set to false."
|
||||||
var a ArrayBool
|
var a ArrayBool
|
||||||
flag.Var(&a, name, description)
|
flag.Var(&a, name, description)
|
||||||
return &a
|
return &a
|
||||||
|
@ -40,6 +42,7 @@ func NewArrayBool(name, description string) *ArrayBool {
|
||||||
func NewArrayInt(name string, defaultValue int, description string) *ArrayInt {
|
func NewArrayInt(name string, defaultValue int, description string) *ArrayInt {
|
||||||
description += fmt.Sprintf(" (default %d)", defaultValue)
|
description += fmt.Sprintf(" (default %d)", defaultValue)
|
||||||
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
||||||
|
description += "\nEmpty values are set to default value."
|
||||||
a := &ArrayInt{
|
a := &ArrayInt{
|
||||||
defaultValue: defaultValue,
|
defaultValue: defaultValue,
|
||||||
}
|
}
|
||||||
|
@ -52,6 +55,7 @@ func NewArrayBytes(name string, defaultValue int64, description string) *ArrayBy
|
||||||
description += "\nSupports the following optional suffixes for size values: KB, MB, GB, TB, KiB, MiB, GiB, TiB."
|
description += "\nSupports the following optional suffixes for size values: KB, MB, GB, TB, KiB, MiB, GiB, TiB."
|
||||||
description += fmt.Sprintf(" (default %d)", defaultValue)
|
description += fmt.Sprintf(" (default %d)", defaultValue)
|
||||||
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
||||||
|
description += "\nEmpty values are set to default value."
|
||||||
a := &ArrayBytes{
|
a := &ArrayBytes{
|
||||||
defaultValue: defaultValue,
|
defaultValue: defaultValue,
|
||||||
}
|
}
|
||||||
|
@ -241,6 +245,9 @@ func (a *ArrayBool) String() string {
|
||||||
func (a *ArrayBool) Set(value string) error {
|
func (a *ArrayBool) Set(value string) error {
|
||||||
values := parseArrayValues(value)
|
values := parseArrayValues(value)
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
|
if v == "" {
|
||||||
|
v = "false"
|
||||||
|
}
|
||||||
b, err := strconv.ParseBool(v)
|
b, err := strconv.ParseBool(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -284,6 +291,9 @@ func (a *ArrayDuration) String() string {
|
||||||
func (a *ArrayDuration) Set(value string) error {
|
func (a *ArrayDuration) Set(value string) error {
|
||||||
values := parseArrayValues(value)
|
values := parseArrayValues(value)
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
|
if v == "" {
|
||||||
|
v = a.defaultValue.String()
|
||||||
|
}
|
||||||
b, err := time.ParseDuration(v)
|
b, err := time.ParseDuration(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -332,6 +342,9 @@ func (a *ArrayInt) String() string {
|
||||||
func (a *ArrayInt) Set(value string) error {
|
func (a *ArrayInt) Set(value string) error {
|
||||||
values := parseArrayValues(value)
|
values := parseArrayValues(value)
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
|
if v == "" {
|
||||||
|
v = fmt.Sprintf("%d", a.defaultValue)
|
||||||
|
}
|
||||||
n, err := strconv.Atoi(v)
|
n, err := strconv.Atoi(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -376,6 +389,9 @@ func (a *ArrayBytes) Set(value string) error {
|
||||||
values := parseArrayValues(value)
|
values := parseArrayValues(value)
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
var b Bytes
|
var b Bytes
|
||||||
|
if v == "" {
|
||||||
|
v = fmt.Sprintf("%d", a.defaultValue)
|
||||||
|
}
|
||||||
if err := b.Set(v); err != nil {
|
if err := b.Set(v); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,6 +165,7 @@ func TestArrayDuration_Set(t *testing.T) {
|
||||||
f := func(s, expectedResult string) {
|
f := func(s, expectedResult string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayDuration
|
var a ArrayDuration
|
||||||
|
a.defaultValue = 42 * time.Second
|
||||||
if err := a.Set(s); err != nil {
|
if err := a.Set(s); err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -176,6 +177,7 @@ func TestArrayDuration_Set(t *testing.T) {
|
||||||
f("", "")
|
f("", "")
|
||||||
f(`1m`, `1m0s`)
|
f(`1m`, `1m0s`)
|
||||||
f(`5m,1s,1h`, `5m0s,1s,1h0m0s`)
|
f(`5m,1s,1h`, `5m0s,1s,1h0m0s`)
|
||||||
|
f(`5m,,1h`, `5m0s,42s,1h0m0s`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayDuration_GetOptionalArg(t *testing.T) {
|
func TestArrayDuration_GetOptionalArg(t *testing.T) {
|
||||||
|
@ -238,6 +240,7 @@ func TestArrayBool_Set(t *testing.T) {
|
||||||
f("", "")
|
f("", "")
|
||||||
f(`true`, `true`)
|
f(`true`, `true`)
|
||||||
f(`false,True,False`, `false,true,false`)
|
f(`false,True,False`, `false,true,false`)
|
||||||
|
f(`1,,False`, `true,false,false`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayBool_GetOptionalArg(t *testing.T) {
|
func TestArrayBool_GetOptionalArg(t *testing.T) {
|
||||||
|
@ -289,6 +292,7 @@ func TestArrayInt_Set(t *testing.T) {
|
||||||
f := func(s, expectedResult string, expectedValues []int) {
|
f := func(s, expectedResult string, expectedValues []int) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayInt
|
var a ArrayInt
|
||||||
|
a.defaultValue = 42
|
||||||
if err := a.Set(s); err != nil {
|
if err := a.Set(s); err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -304,6 +308,7 @@ func TestArrayInt_Set(t *testing.T) {
|
||||||
f("", "", nil)
|
f("", "", nil)
|
||||||
f(`1`, `1`, []int{1})
|
f(`1`, `1`, []int{1})
|
||||||
f(`-2,3,-64`, `-2,3,-64`, []int{-2, 3, -64})
|
f(`-2,3,-64`, `-2,3,-64`, []int{-2, 3, -64})
|
||||||
|
f(`,,-64,`, `42,42,-64,42`, []int{42, 42, -64, 42})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayInt_GetOptionalArg(t *testing.T) {
|
func TestArrayInt_GetOptionalArg(t *testing.T) {
|
||||||
|
@ -357,6 +362,7 @@ func TestArrayBytes_Set(t *testing.T) {
|
||||||
f := func(s, expectedResult string) {
|
f := func(s, expectedResult string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayBytes
|
var a ArrayBytes
|
||||||
|
a.defaultValue = 42
|
||||||
if err := a.Set(s); err != nil {
|
if err := a.Set(s); err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -368,6 +374,7 @@ func TestArrayBytes_Set(t *testing.T) {
|
||||||
f("", "")
|
f("", "")
|
||||||
f(`1`, `1`)
|
f(`1`, `1`)
|
||||||
f(`-2,3,10kb`, `-2,3,10KB`)
|
f(`-2,3,10kb`, `-2,3,10KB`)
|
||||||
|
f(`,,10kb`, `42,42,10KB`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayBytes_GetOptionalArg(t *testing.T) {
|
func TestArrayBytes_GetOptionalArg(t *testing.T) {
|
||||||
|
|
|
@ -47,6 +47,11 @@ func (b *Bytes) String() string {
|
||||||
|
|
||||||
// Set implements flag.Value interface
|
// Set implements flag.Value interface
|
||||||
func (b *Bytes) Set(value string) error {
|
func (b *Bytes) Set(value string) error {
|
||||||
|
if value == "" {
|
||||||
|
b.N = 0
|
||||||
|
b.valueString = ""
|
||||||
|
return nil
|
||||||
|
}
|
||||||
value = normalizeBytesString(value)
|
value = normalizeBytesString(value)
|
||||||
switch {
|
switch {
|
||||||
case strings.HasSuffix(value, "KB"):
|
case strings.HasSuffix(value, "KB"):
|
||||||
|
|
|
@ -12,7 +12,6 @@ func TestBytesSetFailure(t *testing.T) {
|
||||||
t.Fatalf("expecting non-nil error in b.Set(%q)", value)
|
t.Fatalf("expecting non-nil error in b.Set(%q)", value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("")
|
|
||||||
f("foobar")
|
f("foobar")
|
||||||
f("5foobar")
|
f("5foobar")
|
||||||
f("aKB")
|
f("aKB")
|
||||||
|
@ -39,6 +38,7 @@ func TestBytesSetSuccess(t *testing.T) {
|
||||||
t.Fatalf("unexpected valueString; got %q; want %q", valueString, valueExpected)
|
t.Fatalf("unexpected valueString; got %q; want %q", valueString, valueExpected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
f("", 0)
|
||||||
f("0", 0)
|
f("0", 0)
|
||||||
f("1", 1)
|
f("1", 1)
|
||||||
f("-1234", -1234)
|
f("-1234", -1234)
|
||||||
|
|
|
@ -49,6 +49,11 @@ func (d *Duration) String() string {
|
||||||
|
|
||||||
// Set implements flag.Value interface
|
// Set implements flag.Value interface
|
||||||
func (d *Duration) Set(value string) error {
|
func (d *Duration) Set(value string) error {
|
||||||
|
if value == "" {
|
||||||
|
d.msecs = 0
|
||||||
|
d.valueString = ""
|
||||||
|
return nil
|
||||||
|
}
|
||||||
// An attempt to parse value in months.
|
// An attempt to parse value in months.
|
||||||
months, err := strconv.ParseFloat(value, 64)
|
months, err := strconv.ParseFloat(value, 64)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
|
@ -14,7 +14,6 @@ func TestDurationSetFailure(t *testing.T) {
|
||||||
t.Fatalf("expecting non-nil error in d.Set(%q)", value)
|
t.Fatalf("expecting non-nil error in d.Set(%q)", value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("")
|
|
||||||
f("foobar")
|
f("foobar")
|
||||||
f("5foobar")
|
f("5foobar")
|
||||||
f("ah")
|
f("ah")
|
||||||
|
@ -51,6 +50,7 @@ func TestDurationSetSuccess(t *testing.T) {
|
||||||
t.Fatalf("unexpected valueString; got %q; want %q", valueString, valueExpected)
|
t.Fatalf("unexpected valueString; got %q; want %q", valueString, valueExpected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
f("", 0)
|
||||||
f("0", 0)
|
f("0", 0)
|
||||||
f("1", msecsPer31Days)
|
f("1", msecsPer31Days)
|
||||||
f("123.456", 123.456*msecsPer31Days)
|
f("123.456", 123.456*msecsPer31Days)
|
||||||
|
|
Loading…
Reference in a new issue