lib/flagutil: rename Array to ArrayString

This makes the ArrayString more consistent with other Array* types.

While at it, add ArrayBytes type, which will be used for https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3071
This commit is contained in:
Aliaksandr Valialkin 2022-10-01 18:26:05 +03:00
parent b57ca71eb2
commit 6f9ce3f6d6
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
13 changed files with 220 additions and 123 deletions

View file

@ -24,46 +24,46 @@ var (
"By default the rate limit is disabled. It can be useful for limiting load on remote storage when big amounts of buffered data "+
"is sent after temporary unavailability of the remote storage")
sendTimeout = flagutil.NewArrayDuration("remoteWrite.sendTimeout", "Timeout for sending a single block of data to the corresponding -remoteWrite.url")
proxyURL = flagutil.NewArray("remoteWrite.proxyURL", "Optional proxy URL for writing data to the corresponding -remoteWrite.url. "+
proxyURL = flagutil.NewArrayString("remoteWrite.proxyURL", "Optional proxy URL for writing data to the corresponding -remoteWrite.url. "+
"Supported proxies: http, https, socks5. Example: -remoteWrite.proxyURL=socks5://proxy:1234")
tlsInsecureSkipVerify = flagutil.NewArrayBool("remoteWrite.tlsInsecureSkipVerify", "Whether to skip tls verification when connecting to the corresponding -remoteWrite.url")
tlsCertFile = flagutil.NewArray("remoteWrite.tlsCertFile", "Optional path to client-side TLS certificate file to use when connecting "+
tlsCertFile = flagutil.NewArrayString("remoteWrite.tlsCertFile", "Optional path to client-side TLS certificate file to use when connecting "+
"to the corresponding -remoteWrite.url")
tlsKeyFile = flagutil.NewArray("remoteWrite.tlsKeyFile", "Optional path to client-side TLS certificate key to use when connecting to the corresponding -remoteWrite.url")
tlsCAFile = flagutil.NewArray("remoteWrite.tlsCAFile", "Optional path to TLS CA file to use for verifying connections to the corresponding -remoteWrite.url. "+
tlsKeyFile = flagutil.NewArrayString("remoteWrite.tlsKeyFile", "Optional path to client-side TLS certificate key to use when connecting to the corresponding -remoteWrite.url")
tlsCAFile = flagutil.NewArrayString("remoteWrite.tlsCAFile", "Optional path to TLS CA file to use for verifying connections to the corresponding -remoteWrite.url. "+
"By default system CA is used")
tlsServerName = flagutil.NewArray("remoteWrite.tlsServerName", "Optional TLS server name to use for connections to the corresponding -remoteWrite.url. "+
tlsServerName = flagutil.NewArrayString("remoteWrite.tlsServerName", "Optional TLS server name to use for connections to the corresponding -remoteWrite.url. "+
"By default the server name from -remoteWrite.url is used")
headers = flagutil.NewArray("remoteWrite.headers", "Optional HTTP headers to send with each request to the corresponding -remoteWrite.url. "+
headers = flagutil.NewArrayString("remoteWrite.headers", "Optional HTTP headers to send with each request to the corresponding -remoteWrite.url. "+
"For example, -remoteWrite.headers='My-Auth:foobar' would send 'My-Auth: foobar' HTTP header with every request to the corresponding -remoteWrite.url. "+
"Multiple headers must be delimited by '^^': -remoteWrite.headers='header1:value1^^header2:value2'")
basicAuthUsername = flagutil.NewArray("remoteWrite.basicAuth.username", "Optional basic auth username to use for the corresponding -remoteWrite.url")
basicAuthPassword = flagutil.NewArray("remoteWrite.basicAuth.password", "Optional basic auth password to use for the corresponding -remoteWrite.url")
basicAuthPasswordFile = flagutil.NewArray("remoteWrite.basicAuth.passwordFile", "Optional path to basic auth password to use for the corresponding -remoteWrite.url. "+
basicAuthUsername = flagutil.NewArrayString("remoteWrite.basicAuth.username", "Optional basic auth username to use for the corresponding -remoteWrite.url")
basicAuthPassword = flagutil.NewArrayString("remoteWrite.basicAuth.password", "Optional basic auth password to use for the corresponding -remoteWrite.url")
basicAuthPasswordFile = flagutil.NewArrayString("remoteWrite.basicAuth.passwordFile", "Optional path to basic auth password to use for the corresponding -remoteWrite.url. "+
"The file is re-read every second")
bearerToken = flagutil.NewArray("remoteWrite.bearerToken", "Optional bearer auth token to use for the corresponding -remoteWrite.url")
bearerTokenFile = flagutil.NewArray("remoteWrite.bearerTokenFile", "Optional path to bearer token file to use for the corresponding -remoteWrite.url. "+
bearerToken = flagutil.NewArrayString("remoteWrite.bearerToken", "Optional bearer auth token to use for the corresponding -remoteWrite.url")
bearerTokenFile = flagutil.NewArrayString("remoteWrite.bearerTokenFile", "Optional path to bearer token file to use for the corresponding -remoteWrite.url. "+
"The token is re-read from the file every second")
oauth2ClientID = flagutil.NewArray("remoteWrite.oauth2.clientID", "Optional OAuth2 clientID to use for the corresponding -remoteWrite.url")
oauth2ClientSecret = flagutil.NewArray("remoteWrite.oauth2.clientSecret", "Optional OAuth2 clientSecret to use for the corresponding -remoteWrite.url")
oauth2ClientSecretFile = flagutil.NewArray("remoteWrite.oauth2.clientSecretFile", "Optional OAuth2 clientSecretFile to use for the corresponding -remoteWrite.url")
oauth2TokenURL = flagutil.NewArray("remoteWrite.oauth2.tokenUrl", "Optional OAuth2 tokenURL to use for the corresponding -remoteWrite.url")
oauth2Scopes = flagutil.NewArray("remoteWrite.oauth2.scopes", "Optional OAuth2 scopes to use for the corresponding -remoteWrite.url. Scopes must be delimited by ';'")
oauth2ClientID = flagutil.NewArrayString("remoteWrite.oauth2.clientID", "Optional OAuth2 clientID to use for the corresponding -remoteWrite.url")
oauth2ClientSecret = flagutil.NewArrayString("remoteWrite.oauth2.clientSecret", "Optional OAuth2 clientSecret to use for the corresponding -remoteWrite.url")
oauth2ClientSecretFile = flagutil.NewArrayString("remoteWrite.oauth2.clientSecretFile", "Optional OAuth2 clientSecretFile to use for the corresponding -remoteWrite.url")
oauth2TokenURL = flagutil.NewArrayString("remoteWrite.oauth2.tokenUrl", "Optional OAuth2 tokenURL to use for the corresponding -remoteWrite.url")
oauth2Scopes = flagutil.NewArrayString("remoteWrite.oauth2.scopes", "Optional OAuth2 scopes to use for the corresponding -remoteWrite.url. Scopes must be delimited by ';'")
awsUseSigv4 = flagutil.NewArrayBool("remoteWrite.aws.useSigv4", "Enables SigV4 request signing for the corresponding -remoteWrite.url. "+
"It is expected that other -remoteWrite.aws.* command-line flags are set if sigv4 request signing is enabled")
awsEC2Endpoint = flagutil.NewArray("remoteWrite.aws.ec2Endpoint", "Optional AWS EC2 API endpoint to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsSTSEndpoint = flagutil.NewArray("remoteWrite.aws.stsEndpoint", "Optional AWS STS API endpoint to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsRegion = flagutil.NewArray("remoteWrite.aws.region", "Optional AWS region to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsRoleARN = flagutil.NewArray("remoteWrite.aws.roleARN", "Optional AWS roleARN to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsAccessKey = flagutil.NewArray("remoteWrite.aws.accessKey", "Optional AWS AccessKey to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsService = flagutil.NewArray("remoteWrite.aws.service", "Optional AWS Service to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set. "+
awsEC2Endpoint = flagutil.NewArrayString("remoteWrite.aws.ec2Endpoint", "Optional AWS EC2 API endpoint to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsSTSEndpoint = flagutil.NewArrayString("remoteWrite.aws.stsEndpoint", "Optional AWS STS API endpoint to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsRegion = flagutil.NewArrayString("remoteWrite.aws.region", "Optional AWS region to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsRoleARN = flagutil.NewArrayString("remoteWrite.aws.roleARN", "Optional AWS roleARN to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsAccessKey = flagutil.NewArrayString("remoteWrite.aws.accessKey", "Optional AWS AccessKey to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsService = flagutil.NewArrayString("remoteWrite.aws.service", "Optional AWS Service to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set. "+
"Defaults to \"aps\"")
awsSecretKey = flagutil.NewArray("remoteWrite.aws.secretKey", "Optional AWS SecretKey to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsSecretKey = flagutil.NewArrayString("remoteWrite.aws.secretKey", "Optional AWS SecretKey to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
)
type client struct {

View file

@ -13,14 +13,14 @@ import (
)
var (
unparsedLabelsGlobal = flagutil.NewArray("remoteWrite.label", "Optional label in the form 'name=value' to add to all the metrics before sending them to -remoteWrite.url. "+
unparsedLabelsGlobal = flagutil.NewArrayString("remoteWrite.label", "Optional label in the form 'name=value' to add to all the metrics before sending them to -remoteWrite.url. "+
"Pass multiple -remoteWrite.label flags in order to add multiple labels to metrics before sending them to remote storage")
relabelConfigPathGlobal = flag.String("remoteWrite.relabelConfig", "", "Optional path to file with relabel_config entries. "+
"The path can point either to local file or to http url. These entries are applied to all the metrics "+
"before sending them to -remoteWrite.url. See https://docs.victoriametrics.com/vmagent.html#relabeling for details")
relabelDebugGlobal = flag.Bool("remoteWrite.relabelDebug", false, "Whether to log metrics before and after relabeling with -remoteWrite.relabelConfig. "+
"If the -remoteWrite.relabelDebug is enabled, then the metrics aren't sent to remote storage. This is useful for debugging the relabeling configs")
relabelConfigPaths = flagutil.NewArray("remoteWrite.urlRelabelConfig", "Optional path to relabel config for the corresponding -remoteWrite.url. "+
relabelConfigPaths = flagutil.NewArrayString("remoteWrite.urlRelabelConfig", "Optional path to relabel config for the corresponding -remoteWrite.url. "+
"The path can point either to local file or to http url")
relabelDebug = flagutil.NewArrayBool("remoteWrite.urlRelabelDebug", "Whether to log metrics before and after relabeling with -remoteWrite.urlRelabelConfig. "+
"If the -remoteWrite.urlRelabelDebug is enabled, then the metrics aren't sent to the corresponding -remoteWrite.url. "+

View file

@ -26,10 +26,10 @@ import (
)
var (
remoteWriteURLs = flagutil.NewArray("remoteWrite.url", "Remote storage URL to write data to. It must support Prometheus remote_write API. "+
remoteWriteURLs = flagutil.NewArrayString("remoteWrite.url", "Remote storage URL to write data to. It must support Prometheus remote_write API. "+
"It is recommended using VictoriaMetrics as remote storage. Example url: http://<victoriametrics-host>:8428/api/v1/write . "+
"Pass multiple -remoteWrite.url flags in order to replicate data to multiple remote storage systems. See also -remoteWrite.multitenantURL")
remoteWriteMultitenantURLs = flagutil.NewArray("remoteWrite.multitenantURL", "Base path for multitenant remote storage URL to write data to. "+
remoteWriteMultitenantURLs = flagutil.NewArrayString("remoteWrite.multitenantURL", "Base path for multitenant remote storage URL to write data to. "+
"See https://docs.victoriametrics.com/vmagent.html#multitenancy for details. Example url: http://<vminsert>:8480 . "+
"Pass multiple -remoteWrite.multitenantURL flags in order to replicate data to multiple remote storage systems. See also -remoteWrite.url")
tmpDataPath = flag.String("remoteWrite.tmpDataPath", "vmagent-remotewrite-data", "Path to directory where temporary data for remote write component is stored. "+

View file

@ -28,7 +28,7 @@ import (
)
var (
rulePath = flagutil.NewArray("rule", `Path to the file with alert rules.
rulePath = flagutil.NewArrayString("rule", `Path to the file with alert rules.
Supports patterns. Flag can be specified multiple times.
Examples:
-rule="/path/to/file". Path to a single file with alerting rules
@ -36,7 +36,7 @@ Examples:
absolute path to all .yaml files in root.
Rule files may contain %{ENV_VAR} placeholders, which are substituted by the corresponding env vars.`)
ruleTemplatesPath = flagutil.NewArray("rule.templates", `Path or glob pattern to location with go template definitions
ruleTemplatesPath = flagutil.NewArrayString("rule.templates", `Path or glob pattern to location with go template definitions
for rules annotations templating. Flag can be specified multiple times.
Examples:
-rule.templates="/path/to/file". Path to a single file with go templates
@ -62,7 +62,7 @@ absolute path to all .tpl files in root.`)
externalAlertSource = flag.String("external.alert.source", "", `External Alert Source allows to override the Source link for alerts sent to AlertManager for cases where you want to build a custom link to Grafana, Prometheus or any other service.
Supports templating. For example, link to Grafana: 'explore?orgId=1&left=[\"now-1h\",\"now\",\"VictoriaMetrics\",{\"expr\": \"{{$expr|quotesEscape|crlfEscape|queryEscape}}\"},{\"mode\":\"Metrics\"},{\"ui\":[true,true,true,\"none\"]}]'.
If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used.`)
externalLabels = flagutil.NewArray("external.label", "Optional label in the form 'Name=value' to add to all generated recording rules and alerts. "+
externalLabels = flagutil.NewArrayString("external.label", "Optional label in the form 'Name=value' to add to all generated recording rules and alerts. "+
"Pass multiple -label flags in order to add multiple label sets.")
remoteReadLookBack = flag.Duration("remoteRead.lookback", time.Hour, "Lookback defines how far to look into past for alerts timeseries."+

View file

@ -17,32 +17,32 @@ var (
configPath = flag.String("notifier.config", "", "Path to configuration file for notifiers")
suppressDuplicateTargetErrors = flag.Bool("notifier.suppressDuplicateTargetErrors", false, "Whether to suppress 'duplicate target' errors during discovery")
addrs = flagutil.NewArray("notifier.url", "Prometheus alertmanager URL, e.g. http://127.0.0.1:9093")
addrs = flagutil.NewArrayString("notifier.url", "Prometheus alertmanager URL, e.g. http://127.0.0.1:9093")
basicAuthUsername = flagutil.NewArray("notifier.basicAuth.username", "Optional basic auth username for -notifier.url")
basicAuthPassword = flagutil.NewArray("notifier.basicAuth.password", "Optional basic auth password for -notifier.url")
basicAuthPasswordFile = flagutil.NewArray("notifier.basicAuth.passwordFile", "Optional path to basic auth password file for -notifier.url")
basicAuthUsername = flagutil.NewArrayString("notifier.basicAuth.username", "Optional basic auth username for -notifier.url")
basicAuthPassword = flagutil.NewArrayString("notifier.basicAuth.password", "Optional basic auth password for -notifier.url")
basicAuthPasswordFile = flagutil.NewArrayString("notifier.basicAuth.passwordFile", "Optional path to basic auth password file for -notifier.url")
bearerToken = flagutil.NewArray("notifier.bearerToken", "Optional bearer token for -notifier.url")
bearerTokenFile = flagutil.NewArray("notifier.bearerTokenFile", "Optional path to bearer token file for -notifier.url")
bearerToken = flagutil.NewArrayString("notifier.bearerToken", "Optional bearer token for -notifier.url")
bearerTokenFile = flagutil.NewArrayString("notifier.bearerTokenFile", "Optional path to bearer token file for -notifier.url")
tlsInsecureSkipVerify = flagutil.NewArrayBool("notifier.tlsInsecureSkipVerify", "Whether to skip tls verification when connecting to -notifier.url")
tlsCertFile = flagutil.NewArray("notifier.tlsCertFile", "Optional path to client-side TLS certificate file to use when connecting to -notifier.url")
tlsKeyFile = flagutil.NewArray("notifier.tlsKeyFile", "Optional path to client-side TLS certificate key to use when connecting to -notifier.url")
tlsCAFile = flagutil.NewArray("notifier.tlsCAFile", "Optional path to TLS CA file to use for verifying connections to -notifier.url. "+
tlsCertFile = flagutil.NewArrayString("notifier.tlsCertFile", "Optional path to client-side TLS certificate file to use when connecting to -notifier.url")
tlsKeyFile = flagutil.NewArrayString("notifier.tlsKeyFile", "Optional path to client-side TLS certificate key to use when connecting to -notifier.url")
tlsCAFile = flagutil.NewArrayString("notifier.tlsCAFile", "Optional path to TLS CA file to use for verifying connections to -notifier.url. "+
"By default system CA is used")
tlsServerName = flagutil.NewArray("notifier.tlsServerName", "Optional TLS server name to use for connections to -notifier.url. "+
tlsServerName = flagutil.NewArrayString("notifier.tlsServerName", "Optional TLS server name to use for connections to -notifier.url. "+
"By default the server name from -notifier.url is used")
oauth2ClientID = flagutil.NewArray("notifier.oauth2.clientID", "Optional OAuth2 clientID to use for -notifier.url. "+
oauth2ClientID = flagutil.NewArrayString("notifier.oauth2.clientID", "Optional OAuth2 clientID to use for -notifier.url. "+
"If multiple args are set, then they are applied independently for the corresponding -notifier.url")
oauth2ClientSecret = flagutil.NewArray("notifier.oauth2.clientSecret", "Optional OAuth2 clientSecret to use for -notifier.url. "+
oauth2ClientSecret = flagutil.NewArrayString("notifier.oauth2.clientSecret", "Optional OAuth2 clientSecret to use for -notifier.url. "+
"If multiple args are set, then they are applied independently for the corresponding -notifier.url")
oauth2ClientSecretFile = flagutil.NewArray("notifier.oauth2.clientSecretFile", "Optional OAuth2 clientSecretFile to use for -notifier.url. "+
oauth2ClientSecretFile = flagutil.NewArrayString("notifier.oauth2.clientSecretFile", "Optional OAuth2 clientSecretFile to use for -notifier.url. "+
"If multiple args are set, then they are applied independently for the corresponding -notifier.url")
oauth2TokenURL = flagutil.NewArray("notifier.oauth2.tokenUrl", "Optional OAuth2 tokenURL to use for -notifier.url. "+
oauth2TokenURL = flagutil.NewArrayString("notifier.oauth2.tokenUrl", "Optional OAuth2 tokenURL to use for -notifier.url. "+
"If multiple args are set, then they are applied independently for the corresponding -notifier.url")
oauth2Scopes = flagutil.NewArray("notifier.oauth2.scopes", "Optional OAuth2 scopes to use for -notifier.url. Scopes must be delimited by ';'. "+
oauth2Scopes = flagutil.NewArrayString("notifier.oauth2.scopes", "Optional OAuth2 scopes to use for -notifier.url. Scopes must be delimited by ';'. "+
"If multiple args are set, then they are applied independently for the corresponding -notifier.url")
)

View file

@ -58,7 +58,7 @@ var (
httpListenAddr = flag.String("httpListenAddr", ":8480", "Address to listen for http connections")
maxLabelsPerTimeseries = flag.Int("maxLabelsPerTimeseries", 30, "The maximum number of labels accepted per time series. Superfluous labels are dropped. In this case the vm_metrics_with_dropped_labels_total metric at /metrics page is incremented")
maxLabelValueLen = flag.Int("maxLabelValueLen", 16*1024, "The maximum length of label values in the accepted time series. Longer label values are truncated. In this case the vm_too_long_label_values_total metric at /metrics page is incremented")
storageNodes = flagutil.NewArray("storageNode", "Comma-separated addresses of vmstorage nodes; usage: -storageNode=vmstorage-host1,...,vmstorage-hostN")
storageNodes = flagutil.NewArrayString("storageNode", "Comma-separated addresses of vmstorage nodes; usage: -storageNode=vmstorage-host1,...,vmstorage-hostN")
)
var (

View file

@ -48,7 +48,7 @@ var (
resetCacheAuthKey = flag.String("search.resetCacheAuthKey", "", "Optional authKey for resetting rollup cache via /internal/resetRollupResultCache call")
logSlowQueryDuration = flag.Duration("search.logSlowQueryDuration", 5*time.Second, "Log queries with execution time exceeding this value. Zero disables slow query logging")
vmalertProxyURL = flag.String("vmalert.proxyURL", "", "Optional URL for proxying requests to vmalert. For example, if -vmalert.proxyURL=http://vmalert:8880 , then alerting API requests such as /api/v1/rules from Grafana will be proxied to http://vmalert:8880/api/v1/rules")
storageNodes = flagutil.NewArray("storageNode", "Comma-separated addresses of vmstorage nodes; usage: -storageNode=vmstorage-host1,...,vmstorage-hostN")
storageNodes = flagutil.NewArrayString("storageNode", "Comma-separated addresses of vmstorage nodes; usage: -storageNode=vmstorage-host1,...,vmstorage-hostN")
clusternativeListenAddr = flag.String("clusternativeListenAddr", "", "TCP address to listen for requests from other vmselect nodes in multi-level cluster setup. "+
"See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#multi-level-cluster-setup . Usually :8401 must be set. Doesn't work if empty")

View file

@ -46,7 +46,7 @@ var (
"If set to true, the query model becomes closer to InfluxDB data model. If set to true, then -search.maxLookback and -search.maxStalenessInterval are ignored")
maxStepForPointsAdjustment = flag.Duration("search.maxStepForPointsAdjustment", time.Minute, "The maximum step when /api/v1/query_range handler adjusts "+
"points with timestamps closer than -search.latencyOffset to the current time. The adjustment is needed because such points may contain incomplete data")
selectNodes = flagutil.NewArray("selectNode", "Comma-separated addresses of vmselect nodes; usage: -selectNode=vmselect-host1,...,vmselect-hostN")
selectNodes = flagutil.NewArrayString("selectNode", "Comma-separated addresses of vmselect nodes; usage: -selectNode=vmselect-host1,...,vmselect-hostN")
maxUniqueTimeseries = flag.Int("search.maxUniqueTimeseries", 300e3, "The maximum number of unique time series, which can be selected during /api/v1/query and /api/v1/query_range queries. This option allows limiting memory usage")
maxFederateSeries = flag.Int("search.maxFederateSeries", 1e6, "The maximum number of time series, which can be returned from /federate. This option allows limiting memory usage")

View file

@ -8,11 +8,11 @@ import (
"time"
)
// NewArray returns new Array with the given name and description.
func NewArray(name, description string) *Array {
// NewArrayString returns new ArrayString with the given name and description.
func NewArrayString(name, description string) *ArrayString {
description += "\nSupports an `array` of values separated by comma" +
" or specified via multiple flags."
var a Array
var a ArrayString
flag.Var(&a, name, description)
return &a
}
@ -36,7 +36,7 @@ func NewArrayBool(name, description string) *ArrayBool {
}
// NewArrayInt returns new ArrayInt with the given name and description.
func NewArrayInt(name string, description string) *ArrayInt {
func NewArrayInt(name, description string) *ArrayInt {
description += "\nSupports `array` of values separated by comma" +
" or specified via multiple flags."
var a ArrayInt
@ -44,7 +44,16 @@ func NewArrayInt(name string, description string) *ArrayInt {
return &a
}
// Array is a flag that holds an array of values.
// NewArrayBytes returns new ArrayBytes with the given name and description.
func NewArrayBytes(name, description string) *ArrayBytes {
description += "\nSupports `array` of values separated by comma" +
" or specified via multiple flags."
var a ArrayBytes
flag.Var(&a, name, description)
return &a
}
// ArrayString is a flag that holds an array of strings.
//
// It may be set either by specifying multiple flags with the given name
// passed to NewArray or by joining flag values by comma.
@ -57,10 +66,10 @@ func NewArrayInt(name string, description string) *ArrayInt {
// Flag values may be quoted. For instance, the following arg creates an array of ("a", "b, c") items:
//
// -foo='a,"b, c"'
type Array []string
type ArrayString []string
// String implements flag.Value interface
func (a *Array) String() string {
func (a *ArrayString) String() string {
aEscaped := make([]string, len(*a))
for i, v := range *a {
if strings.ContainsAny(v, `", `+"\n") {
@ -72,7 +81,7 @@ func (a *Array) String() string {
}
// Set implements flag.Value interface
func (a *Array) Set(value string) error {
func (a *ArrayString) Set(value string) error {
values := parseArrayValues(value)
*a = append(*a, values...)
return nil
@ -141,7 +150,7 @@ func getNextArrayValue(s string) (string, string) {
}
// GetOptionalArg returns optional arg under the given argIdx.
func (a *Array) GetOptionalArg(argIdx int) string {
func (a *ArrayString) GetOptionalArg(argIdx int) string {
x := *a
if argIdx >= len(x) {
if len(x) == 1 {
@ -153,7 +162,8 @@ func (a *Array) GetOptionalArg(argIdx int) string {
}
// ArrayBool is a flag that holds an array of booleans values.
// have the same api as Array.
//
// Has the same api as ArrayString.
type ArrayBool []bool
// IsBoolFlag implements flag.IsBoolFlag interface
@ -194,7 +204,8 @@ func (a *ArrayBool) GetOptionalArg(argIdx int) bool {
}
// ArrayDuration is a flag that holds an array of time.Duration values.
// have the same api as Array.
//
// Has the same api as ArrayString.
type ArrayDuration []time.Duration
// String implements flag.Value interface
@ -233,6 +244,8 @@ func (a *ArrayDuration) GetOptionalArgOrDefault(argIdx int, defaultValue time.Du
}
// ArrayInt is flag that holds an array of ints.
//
// Has the same api as ArrayString.
type ArrayInt []int
// String implements flag.Value interface
@ -259,7 +272,7 @@ func (a *ArrayInt) Set(value string) error {
}
// GetOptionalArgOrDefault returns optional arg under the given argIdx.
func (a *ArrayInt) GetOptionalArgOrDefault(argIdx int, defaultValue int) int {
func (a *ArrayInt) GetOptionalArgOrDefault(argIdx, defaultValue int) int {
x := *a
if argIdx < len(x) {
return x[argIdx]
@ -269,3 +282,43 @@ func (a *ArrayInt) GetOptionalArgOrDefault(argIdx int, defaultValue int) int {
}
return defaultValue
}
// ArrayBytes is flag that holds an array of Bytes.
//
// Has the same api as ArrayString.
type ArrayBytes []*Bytes
// String implements flag.Value interface
func (a *ArrayBytes) String() string {
x := *a
formattedBytes := make([]string, len(x))
for i, v := range x {
formattedBytes[i] = v.String()
}
return strings.Join(formattedBytes, ",")
}
// Set implemented flag.Value interface
func (a *ArrayBytes) Set(value string) error {
values := parseArrayValues(value)
for _, v := range values {
var b Bytes
if err := b.Set(v); err != nil {
return err
}
*a = append(*a, &b)
}
return nil
}
// GetOptionalArgOrDefault returns optional arg under the given argIdx.
func (a *ArrayBytes) GetOptionalArgOrDefault(argIdx, defaultValue int) int {
x := *a
if argIdx < len(x) {
return x[argIdx].N
}
if len(x) == 1 {
return x[0].N
}
return defaultValue
}

View file

@ -9,21 +9,24 @@ import (
)
var (
fooFlag Array
fooFlagString ArrayString
fooFlagDuration ArrayDuration
fooFlagBool ArrayBool
fooFlagInt ArrayInt
fooFlagBytes ArrayBytes
)
func init() {
os.Args = append(os.Args, "--fooFlag=foo", "--fooFlag=bar")
os.Args = append(os.Args, "--fooFlagDuration=10s", "--fooFlagDuration=5m")
os.Args = append(os.Args, "--fooFlagBool=true", "--fooFlagBool=false,true", "--fooFlagBool")
os.Args = append(os.Args, "--fooFlagInt=1", "--fooFlagInt=2,3")
flag.Var(&fooFlag, "fooFlag", "test")
os.Args = append(os.Args, "-fooFlagString=foo", "-fooFlagString=bar")
os.Args = append(os.Args, "-fooFlagDuration=10s", "-fooFlagDuration=5m")
os.Args = append(os.Args, "-fooFlagBool=true", "-fooFlagBool=false,true", "-fooFlagBool")
os.Args = append(os.Args, "-fooFlagInt=1", "-fooFlagInt=2,3")
os.Args = append(os.Args, "-fooFlagBytes=10MB", "-fooFlagBytes=23,10kib")
flag.Var(&fooFlagString, "fooFlagString", "test")
flag.Var(&fooFlagDuration, "fooFlagDuration", "test")
flag.Var(&fooFlagBool, "fooFlagBool", "test")
flag.Var(&fooFlagInt, "fooFlagInt", "test")
flag.Var(&fooFlagBytes, "fooFlagBytes", "test")
}
func TestMain(m *testing.M) {
@ -31,25 +34,20 @@ func TestMain(m *testing.M) {
os.Exit(m.Run())
}
func TestArray(t *testing.T) {
expected := []string{
func TestArrayString(t *testing.T) {
expected := ArrayString{
"foo",
"bar",
}
if len(expected) != len(fooFlag) {
t.Errorf("len array flag (%d) is not equal to %d", len(fooFlag), len(expected))
}
for i, v := range fooFlag {
if v != expected[i] {
t.Errorf("unexpected item in array %q", v)
}
if !reflect.DeepEqual(expected, fooFlagString) {
t.Fatalf("unexpected flag values; got\n%q\nwant\n%q", fooFlagString, expected)
}
}
func TestArraySet(t *testing.T) {
func TestArrayString_Set(t *testing.T) {
f := func(s string, expectedValues []string) {
t.Helper()
var a Array
var a ArrayString
_ = a.Set(s)
if !reflect.DeepEqual([]string(a), expectedValues) {
t.Fatalf("unexpected values parsed;\ngot\n%q\nwant\n%q", a, expectedValues)
@ -66,10 +64,10 @@ func TestArraySet(t *testing.T) {
f(`,fo,"\"b, a'\\",,r,`, []string{``, `fo`, `"b, a'\`, ``, `r`, ``})
}
func TestArrayGetOptionalArg(t *testing.T) {
func TestArrayString_GetOptionalArg(t *testing.T) {
f := func(s string, argIdx int, expectedValue string) {
t.Helper()
var a Array
var a ArrayString
_ = a.Set(s)
v := a.GetOptionalArg(argIdx)
if v != expectedValue {
@ -85,10 +83,10 @@ func TestArrayGetOptionalArg(t *testing.T) {
f("foo,bar", 2, "")
}
func TestArrayString(t *testing.T) {
func TestArrayString_String(t *testing.T) {
f := func(s string) {
t.Helper()
var a Array
var a ArrayString
_ = a.Set(s)
result := a.String()
if result != s {
@ -105,21 +103,16 @@ func TestArrayString(t *testing.T) {
}
func TestArrayDuration(t *testing.T) {
expected := []time.Duration{
expected := ArrayDuration{
time.Second * 10,
time.Minute * 5,
}
if len(expected) != len(fooFlagDuration) {
t.Errorf("len array flag (%d) is not equal to %d", len(fooFlag), len(expected))
}
for i, v := range fooFlagDuration {
if v != expected[i] {
t.Errorf("unexpected item in array %s", v)
}
if !reflect.DeepEqual(expected, fooFlagDuration) {
t.Fatalf("unexpected flag values; got\n%s\nwant\n%s", fooFlagDuration, expected)
}
}
func TestArrayDurationSet(t *testing.T) {
func TestArrayDuration_Set(t *testing.T) {
f := func(s string, expectedValues []time.Duration) {
t.Helper()
var a ArrayDuration
@ -133,8 +126,8 @@ func TestArrayDurationSet(t *testing.T) {
f(`5m,1s,1h`, []time.Duration{time.Minute * 5, time.Second, time.Hour})
}
func TestArrayDurationGetOptionalArg(t *testing.T) {
f := func(s string, argIdx int, expectedValue, defaultValue time.Duration) {
func TestArrayDuration_GetOptionalArg(t *testing.T) {
f := func(s string, argIdx int, defaultValue, expectedValue time.Duration) {
t.Helper()
var a ArrayDuration
_ = a.Set(s)
@ -146,10 +139,10 @@ func TestArrayDurationGetOptionalArg(t *testing.T) {
f("", 0, time.Second, time.Second)
f("", 1, time.Minute, time.Minute)
f("10s,1m", 1, time.Minute, time.Minute)
f("10s", 3, time.Second*10, time.Minute)
f("10s", 3, time.Minute, time.Second*10)
}
func TestArrayDurationString(t *testing.T) {
func TestArrayDuration_String(t *testing.T) {
f := func(s string) {
t.Helper()
var a ArrayDuration
@ -165,20 +158,15 @@ func TestArrayDurationString(t *testing.T) {
}
func TestArrayBool(t *testing.T) {
expected := []bool{
expected := ArrayBool{
true, false, true, true,
}
if len(expected) != len(fooFlagBool) {
t.Errorf("len array flag (%d) is not equal to %d", len(fooFlag), len(expected))
}
for i, v := range fooFlagBool {
if v != expected[i] {
t.Errorf("unexpected item in array index=%v,value=%v,want=%v", i, v, expected[i])
}
if !reflect.DeepEqual(expected, fooFlagBool) {
t.Fatalf("unexpected flag values; got\n%v\nwant\n%v", fooFlagBool, expected)
}
}
func TestArrayBoolSet(t *testing.T) {
func TestArrayBool_Set(t *testing.T) {
f := func(s string, expectedValues []bool) {
t.Helper()
var a ArrayBool
@ -192,7 +180,7 @@ func TestArrayBoolSet(t *testing.T) {
f(`false,True,False`, []bool{false, true, false})
}
func TestArrayBoolGetOptionalArg(t *testing.T) {
func TestArrayBool_GetOptionalArg(t *testing.T) {
f := func(s string, argIdx int, expectedValue bool) {
t.Helper()
var a ArrayBool
@ -208,7 +196,7 @@ func TestArrayBoolGetOptionalArg(t *testing.T) {
f("true", 2, true)
}
func TestArrayBoolString(t *testing.T) {
func TestArrayBool_String(t *testing.T) {
f := func(s string) {
t.Helper()
var a ArrayBool
@ -225,18 +213,13 @@ func TestArrayBoolString(t *testing.T) {
}
func TestArrayInt(t *testing.T) {
expected := []int{1, 2, 3}
if len(expected) != len(fooFlagInt) {
t.Errorf("len array flag (%d) is not equal to %d", len(fooFlag), len(expected))
}
for i, n := range fooFlagInt {
if n != expected[i] {
t.Errorf("unexpected item in array %d", n)
}
expected := ArrayInt{1, 2, 3}
if !reflect.DeepEqual(expected, fooFlagInt) {
t.Fatalf("unexpected flag values; got\n%d\nwant\n%d", fooFlagInt, expected)
}
}
func TestArrayIntSet(t *testing.T) {
func TestArrayInt_Set(t *testing.T) {
f := func(s string, expectedValues []int) {
t.Helper()
var a ArrayInt
@ -250,8 +233,8 @@ func TestArrayIntSet(t *testing.T) {
f(`-2,3,-64`, []int{-2, 3, -64})
}
func TestArrayIntGetOptionalArg(t *testing.T) {
f := func(s string, argIdx int, expectedValue, defaultValue int) {
func TestArrayInt_GetOptionalArg(t *testing.T) {
f := func(s string, argIdx, defaultValue, expectedValue int) {
t.Helper()
var a ArrayInt
_ = a.Set(s)
@ -262,11 +245,11 @@ func TestArrayIntGetOptionalArg(t *testing.T) {
}
f("", 0, 123, 123)
f("", 1, -34, -34)
f("10,1", 1, 1, 234)
f("10", 3, 10, -34)
f("10,1", 1, 234, 1)
f("10", 3, -34, 10)
}
func TestArrayIntString(t *testing.T) {
func TestArrayInt_String(t *testing.T) {
f := func(s string) {
t.Helper()
var a ArrayInt
@ -280,3 +263,64 @@ func TestArrayIntString(t *testing.T) {
f("10,1")
f("-5,1,123")
}
func TestArrayBytes(t *testing.T) {
expected := []int{10000000, 23, 10240}
result := make([]int, len(fooFlagBytes))
for i, b := range fooFlagBytes {
result[i] = b.N
}
if !reflect.DeepEqual(expected, result) {
t.Fatalf("unexpected flag values; got\n%d\nwant\n%d", result, expected)
}
}
func TestArrayBytes_Set(t *testing.T) {
f := func(s string, expectedValues []int) {
t.Helper()
var a ArrayBytes
_ = a.Set(s)
values := make([]int, len(a))
for i, v := range a {
values[i] = v.N
}
if !reflect.DeepEqual(values, expectedValues) {
t.Fatalf("unexpected values parsed;\ngot\n%d\nwant\n%d", values, expectedValues)
}
}
f("", []int{})
f(`1`, []int{1})
f(`-2,3,10kb`, []int{-2, 3, 10000})
}
func TestArrayBytes_GetOptionalArg(t *testing.T) {
f := func(s string, argIdx, defaultValue, expectedValue int) {
t.Helper()
var a ArrayBytes
_ = a.Set(s)
v := a.GetOptionalArgOrDefault(argIdx, defaultValue)
if v != expectedValue {
t.Fatalf("unexpected value; got %d; want %d", v, expectedValue)
}
}
f("", 0, 123, 123)
f("", 1, -34, -34)
f("10,1", 1, 234, 1)
f("10,1", 3, 234, 234)
f("10Kb", 3, -34, 10000)
}
func TestArrayBytes_String(t *testing.T) {
f := func(s string) {
t.Helper()
var a ArrayBytes
_ = a.Set(s)
result := a.String()
if result != s {
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
}
}
f("")
f("10.5KiB,1")
f("-5,1,123MB")
}

View file

@ -34,7 +34,7 @@ var (
tlsEnable = flag.Bool("tls", false, "Whether to enable TLS for incoming HTTP requests at -httpListenAddr (aka https). -tlsCertFile and -tlsKeyFile must be set if -tls is set")
tlsCertFile = flag.String("tlsCertFile", "", "Path to file with TLS certificate if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower. The provided certificate file is automatically re-read every second, so it can be dynamically updated")
tlsKeyFile = flag.String("tlsKeyFile", "", "Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated")
tlsCipherSuites = flagutil.NewArray("tlsCipherSuites", "Optional list of TLS cipher suites for incoming requests over HTTPS if -tls is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants")
tlsCipherSuites = flagutil.NewArrayString("tlsCipherSuites", "Optional list of TLS cipher suites for incoming requests over HTTPS if -tls is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants")
tlsMinVersion = flag.String("tlsMinVersion", "", "Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. "+
"Supported values: TLS10, TLS11, TLS12, TLS13")

View file

@ -8,7 +8,7 @@ import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
)
var influxDatabaseNames = flagutil.NewArray("influx.databaseNames", "Comma-separated list of database names to return from /query and /influx/query API. "+
var influxDatabaseNames = flagutil.NewArrayString("influx.databaseNames", "Comma-separated list of database names to return from /query and /influx/query API. "+
"This can be needed for accepting data from Telegraf plugins such as https://github.com/fangli/fluent-plugin-influxdb")
// WriteDatabaseNames writes influxDatabaseNames to w.

View file

@ -12,10 +12,10 @@ import (
)
var (
pushURL = flagutil.NewArray("pushmetrics.url", "Optional URL to push metrics exposed at /metrics page. See https://docs.victoriametrics.com/#push-metrics . "+
pushURL = flagutil.NewArrayString("pushmetrics.url", "Optional URL to push metrics exposed at /metrics page. See https://docs.victoriametrics.com/#push-metrics . "+
"By default metrics exposed at /metrics page aren't pushed to any remote storage")
pushInterval = flag.Duration("pushmetrics.interval", 10*time.Second, "Interval for pushing metrics to -pushmetrics.url")
pushExtraLabel = flagutil.NewArray("pushmetrics.extraLabel", "Optional labels to add to metrics pushed to -pushmetrics.url . "+
pushExtraLabel = flagutil.NewArrayString("pushmetrics.extraLabel", "Optional labels to add to metrics pushed to -pushmetrics.url . "+
`For example, -pushmetrics.extraLabel='instance="foo"' adds instance="foo" label to all the metrics pushed to -pushmetrics.url`)
)