mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
vendor: retain v0.46.0 for github.com/prometheus/common , since v0.48.0 leads to build error
The error is: vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/promlint.go:71:38: undefined: expfmt.FmtText
This commit is contained in:
parent
35f592a02c
commit
aae71832e5
12 changed files with 1294 additions and 788 deletions
6
go.mod
6
go.mod
|
@ -2,6 +2,10 @@ module github.com/VictoriaMetrics/VictoriaMetrics
|
||||||
|
|
||||||
go 1.22
|
go 1.22
|
||||||
|
|
||||||
|
// The github.com/prometheus/prometheus v0.50.0 depends on github.com/prometheus/common v0.46.0
|
||||||
|
// TODO: remove this replacement for the new version of github.com/prometheus/prometheus
|
||||||
|
replace github.com/prometheus/common => github.com/prometheus/common v0.46.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/storage v1.38.0
|
cloud.google.com/go/storage v1.38.0
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2
|
||||||
|
@ -106,7 +110,7 @@ require (
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect
|
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
go.opentelemetry.io/collector/featuregate v1.2.0 // indirect
|
go.opentelemetry.io/collector/featuregate v1.0.1 // indirect
|
||||||
go.opentelemetry.io/collector/pdata v1.2.0 // indirect
|
go.opentelemetry.io/collector/pdata v1.2.0 // indirect
|
||||||
go.opentelemetry.io/collector/semconv v0.95.0 // indirect
|
go.opentelemetry.io/collector/semconv v0.95.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
|
||||||
|
|
12
vendor/github.com/prometheus/common/config/http_config.go
generated
vendored
12
vendor/github.com/prometheus/common/config/http_config.go
generated
vendored
|
@ -30,7 +30,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
conntrack "github.com/mwitkow/go-conntrack"
|
"github.com/mwitkow/go-conntrack"
|
||||||
"golang.org/x/net/http/httpproxy"
|
"golang.org/x/net/http/httpproxy"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
@ -378,6 +378,9 @@ func (c *HTTPClientConfig) Validate() error {
|
||||||
if len(c.OAuth2.ClientID) == 0 {
|
if len(c.OAuth2.ClientID) == 0 {
|
||||||
return fmt.Errorf("oauth2 client_id must be configured")
|
return fmt.Errorf("oauth2 client_id must be configured")
|
||||||
}
|
}
|
||||||
|
if len(c.OAuth2.ClientSecret) == 0 && len(c.OAuth2.ClientSecretFile) == 0 {
|
||||||
|
return fmt.Errorf("either oauth2 client_secret or client_secret_file must be configured")
|
||||||
|
}
|
||||||
if len(c.OAuth2.TokenURL) == 0 {
|
if len(c.OAuth2.TokenURL) == 0 {
|
||||||
return fmt.Errorf("oauth2 token_url must be configured")
|
return fmt.Errorf("oauth2 token_url must be configured")
|
||||||
}
|
}
|
||||||
|
@ -726,12 +729,13 @@ func (rt *oauth2RoundTripper) RoundTrip(req *http.Request) (*http.Response, erro
|
||||||
rt.mtx.RLock()
|
rt.mtx.RLock()
|
||||||
changed = secret != rt.secret
|
changed = secret != rt.secret
|
||||||
rt.mtx.RUnlock()
|
rt.mtx.RUnlock()
|
||||||
} else {
|
|
||||||
// Either an inline secret or nothing (use an empty string) was provided.
|
|
||||||
secret = string(rt.config.ClientSecret)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if changed || rt.rt == nil {
|
if changed || rt.rt == nil {
|
||||||
|
if rt.config.ClientSecret != "" {
|
||||||
|
secret = string(rt.config.ClientSecret)
|
||||||
|
}
|
||||||
|
|
||||||
config := &clientcredentials.Config{
|
config := &clientcredentials.Config{
|
||||||
ClientID: rt.config.ClientID,
|
ClientID: rt.config.ClientID,
|
||||||
ClientSecret: secret,
|
ClientSecret: secret,
|
||||||
|
|
18
vendor/github.com/prometheus/common/expfmt/decode.go
generated
vendored
18
vendor/github.com/prometheus/common/expfmt/decode.go
generated
vendored
|
@ -45,7 +45,7 @@ func ResponseFormat(h http.Header) Format {
|
||||||
|
|
||||||
mediatype, params, err := mime.ParseMediaType(ct)
|
mediatype, params, err := mime.ParseMediaType(ct)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmtUnknown
|
return FmtUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
const textType = "text/plain"
|
const textType = "text/plain"
|
||||||
|
@ -53,28 +53,28 @@ func ResponseFormat(h http.Header) Format {
|
||||||
switch mediatype {
|
switch mediatype {
|
||||||
case ProtoType:
|
case ProtoType:
|
||||||
if p, ok := params["proto"]; ok && p != ProtoProtocol {
|
if p, ok := params["proto"]; ok && p != ProtoProtocol {
|
||||||
return fmtUnknown
|
return FmtUnknown
|
||||||
}
|
}
|
||||||
if e, ok := params["encoding"]; ok && e != "delimited" {
|
if e, ok := params["encoding"]; ok && e != "delimited" {
|
||||||
return fmtUnknown
|
return FmtUnknown
|
||||||
}
|
}
|
||||||
return fmtProtoDelim
|
return FmtProtoDelim
|
||||||
|
|
||||||
case textType:
|
case textType:
|
||||||
if v, ok := params["version"]; ok && v != TextVersion {
|
if v, ok := params["version"]; ok && v != TextVersion {
|
||||||
return fmtUnknown
|
return FmtUnknown
|
||||||
}
|
}
|
||||||
return fmtText
|
return FmtText
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmtUnknown
|
return FmtUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDecoder returns a new decoder based on the given input format.
|
// NewDecoder returns a new decoder based on the given input format.
|
||||||
// If the input format does not imply otherwise, a text format decoder is returned.
|
// If the input format does not imply otherwise, a text format decoder is returned.
|
||||||
func NewDecoder(r io.Reader, format Format) Decoder {
|
func NewDecoder(r io.Reader, format Format) Decoder {
|
||||||
switch format.FormatType() {
|
switch format {
|
||||||
case TypeProtoDelim:
|
case FmtProtoDelim:
|
||||||
return &protoDecoder{r: r}
|
return &protoDecoder{r: r}
|
||||||
}
|
}
|
||||||
return &textDecoder{r: r}
|
return &textDecoder{r: r}
|
||||||
|
|
73
vendor/github.com/prometheus/common/expfmt/encode.go
generated
vendored
73
vendor/github.com/prometheus/common/expfmt/encode.go
generated
vendored
|
@ -22,7 +22,6 @@ import (
|
||||||
"google.golang.org/protobuf/encoding/prototext"
|
"google.golang.org/protobuf/encoding/prototext"
|
||||||
|
|
||||||
"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg"
|
"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg"
|
||||||
"github.com/prometheus/common/model"
|
|
||||||
|
|
||||||
dto "github.com/prometheus/client_model/go"
|
dto "github.com/prometheus/client_model/go"
|
||||||
)
|
)
|
||||||
|
@ -62,32 +61,23 @@ func (ec encoderCloser) Close() error {
|
||||||
// as the support is still experimental. To include the option to negotiate
|
// as the support is still experimental. To include the option to negotiate
|
||||||
// FmtOpenMetrics, use NegotiateOpenMetrics.
|
// FmtOpenMetrics, use NegotiateOpenMetrics.
|
||||||
func Negotiate(h http.Header) Format {
|
func Negotiate(h http.Header) Format {
|
||||||
escapingScheme := Format(fmt.Sprintf("; escaping=%s", Format(model.NameEscapingScheme.String())))
|
|
||||||
for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) {
|
for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) {
|
||||||
if escapeParam := ac.Params[model.EscapingKey]; escapeParam != "" {
|
|
||||||
switch Format(escapeParam) {
|
|
||||||
case model.AllowUTF8, model.EscapeUnderscores, model.EscapeDots, model.EscapeValues:
|
|
||||||
escapingScheme = Format(fmt.Sprintf("; escaping=%s", escapeParam))
|
|
||||||
default:
|
|
||||||
// If the escaping parameter is unknown, ignore it.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ver := ac.Params["version"]
|
ver := ac.Params["version"]
|
||||||
if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol {
|
if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol {
|
||||||
switch ac.Params["encoding"] {
|
switch ac.Params["encoding"] {
|
||||||
case "delimited":
|
case "delimited":
|
||||||
return fmtProtoDelim + escapingScheme
|
return FmtProtoDelim
|
||||||
case "text":
|
case "text":
|
||||||
return fmtProtoText + escapingScheme
|
return FmtProtoText
|
||||||
case "compact-text":
|
case "compact-text":
|
||||||
return fmtProtoCompact + escapingScheme
|
return FmtProtoCompact
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") {
|
if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") {
|
||||||
return fmtText + escapingScheme
|
return FmtText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmtText + escapingScheme
|
return FmtText
|
||||||
}
|
}
|
||||||
|
|
||||||
// NegotiateIncludingOpenMetrics works like Negotiate but includes
|
// NegotiateIncludingOpenMetrics works like Negotiate but includes
|
||||||
|
@ -95,40 +85,29 @@ func Negotiate(h http.Header) Format {
|
||||||
// temporary and will disappear once FmtOpenMetrics is fully supported and as
|
// temporary and will disappear once FmtOpenMetrics is fully supported and as
|
||||||
// such may be negotiated by the normal Negotiate function.
|
// such may be negotiated by the normal Negotiate function.
|
||||||
func NegotiateIncludingOpenMetrics(h http.Header) Format {
|
func NegotiateIncludingOpenMetrics(h http.Header) Format {
|
||||||
escapingScheme := Format(fmt.Sprintf("; escaping=%s", Format(model.NameEscapingScheme.String())))
|
|
||||||
for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) {
|
for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) {
|
||||||
if escapeParam := ac.Params[model.EscapingKey]; escapeParam != "" {
|
|
||||||
switch Format(escapeParam) {
|
|
||||||
case model.AllowUTF8, model.EscapeUnderscores, model.EscapeDots, model.EscapeValues:
|
|
||||||
escapingScheme = Format(fmt.Sprintf("; escaping=%s", escapeParam))
|
|
||||||
default:
|
|
||||||
// If the escaping parameter is unknown, ignore it.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ver := ac.Params["version"]
|
ver := ac.Params["version"]
|
||||||
if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol {
|
if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol {
|
||||||
switch ac.Params["encoding"] {
|
switch ac.Params["encoding"] {
|
||||||
case "delimited":
|
case "delimited":
|
||||||
return fmtProtoDelim + escapingScheme
|
return FmtProtoDelim
|
||||||
case "text":
|
case "text":
|
||||||
return fmtProtoText + escapingScheme
|
return FmtProtoText
|
||||||
case "compact-text":
|
case "compact-text":
|
||||||
return fmtProtoCompact + escapingScheme
|
return FmtProtoCompact
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") {
|
if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") {
|
||||||
return fmtText + escapingScheme
|
return FmtText
|
||||||
}
|
}
|
||||||
if ac.Type+"/"+ac.SubType == OpenMetricsType && (ver == OpenMetricsVersion_0_0_1 || ver == OpenMetricsVersion_1_0_0 || ver == "") {
|
if ac.Type+"/"+ac.SubType == OpenMetricsType && (ver == OpenMetricsVersion_0_0_1 || ver == OpenMetricsVersion_1_0_0 || ver == "") {
|
||||||
switch ver {
|
if ver == OpenMetricsVersion_1_0_0 {
|
||||||
case OpenMetricsVersion_1_0_0:
|
return FmtOpenMetrics_1_0_0
|
||||||
return fmtOpenMetrics_1_0_0 + escapingScheme
|
}
|
||||||
default:
|
return FmtOpenMetrics_0_0_1
|
||||||
return fmtOpenMetrics_0_0_1 + escapingScheme
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return FmtText
|
||||||
return fmtText + escapingScheme
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEncoder returns a new encoder based on content type negotiation. All
|
// NewEncoder returns a new encoder based on content type negotiation. All
|
||||||
|
@ -137,13 +116,9 @@ func NegotiateIncludingOpenMetrics(h http.Header) Format {
|
||||||
// for FmtOpenMetrics, but a future (breaking) release will add the Close method
|
// for FmtOpenMetrics, but a future (breaking) release will add the Close method
|
||||||
// to the Encoder interface directly. The current version of the Encoder
|
// to the Encoder interface directly. The current version of the Encoder
|
||||||
// interface is kept for backwards compatibility.
|
// interface is kept for backwards compatibility.
|
||||||
// In cases where the Format does not allow for UTF-8 names, the global
|
|
||||||
// NameEscapingScheme will be applied.
|
|
||||||
func NewEncoder(w io.Writer, format Format) Encoder {
|
func NewEncoder(w io.Writer, format Format) Encoder {
|
||||||
escapingScheme := format.ToEscapingScheme()
|
switch format {
|
||||||
|
case FmtProtoDelim:
|
||||||
switch format.FormatType() {
|
|
||||||
case TypeProtoDelim:
|
|
||||||
return encoderCloser{
|
return encoderCloser{
|
||||||
encode: func(v *dto.MetricFamily) error {
|
encode: func(v *dto.MetricFamily) error {
|
||||||
_, err := protodelim.MarshalTo(w, v)
|
_, err := protodelim.MarshalTo(w, v)
|
||||||
|
@ -151,34 +126,34 @@ func NewEncoder(w io.Writer, format Format) Encoder {
|
||||||
},
|
},
|
||||||
close: func() error { return nil },
|
close: func() error { return nil },
|
||||||
}
|
}
|
||||||
case TypeProtoCompact:
|
case FmtProtoCompact:
|
||||||
return encoderCloser{
|
return encoderCloser{
|
||||||
encode: func(v *dto.MetricFamily) error {
|
encode: func(v *dto.MetricFamily) error {
|
||||||
_, err := fmt.Fprintln(w, model.EscapeMetricFamily(v, escapingScheme).String())
|
_, err := fmt.Fprintln(w, v.String())
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
close: func() error { return nil },
|
close: func() error { return nil },
|
||||||
}
|
}
|
||||||
case TypeProtoText:
|
case FmtProtoText:
|
||||||
return encoderCloser{
|
return encoderCloser{
|
||||||
encode: func(v *dto.MetricFamily) error {
|
encode: func(v *dto.MetricFamily) error {
|
||||||
_, err := fmt.Fprintln(w, prototext.Format(model.EscapeMetricFamily(v, escapingScheme)))
|
_, err := fmt.Fprintln(w, prototext.Format(v))
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
close: func() error { return nil },
|
close: func() error { return nil },
|
||||||
}
|
}
|
||||||
case TypeTextPlain:
|
case FmtText:
|
||||||
return encoderCloser{
|
return encoderCloser{
|
||||||
encode: func(v *dto.MetricFamily) error {
|
encode: func(v *dto.MetricFamily) error {
|
||||||
_, err := MetricFamilyToText(w, model.EscapeMetricFamily(v, escapingScheme))
|
_, err := MetricFamilyToText(w, v)
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
close: func() error { return nil },
|
close: func() error { return nil },
|
||||||
}
|
}
|
||||||
case TypeOpenMetrics:
|
case FmtOpenMetrics_0_0_1, FmtOpenMetrics_1_0_0:
|
||||||
return encoderCloser{
|
return encoderCloser{
|
||||||
encode: func(v *dto.MetricFamily) error {
|
encode: func(v *dto.MetricFamily) error {
|
||||||
_, err := MetricFamilyToOpenMetrics(w, model.EscapeMetricFamily(v, escapingScheme))
|
_, err := MetricFamilyToOpenMetrics(w, v)
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
close: func() error {
|
close: func() error {
|
||||||
|
|
144
vendor/github.com/prometheus/common/expfmt/expfmt.go
generated
vendored
144
vendor/github.com/prometheus/common/expfmt/expfmt.go
generated
vendored
|
@ -14,154 +14,30 @@
|
||||||
// Package expfmt contains tools for reading and writing Prometheus metrics.
|
// Package expfmt contains tools for reading and writing Prometheus metrics.
|
||||||
package expfmt
|
package expfmt
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/prometheus/common/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Format specifies the HTTP content type of the different wire protocols.
|
// Format specifies the HTTP content type of the different wire protocols.
|
||||||
type Format string
|
type Format string
|
||||||
|
|
||||||
// Constants to assemble the Content-Type values for the different wire
|
// Constants to assemble the Content-Type values for the different wire protocols.
|
||||||
// protocols. The Content-Type strings here are all for the legacy exposition
|
|
||||||
// formats, where valid characters for metric names and label names are limited.
|
|
||||||
// Support for arbitrary UTF-8 characters in those names is already partially
|
|
||||||
// implemented in this module (see model.ValidationScheme), but to actually use
|
|
||||||
// it on the wire, new content-type strings will have to be agreed upon and
|
|
||||||
// added here.
|
|
||||||
const (
|
const (
|
||||||
TextVersion = "0.0.4"
|
TextVersion = "0.0.4"
|
||||||
ProtoType = `application/vnd.google.protobuf`
|
ProtoType = `application/vnd.google.protobuf`
|
||||||
ProtoProtocol = `io.prometheus.client.MetricFamily`
|
ProtoProtocol = `io.prometheus.client.MetricFamily`
|
||||||
protoFmt = ProtoType + "; proto=" + ProtoProtocol + ";"
|
ProtoFmt = ProtoType + "; proto=" + ProtoProtocol + ";"
|
||||||
OpenMetricsType = `application/openmetrics-text`
|
OpenMetricsType = `application/openmetrics-text`
|
||||||
OpenMetricsVersion_0_0_1 = "0.0.1"
|
OpenMetricsVersion_0_0_1 = "0.0.1"
|
||||||
OpenMetricsVersion_1_0_0 = "1.0.0"
|
OpenMetricsVersion_1_0_0 = "1.0.0"
|
||||||
|
|
||||||
// The Content-Type values for the different wire protocols. Note that these
|
// The Content-Type values for the different wire protocols.
|
||||||
// values are now unexported. If code was relying on comparisons to these
|
FmtUnknown Format = `<unknown>`
|
||||||
// constants, instead use FormatType().
|
FmtText Format = `text/plain; version=` + TextVersion + `; charset=utf-8`
|
||||||
fmtUnknown Format = `<unknown>`
|
FmtProtoDelim Format = ProtoFmt + ` encoding=delimited`
|
||||||
fmtText Format = `text/plain; version=` + TextVersion + `; charset=utf-8`
|
FmtProtoText Format = ProtoFmt + ` encoding=text`
|
||||||
fmtProtoDelim Format = protoFmt + ` encoding=delimited`
|
FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text`
|
||||||
fmtProtoText Format = protoFmt + ` encoding=text`
|
FmtOpenMetrics_1_0_0 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_1_0_0 + `; charset=utf-8`
|
||||||
fmtProtoCompact Format = protoFmt + ` encoding=compact-text`
|
FmtOpenMetrics_0_0_1 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_0_0_1 + `; charset=utf-8`
|
||||||
fmtOpenMetrics_1_0_0 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_1_0_0 + `; charset=utf-8`
|
|
||||||
fmtOpenMetrics_0_0_1 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_0_0_1 + `; charset=utf-8`
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
hdrContentType = "Content-Type"
|
hdrContentType = "Content-Type"
|
||||||
hdrAccept = "Accept"
|
hdrAccept = "Accept"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FormatType is a Go enum representing the overall category for the given
|
|
||||||
// Format. As the number of Format permutations increases, doing basic string
|
|
||||||
// comparisons are not feasible, so this enum captures the most useful
|
|
||||||
// high-level attribute of the Format string.
|
|
||||||
type FormatType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
TypeUnknown = iota
|
|
||||||
TypeProtoCompact
|
|
||||||
TypeProtoDelim
|
|
||||||
TypeProtoText
|
|
||||||
TypeTextPlain
|
|
||||||
TypeOpenMetrics
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewFormat generates a new Format from the type provided. Mostly used for
|
|
||||||
// tests, most Formats should be generated as part of content negotiation in
|
|
||||||
// encode.go.
|
|
||||||
func NewFormat(t FormatType) Format {
|
|
||||||
switch t {
|
|
||||||
case TypeProtoCompact:
|
|
||||||
return fmtProtoCompact
|
|
||||||
case TypeProtoDelim:
|
|
||||||
return fmtProtoDelim
|
|
||||||
case TypeProtoText:
|
|
||||||
return fmtProtoText
|
|
||||||
case TypeTextPlain:
|
|
||||||
return fmtText
|
|
||||||
case TypeOpenMetrics:
|
|
||||||
return fmtOpenMetrics_1_0_0
|
|
||||||
default:
|
|
||||||
return fmtUnknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FormatType deduces an overall FormatType for the given format.
|
|
||||||
func (f Format) FormatType() FormatType {
|
|
||||||
toks := strings.Split(string(f), ";")
|
|
||||||
if len(toks) < 2 {
|
|
||||||
return TypeUnknown
|
|
||||||
}
|
|
||||||
|
|
||||||
params := make(map[string]string)
|
|
||||||
for i, t := range toks {
|
|
||||||
if i == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
args := strings.Split(t, "=")
|
|
||||||
if len(args) != 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
params[strings.TrimSpace(args[0])] = strings.TrimSpace(args[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
switch strings.TrimSpace(toks[0]) {
|
|
||||||
case ProtoType:
|
|
||||||
if params["proto"] != ProtoProtocol {
|
|
||||||
return TypeUnknown
|
|
||||||
}
|
|
||||||
switch params["encoding"] {
|
|
||||||
case "delimited":
|
|
||||||
return TypeProtoDelim
|
|
||||||
case "text":
|
|
||||||
return TypeProtoText
|
|
||||||
case "compact-text":
|
|
||||||
return TypeProtoCompact
|
|
||||||
default:
|
|
||||||
return TypeUnknown
|
|
||||||
}
|
|
||||||
case OpenMetricsType:
|
|
||||||
if params["charset"] != "utf-8" {
|
|
||||||
return TypeUnknown
|
|
||||||
}
|
|
||||||
return TypeOpenMetrics
|
|
||||||
case "text/plain":
|
|
||||||
v, ok := params["version"]
|
|
||||||
if !ok {
|
|
||||||
return TypeTextPlain
|
|
||||||
}
|
|
||||||
if v == TextVersion {
|
|
||||||
return TypeTextPlain
|
|
||||||
}
|
|
||||||
return TypeUnknown
|
|
||||||
default:
|
|
||||||
return TypeUnknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToEscapingScheme returns an EscapingScheme depending on the Format. Iff the
|
|
||||||
// Format contains a escaping=allow-utf-8 term, it will select NoEscaping. If a valid
|
|
||||||
// "escaping" term exists, that will be used. Otherwise, the global default will
|
|
||||||
// be returned.
|
|
||||||
func (format Format) ToEscapingScheme() model.EscapingScheme {
|
|
||||||
for _, p := range strings.Split(string(format), ";") {
|
|
||||||
toks := strings.Split(p, "=")
|
|
||||||
if len(toks) != 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
key, value := strings.TrimSpace(toks[0]), strings.TrimSpace(toks[1])
|
|
||||||
if key == model.EscapingKey {
|
|
||||||
scheme, err := model.ToEscapingScheme(value)
|
|
||||||
if err != nil {
|
|
||||||
return model.NameEscapingScheme
|
|
||||||
}
|
|
||||||
return scheme
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return model.NameEscapingScheme
|
|
||||||
}
|
|
||||||
|
|
81
vendor/github.com/prometheus/common/expfmt/openmetrics_create.go
generated
vendored
81
vendor/github.com/prometheus/common/expfmt/openmetrics_create.go
generated
vendored
|
@ -35,18 +35,6 @@ import (
|
||||||
// sanity checks. If the input contains duplicate metrics or invalid metric or
|
// sanity checks. If the input contains duplicate metrics or invalid metric or
|
||||||
// label names, the conversion will result in invalid text format output.
|
// label names, the conversion will result in invalid text format output.
|
||||||
//
|
//
|
||||||
// If metric names conform to the legacy validation pattern, they will be placed
|
|
||||||
// outside the brackets in the traditional way, like `foo{}`. If the metric name
|
|
||||||
// fails the legacy validation check, it will be placed quoted inside the
|
|
||||||
// brackets: `{"foo"}`. As stated above, the input is assumed to be santized and
|
|
||||||
// no error will be thrown in this case.
|
|
||||||
//
|
|
||||||
// Similar to metric names, if label names conform to the legacy validation
|
|
||||||
// pattern, they will be unquoted as normal, like `foo{bar="baz"}`. If the label
|
|
||||||
// name fails the legacy validation check, it will be quoted:
|
|
||||||
// `foo{"bar"="baz"}`. As stated above, the input is assumed to be santized and
|
|
||||||
// no error will be thrown in this case.
|
|
||||||
//
|
|
||||||
// This function fulfills the type 'expfmt.encoder'.
|
// This function fulfills the type 'expfmt.encoder'.
|
||||||
//
|
//
|
||||||
// Note that OpenMetrics requires a final `# EOF` line. Since this function acts
|
// Note that OpenMetrics requires a final `# EOF` line. Since this function acts
|
||||||
|
@ -110,7 +98,7 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily) (written int
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n, err = writeName(w, shortName)
|
n, err = w.WriteString(shortName)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -136,7 +124,7 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily) (written int
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n, err = writeName(w, shortName)
|
n, err = w.WriteString(shortName)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -315,9 +303,21 @@ func writeOpenMetricsSample(
|
||||||
floatValue float64, intValue uint64, useIntValue bool,
|
floatValue float64, intValue uint64, useIntValue bool,
|
||||||
exemplar *dto.Exemplar,
|
exemplar *dto.Exemplar,
|
||||||
) (int, error) {
|
) (int, error) {
|
||||||
written := 0
|
var written int
|
||||||
n, err := writeOpenMetricsNameAndLabelPairs(
|
n, err := w.WriteString(name)
|
||||||
w, name+suffix, metric.Label, additionalLabelName, additionalLabelValue,
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
if suffix != "" {
|
||||||
|
n, err = w.WriteString(suffix)
|
||||||
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n, err = writeOpenMetricsLabelPairs(
|
||||||
|
w, metric.Label, additionalLabelName, additionalLabelValue,
|
||||||
)
|
)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -365,58 +365,27 @@ func writeOpenMetricsSample(
|
||||||
return written, nil
|
return written, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeOpenMetricsNameAndLabelPairs works like writeOpenMetricsSample but
|
// writeOpenMetricsLabelPairs works like writeOpenMetrics but formats the float
|
||||||
// formats the float in OpenMetrics style.
|
// in OpenMetrics style.
|
||||||
func writeOpenMetricsNameAndLabelPairs(
|
func writeOpenMetricsLabelPairs(
|
||||||
w enhancedWriter,
|
w enhancedWriter,
|
||||||
name string,
|
|
||||||
in []*dto.LabelPair,
|
in []*dto.LabelPair,
|
||||||
additionalLabelName string, additionalLabelValue float64,
|
additionalLabelName string, additionalLabelValue float64,
|
||||||
) (int, error) {
|
) (int, error) {
|
||||||
|
if len(in) == 0 && additionalLabelName == "" {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
written int
|
written int
|
||||||
separator byte = '{'
|
separator byte = '{'
|
||||||
metricInsideBraces = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if name != "" {
|
|
||||||
// If the name does not pass the legacy validity check, we must put the
|
|
||||||
// metric name inside the braces, quoted.
|
|
||||||
if !model.IsValidLegacyMetricName(model.LabelValue(name)) {
|
|
||||||
metricInsideBraces = true
|
|
||||||
err := w.WriteByte(separator)
|
|
||||||
written++
|
|
||||||
if err != nil {
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
separator = ','
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err := writeName(w, name)
|
|
||||||
written += n
|
|
||||||
if err != nil {
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(in) == 0 && additionalLabelName == "" {
|
|
||||||
if metricInsideBraces {
|
|
||||||
err := w.WriteByte('}')
|
|
||||||
written++
|
|
||||||
if err != nil {
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return written, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, lp := range in {
|
for _, lp := range in {
|
||||||
err := w.WriteByte(separator)
|
err := w.WriteByte(separator)
|
||||||
written++
|
written++
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
n, err := writeName(w, lp.GetName())
|
n, err := w.WriteString(lp.GetName())
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
|
@ -482,7 +451,7 @@ func writeExemplar(w enhancedWriter, e *dto.Exemplar) (int, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
n, err = writeOpenMetricsNameAndLabelPairs(w, "", e.Label, "", 0)
|
n, err = writeOpenMetricsLabelPairs(w, e.Label, "", 0)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
|
|
114
vendor/github.com/prometheus/common/expfmt/text_create.go
generated
vendored
114
vendor/github.com/prometheus/common/expfmt/text_create.go
generated
vendored
|
@ -62,18 +62,6 @@ var (
|
||||||
// contains duplicate metrics or invalid metric or label names, the conversion
|
// contains duplicate metrics or invalid metric or label names, the conversion
|
||||||
// will result in invalid text format output.
|
// will result in invalid text format output.
|
||||||
//
|
//
|
||||||
// If metric names conform to the legacy validation pattern, they will be placed
|
|
||||||
// outside the brackets in the traditional way, like `foo{}`. If the metric name
|
|
||||||
// fails the legacy validation check, it will be placed quoted inside the
|
|
||||||
// brackets: `{"foo"}`. As stated above, the input is assumed to be santized and
|
|
||||||
// no error will be thrown in this case.
|
|
||||||
//
|
|
||||||
// Similar to metric names, if label names conform to the legacy validation
|
|
||||||
// pattern, they will be unquoted as normal, like `foo{bar="baz"}`. If the label
|
|
||||||
// name fails the legacy validation check, it will be quoted:
|
|
||||||
// `foo{"bar"="baz"}`. As stated above, the input is assumed to be santized and
|
|
||||||
// no error will be thrown in this case.
|
|
||||||
//
|
|
||||||
// This method fulfills the type 'prometheus.encoder'.
|
// This method fulfills the type 'prometheus.encoder'.
|
||||||
func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err error) {
|
func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err error) {
|
||||||
// Fail-fast checks.
|
// Fail-fast checks.
|
||||||
|
@ -110,7 +98,7 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err e
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n, err = writeName(w, name)
|
n, err = w.WriteString(name)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -136,7 +124,7 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err e
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n, err = writeName(w, name)
|
n, err = w.WriteString(name)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -292,9 +280,21 @@ func writeSample(
|
||||||
additionalLabelName string, additionalLabelValue float64,
|
additionalLabelName string, additionalLabelValue float64,
|
||||||
value float64,
|
value float64,
|
||||||
) (int, error) {
|
) (int, error) {
|
||||||
written := 0
|
var written int
|
||||||
n, err := writeNameAndLabelPairs(
|
n, err := w.WriteString(name)
|
||||||
w, name+suffix, metric.Label, additionalLabelName, additionalLabelValue,
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
if suffix != "" {
|
||||||
|
n, err = w.WriteString(suffix)
|
||||||
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n, err = writeLabelPairs(
|
||||||
|
w, metric.Label, additionalLabelName, additionalLabelValue,
|
||||||
)
|
)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -330,64 +330,32 @@ func writeSample(
|
||||||
return written, nil
|
return written, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeNameAndLabelPairs converts a slice of LabelPair proto messages plus the
|
// writeLabelPairs converts a slice of LabelPair proto messages plus the
|
||||||
// explicitly given metric name and additional label pair into text formatted as
|
// explicitly given additional label pair into text formatted as required by the
|
||||||
// required by the text format and writes it to 'w'. An empty slice in
|
// text format and writes it to 'w'. An empty slice in combination with an empty
|
||||||
// combination with an empty string 'additionalLabelName' results in nothing
|
// string 'additionalLabelName' results in nothing being written. Otherwise, the
|
||||||
// being written. Otherwise, the label pairs are written, escaped as required by
|
// label pairs are written, escaped as required by the text format, and enclosed
|
||||||
// the text format, and enclosed in '{...}'. The function returns the number of
|
// in '{...}'. The function returns the number of bytes written and any error
|
||||||
// bytes written and any error encountered. If the metric name is not
|
// encountered.
|
||||||
// legacy-valid, it will be put inside the brackets as well. Legacy-invalid
|
func writeLabelPairs(
|
||||||
// label names will also be quoted.
|
|
||||||
func writeNameAndLabelPairs(
|
|
||||||
w enhancedWriter,
|
w enhancedWriter,
|
||||||
name string,
|
|
||||||
in []*dto.LabelPair,
|
in []*dto.LabelPair,
|
||||||
additionalLabelName string, additionalLabelValue float64,
|
additionalLabelName string, additionalLabelValue float64,
|
||||||
) (int, error) {
|
) (int, error) {
|
||||||
|
if len(in) == 0 && additionalLabelName == "" {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
written int
|
written int
|
||||||
separator byte = '{'
|
separator byte = '{'
|
||||||
metricInsideBraces = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if name != "" {
|
|
||||||
// If the name does not pass the legacy validity check, we must put the
|
|
||||||
// metric name inside the braces.
|
|
||||||
if !model.IsValidLegacyMetricName(model.LabelValue(name)) {
|
|
||||||
metricInsideBraces = true
|
|
||||||
err := w.WriteByte(separator)
|
|
||||||
written++
|
|
||||||
if err != nil {
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
separator = ','
|
|
||||||
}
|
|
||||||
n, err := writeName(w, name)
|
|
||||||
written += n
|
|
||||||
if err != nil {
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(in) == 0 && additionalLabelName == "" {
|
|
||||||
if metricInsideBraces {
|
|
||||||
err := w.WriteByte('}')
|
|
||||||
written++
|
|
||||||
if err != nil {
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return written, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, lp := range in {
|
for _, lp := range in {
|
||||||
err := w.WriteByte(separator)
|
err := w.WriteByte(separator)
|
||||||
written++
|
written++
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
n, err := writeName(w, lp.GetName())
|
n, err := w.WriteString(lp.GetName())
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
|
@ -494,27 +462,3 @@ func writeInt(w enhancedWriter, i int64) (int, error) {
|
||||||
numBufPool.Put(bp)
|
numBufPool.Put(bp)
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeName writes a string as-is if it complies with the legacy naming
|
|
||||||
// scheme, or escapes it in double quotes if not.
|
|
||||||
func writeName(w enhancedWriter, name string) (int, error) {
|
|
||||||
if model.IsValidLegacyMetricName(model.LabelValue(name)) {
|
|
||||||
return w.WriteString(name)
|
|
||||||
}
|
|
||||||
var written int
|
|
||||||
var err error
|
|
||||||
err = w.WriteByte('"')
|
|
||||||
written++
|
|
||||||
if err != nil {
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
var n int
|
|
||||||
n, err = writeEscapedString(w, name, true)
|
|
||||||
written += n
|
|
||||||
if err != nil {
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
err = w.WriteByte('"')
|
|
||||||
written++
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
|
|
16
vendor/github.com/prometheus/common/model/labels.go
generated
vendored
16
vendor/github.com/prometheus/common/model/labels.go
generated
vendored
|
@ -97,26 +97,18 @@ var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
|
||||||
// therewith.
|
// therewith.
|
||||||
type LabelName string
|
type LabelName string
|
||||||
|
|
||||||
// IsValid returns true iff name matches the pattern of LabelNameRE for legacy
|
// IsValid is true iff the label name matches the pattern of LabelNameRE. This
|
||||||
// names, and iff it's valid UTF-8 if NameValidationScheme is set to
|
// method, however, does not use LabelNameRE for the check but a much faster
|
||||||
// UTF8Validation. For the legacy matching, it does not use LabelNameRE for the
|
// hardcoded implementation.
|
||||||
// check but a much faster hardcoded implementation.
|
|
||||||
func (ln LabelName) IsValid() bool {
|
func (ln LabelName) IsValid() bool {
|
||||||
if len(ln) == 0 {
|
if len(ln) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
switch NameValidationScheme {
|
|
||||||
case LegacyValidation:
|
|
||||||
for i, b := range ln {
|
for i, b := range ln {
|
||||||
if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) {
|
if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case UTF8Validation:
|
|
||||||
return utf8.ValidString(string(ln))
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("Invalid name validation scheme requested: %d", NameValidationScheme))
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +164,7 @@ func (l LabelNames) String() string {
|
||||||
// A LabelValue is an associated value for a LabelName.
|
// A LabelValue is an associated value for a LabelName.
|
||||||
type LabelValue string
|
type LabelValue string
|
||||||
|
|
||||||
// IsValid returns true iff the string is a valid UTF-8.
|
// IsValid returns true iff the string is a valid UTF8.
|
||||||
func (lv LabelValue) IsValid() bool {
|
func (lv LabelValue) IsValid() bool {
|
||||||
return utf8.ValidString(string(lv))
|
return utf8.ValidString(string(lv))
|
||||||
}
|
}
|
||||||
|
|
362
vendor/github.com/prometheus/common/model/metric.go
generated
vendored
362
vendor/github.com/prometheus/common/model/metric.go
generated
vendored
|
@ -18,77 +18,6 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
|
||||||
|
|
||||||
dto "github.com/prometheus/client_model/go"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// NameValidationScheme determines the method of name validation to be used by
|
|
||||||
// all calls to IsValidMetricName() and LabelName IsValid(). Setting UTF-8 mode
|
|
||||||
// in isolation from other components that don't support UTF-8 may result in
|
|
||||||
// bugs or other undefined behavior. This value is intended to be set by
|
|
||||||
// UTF-8-aware binaries as part of their startup. To avoid need for locking,
|
|
||||||
// this value should be set once, ideally in an init(), before multiple
|
|
||||||
// goroutines are started.
|
|
||||||
NameValidationScheme = LegacyValidation
|
|
||||||
|
|
||||||
// NameEscapingScheme defines the default way that names will be
|
|
||||||
// escaped when presented to systems that do not support UTF-8 names. If the
|
|
||||||
// Content-Type "escaping" term is specified, that will override this value.
|
|
||||||
NameEscapingScheme = ValueEncodingEscaping
|
|
||||||
)
|
|
||||||
|
|
||||||
// ValidationScheme is a Go enum for determining how metric and label names will
|
|
||||||
// be validated by this library.
|
|
||||||
type ValidationScheme int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// LegacyValidation is a setting that requirets that metric and label names
|
|
||||||
// conform to the original Prometheus character requirements described by
|
|
||||||
// MetricNameRE and LabelNameRE.
|
|
||||||
LegacyValidation ValidationScheme = iota
|
|
||||||
|
|
||||||
// UTF8Validation only requires that metric and label names be valid UTF-8
|
|
||||||
// strings.
|
|
||||||
UTF8Validation
|
|
||||||
)
|
|
||||||
|
|
||||||
type EscapingScheme int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// NoEscaping indicates that a name will not be escaped. Unescaped names that
|
|
||||||
// do not conform to the legacy validity check will use a new exposition
|
|
||||||
// format syntax that will be officially standardized in future versions.
|
|
||||||
NoEscaping EscapingScheme = iota
|
|
||||||
|
|
||||||
// UnderscoreEscaping replaces all legacy-invalid characters with underscores.
|
|
||||||
UnderscoreEscaping
|
|
||||||
|
|
||||||
// DotsEscaping is similar to UnderscoreEscaping, except that dots are
|
|
||||||
// converted to `_dot_` and pre-existing underscores are converted to `__`.
|
|
||||||
DotsEscaping
|
|
||||||
|
|
||||||
// ValueEncodingEscaping prepends the name with `U__` and replaces all invalid
|
|
||||||
// characters with the unicode value, surrounded by underscores. Single
|
|
||||||
// underscores are replaced with double underscores.
|
|
||||||
ValueEncodingEscaping
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// EscapingKey is the key in an Accept or Content-Type header that defines how
|
|
||||||
// metric and label names that do not conform to the legacy character
|
|
||||||
// requirements should be escaped when being scraped by a legacy prometheus
|
|
||||||
// system. If a system does not explicitly pass an escaping parameter in the
|
|
||||||
// Accept header, the default NameEscapingScheme will be used.
|
|
||||||
EscapingKey = "escaping"
|
|
||||||
|
|
||||||
// Possible values for Escaping Key:
|
|
||||||
AllowUTF8 = "allow-utf-8" // No escaping required.
|
|
||||||
EscapeUnderscores = "underscores"
|
|
||||||
EscapeDots = "dots"
|
|
||||||
EscapeValues = "values"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MetricNameRE is a regular expression matching valid metric
|
// MetricNameRE is a regular expression matching valid metric
|
||||||
|
@ -155,302 +84,17 @@ func (m Metric) FastFingerprint() Fingerprint {
|
||||||
return LabelSet(m).FastFingerprint()
|
return LabelSet(m).FastFingerprint()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValidMetricName returns true iff name matches the pattern of MetricNameRE
|
// IsValidMetricName returns true iff name matches the pattern of MetricNameRE.
|
||||||
// for legacy names, and iff it's valid UTF-8 if the UTF8Validation scheme is
|
|
||||||
// selected.
|
|
||||||
func IsValidMetricName(n LabelValue) bool {
|
|
||||||
switch NameValidationScheme {
|
|
||||||
case LegacyValidation:
|
|
||||||
return IsValidLegacyMetricName(n)
|
|
||||||
case UTF8Validation:
|
|
||||||
if len(n) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return utf8.ValidString(string(n))
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("Invalid name validation scheme requested: %d", NameValidationScheme))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsValidLegacyMetricName is similar to IsValidMetricName but always uses the
|
|
||||||
// legacy validation scheme regardless of the value of NameValidationScheme.
|
|
||||||
// This function, however, does not use MetricNameRE for the check but a much
|
// This function, however, does not use MetricNameRE for the check but a much
|
||||||
// faster hardcoded implementation.
|
// faster hardcoded implementation.
|
||||||
func IsValidLegacyMetricName(n LabelValue) bool {
|
func IsValidMetricName(n LabelValue) bool {
|
||||||
if len(n) == 0 {
|
if len(n) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for i, b := range n {
|
for i, b := range n {
|
||||||
if !isValidLegacyRune(b, i) {
|
if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == ':' || (b >= '0' && b <= '9' && i > 0)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// EscapeMetricFamily escapes the given metric names and labels with the given
|
|
||||||
// escaping scheme. Returns a new object that uses the same pointers to fields
|
|
||||||
// when possible and creates new escaped versions so as not to mutate the
|
|
||||||
// input.
|
|
||||||
func EscapeMetricFamily(v *dto.MetricFamily, scheme EscapingScheme) *dto.MetricFamily {
|
|
||||||
if v == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if scheme == NoEscaping {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
out := &dto.MetricFamily{
|
|
||||||
Help: v.Help,
|
|
||||||
Type: v.Type,
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the name is nil, copy as-is, don't try to escape.
|
|
||||||
if v.Name == nil || IsValidLegacyMetricName(LabelValue(v.GetName())) {
|
|
||||||
out.Name = v.Name
|
|
||||||
} else {
|
|
||||||
out.Name = proto.String(EscapeName(v.GetName(), scheme))
|
|
||||||
}
|
|
||||||
for _, m := range v.Metric {
|
|
||||||
if !metricNeedsEscaping(m) {
|
|
||||||
out.Metric = append(out.Metric, m)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
escaped := &dto.Metric{
|
|
||||||
Gauge: m.Gauge,
|
|
||||||
Counter: m.Counter,
|
|
||||||
Summary: m.Summary,
|
|
||||||
Untyped: m.Untyped,
|
|
||||||
Histogram: m.Histogram,
|
|
||||||
TimestampMs: m.TimestampMs,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, l := range m.Label {
|
|
||||||
if l.GetName() == MetricNameLabel {
|
|
||||||
if l.Value == nil || IsValidLegacyMetricName(LabelValue(l.GetValue())) {
|
|
||||||
escaped.Label = append(escaped.Label, l)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
escaped.Label = append(escaped.Label, &dto.LabelPair{
|
|
||||||
Name: proto.String(MetricNameLabel),
|
|
||||||
Value: proto.String(EscapeName(l.GetValue(), scheme)),
|
|
||||||
})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if l.Name == nil || IsValidLegacyMetricName(LabelValue(l.GetName())) {
|
|
||||||
escaped.Label = append(escaped.Label, l)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
escaped.Label = append(escaped.Label, &dto.LabelPair{
|
|
||||||
Name: proto.String(EscapeName(l.GetName(), scheme)),
|
|
||||||
Value: l.Value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
out.Metric = append(out.Metric, escaped)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func metricNeedsEscaping(m *dto.Metric) bool {
|
|
||||||
for _, l := range m.Label {
|
|
||||||
if l.GetName() == MetricNameLabel && !IsValidLegacyMetricName(LabelValue(l.GetValue())) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if !IsValidLegacyMetricName(LabelValue(l.GetName())) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
lowerhex = "0123456789abcdef"
|
|
||||||
)
|
|
||||||
|
|
||||||
// EscapeName escapes the incoming name according to the provided escaping
|
|
||||||
// scheme. Depending on the rules of escaping, this may cause no change in the
|
|
||||||
// string that is returned. (Especially NoEscaping, which by definition is a
|
|
||||||
// noop). This function does not do any validation of the name.
|
|
||||||
func EscapeName(name string, scheme EscapingScheme) string {
|
|
||||||
if len(name) == 0 {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
var escaped strings.Builder
|
|
||||||
switch scheme {
|
|
||||||
case NoEscaping:
|
|
||||||
return name
|
|
||||||
case UnderscoreEscaping:
|
|
||||||
if IsValidLegacyMetricName(LabelValue(name)) {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
for i, b := range name {
|
|
||||||
if isValidLegacyRune(b, i) {
|
|
||||||
escaped.WriteRune(b)
|
|
||||||
} else {
|
|
||||||
escaped.WriteRune('_')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return escaped.String()
|
|
||||||
case DotsEscaping:
|
|
||||||
// Do not early return for legacy valid names, we still escape underscores.
|
|
||||||
for i, b := range name {
|
|
||||||
if b == '_' {
|
|
||||||
escaped.WriteString("__")
|
|
||||||
} else if b == '.' {
|
|
||||||
escaped.WriteString("_dot_")
|
|
||||||
} else if isValidLegacyRune(b, i) {
|
|
||||||
escaped.WriteRune(b)
|
|
||||||
} else {
|
|
||||||
escaped.WriteRune('_')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return escaped.String()
|
|
||||||
case ValueEncodingEscaping:
|
|
||||||
if IsValidLegacyMetricName(LabelValue(name)) {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
escaped.WriteString("U__")
|
|
||||||
for i, b := range name {
|
|
||||||
if isValidLegacyRune(b, i) {
|
|
||||||
escaped.WriteRune(b)
|
|
||||||
} else if !utf8.ValidRune(b) {
|
|
||||||
escaped.WriteString("_FFFD_")
|
|
||||||
} else if b < 0x100 {
|
|
||||||
escaped.WriteRune('_')
|
|
||||||
for s := 4; s >= 0; s -= 4 {
|
|
||||||
escaped.WriteByte(lowerhex[b>>uint(s)&0xF])
|
|
||||||
}
|
|
||||||
escaped.WriteRune('_')
|
|
||||||
} else if b < 0x10000 {
|
|
||||||
escaped.WriteRune('_')
|
|
||||||
for s := 12; s >= 0; s -= 4 {
|
|
||||||
escaped.WriteByte(lowerhex[b>>uint(s)&0xF])
|
|
||||||
}
|
|
||||||
escaped.WriteRune('_')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return escaped.String()
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("invalid escaping scheme %d", scheme))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// lower function taken from strconv.atoi
|
|
||||||
func lower(c byte) byte {
|
|
||||||
return c | ('x' - 'X')
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnescapeName unescapes the incoming name according to the provided escaping
|
|
||||||
// scheme if possible. Some schemes are partially or totally non-roundtripable.
|
|
||||||
// If any error is enountered, returns the original input.
|
|
||||||
func UnescapeName(name string, scheme EscapingScheme) string {
|
|
||||||
if len(name) == 0 {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
switch scheme {
|
|
||||||
case NoEscaping:
|
|
||||||
return name
|
|
||||||
case UnderscoreEscaping:
|
|
||||||
// It is not possible to unescape from underscore replacement.
|
|
||||||
return name
|
|
||||||
case DotsEscaping:
|
|
||||||
name = strings.ReplaceAll(name, "_dot_", ".")
|
|
||||||
name = strings.ReplaceAll(name, "__", "_")
|
|
||||||
return name
|
|
||||||
case ValueEncodingEscaping:
|
|
||||||
escapedName, found := strings.CutPrefix(name, "U__")
|
|
||||||
if !found {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
var unescaped strings.Builder
|
|
||||||
TOP:
|
|
||||||
for i := 0; i < len(escapedName); i++ {
|
|
||||||
// All non-underscores are treated normally.
|
|
||||||
if escapedName[i] != '_' {
|
|
||||||
unescaped.WriteByte(escapedName[i])
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
if i >= len(escapedName) {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
// A double underscore is a single underscore.
|
|
||||||
if escapedName[i] == '_' {
|
|
||||||
unescaped.WriteByte('_')
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// We think we are in a UTF-8 code, process it.
|
|
||||||
var utf8Val uint
|
|
||||||
for j := 0; i < len(escapedName); j++ {
|
|
||||||
// This is too many characters for a utf8 value.
|
|
||||||
if j > 4 {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
// Found a closing underscore, convert to a rune, check validity, and append.
|
|
||||||
if escapedName[i] == '_' {
|
|
||||||
utf8Rune := rune(utf8Val)
|
|
||||||
if !utf8.ValidRune(utf8Rune) {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
unescaped.WriteRune(utf8Rune)
|
|
||||||
continue TOP
|
|
||||||
}
|
|
||||||
r := lower(escapedName[i])
|
|
||||||
utf8Val *= 16
|
|
||||||
if r >= '0' && r <= '9' {
|
|
||||||
utf8Val += uint(r) - '0'
|
|
||||||
} else if r >= 'a' && r <= 'f' {
|
|
||||||
utf8Val += uint(r) - 'a' + 10
|
|
||||||
} else {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
// Didn't find closing underscore, invalid.
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
return unescaped.String()
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("invalid escaping scheme %d", scheme))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func isValidLegacyRune(b rune, i int) bool {
|
|
||||||
return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == ':' || (b >= '0' && b <= '9' && i > 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e EscapingScheme) String() string {
|
|
||||||
switch e {
|
|
||||||
case NoEscaping:
|
|
||||||
return AllowUTF8
|
|
||||||
case UnderscoreEscaping:
|
|
||||||
return EscapeUnderscores
|
|
||||||
case DotsEscaping:
|
|
||||||
return EscapeDots
|
|
||||||
case ValueEncodingEscaping:
|
|
||||||
return EscapeValues
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("unknown format scheme %d", e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ToEscapingScheme(s string) (EscapingScheme, error) {
|
|
||||||
if s == "" {
|
|
||||||
return NoEscaping, fmt.Errorf("got empty string instead of escaping scheme")
|
|
||||||
}
|
|
||||||
switch s {
|
|
||||||
case AllowUTF8:
|
|
||||||
return NoEscaping, nil
|
|
||||||
case EscapeUnderscores:
|
|
||||||
return UnderscoreEscaping, nil
|
|
||||||
case EscapeDots:
|
|
||||||
return DotsEscaping, nil
|
|
||||||
case EscapeValues:
|
|
||||||
return ValueEncodingEscaping, nil
|
|
||||||
default:
|
|
||||||
return NoEscaping, fmt.Errorf("unknown format scheme " + s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
10
vendor/go.opentelemetry.io/collector/featuregate/registry.go
generated
vendored
10
vendor/go.opentelemetry.io/collector/featuregate/registry.go
generated
vendored
|
@ -4,7 +4,6 @@
|
||||||
package featuregate // import "go.opentelemetry.io/collector/featuregate"
|
package featuregate // import "go.opentelemetry.io/collector/featuregate"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -23,11 +22,6 @@ var (
|
||||||
idRegexp = regexp.MustCompile(`^[0-9a-zA-Z\.]*$`)
|
idRegexp = regexp.MustCompile(`^[0-9a-zA-Z\.]*$`)
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrAlreadyRegistered is returned when adding a Gate that is already registered.
|
|
||||||
ErrAlreadyRegistered = errors.New("gate is already registered")
|
|
||||||
)
|
|
||||||
|
|
||||||
// GlobalRegistry returns the global Registry.
|
// GlobalRegistry returns the global Registry.
|
||||||
func GlobalRegistry() *Registry {
|
func GlobalRegistry() *Registry {
|
||||||
return globalRegistry
|
return globalRegistry
|
||||||
|
@ -163,7 +157,7 @@ func (r *Registry) Register(id string, stage Stage, opts ...RegisterOption) (*Ga
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, loaded := r.gates.LoadOrStore(id, g); loaded {
|
if _, loaded := r.gates.LoadOrStore(id, g); loaded {
|
||||||
return nil, fmt.Errorf("failed to register %q: %w", id, ErrAlreadyRegistered)
|
return nil, fmt.Errorf("attempted to add pre-existing gate %q", id)
|
||||||
}
|
}
|
||||||
return g, nil
|
return g, nil
|
||||||
}
|
}
|
||||||
|
@ -200,7 +194,7 @@ func (r *Registry) Set(id string, enabled bool) error {
|
||||||
// VisitAll visits all the gates in lexicographical order, calling fn for each.
|
// VisitAll visits all the gates in lexicographical order, calling fn for each.
|
||||||
func (r *Registry) VisitAll(fn func(*Gate)) {
|
func (r *Registry) VisitAll(fn func(*Gate)) {
|
||||||
var gates []*Gate
|
var gates []*Gate
|
||||||
r.gates.Range(func(_, value any) bool {
|
r.gates.Range(func(key, value any) bool {
|
||||||
gates = append(gates, value.(*Gate))
|
gates = append(gates, value.(*Gate))
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
7
vendor/modules.txt
vendored
7
vendor/modules.txt
vendored
|
@ -466,7 +466,7 @@ github.com/prometheus/client_golang/prometheus/testutil/promlint/validations
|
||||||
# github.com/prometheus/client_model v0.6.0
|
# github.com/prometheus/client_model v0.6.0
|
||||||
## explicit; go 1.19
|
## explicit; go 1.19
|
||||||
github.com/prometheus/client_model/go
|
github.com/prometheus/client_model/go
|
||||||
# github.com/prometheus/common v0.48.0
|
# github.com/prometheus/common v0.48.0 => github.com/prometheus/common v0.46.0
|
||||||
## explicit; go 1.20
|
## explicit; go 1.20
|
||||||
github.com/prometheus/common/config
|
github.com/prometheus/common/config
|
||||||
github.com/prometheus/common/expfmt
|
github.com/prometheus/common/expfmt
|
||||||
|
@ -579,8 +579,8 @@ go.opencensus.io/trace
|
||||||
go.opencensus.io/trace/internal
|
go.opencensus.io/trace/internal
|
||||||
go.opencensus.io/trace/propagation
|
go.opencensus.io/trace/propagation
|
||||||
go.opencensus.io/trace/tracestate
|
go.opencensus.io/trace/tracestate
|
||||||
# go.opentelemetry.io/collector/featuregate v1.2.0
|
# go.opentelemetry.io/collector/featuregate v1.0.1
|
||||||
## explicit; go 1.21
|
## explicit; go 1.20
|
||||||
go.opentelemetry.io/collector/featuregate
|
go.opentelemetry.io/collector/featuregate
|
||||||
# go.opentelemetry.io/collector/pdata v1.2.0
|
# go.opentelemetry.io/collector/pdata v1.2.0
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
|
@ -870,3 +870,4 @@ k8s.io/klog/v2/internal/sloghandler
|
||||||
# k8s.io/utils v0.0.0-20240102154912-e7106e64919e
|
# k8s.io/utils v0.0.0-20240102154912-e7106e64919e
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
k8s.io/utils/clock
|
k8s.io/utils/clock
|
||||||
|
# github.com/prometheus/common => github.com/prometheus/common v0.46.0
|
||||||
|
|
Loading…
Reference in a new issue