mirror of
https://github.com/openfaas/faas.git
synced 2025-06-18 03:56:37 +00:00
Merge master into breakout_swarm
Signed-off-by: Alex Ellis <alexellis2@gmail.com>
This commit is contained in:
6
gateway/vendor/github.com/prometheus/common/.travis.yml
generated
vendored
Normal file
6
gateway/vendor/github.com/prometheus/common/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
sudo: false
|
||||
|
||||
language: go
|
||||
go:
|
||||
- 1.7.5
|
||||
- tip
|
18
gateway/vendor/github.com/prometheus/common/CONTRIBUTING.md
generated
vendored
Normal file
18
gateway/vendor/github.com/prometheus/common/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
# Contributing
|
||||
|
||||
Prometheus uses GitHub to manage reviews of pull requests.
|
||||
|
||||
* If you have a trivial fix or improvement, go ahead and create a pull request,
|
||||
addressing (with `@...`) the maintainer of this repository (see
|
||||
[MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request.
|
||||
|
||||
* If you plan to do something more involved, first discuss your ideas
|
||||
on our [mailing list](https://groups.google.com/forum/?fromgroups#!forum/prometheus-developers).
|
||||
This will avoid unnecessary work and surely give you and us a good deal
|
||||
of inspiration.
|
||||
|
||||
* Relevant coding style guidelines are the [Go Code Review
|
||||
Comments](https://code.google.com/p/go-wiki/wiki/CodeReviewComments)
|
||||
and the _Formatting and style_ section of Peter Bourgon's [Go: Best
|
||||
Practices for Production
|
||||
Environments](http://peter.bourgon.org/go-in-production/#formatting-and-style).
|
1
gateway/vendor/github.com/prometheus/common/MAINTAINERS.md
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/MAINTAINERS.md
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
* Fabian Reinartz <fabian.reinartz@coreos.com>
|
47
gateway/vendor/github.com/prometheus/common/config/config.go
generated
vendored
Normal file
47
gateway/vendor/github.com/prometheus/common/config/config.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2016 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func checkOverflow(m map[string]interface{}, ctx string) error {
|
||||
if len(m) > 0 {
|
||||
var keys []string
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
return fmt.Errorf("unknown fields in %s: %s", ctx, strings.Join(keys, ", "))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Secret special type for storing secrets.
|
||||
type Secret string
|
||||
|
||||
// MarshalYAML implements the yaml.Marshaler interface for Secrets.
|
||||
func (s Secret) MarshalYAML() (interface{}, error) {
|
||||
if s != "" {
|
||||
return "<secret>", nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
//UnmarshalYAML implements the yaml.Unmarshaler interface for Secrets.
|
||||
func (s *Secret) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
type plain Secret
|
||||
return unmarshal((*plain)(s))
|
||||
}
|
279
gateway/vendor/github.com/prometheus/common/config/http_config.go
generated
vendored
Normal file
279
gateway/vendor/github.com/prometheus/common/config/http_config.go
generated
vendored
Normal file
@ -0,0 +1,279 @@
|
||||
// Copyright 2016 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// BasicAuth contains basic HTTP authentication credentials.
|
||||
type BasicAuth struct {
|
||||
Username string `yaml:"username"`
|
||||
Password Secret `yaml:"password"`
|
||||
|
||||
// Catches all undefined fields and must be empty after parsing.
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// URL is a custom URL type that allows validation at configuration load time.
|
||||
type URL struct {
|
||||
*url.URL
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface for URLs.
|
||||
func (u *URL) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
var s string
|
||||
if err := unmarshal(&s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
urlp, err := url.Parse(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.URL = urlp
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalYAML implements the yaml.Marshaler interface for URLs.
|
||||
func (u URL) MarshalYAML() (interface{}, error) {
|
||||
if u.URL != nil {
|
||||
return u.String(), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// HTTPClientConfig configures an HTTP client.
|
||||
type HTTPClientConfig struct {
|
||||
// The HTTP basic authentication credentials for the targets.
|
||||
BasicAuth *BasicAuth `yaml:"basic_auth,omitempty"`
|
||||
// The bearer token for the targets.
|
||||
BearerToken Secret `yaml:"bearer_token,omitempty"`
|
||||
// The bearer token file for the targets.
|
||||
BearerTokenFile string `yaml:"bearer_token_file,omitempty"`
|
||||
// HTTP proxy server to use to connect to the targets.
|
||||
ProxyURL URL `yaml:"proxy_url,omitempty"`
|
||||
// TLSConfig to use to connect to the targets.
|
||||
TLSConfig TLSConfig `yaml:"tls_config,omitempty"`
|
||||
|
||||
// Catches all undefined fields and must be empty after parsing.
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
func (c *HTTPClientConfig) validate() error {
|
||||
if len(c.BearerToken) > 0 && len(c.BearerTokenFile) > 0 {
|
||||
return fmt.Errorf("at most one of bearer_token & bearer_token_file must be configured")
|
||||
}
|
||||
if c.BasicAuth != nil && (len(c.BearerToken) > 0 || len(c.BearerTokenFile) > 0) {
|
||||
return fmt.Errorf("at most one of basic_auth, bearer_token & bearer_token_file must be configured")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface
|
||||
func (c *HTTPClientConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
type plain HTTPClientConfig
|
||||
err := unmarshal((*plain)(c))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = c.validate()
|
||||
if err != nil {
|
||||
return c.validate()
|
||||
}
|
||||
return checkOverflow(c.XXX, "http_client_config")
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||
func (a *BasicAuth) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
type plain BasicAuth
|
||||
err := unmarshal((*plain)(a))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return checkOverflow(a.XXX, "basic_auth")
|
||||
}
|
||||
|
||||
// NewHTTPClientFromConfig returns a new HTTP client configured for the
|
||||
// given config.HTTPClientConfig.
|
||||
func NewHTTPClientFromConfig(cfg *HTTPClientConfig) (*http.Client, error) {
|
||||
tlsConfig, err := NewTLSConfig(&cfg.TLSConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// It's the caller's job to handle timeouts
|
||||
var rt http.RoundTripper = &http.Transport{
|
||||
Proxy: http.ProxyURL(cfg.ProxyURL.URL),
|
||||
DisableKeepAlives: true,
|
||||
TLSClientConfig: tlsConfig,
|
||||
}
|
||||
|
||||
// If a bearer token is provided, create a round tripper that will set the
|
||||
// Authorization header correctly on each request.
|
||||
bearerToken := cfg.BearerToken
|
||||
if len(bearerToken) == 0 && len(cfg.BearerTokenFile) > 0 {
|
||||
b, err := ioutil.ReadFile(cfg.BearerTokenFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read bearer token file %s: %s", cfg.BearerTokenFile, err)
|
||||
}
|
||||
bearerToken = Secret(strings.TrimSpace(string(b)))
|
||||
}
|
||||
|
||||
if len(bearerToken) > 0 {
|
||||
rt = NewBearerAuthRoundTripper(bearerToken, rt)
|
||||
}
|
||||
|
||||
if cfg.BasicAuth != nil {
|
||||
rt = NewBasicAuthRoundTripper(cfg.BasicAuth.Username, Secret(cfg.BasicAuth.Password), rt)
|
||||
}
|
||||
|
||||
// Return a new client with the configured round tripper.
|
||||
return &http.Client{Transport: rt}, nil
|
||||
}
|
||||
|
||||
type bearerAuthRoundTripper struct {
|
||||
bearerToken Secret
|
||||
rt http.RoundTripper
|
||||
}
|
||||
|
||||
type basicAuthRoundTripper struct {
|
||||
username string
|
||||
password Secret
|
||||
rt http.RoundTripper
|
||||
}
|
||||
|
||||
// NewBasicAuthRoundTripper will apply a BASIC auth authorization header to a request unless it has
|
||||
// already been set.
|
||||
func NewBasicAuthRoundTripper(username string, password Secret, rt http.RoundTripper) http.RoundTripper {
|
||||
return &basicAuthRoundTripper{username, password, rt}
|
||||
}
|
||||
|
||||
func (rt *bearerAuthRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
if len(req.Header.Get("Authorization")) == 0 {
|
||||
req = cloneRequest(req)
|
||||
req.Header.Set("Authorization", "Bearer "+string(rt.bearerToken))
|
||||
}
|
||||
|
||||
return rt.rt.RoundTrip(req)
|
||||
}
|
||||
|
||||
// NewBearerAuthRoundTripper adds the provided bearer token to a request unless the authorization
|
||||
// header has already been set.
|
||||
func NewBearerAuthRoundTripper(bearer Secret, rt http.RoundTripper) http.RoundTripper {
|
||||
return &bearerAuthRoundTripper{bearer, rt}
|
||||
}
|
||||
|
||||
func (rt *basicAuthRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
if len(req.Header.Get("Authorization")) != 0 {
|
||||
return rt.RoundTrip(req)
|
||||
}
|
||||
req = cloneRequest(req)
|
||||
req.SetBasicAuth(rt.username, string(rt.password))
|
||||
return rt.rt.RoundTrip(req)
|
||||
}
|
||||
|
||||
// cloneRequest returns a clone of the provided *http.Request.
|
||||
// The clone is a shallow copy of the struct and its Header map.
|
||||
func cloneRequest(r *http.Request) *http.Request {
|
||||
// Shallow copy of the struct.
|
||||
r2 := new(http.Request)
|
||||
*r2 = *r
|
||||
// Deep copy of the Header.
|
||||
r2.Header = make(http.Header)
|
||||
for k, s := range r.Header {
|
||||
r2.Header[k] = s
|
||||
}
|
||||
return r2
|
||||
}
|
||||
|
||||
// NewTLSConfig creates a new tls.Config from the given config.TLSConfig.
|
||||
func NewTLSConfig(cfg *TLSConfig) (*tls.Config, error) {
|
||||
tlsConfig := &tls.Config{InsecureSkipVerify: cfg.InsecureSkipVerify}
|
||||
|
||||
// If a CA cert is provided then let's read it in so we can validate the
|
||||
// scrape target's certificate properly.
|
||||
if len(cfg.CAFile) > 0 {
|
||||
caCertPool := x509.NewCertPool()
|
||||
// Load CA cert.
|
||||
caCert, err := ioutil.ReadFile(cfg.CAFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to use specified CA cert %s: %s", cfg.CAFile, err)
|
||||
}
|
||||
caCertPool.AppendCertsFromPEM(caCert)
|
||||
tlsConfig.RootCAs = caCertPool
|
||||
}
|
||||
|
||||
if len(cfg.ServerName) > 0 {
|
||||
tlsConfig.ServerName = cfg.ServerName
|
||||
}
|
||||
|
||||
// If a client cert & key is provided then configure TLS config accordingly.
|
||||
if len(cfg.CertFile) > 0 && len(cfg.KeyFile) == 0 {
|
||||
return nil, fmt.Errorf("client cert file %q specified without client key file", cfg.CertFile)
|
||||
} else if len(cfg.KeyFile) > 0 && len(cfg.CertFile) == 0 {
|
||||
return nil, fmt.Errorf("client key file %q specified without client cert file", cfg.KeyFile)
|
||||
} else if len(cfg.CertFile) > 0 && len(cfg.KeyFile) > 0 {
|
||||
cert, err := tls.LoadX509KeyPair(cfg.CertFile, cfg.KeyFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to use specified client cert (%s) & key (%s): %s", cfg.CertFile, cfg.KeyFile, err)
|
||||
}
|
||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
tlsConfig.BuildNameToCertificate()
|
||||
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
||||
// TLSConfig configures the options for TLS connections.
|
||||
type TLSConfig struct {
|
||||
// The CA cert to use for the targets.
|
||||
CAFile string `yaml:"ca_file,omitempty"`
|
||||
// The client cert file for the targets.
|
||||
CertFile string `yaml:"cert_file,omitempty"`
|
||||
// The client key file for the targets.
|
||||
KeyFile string `yaml:"key_file,omitempty"`
|
||||
// Used to verify the hostname for the targets.
|
||||
ServerName string `yaml:"server_name,omitempty"`
|
||||
// Disable target certificate validation.
|
||||
InsecureSkipVerify bool `yaml:"insecure_skip_verify"`
|
||||
|
||||
// Catches all undefined fields and must be empty after parsing.
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||
func (c *TLSConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
type plain TLSConfig
|
||||
if err := unmarshal((*plain)(c)); err != nil {
|
||||
return err
|
||||
}
|
||||
return checkOverflow(c.XXX, "TLS config")
|
||||
}
|
||||
|
||||
func (c HTTPClientConfig) String() string {
|
||||
b, err := yaml.Marshal(c)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("<error creating http client config string: %s>", err)
|
||||
}
|
||||
return string(b)
|
||||
}
|
157
gateway/vendor/github.com/prometheus/common/config/http_config_test.go
generated
vendored
Normal file
157
gateway/vendor/github.com/prometheus/common/config/http_config_test.go
generated
vendored
Normal file
@ -0,0 +1,157 @@
|
||||
// Copyright 2015 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
var invalidHTTPClientConfigs = []struct {
|
||||
httpClientConfigFile string
|
||||
errMsg string
|
||||
}{
|
||||
{
|
||||
httpClientConfigFile: "testdata/http.conf.bearer-token-and-file-set.bad.yml",
|
||||
errMsg: "at most one of bearer_token & bearer_token_file must be configured",
|
||||
},
|
||||
{
|
||||
httpClientConfigFile: "testdata/http.conf.empty.bad.yml",
|
||||
errMsg: "at most one of basic_auth, bearer_token & bearer_token_file must be configured",
|
||||
},
|
||||
}
|
||||
|
||||
func TestAuthRoundTrippers(t *testing.T) {
|
||||
|
||||
cfg, _, err := LoadHTTPConfigFile("testdata/http.conf.good.yml")
|
||||
if err != nil {
|
||||
t.Errorf("Error loading HTTP client config: %v", err)
|
||||
}
|
||||
|
||||
tlsConfig, err := NewTLSConfig(&cfg.TLSConfig)
|
||||
if err != nil {
|
||||
t.Errorf("Error creating new TLS config: %v", err)
|
||||
}
|
||||
|
||||
rt := &http.Transport{
|
||||
Proxy: http.ProxyURL(cfg.ProxyURL.URL),
|
||||
DisableKeepAlives: true,
|
||||
TLSClientConfig: tlsConfig,
|
||||
}
|
||||
req := new(http.Request)
|
||||
|
||||
bearerAuthRoundTripper := NewBearerAuthRoundTripper("mysecret", rt)
|
||||
bearerAuthRoundTripper.RoundTrip(req)
|
||||
|
||||
basicAuthRoundTripper := NewBasicAuthRoundTripper("username", "password", rt)
|
||||
basicAuthRoundTripper.RoundTrip(req)
|
||||
}
|
||||
|
||||
func TestHideHTTPClientConfigSecrets(t *testing.T) {
|
||||
c, _, err := LoadHTTPConfigFile("testdata/http.conf.good.yml")
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing %s: %s", "testdata/http.conf.good.yml", err)
|
||||
}
|
||||
|
||||
// String method must not reveal authentication credentials.
|
||||
s := c.String()
|
||||
if strings.Contains(s, "mysecret") {
|
||||
t.Fatal("http client config's String method reveals authentication credentials.")
|
||||
}
|
||||
}
|
||||
|
||||
func mustParseURL(u string) *URL {
|
||||
parsed, err := url.Parse(u)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &URL{URL: parsed}
|
||||
}
|
||||
|
||||
func TestNewClientFromConfig(t *testing.T) {
|
||||
cfg, _, err := LoadHTTPConfigFile("testdata/http.conf.good.yml")
|
||||
if err != nil {
|
||||
t.Errorf("Error loading HTTP client config: %v", err)
|
||||
}
|
||||
_, err = NewHTTPClientFromConfig(cfg)
|
||||
if err != nil {
|
||||
t.Errorf("Error creating new client from config: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewClientFromInvalidConfig(t *testing.T) {
|
||||
cfg, _, err := LoadHTTPConfigFile("testdata/http.conf.invalid-bearer-token-file.bad.yml")
|
||||
if err != nil {
|
||||
t.Errorf("Error loading HTTP client config: %v", err)
|
||||
}
|
||||
_, err = NewHTTPClientFromConfig(cfg)
|
||||
if err == nil {
|
||||
t.Error("Expected error creating new client from invalid config but got none")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "unable to read bearer token file file: open file: no such file or directory") {
|
||||
t.Errorf("Expected error with config but got: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateHTTPConfig(t *testing.T) {
|
||||
cfg, _, err := LoadHTTPConfigFile("testdata/http.conf.good.yml")
|
||||
if err != nil {
|
||||
t.Errorf("Error loading HTTP client config: %v", err)
|
||||
}
|
||||
err = cfg.validate()
|
||||
if err != nil {
|
||||
t.Fatalf("Error validating %s: %s", "testdata/http.conf.good.yml", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidHTTPConfigs(t *testing.T) {
|
||||
for _, ee := range invalidHTTPClientConfigs {
|
||||
_, _, err := LoadHTTPConfigFile(ee.httpClientConfigFile)
|
||||
if err == nil {
|
||||
t.Error("Expected error with config but got none")
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(err.Error(), ee.errMsg) {
|
||||
t.Errorf("Expected error for invalid HTTP client configuration to contain %q but got: %s", ee.errMsg, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LoadHTTPConfig parses the YAML input s into a HTTPClientConfig.
|
||||
func LoadHTTPConfig(s string) (*HTTPClientConfig, error) {
|
||||
cfg := &HTTPClientConfig{}
|
||||
err := yaml.Unmarshal([]byte(s), cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
// LoadHTTPConfigFile parses the given YAML file into a HTTPClientConfig.
|
||||
func LoadHTTPConfigFile(filename string) (*HTTPClientConfig, []byte, error) {
|
||||
content, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
cfg, err := LoadHTTPConfig(string(content))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return cfg, content, nil
|
||||
}
|
5
gateway/vendor/github.com/prometheus/common/config/testdata/http.conf.bearer-token-and-file-set.bad.yml
generated
vendored
Normal file
5
gateway/vendor/github.com/prometheus/common/config/testdata/http.conf.bearer-token-and-file-set.bad.yml
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
basic_auth:
|
||||
username: username
|
||||
password: "mysecret"
|
||||
bearer_token: mysecret
|
||||
bearer_token_file: file
|
4
gateway/vendor/github.com/prometheus/common/config/testdata/http.conf.empty.bad.yml
generated
vendored
Normal file
4
gateway/vendor/github.com/prometheus/common/config/testdata/http.conf.empty.bad.yml
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
basic_auth:
|
||||
username: username
|
||||
password: mysecret
|
||||
bearer_token_file: file
|
4
gateway/vendor/github.com/prometheus/common/config/testdata/http.conf.good.yml
generated
vendored
Normal file
4
gateway/vendor/github.com/prometheus/common/config/testdata/http.conf.good.yml
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
basic_auth:
|
||||
username: username
|
||||
password: "mysecret"
|
||||
proxy_url: "http://remote.host"
|
1
gateway/vendor/github.com/prometheus/common/config/testdata/http.conf.invalid-bearer-token-file.bad.yml
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/config/testdata/http.conf.invalid-bearer-token-file.bad.yml
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
bearer_token_file: file
|
1
gateway/vendor/github.com/prometheus/common/config/testdata/tls_config.cert_no_key.bad.yml
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/config/testdata/tls_config.cert_no_key.bad.yml
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
cert_file: somefile
|
0
gateway/vendor/github.com/prometheus/common/config/testdata/tls_config.empty.good.yml
generated
vendored
Normal file
0
gateway/vendor/github.com/prometheus/common/config/testdata/tls_config.empty.good.yml
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/config/testdata/tls_config.insecure.good.yml
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/config/testdata/tls_config.insecure.good.yml
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
insecure_skip_verify: true
|
1
gateway/vendor/github.com/prometheus/common/config/testdata/tls_config.invalid_field.bad.yml
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/config/testdata/tls_config.invalid_field.bad.yml
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
something_invalid: true
|
1
gateway/vendor/github.com/prometheus/common/config/testdata/tls_config.key_no_cert.bad.yml
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/config/testdata/tls_config.key_no_cert.bad.yml
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
key_file: somefile
|
92
gateway/vendor/github.com/prometheus/common/config/tls_config_test.go
generated
vendored
Normal file
92
gateway/vendor/github.com/prometheus/common/config/tls_config_test.go
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright 2016 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// LoadTLSConfig parses the given YAML file into a tls.Config.
|
||||
func LoadTLSConfig(filename string) (*tls.Config, error) {
|
||||
content, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg := &TLSConfig{}
|
||||
if err = yaml.Unmarshal(content, cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewTLSConfig(cfg)
|
||||
}
|
||||
|
||||
var expectedTLSConfigs = []struct {
|
||||
filename string
|
||||
config *tls.Config
|
||||
}{
|
||||
{
|
||||
filename: "tls_config.empty.good.yml",
|
||||
config: &tls.Config{},
|
||||
}, {
|
||||
filename: "tls_config.insecure.good.yml",
|
||||
config: &tls.Config{InsecureSkipVerify: true},
|
||||
},
|
||||
}
|
||||
|
||||
func TestValidTLSConfig(t *testing.T) {
|
||||
for _, cfg := range expectedTLSConfigs {
|
||||
cfg.config.BuildNameToCertificate()
|
||||
got, err := LoadTLSConfig("testdata/" + cfg.filename)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing %s: %s", cfg.filename, err)
|
||||
}
|
||||
if !reflect.DeepEqual(*got, *cfg.config) {
|
||||
t.Fatalf("%v: unexpected config result: \n\n%v\n expected\n\n%v", cfg.filename, got, cfg.config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var expectedTLSConfigErrors = []struct {
|
||||
filename string
|
||||
errMsg string
|
||||
}{
|
||||
{
|
||||
filename: "tls_config.invalid_field.bad.yml",
|
||||
errMsg: "unknown fields in",
|
||||
}, {
|
||||
filename: "tls_config.cert_no_key.bad.yml",
|
||||
errMsg: "specified without client key file",
|
||||
}, {
|
||||
filename: "tls_config.key_no_cert.bad.yml",
|
||||
errMsg: "specified without client cert file",
|
||||
},
|
||||
}
|
||||
|
||||
func TestBadTLSConfigs(t *testing.T) {
|
||||
for _, ee := range expectedTLSConfigErrors {
|
||||
_, err := LoadTLSConfig("testdata/" + ee.filename)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error parsing %s but got none", ee.filename)
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(err.Error(), ee.errMsg) {
|
||||
t.Errorf("Expected error for %s to contain %q but got: %s", ee.filename, ee.errMsg, err)
|
||||
}
|
||||
}
|
||||
}
|
167
gateway/vendor/github.com/prometheus/common/expfmt/bench_test.go
generated
vendored
Normal file
167
gateway/vendor/github.com/prometheus/common/expfmt/bench_test.go
generated
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
// Copyright 2015 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package expfmt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/matttproud/golang_protobuf_extensions/pbutil"
|
||||
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
)
|
||||
|
||||
var parser TextParser
|
||||
|
||||
// Benchmarks to show how much penalty text format parsing actually inflicts.
|
||||
//
|
||||
// Example results on Linux 3.13.0, Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz, go1.4.
|
||||
//
|
||||
// BenchmarkParseText 1000 1188535 ns/op 205085 B/op 6135 allocs/op
|
||||
// BenchmarkParseTextGzip 1000 1376567 ns/op 246224 B/op 6151 allocs/op
|
||||
// BenchmarkParseProto 10000 172790 ns/op 52258 B/op 1160 allocs/op
|
||||
// BenchmarkParseProtoGzip 5000 324021 ns/op 94931 B/op 1211 allocs/op
|
||||
// BenchmarkParseProtoMap 10000 187946 ns/op 58714 B/op 1203 allocs/op
|
||||
//
|
||||
// CONCLUSION: The overhead for the map is negligible. Text format needs ~5x more allocations.
|
||||
// Without compression, it needs ~7x longer, but with compression (the more relevant scenario),
|
||||
// the difference becomes less relevant, only ~4x.
|
||||
//
|
||||
// The test data contains 248 samples.
|
||||
|
||||
// BenchmarkParseText benchmarks the parsing of a text-format scrape into metric
|
||||
// family DTOs.
|
||||
func BenchmarkParseText(b *testing.B) {
|
||||
b.StopTimer()
|
||||
data, err := ioutil.ReadFile("testdata/text")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, err := parser.TextToMetricFamilies(bytes.NewReader(data)); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkParseTextGzip benchmarks the parsing of a gzipped text-format scrape
|
||||
// into metric family DTOs.
|
||||
func BenchmarkParseTextGzip(b *testing.B) {
|
||||
b.StopTimer()
|
||||
data, err := ioutil.ReadFile("testdata/text.gz")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
in, err := gzip.NewReader(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
if _, err := parser.TextToMetricFamilies(in); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkParseProto benchmarks the parsing of a protobuf-format scrape into
|
||||
// metric family DTOs. Note that this does not build a map of metric families
|
||||
// (as the text version does), because it is not required for Prometheus
|
||||
// ingestion either. (However, it is required for the text-format parsing, as
|
||||
// the metric family might be sprinkled all over the text, while the
|
||||
// protobuf-format guarantees bundling at one place.)
|
||||
func BenchmarkParseProto(b *testing.B) {
|
||||
b.StopTimer()
|
||||
data, err := ioutil.ReadFile("testdata/protobuf")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
family := &dto.MetricFamily{}
|
||||
in := bytes.NewReader(data)
|
||||
for {
|
||||
family.Reset()
|
||||
if _, err := pbutil.ReadDelimited(in, family); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkParseProtoGzip is like BenchmarkParseProto above, but parses gzipped
|
||||
// protobuf format.
|
||||
func BenchmarkParseProtoGzip(b *testing.B) {
|
||||
b.StopTimer()
|
||||
data, err := ioutil.ReadFile("testdata/protobuf.gz")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
family := &dto.MetricFamily{}
|
||||
in, err := gzip.NewReader(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
for {
|
||||
family.Reset()
|
||||
if _, err := pbutil.ReadDelimited(in, family); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkParseProtoMap is like BenchmarkParseProto but DOES put the parsed
|
||||
// metric family DTOs into a map. This is not happening during Prometheus
|
||||
// ingestion. It is just here to measure the overhead of that map creation and
|
||||
// separate it from the overhead of the text format parsing.
|
||||
func BenchmarkParseProtoMap(b *testing.B) {
|
||||
b.StopTimer()
|
||||
data, err := ioutil.ReadFile("testdata/protobuf")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
families := map[string]*dto.MetricFamily{}
|
||||
in := bytes.NewReader(data)
|
||||
for {
|
||||
family := &dto.MetricFamily{}
|
||||
if _, err := pbutil.ReadDelimited(in, family); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
b.Fatal(err)
|
||||
}
|
||||
families[family.GetName()] = family
|
||||
}
|
||||
}
|
||||
}
|
435
gateway/vendor/github.com/prometheus/common/expfmt/decode_test.go
generated
vendored
Normal file
435
gateway/vendor/github.com/prometheus/common/expfmt/decode_test.go
generated
vendored
Normal file
@ -0,0 +1,435 @@
|
||||
// Copyright 2015 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package expfmt
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
|
||||
"github.com/prometheus/common/model"
|
||||
)
|
||||
|
||||
func TestTextDecoder(t *testing.T) {
|
||||
var (
|
||||
ts = model.Now()
|
||||
in = `
|
||||
# Only a quite simple scenario with two metric families.
|
||||
# More complicated tests of the parser itself can be found in the text package.
|
||||
# TYPE mf2 counter
|
||||
mf2 3
|
||||
mf1{label="value1"} -3.14 123456
|
||||
mf1{label="value2"} 42
|
||||
mf2 4
|
||||
`
|
||||
out = model.Vector{
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "mf1",
|
||||
"label": "value1",
|
||||
},
|
||||
Value: -3.14,
|
||||
Timestamp: 123456,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "mf1",
|
||||
"label": "value2",
|
||||
},
|
||||
Value: 42,
|
||||
Timestamp: ts,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "mf2",
|
||||
},
|
||||
Value: 3,
|
||||
Timestamp: ts,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "mf2",
|
||||
},
|
||||
Value: 4,
|
||||
Timestamp: ts,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
dec := &SampleDecoder{
|
||||
Dec: &textDecoder{r: strings.NewReader(in)},
|
||||
Opts: &DecodeOptions{
|
||||
Timestamp: ts,
|
||||
},
|
||||
}
|
||||
var all model.Vector
|
||||
for {
|
||||
var smpls model.Vector
|
||||
err := dec.Decode(&smpls)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
all = append(all, smpls...)
|
||||
}
|
||||
sort.Sort(all)
|
||||
sort.Sort(out)
|
||||
if !reflect.DeepEqual(all, out) {
|
||||
t.Fatalf("output does not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProtoDecoder(t *testing.T) {
|
||||
|
||||
var testTime = model.Now()
|
||||
|
||||
scenarios := []struct {
|
||||
in string
|
||||
expected model.Vector
|
||||
fail bool
|
||||
}{
|
||||
{
|
||||
in: "",
|
||||
},
|
||||
{
|
||||
in: "\x8f\x01\n\rrequest_count\x12\x12Number of requests\x18\x00\"0\n#\n\x0fsome_!abel_name\x12\x10some_label_value\x1a\t\t\x00\x00\x00\x00\x00\x00E\xc0\"6\n)\n\x12another_label_name\x12\x13another_label_value\x1a\t\t\x00\x00\x00\x00\x00\x00U@",
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
in: "\x8f\x01\n\rrequest_count\x12\x12Number of requests\x18\x00\"0\n#\n\x0fsome_label_name\x12\x10some_label_value\x1a\t\t\x00\x00\x00\x00\x00\x00E\xc0\"6\n)\n\x12another_label_name\x12\x13another_label_value\x1a\t\t\x00\x00\x00\x00\x00\x00U@",
|
||||
expected: model.Vector{
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_count",
|
||||
"some_label_name": "some_label_value",
|
||||
},
|
||||
Value: -42,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_count",
|
||||
"another_label_name": "another_label_value",
|
||||
},
|
||||
Value: 84,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
in: "\xb9\x01\n\rrequest_count\x12\x12Number of requests\x18\x02\"O\n#\n\x0fsome_label_name\x12\x10some_label_value\"(\x1a\x12\t\xaeG\xe1z\x14\xae\xef?\x11\x00\x00\x00\x00\x00\x00E\xc0\x1a\x12\t+\x87\x16\xd9\xce\xf7\xef?\x11\x00\x00\x00\x00\x00\x00U\xc0\"A\n)\n\x12another_label_name\x12\x13another_label_value\"\x14\x1a\x12\t\x00\x00\x00\x00\x00\x00\xe0?\x11\x00\x00\x00\x00\x00\x00$@",
|
||||
expected: model.Vector{
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_count_count",
|
||||
"some_label_name": "some_label_value",
|
||||
},
|
||||
Value: 0,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_count_sum",
|
||||
"some_label_name": "some_label_value",
|
||||
},
|
||||
Value: 0,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_count",
|
||||
"some_label_name": "some_label_value",
|
||||
"quantile": "0.99",
|
||||
},
|
||||
Value: -42,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_count",
|
||||
"some_label_name": "some_label_value",
|
||||
"quantile": "0.999",
|
||||
},
|
||||
Value: -84,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_count_count",
|
||||
"another_label_name": "another_label_value",
|
||||
},
|
||||
Value: 0,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_count_sum",
|
||||
"another_label_name": "another_label_value",
|
||||
},
|
||||
Value: 0,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_count",
|
||||
"another_label_name": "another_label_value",
|
||||
"quantile": "0.5",
|
||||
},
|
||||
Value: 10,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
in: "\x8d\x01\n\x1drequest_duration_microseconds\x12\x15The response latency.\x18\x04\"S:Q\b\x85\x15\x11\xcd\xcc\xccL\x8f\xcb:A\x1a\v\b{\x11\x00\x00\x00\x00\x00\x00Y@\x1a\f\b\x9c\x03\x11\x00\x00\x00\x00\x00\x00^@\x1a\f\b\xd0\x04\x11\x00\x00\x00\x00\x00\x00b@\x1a\f\b\xf4\v\x11\x9a\x99\x99\x99\x99\x99e@\x1a\f\b\x85\x15\x11\x00\x00\x00\x00\x00\x00\xf0\u007f",
|
||||
expected: model.Vector{
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_duration_microseconds_bucket",
|
||||
"le": "100",
|
||||
},
|
||||
Value: 123,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_duration_microseconds_bucket",
|
||||
"le": "120",
|
||||
},
|
||||
Value: 412,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_duration_microseconds_bucket",
|
||||
"le": "144",
|
||||
},
|
||||
Value: 592,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_duration_microseconds_bucket",
|
||||
"le": "172.8",
|
||||
},
|
||||
Value: 1524,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_duration_microseconds_bucket",
|
||||
"le": "+Inf",
|
||||
},
|
||||
Value: 2693,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_duration_microseconds_sum",
|
||||
},
|
||||
Value: 1756047.3,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_duration_microseconds_count",
|
||||
},
|
||||
Value: 2693,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// The metric type is unset in this protobuf, which needs to be handled
|
||||
// correctly by the decoder.
|
||||
in: "\x1c\n\rrequest_count\"\v\x1a\t\t\x00\x00\x00\x00\x00\x00\xf0?",
|
||||
expected: model.Vector{
|
||||
&model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "request_count",
|
||||
},
|
||||
Value: 1,
|
||||
Timestamp: testTime,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
dec := &SampleDecoder{
|
||||
Dec: &protoDecoder{r: strings.NewReader(scenario.in)},
|
||||
Opts: &DecodeOptions{
|
||||
Timestamp: testTime,
|
||||
},
|
||||
}
|
||||
|
||||
var all model.Vector
|
||||
for {
|
||||
var smpls model.Vector
|
||||
err := dec.Decode(&smpls)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if scenario.fail {
|
||||
if err == nil {
|
||||
t.Fatal("Expected error but got none")
|
||||
}
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
all = append(all, smpls...)
|
||||
}
|
||||
sort.Sort(all)
|
||||
sort.Sort(scenario.expected)
|
||||
if !reflect.DeepEqual(all, scenario.expected) {
|
||||
t.Fatalf("%d. output does not match, want: %#v, got %#v", i, scenario.expected, all)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testDiscriminatorHTTPHeader(t testing.TB) {
|
||||
var scenarios = []struct {
|
||||
input map[string]string
|
||||
output Format
|
||||
err error
|
||||
}{
|
||||
{
|
||||
input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="io.prometheus.client.MetricFamily"; encoding="delimited"`},
|
||||
output: FmtProtoDelim,
|
||||
},
|
||||
{
|
||||
input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="illegal"; encoding="delimited"`},
|
||||
output: FmtUnknown,
|
||||
},
|
||||
{
|
||||
input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="io.prometheus.client.MetricFamily"; encoding="illegal"`},
|
||||
output: FmtUnknown,
|
||||
},
|
||||
{
|
||||
input: map[string]string{"Content-Type": `text/plain; version=0.0.4`},
|
||||
output: FmtText,
|
||||
},
|
||||
{
|
||||
input: map[string]string{"Content-Type": `text/plain`},
|
||||
output: FmtText,
|
||||
},
|
||||
{
|
||||
input: map[string]string{"Content-Type": `text/plain; version=0.0.3`},
|
||||
output: FmtUnknown,
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
var header http.Header
|
||||
|
||||
if len(scenario.input) > 0 {
|
||||
header = http.Header{}
|
||||
}
|
||||
|
||||
for key, value := range scenario.input {
|
||||
header.Add(key, value)
|
||||
}
|
||||
|
||||
actual := ResponseFormat(header)
|
||||
|
||||
if scenario.output != actual {
|
||||
t.Errorf("%d. expected %s, got %s", i, scenario.output, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiscriminatorHTTPHeader(t *testing.T) {
|
||||
testDiscriminatorHTTPHeader(t)
|
||||
}
|
||||
|
||||
func BenchmarkDiscriminatorHTTPHeader(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
testDiscriminatorHTTPHeader(b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractSamples(t *testing.T) {
|
||||
var (
|
||||
goodMetricFamily1 = &dto.MetricFamily{
|
||||
Name: proto.String("foo"),
|
||||
Help: proto.String("Help for foo."),
|
||||
Type: dto.MetricType_COUNTER.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Counter: &dto.Counter{
|
||||
Value: proto.Float64(4711),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
goodMetricFamily2 = &dto.MetricFamily{
|
||||
Name: proto.String("bar"),
|
||||
Help: proto.String("Help for bar."),
|
||||
Type: dto.MetricType_GAUGE.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Gauge: &dto.Gauge{
|
||||
Value: proto.Float64(3.14),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
badMetricFamily = &dto.MetricFamily{
|
||||
Name: proto.String("bad"),
|
||||
Help: proto.String("Help for bad."),
|
||||
Type: dto.MetricType(42).Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Gauge: &dto.Gauge{
|
||||
Value: proto.Float64(2.7),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
opts = &DecodeOptions{
|
||||
Timestamp: 42,
|
||||
}
|
||||
)
|
||||
|
||||
got, err := ExtractSamples(opts, goodMetricFamily1, goodMetricFamily2)
|
||||
if err != nil {
|
||||
t.Error("Unexpected error from ExtractSamples:", err)
|
||||
}
|
||||
want := model.Vector{
|
||||
&model.Sample{Metric: model.Metric{model.MetricNameLabel: "foo"}, Value: 4711, Timestamp: 42},
|
||||
&model.Sample{Metric: model.Metric{model.MetricNameLabel: "bar"}, Value: 3.14, Timestamp: 42},
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("unexpected samples extracted, got: %v, want: %v", got, want)
|
||||
}
|
||||
|
||||
got, err = ExtractSamples(opts, goodMetricFamily1, badMetricFamily, goodMetricFamily2)
|
||||
if err == nil {
|
||||
t.Error("Expected error from ExtractSamples")
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("unexpected samples extracted, got: %v, want: %v", got, want)
|
||||
}
|
||||
}
|
2
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_0
generated
vendored
Normal file
2
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_0
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
|
6
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_1
generated
vendored
Normal file
6
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_1
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
minimal_metric 1.234
|
||||
another_metric -3e3 103948
|
||||
# Even that:
|
||||
no_labels{} 3
|
||||
# HELP line for non-existing metric will be ignored.
|
12
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_2
generated
vendored
Normal file
12
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_2
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
# A normal comment.
|
||||
#
|
||||
# TYPE name counter
|
||||
name{labelname="val1",basename="basevalue"} NaN
|
||||
name {labelname="val2",basename="base\"v\\al\nue"} 0.23 1234567890
|
||||
# HELP name two-line\n doc str\\ing
|
||||
|
||||
# HELP name2 doc str"ing 2
|
||||
# TYPE name2 gauge
|
||||
name2{labelname="val2" ,basename = "basevalue2" } +Inf 54321
|
||||
name2{ labelname = "val1" , }-Inf
|
22
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_3
generated
vendored
Normal file
22
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_3
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
# TYPE my_summary summary
|
||||
my_summary{n1="val1",quantile="0.5"} 110
|
||||
decoy -1 -2
|
||||
my_summary{n1="val1",quantile="0.9"} 140 1
|
||||
my_summary_count{n1="val1"} 42
|
||||
# Latest timestamp wins in case of a summary.
|
||||
my_summary_sum{n1="val1"} 4711 2
|
||||
fake_sum{n1="val1"} 2001
|
||||
# TYPE another_summary summary
|
||||
another_summary_count{n2="val2",n1="val1"} 20
|
||||
my_summary_count{n2="val2",n1="val1"} 5 5
|
||||
another_summary{n1="val1",n2="val2",quantile=".3"} -1.2
|
||||
my_summary_sum{n1="val2"} 08 15
|
||||
my_summary{n1="val3", quantile="0.2"} 4711
|
||||
my_summary{n1="val1",n2="val2",quantile="-12.34",} NaN
|
||||
# some
|
||||
# funny comments
|
||||
# HELP
|
||||
# HELP
|
||||
# HELP my_summary
|
||||
# HELP my_summary
|
10
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_4
generated
vendored
Normal file
10
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_4
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
# HELP request_duration_microseconds The response latency.
|
||||
# TYPE request_duration_microseconds histogram
|
||||
request_duration_microseconds_bucket{le="100"} 123
|
||||
request_duration_microseconds_bucket{le="120"} 412
|
||||
request_duration_microseconds_bucket{le="144"} 592
|
||||
request_duration_microseconds_bucket{le="172.8"} 1524
|
||||
request_duration_microseconds_bucket{le="+Inf"} 2693
|
||||
request_duration_microseconds_sum 1.7560473e+06
|
||||
request_duration_microseconds_count 2693
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_0
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_0
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
bla 3.14
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_1
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_1
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
metric{label="\t"} 3.14
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_10
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_10
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
metric{label="bla"} 3.14 2 3
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_11
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_11
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
metric{label="bla"} blubb
|
3
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_12
generated
vendored
Normal file
3
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_12
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
# HELP metric one
|
||||
# HELP metric two
|
3
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_13
generated
vendored
Normal file
3
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_13
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
# TYPE metric counter
|
||||
# TYPE metric untyped
|
3
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_14
generated
vendored
Normal file
3
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_14
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
metric 4.12
|
||||
# TYPE metric counter
|
2
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_15
generated
vendored
Normal file
2
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_15
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
# TYPE metric bla
|
2
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_16
generated
vendored
Normal file
2
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_16
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
# TYPE met-ric
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_17
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_17
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
@invalidmetric{label="bla"} 3.14 2
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_18
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_18
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{label="bla"} 3.14 2
|
3
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_19
generated
vendored
Normal file
3
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_19
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
# TYPE metric histogram
|
||||
metric_bucket{le="bla"} 3.14
|
3
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_2
generated
vendored
Normal file
3
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_2
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
metric{label="new
|
||||
line"} 3.14
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_3
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_3
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
metric{@="bla"} 3.14
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_4
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_4
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
metric{__name__="bla"} 3.14
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_5
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_5
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
metric{label+="bla"} 3.14
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_6
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_6
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
metric{label=bla} 3.14
|
3
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_7
generated
vendored
Normal file
3
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_7
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
# TYPE metric summary
|
||||
metric{quantile="bla"} 3.14
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_8
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_8
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
metric{label="bla"+} 3.14
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_9
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_9
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
metric{label="bla"} 3.14 2.72
|
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/minimal
generated
vendored
Normal file
1
gateway/vendor/github.com/prometheus/common/expfmt/fuzz/corpus/minimal
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
m{} 0
|
46
gateway/vendor/github.com/prometheus/common/expfmt/testdata/json2
generated
vendored
Normal file
46
gateway/vendor/github.com/prometheus/common/expfmt/testdata/json2
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"baseLabels": {
|
||||
"__name__": "rpc_calls_total",
|
||||
"job": "batch_job"
|
||||
},
|
||||
"docstring": "RPC calls.",
|
||||
"metric": {
|
||||
"type": "counter",
|
||||
"value": [
|
||||
{
|
||||
"labels": {
|
||||
"service": "zed"
|
||||
},
|
||||
"value": 25
|
||||
},
|
||||
{
|
||||
"labels": {
|
||||
"service": "bar"
|
||||
},
|
||||
"value": 24
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"baseLabels": {
|
||||
"__name__": "rpc_latency_microseconds"
|
||||
},
|
||||
"docstring": "RPC latency.",
|
||||
"metric": {
|
||||
"type": "histogram",
|
||||
"value": [
|
||||
{
|
||||
"labels": {
|
||||
"service": "foo"
|
||||
},
|
||||
"value": {
|
||||
"0.010000": 15,
|
||||
"0.990000": 17
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
46
gateway/vendor/github.com/prometheus/common/expfmt/testdata/json2_bad
generated
vendored
Normal file
46
gateway/vendor/github.com/prometheus/common/expfmt/testdata/json2_bad
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"baseLabels": {
|
||||
"__name__": "rpc_calls_total",
|
||||
"job": "batch_job"
|
||||
},
|
||||
"docstring": "RPC calls.",
|
||||
"metric": {
|
||||
"type": "counter",
|
||||
"value": [
|
||||
{
|
||||
"labels": {
|
||||
"servic|e": "zed"
|
||||
},
|
||||
"value": 25
|
||||
},
|
||||
{
|
||||
"labels": {
|
||||
"service": "bar"
|
||||
},
|
||||
"value": 24
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"baseLabels": {
|
||||
"__name__": "rpc_latency_microseconds"
|
||||
},
|
||||
"docstring": "RPC latency.",
|
||||
"metric": {
|
||||
"type": "histogram",
|
||||
"value": [
|
||||
{
|
||||
"labels": {
|
||||
"service": "foo"
|
||||
},
|
||||
"value": {
|
||||
"0.010000": 15,
|
||||
"0.990000": 17
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
BIN
gateway/vendor/github.com/prometheus/common/expfmt/testdata/protobuf
generated
vendored
Normal file
BIN
gateway/vendor/github.com/prometheus/common/expfmt/testdata/protobuf
generated
vendored
Normal file
Binary file not shown.
BIN
gateway/vendor/github.com/prometheus/common/expfmt/testdata/protobuf.gz
generated
vendored
Normal file
BIN
gateway/vendor/github.com/prometheus/common/expfmt/testdata/protobuf.gz
generated
vendored
Normal file
Binary file not shown.
322
gateway/vendor/github.com/prometheus/common/expfmt/testdata/text
generated
vendored
Normal file
322
gateway/vendor/github.com/prometheus/common/expfmt/testdata/text
generated
vendored
Normal file
@ -0,0 +1,322 @@
|
||||
# HELP http_request_duration_microseconds The HTTP request latencies in microseconds.
|
||||
# TYPE http_request_duration_microseconds summary
|
||||
http_request_duration_microseconds{handler="/",quantile="0.5"} 0
|
||||
http_request_duration_microseconds{handler="/",quantile="0.9"} 0
|
||||
http_request_duration_microseconds{handler="/",quantile="0.99"} 0
|
||||
http_request_duration_microseconds_sum{handler="/"} 0
|
||||
http_request_duration_microseconds_count{handler="/"} 0
|
||||
http_request_duration_microseconds{handler="/alerts",quantile="0.5"} 0
|
||||
http_request_duration_microseconds{handler="/alerts",quantile="0.9"} 0
|
||||
http_request_duration_microseconds{handler="/alerts",quantile="0.99"} 0
|
||||
http_request_duration_microseconds_sum{handler="/alerts"} 0
|
||||
http_request_duration_microseconds_count{handler="/alerts"} 0
|
||||
http_request_duration_microseconds{handler="/api/metrics",quantile="0.5"} 0
|
||||
http_request_duration_microseconds{handler="/api/metrics",quantile="0.9"} 0
|
||||
http_request_duration_microseconds{handler="/api/metrics",quantile="0.99"} 0
|
||||
http_request_duration_microseconds_sum{handler="/api/metrics"} 0
|
||||
http_request_duration_microseconds_count{handler="/api/metrics"} 0
|
||||
http_request_duration_microseconds{handler="/api/query",quantile="0.5"} 0
|
||||
http_request_duration_microseconds{handler="/api/query",quantile="0.9"} 0
|
||||
http_request_duration_microseconds{handler="/api/query",quantile="0.99"} 0
|
||||
http_request_duration_microseconds_sum{handler="/api/query"} 0
|
||||
http_request_duration_microseconds_count{handler="/api/query"} 0
|
||||
http_request_duration_microseconds{handler="/api/query_range",quantile="0.5"} 0
|
||||
http_request_duration_microseconds{handler="/api/query_range",quantile="0.9"} 0
|
||||
http_request_duration_microseconds{handler="/api/query_range",quantile="0.99"} 0
|
||||
http_request_duration_microseconds_sum{handler="/api/query_range"} 0
|
||||
http_request_duration_microseconds_count{handler="/api/query_range"} 0
|
||||
http_request_duration_microseconds{handler="/api/targets",quantile="0.5"} 0
|
||||
http_request_duration_microseconds{handler="/api/targets",quantile="0.9"} 0
|
||||
http_request_duration_microseconds{handler="/api/targets",quantile="0.99"} 0
|
||||
http_request_duration_microseconds_sum{handler="/api/targets"} 0
|
||||
http_request_duration_microseconds_count{handler="/api/targets"} 0
|
||||
http_request_duration_microseconds{handler="/consoles/",quantile="0.5"} 0
|
||||
http_request_duration_microseconds{handler="/consoles/",quantile="0.9"} 0
|
||||
http_request_duration_microseconds{handler="/consoles/",quantile="0.99"} 0
|
||||
http_request_duration_microseconds_sum{handler="/consoles/"} 0
|
||||
http_request_duration_microseconds_count{handler="/consoles/"} 0
|
||||
http_request_duration_microseconds{handler="/graph",quantile="0.5"} 0
|
||||
http_request_duration_microseconds{handler="/graph",quantile="0.9"} 0
|
||||
http_request_duration_microseconds{handler="/graph",quantile="0.99"} 0
|
||||
http_request_duration_microseconds_sum{handler="/graph"} 0
|
||||
http_request_duration_microseconds_count{handler="/graph"} 0
|
||||
http_request_duration_microseconds{handler="/heap",quantile="0.5"} 0
|
||||
http_request_duration_microseconds{handler="/heap",quantile="0.9"} 0
|
||||
http_request_duration_microseconds{handler="/heap",quantile="0.99"} 0
|
||||
http_request_duration_microseconds_sum{handler="/heap"} 0
|
||||
http_request_duration_microseconds_count{handler="/heap"} 0
|
||||
http_request_duration_microseconds{handler="/static/",quantile="0.5"} 0
|
||||
http_request_duration_microseconds{handler="/static/",quantile="0.9"} 0
|
||||
http_request_duration_microseconds{handler="/static/",quantile="0.99"} 0
|
||||
http_request_duration_microseconds_sum{handler="/static/"} 0
|
||||
http_request_duration_microseconds_count{handler="/static/"} 0
|
||||
http_request_duration_microseconds{handler="prometheus",quantile="0.5"} 1307.275
|
||||
http_request_duration_microseconds{handler="prometheus",quantile="0.9"} 1858.632
|
||||
http_request_duration_microseconds{handler="prometheus",quantile="0.99"} 3087.384
|
||||
http_request_duration_microseconds_sum{handler="prometheus"} 179886.5000000001
|
||||
http_request_duration_microseconds_count{handler="prometheus"} 119
|
||||
# HELP http_request_size_bytes The HTTP request sizes in bytes.
|
||||
# TYPE http_request_size_bytes summary
|
||||
http_request_size_bytes{handler="/",quantile="0.5"} 0
|
||||
http_request_size_bytes{handler="/",quantile="0.9"} 0
|
||||
http_request_size_bytes{handler="/",quantile="0.99"} 0
|
||||
http_request_size_bytes_sum{handler="/"} 0
|
||||
http_request_size_bytes_count{handler="/"} 0
|
||||
http_request_size_bytes{handler="/alerts",quantile="0.5"} 0
|
||||
http_request_size_bytes{handler="/alerts",quantile="0.9"} 0
|
||||
http_request_size_bytes{handler="/alerts",quantile="0.99"} 0
|
||||
http_request_size_bytes_sum{handler="/alerts"} 0
|
||||
http_request_size_bytes_count{handler="/alerts"} 0
|
||||
http_request_size_bytes{handler="/api/metrics",quantile="0.5"} 0
|
||||
http_request_size_bytes{handler="/api/metrics",quantile="0.9"} 0
|
||||
http_request_size_bytes{handler="/api/metrics",quantile="0.99"} 0
|
||||
http_request_size_bytes_sum{handler="/api/metrics"} 0
|
||||
http_request_size_bytes_count{handler="/api/metrics"} 0
|
||||
http_request_size_bytes{handler="/api/query",quantile="0.5"} 0
|
||||
http_request_size_bytes{handler="/api/query",quantile="0.9"} 0
|
||||
http_request_size_bytes{handler="/api/query",quantile="0.99"} 0
|
||||
http_request_size_bytes_sum{handler="/api/query"} 0
|
||||
http_request_size_bytes_count{handler="/api/query"} 0
|
||||
http_request_size_bytes{handler="/api/query_range",quantile="0.5"} 0
|
||||
http_request_size_bytes{handler="/api/query_range",quantile="0.9"} 0
|
||||
http_request_size_bytes{handler="/api/query_range",quantile="0.99"} 0
|
||||
http_request_size_bytes_sum{handler="/api/query_range"} 0
|
||||
http_request_size_bytes_count{handler="/api/query_range"} 0
|
||||
http_request_size_bytes{handler="/api/targets",quantile="0.5"} 0
|
||||
http_request_size_bytes{handler="/api/targets",quantile="0.9"} 0
|
||||
http_request_size_bytes{handler="/api/targets",quantile="0.99"} 0
|
||||
http_request_size_bytes_sum{handler="/api/targets"} 0
|
||||
http_request_size_bytes_count{handler="/api/targets"} 0
|
||||
http_request_size_bytes{handler="/consoles/",quantile="0.5"} 0
|
||||
http_request_size_bytes{handler="/consoles/",quantile="0.9"} 0
|
||||
http_request_size_bytes{handler="/consoles/",quantile="0.99"} 0
|
||||
http_request_size_bytes_sum{handler="/consoles/"} 0
|
||||
http_request_size_bytes_count{handler="/consoles/"} 0
|
||||
http_request_size_bytes{handler="/graph",quantile="0.5"} 0
|
||||
http_request_size_bytes{handler="/graph",quantile="0.9"} 0
|
||||
http_request_size_bytes{handler="/graph",quantile="0.99"} 0
|
||||
http_request_size_bytes_sum{handler="/graph"} 0
|
||||
http_request_size_bytes_count{handler="/graph"} 0
|
||||
http_request_size_bytes{handler="/heap",quantile="0.5"} 0
|
||||
http_request_size_bytes{handler="/heap",quantile="0.9"} 0
|
||||
http_request_size_bytes{handler="/heap",quantile="0.99"} 0
|
||||
http_request_size_bytes_sum{handler="/heap"} 0
|
||||
http_request_size_bytes_count{handler="/heap"} 0
|
||||
http_request_size_bytes{handler="/static/",quantile="0.5"} 0
|
||||
http_request_size_bytes{handler="/static/",quantile="0.9"} 0
|
||||
http_request_size_bytes{handler="/static/",quantile="0.99"} 0
|
||||
http_request_size_bytes_sum{handler="/static/"} 0
|
||||
http_request_size_bytes_count{handler="/static/"} 0
|
||||
http_request_size_bytes{handler="prometheus",quantile="0.5"} 291
|
||||
http_request_size_bytes{handler="prometheus",quantile="0.9"} 291
|
||||
http_request_size_bytes{handler="prometheus",quantile="0.99"} 291
|
||||
http_request_size_bytes_sum{handler="prometheus"} 34488
|
||||
http_request_size_bytes_count{handler="prometheus"} 119
|
||||
# HELP http_requests_total Total number of HTTP requests made.
|
||||
# TYPE http_requests_total counter
|
||||
http_requests_total{code="200",handler="prometheus",method="get"} 119
|
||||
# HELP http_response_size_bytes The HTTP response sizes in bytes.
|
||||
# TYPE http_response_size_bytes summary
|
||||
http_response_size_bytes{handler="/",quantile="0.5"} 0
|
||||
http_response_size_bytes{handler="/",quantile="0.9"} 0
|
||||
http_response_size_bytes{handler="/",quantile="0.99"} 0
|
||||
http_response_size_bytes_sum{handler="/"} 0
|
||||
http_response_size_bytes_count{handler="/"} 0
|
||||
http_response_size_bytes{handler="/alerts",quantile="0.5"} 0
|
||||
http_response_size_bytes{handler="/alerts",quantile="0.9"} 0
|
||||
http_response_size_bytes{handler="/alerts",quantile="0.99"} 0
|
||||
http_response_size_bytes_sum{handler="/alerts"} 0
|
||||
http_response_size_bytes_count{handler="/alerts"} 0
|
||||
http_response_size_bytes{handler="/api/metrics",quantile="0.5"} 0
|
||||
http_response_size_bytes{handler="/api/metrics",quantile="0.9"} 0
|
||||
http_response_size_bytes{handler="/api/metrics",quantile="0.99"} 0
|
||||
http_response_size_bytes_sum{handler="/api/metrics"} 0
|
||||
http_response_size_bytes_count{handler="/api/metrics"} 0
|
||||
http_response_size_bytes{handler="/api/query",quantile="0.5"} 0
|
||||
http_response_size_bytes{handler="/api/query",quantile="0.9"} 0
|
||||
http_response_size_bytes{handler="/api/query",quantile="0.99"} 0
|
||||
http_response_size_bytes_sum{handler="/api/query"} 0
|
||||
http_response_size_bytes_count{handler="/api/query"} 0
|
||||
http_response_size_bytes{handler="/api/query_range",quantile="0.5"} 0
|
||||
http_response_size_bytes{handler="/api/query_range",quantile="0.9"} 0
|
||||
http_response_size_bytes{handler="/api/query_range",quantile="0.99"} 0
|
||||
http_response_size_bytes_sum{handler="/api/query_range"} 0
|
||||
http_response_size_bytes_count{handler="/api/query_range"} 0
|
||||
http_response_size_bytes{handler="/api/targets",quantile="0.5"} 0
|
||||
http_response_size_bytes{handler="/api/targets",quantile="0.9"} 0
|
||||
http_response_size_bytes{handler="/api/targets",quantile="0.99"} 0
|
||||
http_response_size_bytes_sum{handler="/api/targets"} 0
|
||||
http_response_size_bytes_count{handler="/api/targets"} 0
|
||||
http_response_size_bytes{handler="/consoles/",quantile="0.5"} 0
|
||||
http_response_size_bytes{handler="/consoles/",quantile="0.9"} 0
|
||||
http_response_size_bytes{handler="/consoles/",quantile="0.99"} 0
|
||||
http_response_size_bytes_sum{handler="/consoles/"} 0
|
||||
http_response_size_bytes_count{handler="/consoles/"} 0
|
||||
http_response_size_bytes{handler="/graph",quantile="0.5"} 0
|
||||
http_response_size_bytes{handler="/graph",quantile="0.9"} 0
|
||||
http_response_size_bytes{handler="/graph",quantile="0.99"} 0
|
||||
http_response_size_bytes_sum{handler="/graph"} 0
|
||||
http_response_size_bytes_count{handler="/graph"} 0
|
||||
http_response_size_bytes{handler="/heap",quantile="0.5"} 0
|
||||
http_response_size_bytes{handler="/heap",quantile="0.9"} 0
|
||||
http_response_size_bytes{handler="/heap",quantile="0.99"} 0
|
||||
http_response_size_bytes_sum{handler="/heap"} 0
|
||||
http_response_size_bytes_count{handler="/heap"} 0
|
||||
http_response_size_bytes{handler="/static/",quantile="0.5"} 0
|
||||
http_response_size_bytes{handler="/static/",quantile="0.9"} 0
|
||||
http_response_size_bytes{handler="/static/",quantile="0.99"} 0
|
||||
http_response_size_bytes_sum{handler="/static/"} 0
|
||||
http_response_size_bytes_count{handler="/static/"} 0
|
||||
http_response_size_bytes{handler="prometheus",quantile="0.5"} 2049
|
||||
http_response_size_bytes{handler="prometheus",quantile="0.9"} 2058
|
||||
http_response_size_bytes{handler="prometheus",quantile="0.99"} 2064
|
||||
http_response_size_bytes_sum{handler="prometheus"} 247001
|
||||
http_response_size_bytes_count{handler="prometheus"} 119
|
||||
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
|
||||
# TYPE process_cpu_seconds_total counter
|
||||
process_cpu_seconds_total 0.55
|
||||
# HELP go_goroutines Number of goroutines that currently exist.
|
||||
# TYPE go_goroutines gauge
|
||||
go_goroutines 70
|
||||
# HELP process_max_fds Maximum number of open file descriptors.
|
||||
# TYPE process_max_fds gauge
|
||||
process_max_fds 8192
|
||||
# HELP process_open_fds Number of open file descriptors.
|
||||
# TYPE process_open_fds gauge
|
||||
process_open_fds 29
|
||||
# HELP process_resident_memory_bytes Resident memory size in bytes.
|
||||
# TYPE process_resident_memory_bytes gauge
|
||||
process_resident_memory_bytes 5.3870592e+07
|
||||
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
|
||||
# TYPE process_start_time_seconds gauge
|
||||
process_start_time_seconds 1.42236894836e+09
|
||||
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
|
||||
# TYPE process_virtual_memory_bytes gauge
|
||||
process_virtual_memory_bytes 5.41478912e+08
|
||||
# HELP prometheus_dns_sd_lookup_failures_total The number of DNS-SD lookup failures.
|
||||
# TYPE prometheus_dns_sd_lookup_failures_total counter
|
||||
prometheus_dns_sd_lookup_failures_total 0
|
||||
# HELP prometheus_dns_sd_lookups_total The number of DNS-SD lookups.
|
||||
# TYPE prometheus_dns_sd_lookups_total counter
|
||||
prometheus_dns_sd_lookups_total 7
|
||||
# HELP prometheus_evaluator_duration_milliseconds The duration for all evaluations to execute.
|
||||
# TYPE prometheus_evaluator_duration_milliseconds summary
|
||||
prometheus_evaluator_duration_milliseconds{quantile="0.01"} 0
|
||||
prometheus_evaluator_duration_milliseconds{quantile="0.05"} 0
|
||||
prometheus_evaluator_duration_milliseconds{quantile="0.5"} 0
|
||||
prometheus_evaluator_duration_milliseconds{quantile="0.9"} 1
|
||||
prometheus_evaluator_duration_milliseconds{quantile="0.99"} 1
|
||||
prometheus_evaluator_duration_milliseconds_sum 12
|
||||
prometheus_evaluator_duration_milliseconds_count 23
|
||||
# HELP prometheus_local_storage_checkpoint_duration_milliseconds The duration (in milliseconds) it took to checkpoint in-memory metrics and head chunks.
|
||||
# TYPE prometheus_local_storage_checkpoint_duration_milliseconds gauge
|
||||
prometheus_local_storage_checkpoint_duration_milliseconds 0
|
||||
# HELP prometheus_local_storage_chunk_ops_total The total number of chunk operations by their type.
|
||||
# TYPE prometheus_local_storage_chunk_ops_total counter
|
||||
prometheus_local_storage_chunk_ops_total{type="create"} 598
|
||||
prometheus_local_storage_chunk_ops_total{type="persist"} 174
|
||||
prometheus_local_storage_chunk_ops_total{type="pin"} 920
|
||||
prometheus_local_storage_chunk_ops_total{type="transcode"} 415
|
||||
prometheus_local_storage_chunk_ops_total{type="unpin"} 920
|
||||
# HELP prometheus_local_storage_indexing_batch_latency_milliseconds Quantiles for batch indexing latencies in milliseconds.
|
||||
# TYPE prometheus_local_storage_indexing_batch_latency_milliseconds summary
|
||||
prometheus_local_storage_indexing_batch_latency_milliseconds{quantile="0.5"} 0
|
||||
prometheus_local_storage_indexing_batch_latency_milliseconds{quantile="0.9"} 0
|
||||
prometheus_local_storage_indexing_batch_latency_milliseconds{quantile="0.99"} 0
|
||||
prometheus_local_storage_indexing_batch_latency_milliseconds_sum 0
|
||||
prometheus_local_storage_indexing_batch_latency_milliseconds_count 1
|
||||
# HELP prometheus_local_storage_indexing_batch_sizes Quantiles for indexing batch sizes (number of metrics per batch).
|
||||
# TYPE prometheus_local_storage_indexing_batch_sizes summary
|
||||
prometheus_local_storage_indexing_batch_sizes{quantile="0.5"} 2
|
||||
prometheus_local_storage_indexing_batch_sizes{quantile="0.9"} 2
|
||||
prometheus_local_storage_indexing_batch_sizes{quantile="0.99"} 2
|
||||
prometheus_local_storage_indexing_batch_sizes_sum 2
|
||||
prometheus_local_storage_indexing_batch_sizes_count 1
|
||||
# HELP prometheus_local_storage_indexing_queue_capacity The capacity of the indexing queue.
|
||||
# TYPE prometheus_local_storage_indexing_queue_capacity gauge
|
||||
prometheus_local_storage_indexing_queue_capacity 16384
|
||||
# HELP prometheus_local_storage_indexing_queue_length The number of metrics waiting to be indexed.
|
||||
# TYPE prometheus_local_storage_indexing_queue_length gauge
|
||||
prometheus_local_storage_indexing_queue_length 0
|
||||
# HELP prometheus_local_storage_ingested_samples_total The total number of samples ingested.
|
||||
# TYPE prometheus_local_storage_ingested_samples_total counter
|
||||
prometheus_local_storage_ingested_samples_total 30473
|
||||
# HELP prometheus_local_storage_invalid_preload_requests_total The total number of preload requests referring to a non-existent series. This is an indication of outdated label indexes.
|
||||
# TYPE prometheus_local_storage_invalid_preload_requests_total counter
|
||||
prometheus_local_storage_invalid_preload_requests_total 0
|
||||
# HELP prometheus_local_storage_memory_chunkdescs The current number of chunk descriptors in memory.
|
||||
# TYPE prometheus_local_storage_memory_chunkdescs gauge
|
||||
prometheus_local_storage_memory_chunkdescs 1059
|
||||
# HELP prometheus_local_storage_memory_chunks The current number of chunks in memory, excluding cloned chunks (i.e. chunks without a descriptor).
|
||||
# TYPE prometheus_local_storage_memory_chunks gauge
|
||||
prometheus_local_storage_memory_chunks 1020
|
||||
# HELP prometheus_local_storage_memory_series The current number of series in memory.
|
||||
# TYPE prometheus_local_storage_memory_series gauge
|
||||
prometheus_local_storage_memory_series 424
|
||||
# HELP prometheus_local_storage_persist_latency_microseconds A summary of latencies for persisting each chunk.
|
||||
# TYPE prometheus_local_storage_persist_latency_microseconds summary
|
||||
prometheus_local_storage_persist_latency_microseconds{quantile="0.5"} 30.377
|
||||
prometheus_local_storage_persist_latency_microseconds{quantile="0.9"} 203.539
|
||||
prometheus_local_storage_persist_latency_microseconds{quantile="0.99"} 2626.463
|
||||
prometheus_local_storage_persist_latency_microseconds_sum 20424.415
|
||||
prometheus_local_storage_persist_latency_microseconds_count 174
|
||||
# HELP prometheus_local_storage_persist_queue_capacity The total capacity of the persist queue.
|
||||
# TYPE prometheus_local_storage_persist_queue_capacity gauge
|
||||
prometheus_local_storage_persist_queue_capacity 1024
|
||||
# HELP prometheus_local_storage_persist_queue_length The current number of chunks waiting in the persist queue.
|
||||
# TYPE prometheus_local_storage_persist_queue_length gauge
|
||||
prometheus_local_storage_persist_queue_length 0
|
||||
# HELP prometheus_local_storage_series_ops_total The total number of series operations by their type.
|
||||
# TYPE prometheus_local_storage_series_ops_total counter
|
||||
prometheus_local_storage_series_ops_total{type="create"} 2
|
||||
prometheus_local_storage_series_ops_total{type="maintenance_in_memory"} 11
|
||||
# HELP prometheus_notifications_latency_milliseconds Latency quantiles for sending alert notifications (not including dropped notifications).
|
||||
# TYPE prometheus_notifications_latency_milliseconds summary
|
||||
prometheus_notifications_latency_milliseconds{quantile="0.5"} 0
|
||||
prometheus_notifications_latency_milliseconds{quantile="0.9"} 0
|
||||
prometheus_notifications_latency_milliseconds{quantile="0.99"} 0
|
||||
prometheus_notifications_latency_milliseconds_sum 0
|
||||
prometheus_notifications_latency_milliseconds_count 0
|
||||
# HELP prometheus_notifications_queue_capacity The capacity of the alert notifications queue.
|
||||
# TYPE prometheus_notifications_queue_capacity gauge
|
||||
prometheus_notifications_queue_capacity 100
|
||||
# HELP prometheus_notifications_queue_length The number of alert notifications in the queue.
|
||||
# TYPE prometheus_notifications_queue_length gauge
|
||||
prometheus_notifications_queue_length 0
|
||||
# HELP prometheus_rule_evaluation_duration_milliseconds The duration for a rule to execute.
|
||||
# TYPE prometheus_rule_evaluation_duration_milliseconds summary
|
||||
prometheus_rule_evaluation_duration_milliseconds{rule_type="alerting",quantile="0.5"} 0
|
||||
prometheus_rule_evaluation_duration_milliseconds{rule_type="alerting",quantile="0.9"} 0
|
||||
prometheus_rule_evaluation_duration_milliseconds{rule_type="alerting",quantile="0.99"} 2
|
||||
prometheus_rule_evaluation_duration_milliseconds_sum{rule_type="alerting"} 12
|
||||
prometheus_rule_evaluation_duration_milliseconds_count{rule_type="alerting"} 115
|
||||
prometheus_rule_evaluation_duration_milliseconds{rule_type="recording",quantile="0.5"} 0
|
||||
prometheus_rule_evaluation_duration_milliseconds{rule_type="recording",quantile="0.9"} 0
|
||||
prometheus_rule_evaluation_duration_milliseconds{rule_type="recording",quantile="0.99"} 3
|
||||
prometheus_rule_evaluation_duration_milliseconds_sum{rule_type="recording"} 15
|
||||
prometheus_rule_evaluation_duration_milliseconds_count{rule_type="recording"} 115
|
||||
# HELP prometheus_rule_evaluation_failures_total The total number of rule evaluation failures.
|
||||
# TYPE prometheus_rule_evaluation_failures_total counter
|
||||
prometheus_rule_evaluation_failures_total 0
|
||||
# HELP prometheus_samples_queue_capacity Capacity of the queue for unwritten samples.
|
||||
# TYPE prometheus_samples_queue_capacity gauge
|
||||
prometheus_samples_queue_capacity 4096
|
||||
# HELP prometheus_samples_queue_length Current number of items in the queue for unwritten samples. Each item comprises all samples exposed by one target as one metric family (i.e. metrics of the same name).
|
||||
# TYPE prometheus_samples_queue_length gauge
|
||||
prometheus_samples_queue_length 0
|
||||
# HELP prometheus_target_interval_length_seconds Actual intervals between scrapes.
|
||||
# TYPE prometheus_target_interval_length_seconds summary
|
||||
prometheus_target_interval_length_seconds{interval="15s",quantile="0.01"} 14
|
||||
prometheus_target_interval_length_seconds{interval="15s",quantile="0.05"} 14
|
||||
prometheus_target_interval_length_seconds{interval="15s",quantile="0.5"} 15
|
||||
prometheus_target_interval_length_seconds{interval="15s",quantile="0.9"} 15
|
||||
prometheus_target_interval_length_seconds{interval="15s",quantile="0.99"} 15
|
||||
prometheus_target_interval_length_seconds_sum{interval="15s"} 175
|
||||
prometheus_target_interval_length_seconds_count{interval="15s"} 12
|
||||
prometheus_target_interval_length_seconds{interval="1s",quantile="0.01"} 0
|
||||
prometheus_target_interval_length_seconds{interval="1s",quantile="0.05"} 0
|
||||
prometheus_target_interval_length_seconds{interval="1s",quantile="0.5"} 0
|
||||
prometheus_target_interval_length_seconds{interval="1s",quantile="0.9"} 1
|
||||
prometheus_target_interval_length_seconds{interval="1s",quantile="0.99"} 1
|
||||
prometheus_target_interval_length_seconds_sum{interval="1s"} 55
|
||||
prometheus_target_interval_length_seconds_count{interval="1s"} 117
|
BIN
gateway/vendor/github.com/prometheus/common/expfmt/testdata/text.gz
generated
vendored
Normal file
BIN
gateway/vendor/github.com/prometheus/common/expfmt/testdata/text.gz
generated
vendored
Normal file
Binary file not shown.
443
gateway/vendor/github.com/prometheus/common/expfmt/text_create_test.go
generated
vendored
Normal file
443
gateway/vendor/github.com/prometheus/common/expfmt/text_create_test.go
generated
vendored
Normal file
@ -0,0 +1,443 @@
|
||||
// Copyright 2014 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package expfmt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
)
|
||||
|
||||
func testCreate(t testing.TB) {
|
||||
var scenarios = []struct {
|
||||
in *dto.MetricFamily
|
||||
out string
|
||||
}{
|
||||
// 0: Counter, NaN as value, timestamp given.
|
||||
{
|
||||
in: &dto.MetricFamily{
|
||||
Name: proto.String("name"),
|
||||
Help: proto.String("two-line\n doc str\\ing"),
|
||||
Type: dto.MetricType_COUNTER.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("labelname"),
|
||||
Value: proto.String("val1"),
|
||||
},
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("basename"),
|
||||
Value: proto.String("basevalue"),
|
||||
},
|
||||
},
|
||||
Counter: &dto.Counter{
|
||||
Value: proto.Float64(math.NaN()),
|
||||
},
|
||||
},
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("labelname"),
|
||||
Value: proto.String("val2"),
|
||||
},
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("basename"),
|
||||
Value: proto.String("basevalue"),
|
||||
},
|
||||
},
|
||||
Counter: &dto.Counter{
|
||||
Value: proto.Float64(.23),
|
||||
},
|
||||
TimestampMs: proto.Int64(1234567890),
|
||||
},
|
||||
},
|
||||
},
|
||||
out: `# HELP name two-line\n doc str\\ing
|
||||
# TYPE name counter
|
||||
name{labelname="val1",basename="basevalue"} NaN
|
||||
name{labelname="val2",basename="basevalue"} 0.23 1234567890
|
||||
`,
|
||||
},
|
||||
// 1: Gauge, some escaping required, +Inf as value, multi-byte characters in label values.
|
||||
{
|
||||
in: &dto.MetricFamily{
|
||||
Name: proto.String("gauge_name"),
|
||||
Help: proto.String("gauge\ndoc\nstr\"ing"),
|
||||
Type: dto.MetricType_GAUGE.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("name_1"),
|
||||
Value: proto.String("val with\nnew line"),
|
||||
},
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("name_2"),
|
||||
Value: proto.String("val with \\backslash and \"quotes\""),
|
||||
},
|
||||
},
|
||||
Gauge: &dto.Gauge{
|
||||
Value: proto.Float64(math.Inf(+1)),
|
||||
},
|
||||
},
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("name_1"),
|
||||
Value: proto.String("Björn"),
|
||||
},
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("name_2"),
|
||||
Value: proto.String("佖佥"),
|
||||
},
|
||||
},
|
||||
Gauge: &dto.Gauge{
|
||||
Value: proto.Float64(3.14E42),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
out: `# HELP gauge_name gauge\ndoc\nstr"ing
|
||||
# TYPE gauge_name gauge
|
||||
gauge_name{name_1="val with\nnew line",name_2="val with \\backslash and \"quotes\""} +Inf
|
||||
gauge_name{name_1="Björn",name_2="佖佥"} 3.14e+42
|
||||
`,
|
||||
},
|
||||
// 2: Untyped, no help, one sample with no labels and -Inf as value, another sample with one label.
|
||||
{
|
||||
in: &dto.MetricFamily{
|
||||
Name: proto.String("untyped_name"),
|
||||
Type: dto.MetricType_UNTYPED.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Untyped: &dto.Untyped{
|
||||
Value: proto.Float64(math.Inf(-1)),
|
||||
},
|
||||
},
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("name_1"),
|
||||
Value: proto.String("value 1"),
|
||||
},
|
||||
},
|
||||
Untyped: &dto.Untyped{
|
||||
Value: proto.Float64(-1.23e-45),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
out: `# TYPE untyped_name untyped
|
||||
untyped_name -Inf
|
||||
untyped_name{name_1="value 1"} -1.23e-45
|
||||
`,
|
||||
},
|
||||
// 3: Summary.
|
||||
{
|
||||
in: &dto.MetricFamily{
|
||||
Name: proto.String("summary_name"),
|
||||
Help: proto.String("summary docstring"),
|
||||
Type: dto.MetricType_SUMMARY.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Summary: &dto.Summary{
|
||||
SampleCount: proto.Uint64(42),
|
||||
SampleSum: proto.Float64(-3.4567),
|
||||
Quantile: []*dto.Quantile{
|
||||
&dto.Quantile{
|
||||
Quantile: proto.Float64(0.5),
|
||||
Value: proto.Float64(-1.23),
|
||||
},
|
||||
&dto.Quantile{
|
||||
Quantile: proto.Float64(0.9),
|
||||
Value: proto.Float64(.2342354),
|
||||
},
|
||||
&dto.Quantile{
|
||||
Quantile: proto.Float64(0.99),
|
||||
Value: proto.Float64(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("name_1"),
|
||||
Value: proto.String("value 1"),
|
||||
},
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("name_2"),
|
||||
Value: proto.String("value 2"),
|
||||
},
|
||||
},
|
||||
Summary: &dto.Summary{
|
||||
SampleCount: proto.Uint64(4711),
|
||||
SampleSum: proto.Float64(2010.1971),
|
||||
Quantile: []*dto.Quantile{
|
||||
&dto.Quantile{
|
||||
Quantile: proto.Float64(0.5),
|
||||
Value: proto.Float64(1),
|
||||
},
|
||||
&dto.Quantile{
|
||||
Quantile: proto.Float64(0.9),
|
||||
Value: proto.Float64(2),
|
||||
},
|
||||
&dto.Quantile{
|
||||
Quantile: proto.Float64(0.99),
|
||||
Value: proto.Float64(3),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
out: `# HELP summary_name summary docstring
|
||||
# TYPE summary_name summary
|
||||
summary_name{quantile="0.5"} -1.23
|
||||
summary_name{quantile="0.9"} 0.2342354
|
||||
summary_name{quantile="0.99"} 0
|
||||
summary_name_sum -3.4567
|
||||
summary_name_count 42
|
||||
summary_name{name_1="value 1",name_2="value 2",quantile="0.5"} 1
|
||||
summary_name{name_1="value 1",name_2="value 2",quantile="0.9"} 2
|
||||
summary_name{name_1="value 1",name_2="value 2",quantile="0.99"} 3
|
||||
summary_name_sum{name_1="value 1",name_2="value 2"} 2010.1971
|
||||
summary_name_count{name_1="value 1",name_2="value 2"} 4711
|
||||
`,
|
||||
},
|
||||
// 4: Histogram
|
||||
{
|
||||
in: &dto.MetricFamily{
|
||||
Name: proto.String("request_duration_microseconds"),
|
||||
Help: proto.String("The response latency."),
|
||||
Type: dto.MetricType_HISTOGRAM.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Histogram: &dto.Histogram{
|
||||
SampleCount: proto.Uint64(2693),
|
||||
SampleSum: proto.Float64(1756047.3),
|
||||
Bucket: []*dto.Bucket{
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(100),
|
||||
CumulativeCount: proto.Uint64(123),
|
||||
},
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(120),
|
||||
CumulativeCount: proto.Uint64(412),
|
||||
},
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(144),
|
||||
CumulativeCount: proto.Uint64(592),
|
||||
},
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(172.8),
|
||||
CumulativeCount: proto.Uint64(1524),
|
||||
},
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(math.Inf(+1)),
|
||||
CumulativeCount: proto.Uint64(2693),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
out: `# HELP request_duration_microseconds The response latency.
|
||||
# TYPE request_duration_microseconds histogram
|
||||
request_duration_microseconds_bucket{le="100"} 123
|
||||
request_duration_microseconds_bucket{le="120"} 412
|
||||
request_duration_microseconds_bucket{le="144"} 592
|
||||
request_duration_microseconds_bucket{le="172.8"} 1524
|
||||
request_duration_microseconds_bucket{le="+Inf"} 2693
|
||||
request_duration_microseconds_sum 1.7560473e+06
|
||||
request_duration_microseconds_count 2693
|
||||
`,
|
||||
},
|
||||
// 5: Histogram with missing +Inf bucket.
|
||||
{
|
||||
in: &dto.MetricFamily{
|
||||
Name: proto.String("request_duration_microseconds"),
|
||||
Help: proto.String("The response latency."),
|
||||
Type: dto.MetricType_HISTOGRAM.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Histogram: &dto.Histogram{
|
||||
SampleCount: proto.Uint64(2693),
|
||||
SampleSum: proto.Float64(1756047.3),
|
||||
Bucket: []*dto.Bucket{
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(100),
|
||||
CumulativeCount: proto.Uint64(123),
|
||||
},
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(120),
|
||||
CumulativeCount: proto.Uint64(412),
|
||||
},
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(144),
|
||||
CumulativeCount: proto.Uint64(592),
|
||||
},
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(172.8),
|
||||
CumulativeCount: proto.Uint64(1524),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
out: `# HELP request_duration_microseconds The response latency.
|
||||
# TYPE request_duration_microseconds histogram
|
||||
request_duration_microseconds_bucket{le="100"} 123
|
||||
request_duration_microseconds_bucket{le="120"} 412
|
||||
request_duration_microseconds_bucket{le="144"} 592
|
||||
request_duration_microseconds_bucket{le="172.8"} 1524
|
||||
request_duration_microseconds_bucket{le="+Inf"} 2693
|
||||
request_duration_microseconds_sum 1.7560473e+06
|
||||
request_duration_microseconds_count 2693
|
||||
`,
|
||||
},
|
||||
// 6: No metric type, should result in default type Counter.
|
||||
{
|
||||
in: &dto.MetricFamily{
|
||||
Name: proto.String("name"),
|
||||
Help: proto.String("doc string"),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Counter: &dto.Counter{
|
||||
Value: proto.Float64(math.Inf(-1)),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
out: `# HELP name doc string
|
||||
# TYPE name counter
|
||||
name -Inf
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
out := bytes.NewBuffer(make([]byte, 0, len(scenario.out)))
|
||||
n, err := MetricFamilyToText(out, scenario.in)
|
||||
if err != nil {
|
||||
t.Errorf("%d. error: %s", i, err)
|
||||
continue
|
||||
}
|
||||
if expected, got := len(scenario.out), n; expected != got {
|
||||
t.Errorf(
|
||||
"%d. expected %d bytes written, got %d",
|
||||
i, expected, got,
|
||||
)
|
||||
}
|
||||
if expected, got := scenario.out, out.String(); expected != got {
|
||||
t.Errorf(
|
||||
"%d. expected out=%q, got %q",
|
||||
i, expected, got,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
testCreate(t)
|
||||
}
|
||||
|
||||
func BenchmarkCreate(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
testCreate(b)
|
||||
}
|
||||
}
|
||||
|
||||
func testCreateError(t testing.TB) {
|
||||
var scenarios = []struct {
|
||||
in *dto.MetricFamily
|
||||
err string
|
||||
}{
|
||||
// 0: No metric.
|
||||
{
|
||||
in: &dto.MetricFamily{
|
||||
Name: proto.String("name"),
|
||||
Help: proto.String("doc string"),
|
||||
Type: dto.MetricType_COUNTER.Enum(),
|
||||
Metric: []*dto.Metric{},
|
||||
},
|
||||
err: "MetricFamily has no metrics",
|
||||
},
|
||||
// 1: No metric name.
|
||||
{
|
||||
in: &dto.MetricFamily{
|
||||
Help: proto.String("doc string"),
|
||||
Type: dto.MetricType_UNTYPED.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Untyped: &dto.Untyped{
|
||||
Value: proto.Float64(math.Inf(-1)),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "MetricFamily has no name",
|
||||
},
|
||||
// 2: Wrong type.
|
||||
{
|
||||
in: &dto.MetricFamily{
|
||||
Name: proto.String("name"),
|
||||
Help: proto.String("doc string"),
|
||||
Type: dto.MetricType_COUNTER.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Untyped: &dto.Untyped{
|
||||
Value: proto.Float64(math.Inf(-1)),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "expected counter in metric",
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
var out bytes.Buffer
|
||||
_, err := MetricFamilyToText(&out, scenario.in)
|
||||
if err == nil {
|
||||
t.Errorf("%d. expected error, got nil", i)
|
||||
continue
|
||||
}
|
||||
if expected, got := scenario.err, err.Error(); strings.Index(got, expected) != 0 {
|
||||
t.Errorf(
|
||||
"%d. expected error starting with %q, got %q",
|
||||
i, expected, got,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestCreateError(t *testing.T) {
|
||||
testCreateError(t)
|
||||
}
|
||||
|
||||
func BenchmarkCreateError(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
testCreateError(b)
|
||||
}
|
||||
}
|
593
gateway/vendor/github.com/prometheus/common/expfmt/text_parse_test.go
generated
vendored
Normal file
593
gateway/vendor/github.com/prometheus/common/expfmt/text_parse_test.go
generated
vendored
Normal file
@ -0,0 +1,593 @@
|
||||
// Copyright 2014 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package expfmt
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
)
|
||||
|
||||
func testTextParse(t testing.TB) {
|
||||
var scenarios = []struct {
|
||||
in string
|
||||
out []*dto.MetricFamily
|
||||
}{
|
||||
// 0: Empty lines as input.
|
||||
{
|
||||
in: `
|
||||
|
||||
`,
|
||||
out: []*dto.MetricFamily{},
|
||||
},
|
||||
// 1: Minimal case.
|
||||
{
|
||||
in: `
|
||||
minimal_metric 1.234
|
||||
another_metric -3e3 103948
|
||||
# Even that:
|
||||
no_labels{} 3
|
||||
# HELP line for non-existing metric will be ignored.
|
||||
`,
|
||||
out: []*dto.MetricFamily{
|
||||
&dto.MetricFamily{
|
||||
Name: proto.String("minimal_metric"),
|
||||
Type: dto.MetricType_UNTYPED.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Untyped: &dto.Untyped{
|
||||
Value: proto.Float64(1.234),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&dto.MetricFamily{
|
||||
Name: proto.String("another_metric"),
|
||||
Type: dto.MetricType_UNTYPED.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Untyped: &dto.Untyped{
|
||||
Value: proto.Float64(-3e3),
|
||||
},
|
||||
TimestampMs: proto.Int64(103948),
|
||||
},
|
||||
},
|
||||
},
|
||||
&dto.MetricFamily{
|
||||
Name: proto.String("no_labels"),
|
||||
Type: dto.MetricType_UNTYPED.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Untyped: &dto.Untyped{
|
||||
Value: proto.Float64(3),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// 2: Counters & gauges, docstrings, various whitespace, escape sequences.
|
||||
{
|
||||
in: `
|
||||
# A normal comment.
|
||||
#
|
||||
# TYPE name counter
|
||||
name{labelname="val1",basename="basevalue"} NaN
|
||||
name {labelname="val2",basename="base\"v\\al\nue"} 0.23 1234567890
|
||||
# HELP name two-line\n doc str\\ing
|
||||
|
||||
# HELP name2 doc str"ing 2
|
||||
# TYPE name2 gauge
|
||||
name2{labelname="val2" ,basename = "basevalue2" } +Inf 54321
|
||||
name2{ labelname = "val1" , }-Inf
|
||||
`,
|
||||
out: []*dto.MetricFamily{
|
||||
&dto.MetricFamily{
|
||||
Name: proto.String("name"),
|
||||
Help: proto.String("two-line\n doc str\\ing"),
|
||||
Type: dto.MetricType_COUNTER.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("labelname"),
|
||||
Value: proto.String("val1"),
|
||||
},
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("basename"),
|
||||
Value: proto.String("basevalue"),
|
||||
},
|
||||
},
|
||||
Counter: &dto.Counter{
|
||||
Value: proto.Float64(math.NaN()),
|
||||
},
|
||||
},
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("labelname"),
|
||||
Value: proto.String("val2"),
|
||||
},
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("basename"),
|
||||
Value: proto.String("base\"v\\al\nue"),
|
||||
},
|
||||
},
|
||||
Counter: &dto.Counter{
|
||||
Value: proto.Float64(.23),
|
||||
},
|
||||
TimestampMs: proto.Int64(1234567890),
|
||||
},
|
||||
},
|
||||
},
|
||||
&dto.MetricFamily{
|
||||
Name: proto.String("name2"),
|
||||
Help: proto.String("doc str\"ing 2"),
|
||||
Type: dto.MetricType_GAUGE.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("labelname"),
|
||||
Value: proto.String("val2"),
|
||||
},
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("basename"),
|
||||
Value: proto.String("basevalue2"),
|
||||
},
|
||||
},
|
||||
Gauge: &dto.Gauge{
|
||||
Value: proto.Float64(math.Inf(+1)),
|
||||
},
|
||||
TimestampMs: proto.Int64(54321),
|
||||
},
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("labelname"),
|
||||
Value: proto.String("val1"),
|
||||
},
|
||||
},
|
||||
Gauge: &dto.Gauge{
|
||||
Value: proto.Float64(math.Inf(-1)),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// 3: The evil summary, mixed with other types and funny comments.
|
||||
{
|
||||
in: `
|
||||
# TYPE my_summary summary
|
||||
my_summary{n1="val1",quantile="0.5"} 110
|
||||
decoy -1 -2
|
||||
my_summary{n1="val1",quantile="0.9"} 140 1
|
||||
my_summary_count{n1="val1"} 42
|
||||
# Latest timestamp wins in case of a summary.
|
||||
my_summary_sum{n1="val1"} 4711 2
|
||||
fake_sum{n1="val1"} 2001
|
||||
# TYPE another_summary summary
|
||||
another_summary_count{n2="val2",n1="val1"} 20
|
||||
my_summary_count{n2="val2",n1="val1"} 5 5
|
||||
another_summary{n1="val1",n2="val2",quantile=".3"} -1.2
|
||||
my_summary_sum{n1="val2"} 08 15
|
||||
my_summary{n1="val3", quantile="0.2"} 4711
|
||||
my_summary{n1="val1",n2="val2",quantile="-12.34",} NaN
|
||||
# some
|
||||
# funny comments
|
||||
# HELP
|
||||
# HELP
|
||||
# HELP my_summary
|
||||
# HELP my_summary
|
||||
`,
|
||||
out: []*dto.MetricFamily{
|
||||
&dto.MetricFamily{
|
||||
Name: proto.String("fake_sum"),
|
||||
Type: dto.MetricType_UNTYPED.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("n1"),
|
||||
Value: proto.String("val1"),
|
||||
},
|
||||
},
|
||||
Untyped: &dto.Untyped{
|
||||
Value: proto.Float64(2001),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&dto.MetricFamily{
|
||||
Name: proto.String("decoy"),
|
||||
Type: dto.MetricType_UNTYPED.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Untyped: &dto.Untyped{
|
||||
Value: proto.Float64(-1),
|
||||
},
|
||||
TimestampMs: proto.Int64(-2),
|
||||
},
|
||||
},
|
||||
},
|
||||
&dto.MetricFamily{
|
||||
Name: proto.String("my_summary"),
|
||||
Type: dto.MetricType_SUMMARY.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("n1"),
|
||||
Value: proto.String("val1"),
|
||||
},
|
||||
},
|
||||
Summary: &dto.Summary{
|
||||
SampleCount: proto.Uint64(42),
|
||||
SampleSum: proto.Float64(4711),
|
||||
Quantile: []*dto.Quantile{
|
||||
&dto.Quantile{
|
||||
Quantile: proto.Float64(0.5),
|
||||
Value: proto.Float64(110),
|
||||
},
|
||||
&dto.Quantile{
|
||||
Quantile: proto.Float64(0.9),
|
||||
Value: proto.Float64(140),
|
||||
},
|
||||
},
|
||||
},
|
||||
TimestampMs: proto.Int64(2),
|
||||
},
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("n2"),
|
||||
Value: proto.String("val2"),
|
||||
},
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("n1"),
|
||||
Value: proto.String("val1"),
|
||||
},
|
||||
},
|
||||
Summary: &dto.Summary{
|
||||
SampleCount: proto.Uint64(5),
|
||||
Quantile: []*dto.Quantile{
|
||||
&dto.Quantile{
|
||||
Quantile: proto.Float64(-12.34),
|
||||
Value: proto.Float64(math.NaN()),
|
||||
},
|
||||
},
|
||||
},
|
||||
TimestampMs: proto.Int64(5),
|
||||
},
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("n1"),
|
||||
Value: proto.String("val2"),
|
||||
},
|
||||
},
|
||||
Summary: &dto.Summary{
|
||||
SampleSum: proto.Float64(8),
|
||||
},
|
||||
TimestampMs: proto.Int64(15),
|
||||
},
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("n1"),
|
||||
Value: proto.String("val3"),
|
||||
},
|
||||
},
|
||||
Summary: &dto.Summary{
|
||||
Quantile: []*dto.Quantile{
|
||||
&dto.Quantile{
|
||||
Quantile: proto.Float64(0.2),
|
||||
Value: proto.Float64(4711),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&dto.MetricFamily{
|
||||
Name: proto.String("another_summary"),
|
||||
Type: dto.MetricType_SUMMARY.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Label: []*dto.LabelPair{
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("n2"),
|
||||
Value: proto.String("val2"),
|
||||
},
|
||||
&dto.LabelPair{
|
||||
Name: proto.String("n1"),
|
||||
Value: proto.String("val1"),
|
||||
},
|
||||
},
|
||||
Summary: &dto.Summary{
|
||||
SampleCount: proto.Uint64(20),
|
||||
Quantile: []*dto.Quantile{
|
||||
&dto.Quantile{
|
||||
Quantile: proto.Float64(0.3),
|
||||
Value: proto.Float64(-1.2),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// 4: The histogram.
|
||||
{
|
||||
in: `
|
||||
# HELP request_duration_microseconds The response latency.
|
||||
# TYPE request_duration_microseconds histogram
|
||||
request_duration_microseconds_bucket{le="100"} 123
|
||||
request_duration_microseconds_bucket{le="120"} 412
|
||||
request_duration_microseconds_bucket{le="144"} 592
|
||||
request_duration_microseconds_bucket{le="172.8"} 1524
|
||||
request_duration_microseconds_bucket{le="+Inf"} 2693
|
||||
request_duration_microseconds_sum 1.7560473e+06
|
||||
request_duration_microseconds_count 2693
|
||||
`,
|
||||
out: []*dto.MetricFamily{
|
||||
{
|
||||
Name: proto.String("request_duration_microseconds"),
|
||||
Help: proto.String("The response latency."),
|
||||
Type: dto.MetricType_HISTOGRAM.Enum(),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Histogram: &dto.Histogram{
|
||||
SampleCount: proto.Uint64(2693),
|
||||
SampleSum: proto.Float64(1756047.3),
|
||||
Bucket: []*dto.Bucket{
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(100),
|
||||
CumulativeCount: proto.Uint64(123),
|
||||
},
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(120),
|
||||
CumulativeCount: proto.Uint64(412),
|
||||
},
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(144),
|
||||
CumulativeCount: proto.Uint64(592),
|
||||
},
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(172.8),
|
||||
CumulativeCount: proto.Uint64(1524),
|
||||
},
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(math.Inf(+1)),
|
||||
CumulativeCount: proto.Uint64(2693),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
out, err := parser.TextToMetricFamilies(strings.NewReader(scenario.in))
|
||||
if err != nil {
|
||||
t.Errorf("%d. error: %s", i, err)
|
||||
continue
|
||||
}
|
||||
if expected, got := len(scenario.out), len(out); expected != got {
|
||||
t.Errorf(
|
||||
"%d. expected %d MetricFamilies, got %d",
|
||||
i, expected, got,
|
||||
)
|
||||
}
|
||||
for _, expected := range scenario.out {
|
||||
got, ok := out[expected.GetName()]
|
||||
if !ok {
|
||||
t.Errorf(
|
||||
"%d. expected MetricFamily %q, found none",
|
||||
i, expected.GetName(),
|
||||
)
|
||||
continue
|
||||
}
|
||||
if expected.String() != got.String() {
|
||||
t.Errorf(
|
||||
"%d. expected MetricFamily %s, got %s",
|
||||
i, expected, got,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTextParse(t *testing.T) {
|
||||
testTextParse(t)
|
||||
}
|
||||
|
||||
func BenchmarkTextParse(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
testTextParse(b)
|
||||
}
|
||||
}
|
||||
|
||||
func testTextParseError(t testing.TB) {
|
||||
var scenarios = []struct {
|
||||
in string
|
||||
err string
|
||||
}{
|
||||
// 0: No new-line at end of input.
|
||||
{
|
||||
in: `
|
||||
bla 3.14
|
||||
blubber 42`,
|
||||
err: "text format parsing error in line 3: unexpected end of input stream",
|
||||
},
|
||||
// 1: Invalid escape sequence in label value.
|
||||
{
|
||||
in: `metric{label="\t"} 3.14`,
|
||||
err: "text format parsing error in line 1: invalid escape sequence",
|
||||
},
|
||||
// 2: Newline in label value.
|
||||
{
|
||||
in: `
|
||||
metric{label="new
|
||||
line"} 3.14
|
||||
`,
|
||||
err: `text format parsing error in line 2: label value "new" contains unescaped new-line`,
|
||||
},
|
||||
// 3:
|
||||
{
|
||||
in: `metric{@="bla"} 3.14`,
|
||||
err: "text format parsing error in line 1: invalid label name for metric",
|
||||
},
|
||||
// 4:
|
||||
{
|
||||
in: `metric{__name__="bla"} 3.14`,
|
||||
err: `text format parsing error in line 1: label name "__name__" is reserved`,
|
||||
},
|
||||
// 5:
|
||||
{
|
||||
in: `metric{label+="bla"} 3.14`,
|
||||
err: "text format parsing error in line 1: expected '=' after label name",
|
||||
},
|
||||
// 6:
|
||||
{
|
||||
in: `metric{label=bla} 3.14`,
|
||||
err: "text format parsing error in line 1: expected '\"' at start of label value",
|
||||
},
|
||||
// 7:
|
||||
{
|
||||
in: `
|
||||
# TYPE metric summary
|
||||
metric{quantile="bla"} 3.14
|
||||
`,
|
||||
err: "text format parsing error in line 3: expected float as value for 'quantile' label",
|
||||
},
|
||||
// 8:
|
||||
{
|
||||
in: `metric{label="bla"+} 3.14`,
|
||||
err: "text format parsing error in line 1: unexpected end of label value",
|
||||
},
|
||||
// 9:
|
||||
{
|
||||
in: `metric{label="bla"} 3.14 2.72
|
||||
`,
|
||||
err: "text format parsing error in line 1: expected integer as timestamp",
|
||||
},
|
||||
// 10:
|
||||
{
|
||||
in: `metric{label="bla"} 3.14 2 3
|
||||
`,
|
||||
err: "text format parsing error in line 1: spurious string after timestamp",
|
||||
},
|
||||
// 11:
|
||||
{
|
||||
in: `metric{label="bla"} blubb
|
||||
`,
|
||||
err: "text format parsing error in line 1: expected float as value",
|
||||
},
|
||||
// 12:
|
||||
{
|
||||
in: `
|
||||
# HELP metric one
|
||||
# HELP metric two
|
||||
`,
|
||||
err: "text format parsing error in line 3: second HELP line for metric name",
|
||||
},
|
||||
// 13:
|
||||
{
|
||||
in: `
|
||||
# TYPE metric counter
|
||||
# TYPE metric untyped
|
||||
`,
|
||||
err: `text format parsing error in line 3: second TYPE line for metric name "metric", or TYPE reported after samples`,
|
||||
},
|
||||
// 14:
|
||||
{
|
||||
in: `
|
||||
metric 4.12
|
||||
# TYPE metric counter
|
||||
`,
|
||||
err: `text format parsing error in line 3: second TYPE line for metric name "metric", or TYPE reported after samples`,
|
||||
},
|
||||
// 14:
|
||||
{
|
||||
in: `
|
||||
# TYPE metric bla
|
||||
`,
|
||||
err: "text format parsing error in line 2: unknown metric type",
|
||||
},
|
||||
// 15:
|
||||
{
|
||||
in: `
|
||||
# TYPE met-ric
|
||||
`,
|
||||
err: "text format parsing error in line 2: invalid metric name in comment",
|
||||
},
|
||||
// 16:
|
||||
{
|
||||
in: `@invalidmetric{label="bla"} 3.14 2`,
|
||||
err: "text format parsing error in line 1: invalid metric name",
|
||||
},
|
||||
// 17:
|
||||
{
|
||||
in: `{label="bla"} 3.14 2`,
|
||||
err: "text format parsing error in line 1: invalid metric name",
|
||||
},
|
||||
// 18:
|
||||
{
|
||||
in: `
|
||||
# TYPE metric histogram
|
||||
metric_bucket{le="bla"} 3.14
|
||||
`,
|
||||
err: "text format parsing error in line 3: expected float as value for 'le' label",
|
||||
},
|
||||
// 19: Invalid UTF-8 in label value.
|
||||
{
|
||||
in: "metric{l=\"\xbd\"} 3.14\n",
|
||||
err: "text format parsing error in line 1: invalid label value \"\\xbd\"",
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
_, err := parser.TextToMetricFamilies(strings.NewReader(scenario.in))
|
||||
if err == nil {
|
||||
t.Errorf("%d. expected error, got nil", i)
|
||||
continue
|
||||
}
|
||||
if expected, got := scenario.err, err.Error(); strings.Index(got, expected) != 0 {
|
||||
t.Errorf(
|
||||
"%d. expected error starting with %q, got %q",
|
||||
i, expected, got,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestTextParseError(t *testing.T) {
|
||||
testTextParseError(t)
|
||||
}
|
||||
|
||||
func BenchmarkParseError(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
testTextParseError(b)
|
||||
}
|
||||
}
|
33
gateway/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg_test.go
generated
vendored
Normal file
33
gateway/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg_test.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
package goautoneg
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var chrome = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
|
||||
|
||||
func TestParseAccept(t *testing.T) {
|
||||
alternatives := []string{"text/html", "image/png"}
|
||||
content_type := Negotiate(chrome, alternatives)
|
||||
if content_type != "image/png" {
|
||||
t.Errorf("got %s expected image/png", content_type)
|
||||
}
|
||||
|
||||
alternatives = []string{"text/html", "text/plain", "text/n3"}
|
||||
content_type = Negotiate(chrome, alternatives)
|
||||
if content_type != "text/html" {
|
||||
t.Errorf("got %s expected text/html", content_type)
|
||||
}
|
||||
|
||||
alternatives = []string{"text/n3", "text/plain"}
|
||||
content_type = Negotiate(chrome, alternatives)
|
||||
if content_type != "text/plain" {
|
||||
t.Errorf("got %s expected text/plain", content_type)
|
||||
}
|
||||
|
||||
alternatives = []string{"text/n3", "application/rdf+xml"}
|
||||
content_type = Negotiate(chrome, alternatives)
|
||||
if content_type != "text/n3" {
|
||||
t.Errorf("got %s expected text/n3", content_type)
|
||||
}
|
||||
}
|
89
gateway/vendor/github.com/prometheus/common/log/eventlog_formatter.go
generated
vendored
Normal file
89
gateway/vendor/github.com/prometheus/common/log/eventlog_formatter.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright 2015 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build windows
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/windows/svc/eventlog"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
setEventlogFormatter = func(l logger, name string, debugAsInfo bool) error {
|
||||
if name == "" {
|
||||
return fmt.Errorf("missing name parameter")
|
||||
}
|
||||
|
||||
fmter, err := newEventlogger(name, debugAsInfo, l.entry.Logger.Formatter)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error creating eventlog formatter: %v\n", err)
|
||||
l.Errorf("can't connect logger to eventlog: %v", err)
|
||||
return err
|
||||
}
|
||||
l.entry.Logger.Formatter = fmter
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type eventlogger struct {
|
||||
log *eventlog.Log
|
||||
debugAsInfo bool
|
||||
wrap logrus.Formatter
|
||||
}
|
||||
|
||||
func newEventlogger(name string, debugAsInfo bool, fmter logrus.Formatter) (*eventlogger, error) {
|
||||
logHandle, err := eventlog.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &eventlogger{log: logHandle, debugAsInfo: debugAsInfo, wrap: fmter}, nil
|
||||
}
|
||||
|
||||
func (s *eventlogger) Format(e *logrus.Entry) ([]byte, error) {
|
||||
data, err := s.wrap.Format(e)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "eventlogger: can't format entry: %v\n", err)
|
||||
return data, err
|
||||
}
|
||||
|
||||
switch e.Level {
|
||||
case logrus.PanicLevel:
|
||||
fallthrough
|
||||
case logrus.FatalLevel:
|
||||
fallthrough
|
||||
case logrus.ErrorLevel:
|
||||
err = s.log.Error(102, e.Message)
|
||||
case logrus.WarnLevel:
|
||||
err = s.log.Warning(101, e.Message)
|
||||
case logrus.InfoLevel:
|
||||
err = s.log.Info(100, e.Message)
|
||||
case logrus.DebugLevel:
|
||||
if s.debugAsInfo {
|
||||
err = s.log.Info(100, e.Message)
|
||||
}
|
||||
default:
|
||||
err = s.log.Info(100, e.Message)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "eventlogger: can't send log to eventlog: %v\n", err)
|
||||
}
|
||||
|
||||
return data, err
|
||||
}
|
364
gateway/vendor/github.com/prometheus/common/log/log.go
generated
vendored
Normal file
364
gateway/vendor/github.com/prometheus/common/log/log.go
generated
vendored
Normal file
@ -0,0 +1,364 @@
|
||||
// Copyright 2015 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
// setSyslogFormatter is nil if the target architecture does not support syslog.
|
||||
var setSyslogFormatter func(logger, string, string) error
|
||||
|
||||
// setEventlogFormatter is nil if the target OS does not support Eventlog (i.e., is not Windows).
|
||||
var setEventlogFormatter func(logger, string, bool) error
|
||||
|
||||
func setJSONFormatter() {
|
||||
origLogger.Formatter = &logrus.JSONFormatter{}
|
||||
}
|
||||
|
||||
type loggerSettings struct {
|
||||
level string
|
||||
format string
|
||||
}
|
||||
|
||||
func (s *loggerSettings) apply(ctx *kingpin.ParseContext) error {
|
||||
err := baseLogger.SetLevel(s.level)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = baseLogger.SetFormat(s.format)
|
||||
return err
|
||||
}
|
||||
|
||||
// AddFlags adds the flags used by this package to the Kingpin application.
|
||||
// To use the default Kingpin application, call AddFlags(kingpin.CommandLine)
|
||||
func AddFlags(a *kingpin.Application) {
|
||||
s := loggerSettings{}
|
||||
a.Flag("log.level", "Only log messages with the given severity or above. Valid levels: [debug, info, warn, error, fatal]").
|
||||
Default(origLogger.Level.String()).
|
||||
StringVar(&s.level)
|
||||
defaultFormat := url.URL{Scheme: "logger", Opaque: "stderr"}
|
||||
a.Flag("log.format", `Set the log target and format. Example: "logger:syslog?appname=bob&local=7" or "logger:stdout?json=true"`).
|
||||
Default(defaultFormat.String()).
|
||||
StringVar(&s.format)
|
||||
a.Action(s.apply)
|
||||
}
|
||||
|
||||
// Logger is the interface for loggers used in the Prometheus components.
|
||||
type Logger interface {
|
||||
Debug(...interface{})
|
||||
Debugln(...interface{})
|
||||
Debugf(string, ...interface{})
|
||||
|
||||
Info(...interface{})
|
||||
Infoln(...interface{})
|
||||
Infof(string, ...interface{})
|
||||
|
||||
Warn(...interface{})
|
||||
Warnln(...interface{})
|
||||
Warnf(string, ...interface{})
|
||||
|
||||
Error(...interface{})
|
||||
Errorln(...interface{})
|
||||
Errorf(string, ...interface{})
|
||||
|
||||
Fatal(...interface{})
|
||||
Fatalln(...interface{})
|
||||
Fatalf(string, ...interface{})
|
||||
|
||||
With(key string, value interface{}) Logger
|
||||
|
||||
SetFormat(string) error
|
||||
SetLevel(string) error
|
||||
}
|
||||
|
||||
type logger struct {
|
||||
entry *logrus.Entry
|
||||
}
|
||||
|
||||
func (l logger) With(key string, value interface{}) Logger {
|
||||
return logger{l.entry.WithField(key, value)}
|
||||
}
|
||||
|
||||
// Debug logs a message at level Debug on the standard logger.
|
||||
func (l logger) Debug(args ...interface{}) {
|
||||
l.sourced().Debug(args...)
|
||||
}
|
||||
|
||||
// Debug logs a message at level Debug on the standard logger.
|
||||
func (l logger) Debugln(args ...interface{}) {
|
||||
l.sourced().Debugln(args...)
|
||||
}
|
||||
|
||||
// Debugf logs a message at level Debug on the standard logger.
|
||||
func (l logger) Debugf(format string, args ...interface{}) {
|
||||
l.sourced().Debugf(format, args...)
|
||||
}
|
||||
|
||||
// Info logs a message at level Info on the standard logger.
|
||||
func (l logger) Info(args ...interface{}) {
|
||||
l.sourced().Info(args...)
|
||||
}
|
||||
|
||||
// Info logs a message at level Info on the standard logger.
|
||||
func (l logger) Infoln(args ...interface{}) {
|
||||
l.sourced().Infoln(args...)
|
||||
}
|
||||
|
||||
// Infof logs a message at level Info on the standard logger.
|
||||
func (l logger) Infof(format string, args ...interface{}) {
|
||||
l.sourced().Infof(format, args...)
|
||||
}
|
||||
|
||||
// Warn logs a message at level Warn on the standard logger.
|
||||
func (l logger) Warn(args ...interface{}) {
|
||||
l.sourced().Warn(args...)
|
||||
}
|
||||
|
||||
// Warn logs a message at level Warn on the standard logger.
|
||||
func (l logger) Warnln(args ...interface{}) {
|
||||
l.sourced().Warnln(args...)
|
||||
}
|
||||
|
||||
// Warnf logs a message at level Warn on the standard logger.
|
||||
func (l logger) Warnf(format string, args ...interface{}) {
|
||||
l.sourced().Warnf(format, args...)
|
||||
}
|
||||
|
||||
// Error logs a message at level Error on the standard logger.
|
||||
func (l logger) Error(args ...interface{}) {
|
||||
l.sourced().Error(args...)
|
||||
}
|
||||
|
||||
// Error logs a message at level Error on the standard logger.
|
||||
func (l logger) Errorln(args ...interface{}) {
|
||||
l.sourced().Errorln(args...)
|
||||
}
|
||||
|
||||
// Errorf logs a message at level Error on the standard logger.
|
||||
func (l logger) Errorf(format string, args ...interface{}) {
|
||||
l.sourced().Errorf(format, args...)
|
||||
}
|
||||
|
||||
// Fatal logs a message at level Fatal on the standard logger.
|
||||
func (l logger) Fatal(args ...interface{}) {
|
||||
l.sourced().Fatal(args...)
|
||||
}
|
||||
|
||||
// Fatal logs a message at level Fatal on the standard logger.
|
||||
func (l logger) Fatalln(args ...interface{}) {
|
||||
l.sourced().Fatalln(args...)
|
||||
}
|
||||
|
||||
// Fatalf logs a message at level Fatal on the standard logger.
|
||||
func (l logger) Fatalf(format string, args ...interface{}) {
|
||||
l.sourced().Fatalf(format, args...)
|
||||
}
|
||||
|
||||
func (l logger) SetLevel(level string) error {
|
||||
lvl, err := logrus.ParseLevel(level)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.entry.Logger.Level = lvl
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l logger) SetFormat(format string) error {
|
||||
u, err := url.Parse(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if u.Scheme != "logger" {
|
||||
return fmt.Errorf("invalid scheme %s", u.Scheme)
|
||||
}
|
||||
jsonq := u.Query().Get("json")
|
||||
if jsonq == "true" {
|
||||
setJSONFormatter()
|
||||
}
|
||||
|
||||
switch u.Opaque {
|
||||
case "syslog":
|
||||
if setSyslogFormatter == nil {
|
||||
return fmt.Errorf("system does not support syslog")
|
||||
}
|
||||
appname := u.Query().Get("appname")
|
||||
facility := u.Query().Get("local")
|
||||
return setSyslogFormatter(l, appname, facility)
|
||||
case "eventlog":
|
||||
if setEventlogFormatter == nil {
|
||||
return fmt.Errorf("system does not support eventlog")
|
||||
}
|
||||
name := u.Query().Get("name")
|
||||
debugAsInfo := false
|
||||
debugAsInfoRaw := u.Query().Get("debugAsInfo")
|
||||
if parsedDebugAsInfo, err := strconv.ParseBool(debugAsInfoRaw); err == nil {
|
||||
debugAsInfo = parsedDebugAsInfo
|
||||
}
|
||||
return setEventlogFormatter(l, name, debugAsInfo)
|
||||
case "stdout":
|
||||
l.entry.Logger.Out = os.Stdout
|
||||
case "stderr":
|
||||
l.entry.Logger.Out = os.Stderr
|
||||
default:
|
||||
return fmt.Errorf("unsupported logger %q", u.Opaque)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// sourced adds a source field to the logger that contains
|
||||
// the file name and line where the logging happened.
|
||||
func (l logger) sourced() *logrus.Entry {
|
||||
_, file, line, ok := runtime.Caller(2)
|
||||
if !ok {
|
||||
file = "<???>"
|
||||
line = 1
|
||||
} else {
|
||||
slash := strings.LastIndex(file, "/")
|
||||
file = file[slash+1:]
|
||||
}
|
||||
return l.entry.WithField("source", fmt.Sprintf("%s:%d", file, line))
|
||||
}
|
||||
|
||||
var origLogger = logrus.New()
|
||||
var baseLogger = logger{entry: logrus.NewEntry(origLogger)}
|
||||
|
||||
// Base returns the default Logger logging to
|
||||
func Base() Logger {
|
||||
return baseLogger
|
||||
}
|
||||
|
||||
// NewLogger returns a new Logger logging to out.
|
||||
func NewLogger(w io.Writer) Logger {
|
||||
l := logrus.New()
|
||||
l.Out = w
|
||||
return logger{entry: logrus.NewEntry(l)}
|
||||
}
|
||||
|
||||
// NewNopLogger returns a logger that discards all log messages.
|
||||
func NewNopLogger() Logger {
|
||||
l := logrus.New()
|
||||
l.Out = ioutil.Discard
|
||||
return logger{entry: logrus.NewEntry(l)}
|
||||
}
|
||||
|
||||
// With adds a field to the logger.
|
||||
func With(key string, value interface{}) Logger {
|
||||
return baseLogger.With(key, value)
|
||||
}
|
||||
|
||||
// Debug logs a message at level Debug on the standard logger.
|
||||
func Debug(args ...interface{}) {
|
||||
baseLogger.sourced().Debug(args...)
|
||||
}
|
||||
|
||||
// Debugln logs a message at level Debug on the standard logger.
|
||||
func Debugln(args ...interface{}) {
|
||||
baseLogger.sourced().Debugln(args...)
|
||||
}
|
||||
|
||||
// Debugf logs a message at level Debug on the standard logger.
|
||||
func Debugf(format string, args ...interface{}) {
|
||||
baseLogger.sourced().Debugf(format, args...)
|
||||
}
|
||||
|
||||
// Info logs a message at level Info on the standard logger.
|
||||
func Info(args ...interface{}) {
|
||||
baseLogger.sourced().Info(args...)
|
||||
}
|
||||
|
||||
// Infoln logs a message at level Info on the standard logger.
|
||||
func Infoln(args ...interface{}) {
|
||||
baseLogger.sourced().Infoln(args...)
|
||||
}
|
||||
|
||||
// Infof logs a message at level Info on the standard logger.
|
||||
func Infof(format string, args ...interface{}) {
|
||||
baseLogger.sourced().Infof(format, args...)
|
||||
}
|
||||
|
||||
// Warn logs a message at level Warn on the standard logger.
|
||||
func Warn(args ...interface{}) {
|
||||
baseLogger.sourced().Warn(args...)
|
||||
}
|
||||
|
||||
// Warnln logs a message at level Warn on the standard logger.
|
||||
func Warnln(args ...interface{}) {
|
||||
baseLogger.sourced().Warnln(args...)
|
||||
}
|
||||
|
||||
// Warnf logs a message at level Warn on the standard logger.
|
||||
func Warnf(format string, args ...interface{}) {
|
||||
baseLogger.sourced().Warnf(format, args...)
|
||||
}
|
||||
|
||||
// Error logs a message at level Error on the standard logger.
|
||||
func Error(args ...interface{}) {
|
||||
baseLogger.sourced().Error(args...)
|
||||
}
|
||||
|
||||
// Errorln logs a message at level Error on the standard logger.
|
||||
func Errorln(args ...interface{}) {
|
||||
baseLogger.sourced().Errorln(args...)
|
||||
}
|
||||
|
||||
// Errorf logs a message at level Error on the standard logger.
|
||||
func Errorf(format string, args ...interface{}) {
|
||||
baseLogger.sourced().Errorf(format, args...)
|
||||
}
|
||||
|
||||
// Fatal logs a message at level Fatal on the standard logger.
|
||||
func Fatal(args ...interface{}) {
|
||||
baseLogger.sourced().Fatal(args...)
|
||||
}
|
||||
|
||||
// Fatalln logs a message at level Fatal on the standard logger.
|
||||
func Fatalln(args ...interface{}) {
|
||||
baseLogger.sourced().Fatalln(args...)
|
||||
}
|
||||
|
||||
// Fatalf logs a message at level Fatal on the standard logger.
|
||||
func Fatalf(format string, args ...interface{}) {
|
||||
baseLogger.sourced().Fatalf(format, args...)
|
||||
}
|
||||
|
||||
// AddHook adds hook to Prometheus' original logger.
|
||||
func AddHook(hook logrus.Hook) {
|
||||
origLogger.Hooks.Add(hook)
|
||||
}
|
||||
|
||||
type errorLogWriter struct{}
|
||||
|
||||
func (errorLogWriter) Write(b []byte) (int, error) {
|
||||
baseLogger.sourced().Error(string(b))
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
// NewErrorLogger returns a log.Logger that is meant to be used
|
||||
// in the ErrorLog field of an http.Server to log HTTP server errors.
|
||||
func NewErrorLogger() *log.Logger {
|
||||
return log.New(&errorLogWriter{}, "", 0)
|
||||
}
|
39
gateway/vendor/github.com/prometheus/common/log/log_test.go
generated
vendored
Normal file
39
gateway/vendor/github.com/prometheus/common/log/log_test.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright 2015 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func TestFileLineLogging(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
origLogger.Out = &buf
|
||||
origLogger.Formatter = &logrus.TextFormatter{
|
||||
DisableColors: true,
|
||||
}
|
||||
|
||||
// The default logging level should be "info".
|
||||
Debug("This debug-level line should not show up in the output.")
|
||||
Infof("This %s-level line should show up in the output.", "info")
|
||||
|
||||
re := `^time=".*" level=info msg="This info-level line should show up in the output." source="log_test.go:33"\n$`
|
||||
if !regexp.MustCompile(re).Match(buf.Bytes()) {
|
||||
t.Fatalf("%q did not match expected regex %q", buf.String(), re)
|
||||
}
|
||||
}
|
126
gateway/vendor/github.com/prometheus/common/log/syslog_formatter.go
generated
vendored
Normal file
126
gateway/vendor/github.com/prometheus/common/log/syslog_formatter.go
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
// Copyright 2015 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build !windows,!nacl,!plan9
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/syslog"
|
||||
"os"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var _ logrus.Formatter = (*syslogger)(nil)
|
||||
|
||||
func init() {
|
||||
setSyslogFormatter = func(l logger, appname, local string) error {
|
||||
if appname == "" {
|
||||
return fmt.Errorf("missing appname parameter")
|
||||
}
|
||||
if local == "" {
|
||||
return fmt.Errorf("missing local parameter")
|
||||
}
|
||||
|
||||
fmter, err := newSyslogger(appname, local, l.entry.Logger.Formatter)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error creating syslog formatter: %v\n", err)
|
||||
l.entry.Errorf("can't connect logger to syslog: %v", err)
|
||||
return err
|
||||
}
|
||||
l.entry.Logger.Formatter = fmter
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var prefixTag []byte
|
||||
|
||||
type syslogger struct {
|
||||
wrap logrus.Formatter
|
||||
out *syslog.Writer
|
||||
}
|
||||
|
||||
func newSyslogger(appname string, facility string, fmter logrus.Formatter) (*syslogger, error) {
|
||||
priority, err := getFacility(facility)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := syslog.New(priority, appname)
|
||||
_, isJSON := fmter.(*logrus.JSONFormatter)
|
||||
if isJSON {
|
||||
// add cee tag to json formatted syslogs
|
||||
prefixTag = []byte("@cee:")
|
||||
}
|
||||
return &syslogger{
|
||||
out: out,
|
||||
wrap: fmter,
|
||||
}, err
|
||||
}
|
||||
|
||||
func getFacility(facility string) (syslog.Priority, error) {
|
||||
switch facility {
|
||||
case "0":
|
||||
return syslog.LOG_LOCAL0, nil
|
||||
case "1":
|
||||
return syslog.LOG_LOCAL1, nil
|
||||
case "2":
|
||||
return syslog.LOG_LOCAL2, nil
|
||||
case "3":
|
||||
return syslog.LOG_LOCAL3, nil
|
||||
case "4":
|
||||
return syslog.LOG_LOCAL4, nil
|
||||
case "5":
|
||||
return syslog.LOG_LOCAL5, nil
|
||||
case "6":
|
||||
return syslog.LOG_LOCAL6, nil
|
||||
case "7":
|
||||
return syslog.LOG_LOCAL7, nil
|
||||
}
|
||||
return syslog.LOG_LOCAL0, fmt.Errorf("invalid local(%s) for syslog", facility)
|
||||
}
|
||||
|
||||
func (s *syslogger) Format(e *logrus.Entry) ([]byte, error) {
|
||||
data, err := s.wrap.Format(e)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "syslogger: can't format entry: %v\n", err)
|
||||
return data, err
|
||||
}
|
||||
// only append tag to data sent to syslog (line), not to what
|
||||
// is returned
|
||||
line := string(append(prefixTag, data...))
|
||||
|
||||
switch e.Level {
|
||||
case logrus.PanicLevel:
|
||||
err = s.out.Crit(line)
|
||||
case logrus.FatalLevel:
|
||||
err = s.out.Crit(line)
|
||||
case logrus.ErrorLevel:
|
||||
err = s.out.Err(line)
|
||||
case logrus.WarnLevel:
|
||||
err = s.out.Warning(line)
|
||||
case logrus.InfoLevel:
|
||||
err = s.out.Info(line)
|
||||
case logrus.DebugLevel:
|
||||
err = s.out.Debug(line)
|
||||
default:
|
||||
err = s.out.Notice(line)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "syslogger: can't send log to syslog: %v\n", err)
|
||||
}
|
||||
|
||||
return data, err
|
||||
}
|
52
gateway/vendor/github.com/prometheus/common/log/syslog_formatter_test.go
generated
vendored
Normal file
52
gateway/vendor/github.com/prometheus/common/log/syslog_formatter_test.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright 2015 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build !windows,!nacl,!plan9
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log/syslog"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetFacility(t *testing.T) {
|
||||
testCases := []struct {
|
||||
facility string
|
||||
expectedPriority syslog.Priority
|
||||
expectedErr error
|
||||
}{
|
||||
{"0", syslog.LOG_LOCAL0, nil},
|
||||
{"1", syslog.LOG_LOCAL1, nil},
|
||||
{"2", syslog.LOG_LOCAL2, nil},
|
||||
{"3", syslog.LOG_LOCAL3, nil},
|
||||
{"4", syslog.LOG_LOCAL4, nil},
|
||||
{"5", syslog.LOG_LOCAL5, nil},
|
||||
{"6", syslog.LOG_LOCAL6, nil},
|
||||
{"7", syslog.LOG_LOCAL7, nil},
|
||||
{"8", syslog.LOG_LOCAL0, errors.New("invalid local(8) for syslog")},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
priority, err := getFacility(tc.facility)
|
||||
if err != tc.expectedErr {
|
||||
if err.Error() != tc.expectedErr.Error() {
|
||||
t.Errorf("want %s, got %s", tc.expectedErr.Error(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if priority != tc.expectedPriority {
|
||||
t.Errorf("want %q, got %q", tc.expectedPriority, priority)
|
||||
}
|
||||
}
|
||||
}
|
118
gateway/vendor/github.com/prometheus/common/model/alert_test.go
generated
vendored
Normal file
118
gateway/vendor/github.com/prometheus/common/model/alert_test.go
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
// Copyright 2013 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestAlertValidate(t *testing.T) {
|
||||
ts := time.Now()
|
||||
|
||||
var cases = []struct {
|
||||
alert *Alert
|
||||
err string
|
||||
}{
|
||||
{
|
||||
alert: &Alert{
|
||||
Labels: LabelSet{"a": "b"},
|
||||
StartsAt: ts,
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: &Alert{
|
||||
Labels: LabelSet{"a": "b"},
|
||||
},
|
||||
err: "start time missing",
|
||||
},
|
||||
{
|
||||
alert: &Alert{
|
||||
Labels: LabelSet{"a": "b"},
|
||||
StartsAt: ts,
|
||||
EndsAt: ts,
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: &Alert{
|
||||
Labels: LabelSet{"a": "b"},
|
||||
StartsAt: ts,
|
||||
EndsAt: ts.Add(1 * time.Minute),
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: &Alert{
|
||||
Labels: LabelSet{"a": "b"},
|
||||
StartsAt: ts,
|
||||
EndsAt: ts.Add(-1 * time.Minute),
|
||||
},
|
||||
err: "start time must be before end time",
|
||||
},
|
||||
{
|
||||
alert: &Alert{
|
||||
StartsAt: ts,
|
||||
},
|
||||
err: "at least one label pair required",
|
||||
},
|
||||
{
|
||||
alert: &Alert{
|
||||
Labels: LabelSet{"a": "b", "!bad": "label"},
|
||||
StartsAt: ts,
|
||||
},
|
||||
err: "invalid label set: invalid name",
|
||||
},
|
||||
{
|
||||
alert: &Alert{
|
||||
Labels: LabelSet{"a": "b", "bad": "\xfflabel"},
|
||||
StartsAt: ts,
|
||||
},
|
||||
err: "invalid label set: invalid value",
|
||||
},
|
||||
{
|
||||
alert: &Alert{
|
||||
Labels: LabelSet{"a": "b"},
|
||||
Annotations: LabelSet{"!bad": "label"},
|
||||
StartsAt: ts,
|
||||
},
|
||||
err: "invalid annotations: invalid name",
|
||||
},
|
||||
{
|
||||
alert: &Alert{
|
||||
Labels: LabelSet{"a": "b"},
|
||||
Annotations: LabelSet{"bad": "\xfflabel"},
|
||||
StartsAt: ts,
|
||||
},
|
||||
err: "invalid annotations: invalid value",
|
||||
},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
err := c.alert.Validate()
|
||||
if err == nil {
|
||||
if c.err == "" {
|
||||
continue
|
||||
}
|
||||
t.Errorf("%d. Expected error %q but got none", i, c.err)
|
||||
continue
|
||||
}
|
||||
if c.err == "" && err != nil {
|
||||
t.Errorf("%d. Expected no error but got %q", i, err)
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(err.Error(), c.err) {
|
||||
t.Errorf("%d. Expected error to contain %q but got %q", i, c.err, err)
|
||||
}
|
||||
}
|
||||
}
|
140
gateway/vendor/github.com/prometheus/common/model/labels_test.go
generated
vendored
Normal file
140
gateway/vendor/github.com/prometheus/common/model/labels_test.go
generated
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
// Copyright 2013 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testLabelNames(t testing.TB) {
|
||||
var scenarios = []struct {
|
||||
in LabelNames
|
||||
out LabelNames
|
||||
}{
|
||||
{
|
||||
in: LabelNames{"ZZZ", "zzz"},
|
||||
out: LabelNames{"ZZZ", "zzz"},
|
||||
},
|
||||
{
|
||||
in: LabelNames{"aaa", "AAA"},
|
||||
out: LabelNames{"AAA", "aaa"},
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
sort.Sort(scenario.in)
|
||||
|
||||
for j, expected := range scenario.out {
|
||||
if expected != scenario.in[j] {
|
||||
t.Errorf("%d.%d expected %s, got %s", i, j, expected, scenario.in[j])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLabelNames(t *testing.T) {
|
||||
testLabelNames(t)
|
||||
}
|
||||
|
||||
func BenchmarkLabelNames(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
testLabelNames(b)
|
||||
}
|
||||
}
|
||||
|
||||
func testLabelValues(t testing.TB) {
|
||||
var scenarios = []struct {
|
||||
in LabelValues
|
||||
out LabelValues
|
||||
}{
|
||||
{
|
||||
in: LabelValues{"ZZZ", "zzz"},
|
||||
out: LabelValues{"ZZZ", "zzz"},
|
||||
},
|
||||
{
|
||||
in: LabelValues{"aaa", "AAA"},
|
||||
out: LabelValues{"AAA", "aaa"},
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
sort.Sort(scenario.in)
|
||||
|
||||
for j, expected := range scenario.out {
|
||||
if expected != scenario.in[j] {
|
||||
t.Errorf("%d.%d expected %s, got %s", i, j, expected, scenario.in[j])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLabelValues(t *testing.T) {
|
||||
testLabelValues(t)
|
||||
}
|
||||
|
||||
func BenchmarkLabelValues(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
testLabelValues(b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLabelNameIsValid(t *testing.T) {
|
||||
var scenarios = []struct {
|
||||
ln LabelName
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
ln: "Avalid_23name",
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
ln: "_Avalid_23name",
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
ln: "1valid_23name",
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
ln: "avalid_23name",
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
ln: "Ava:lid_23name",
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
ln: "a lid_23name",
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
ln: ":leading_colon",
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
ln: "colon:in:the:middle",
|
||||
valid: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
if s.ln.IsValid() != s.valid {
|
||||
t.Errorf("Expected %v for %q using IsValid method", s.valid, s.ln)
|
||||
}
|
||||
if LabelNameRE.MatchString(string(s.ln)) != s.valid {
|
||||
t.Errorf("Expected %v for %q using regexp match", s.valid, s.ln)
|
||||
}
|
||||
}
|
||||
}
|
132
gateway/vendor/github.com/prometheus/common/model/metric_test.go
generated
vendored
Normal file
132
gateway/vendor/github.com/prometheus/common/model/metric_test.go
generated
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright 2013 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package model
|
||||
|
||||
import "testing"
|
||||
|
||||
func testMetric(t testing.TB) {
|
||||
var scenarios = []struct {
|
||||
input LabelSet
|
||||
fingerprint Fingerprint
|
||||
fastFingerprint Fingerprint
|
||||
}{
|
||||
{
|
||||
input: LabelSet{},
|
||||
fingerprint: 14695981039346656037,
|
||||
fastFingerprint: 14695981039346656037,
|
||||
},
|
||||
{
|
||||
input: LabelSet{
|
||||
"first_name": "electro",
|
||||
"occupation": "robot",
|
||||
"manufacturer": "westinghouse",
|
||||
},
|
||||
fingerprint: 5911716720268894962,
|
||||
fastFingerprint: 11310079640881077873,
|
||||
},
|
||||
{
|
||||
input: LabelSet{
|
||||
"x": "y",
|
||||
},
|
||||
fingerprint: 8241431561484471700,
|
||||
fastFingerprint: 13948396922932177635,
|
||||
},
|
||||
{
|
||||
input: LabelSet{
|
||||
"a": "bb",
|
||||
"b": "c",
|
||||
},
|
||||
fingerprint: 3016285359649981711,
|
||||
fastFingerprint: 3198632812309449502,
|
||||
},
|
||||
{
|
||||
input: LabelSet{
|
||||
"a": "b",
|
||||
"bb": "c",
|
||||
},
|
||||
fingerprint: 7122421792099404749,
|
||||
fastFingerprint: 5774953389407657638,
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
input := Metric(scenario.input)
|
||||
|
||||
if scenario.fingerprint != input.Fingerprint() {
|
||||
t.Errorf("%d. expected %d, got %d", i, scenario.fingerprint, input.Fingerprint())
|
||||
}
|
||||
if scenario.fastFingerprint != input.FastFingerprint() {
|
||||
t.Errorf("%d. expected %d, got %d", i, scenario.fastFingerprint, input.FastFingerprint())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetric(t *testing.T) {
|
||||
testMetric(t)
|
||||
}
|
||||
|
||||
func BenchmarkMetric(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
testMetric(b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetricNameIsValid(t *testing.T) {
|
||||
var scenarios = []struct {
|
||||
mn LabelValue
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
mn: "Avalid_23name",
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
mn: "_Avalid_23name",
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
mn: "1valid_23name",
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
mn: "avalid_23name",
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
mn: "Ava:lid_23name",
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
mn: "a lid_23name",
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
mn: ":leading_colon",
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
mn: "colon:in:the:middle",
|
||||
valid: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
if IsValidMetricName(s.mn) != s.valid {
|
||||
t.Errorf("Expected %v for %q using IsValidMetricName function", s.valid, s.mn)
|
||||
}
|
||||
if MetricNameRE.MatchString(string(s.mn)) != s.valid {
|
||||
t.Errorf("Expected %v for %q using regexp matching", s.valid, s.mn)
|
||||
}
|
||||
}
|
||||
}
|
314
gateway/vendor/github.com/prometheus/common/model/signature_test.go
generated
vendored
Normal file
314
gateway/vendor/github.com/prometheus/common/model/signature_test.go
generated
vendored
Normal file
@ -0,0 +1,314 @@
|
||||
// Copyright 2014 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLabelsToSignature(t *testing.T) {
|
||||
var scenarios = []struct {
|
||||
in map[string]string
|
||||
out uint64
|
||||
}{
|
||||
{
|
||||
in: map[string]string{},
|
||||
out: 14695981039346656037,
|
||||
},
|
||||
{
|
||||
in: map[string]string{"name": "garland, briggs", "fear": "love is not enough"},
|
||||
out: 5799056148416392346,
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
actual := LabelsToSignature(scenario.in)
|
||||
|
||||
if actual != scenario.out {
|
||||
t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetricToFingerprint(t *testing.T) {
|
||||
var scenarios = []struct {
|
||||
in LabelSet
|
||||
out Fingerprint
|
||||
}{
|
||||
{
|
||||
in: LabelSet{},
|
||||
out: 14695981039346656037,
|
||||
},
|
||||
{
|
||||
in: LabelSet{"name": "garland, briggs", "fear": "love is not enough"},
|
||||
out: 5799056148416392346,
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
actual := labelSetToFingerprint(scenario.in)
|
||||
|
||||
if actual != scenario.out {
|
||||
t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetricToFastFingerprint(t *testing.T) {
|
||||
var scenarios = []struct {
|
||||
in LabelSet
|
||||
out Fingerprint
|
||||
}{
|
||||
{
|
||||
in: LabelSet{},
|
||||
out: 14695981039346656037,
|
||||
},
|
||||
{
|
||||
in: LabelSet{"name": "garland, briggs", "fear": "love is not enough"},
|
||||
out: 12952432476264840823,
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
actual := labelSetToFastFingerprint(scenario.in)
|
||||
|
||||
if actual != scenario.out {
|
||||
t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignatureForLabels(t *testing.T) {
|
||||
var scenarios = []struct {
|
||||
in Metric
|
||||
labels LabelNames
|
||||
out uint64
|
||||
}{
|
||||
{
|
||||
in: Metric{},
|
||||
labels: nil,
|
||||
out: 14695981039346656037,
|
||||
},
|
||||
{
|
||||
in: Metric{},
|
||||
labels: LabelNames{"empty"},
|
||||
out: 7187873163539638612,
|
||||
},
|
||||
{
|
||||
in: Metric{"name": "garland, briggs", "fear": "love is not enough"},
|
||||
labels: LabelNames{"empty"},
|
||||
out: 7187873163539638612,
|
||||
},
|
||||
{
|
||||
in: Metric{"name": "garland, briggs", "fear": "love is not enough"},
|
||||
labels: LabelNames{"fear", "name"},
|
||||
out: 5799056148416392346,
|
||||
},
|
||||
{
|
||||
in: Metric{"name": "garland, briggs", "fear": "love is not enough", "foo": "bar"},
|
||||
labels: LabelNames{"fear", "name"},
|
||||
out: 5799056148416392346,
|
||||
},
|
||||
{
|
||||
in: Metric{"name": "garland, briggs", "fear": "love is not enough"},
|
||||
labels: LabelNames{},
|
||||
out: 14695981039346656037,
|
||||
},
|
||||
{
|
||||
in: Metric{"name": "garland, briggs", "fear": "love is not enough"},
|
||||
labels: nil,
|
||||
out: 14695981039346656037,
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
actual := SignatureForLabels(scenario.in, scenario.labels...)
|
||||
|
||||
if actual != scenario.out {
|
||||
t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignatureWithoutLabels(t *testing.T) {
|
||||
var scenarios = []struct {
|
||||
in Metric
|
||||
labels map[LabelName]struct{}
|
||||
out uint64
|
||||
}{
|
||||
{
|
||||
in: Metric{},
|
||||
labels: nil,
|
||||
out: 14695981039346656037,
|
||||
},
|
||||
{
|
||||
in: Metric{"name": "garland, briggs", "fear": "love is not enough"},
|
||||
labels: map[LabelName]struct{}{"fear": struct{}{}, "name": struct{}{}},
|
||||
out: 14695981039346656037,
|
||||
},
|
||||
{
|
||||
in: Metric{"name": "garland, briggs", "fear": "love is not enough", "foo": "bar"},
|
||||
labels: map[LabelName]struct{}{"foo": struct{}{}},
|
||||
out: 5799056148416392346,
|
||||
},
|
||||
{
|
||||
in: Metric{"name": "garland, briggs", "fear": "love is not enough"},
|
||||
labels: map[LabelName]struct{}{},
|
||||
out: 5799056148416392346,
|
||||
},
|
||||
{
|
||||
in: Metric{"name": "garland, briggs", "fear": "love is not enough"},
|
||||
labels: nil,
|
||||
out: 5799056148416392346,
|
||||
},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
actual := SignatureWithoutLabels(scenario.in, scenario.labels)
|
||||
|
||||
if actual != scenario.out {
|
||||
t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkLabelToSignature(b *testing.B, l map[string]string, e uint64) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
if a := LabelsToSignature(l); a != e {
|
||||
b.Fatalf("expected signature of %d for %s, got %d", e, l, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkLabelToSignatureScalar(b *testing.B) {
|
||||
benchmarkLabelToSignature(b, nil, 14695981039346656037)
|
||||
}
|
||||
|
||||
func BenchmarkLabelToSignatureSingle(b *testing.B) {
|
||||
benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value"}, 5146282821936882169)
|
||||
}
|
||||
|
||||
func BenchmarkLabelToSignatureDouble(b *testing.B) {
|
||||
benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value"}, 3195800080984914717)
|
||||
}
|
||||
|
||||
func BenchmarkLabelToSignatureTriple(b *testing.B) {
|
||||
benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 13843036195897128121)
|
||||
}
|
||||
|
||||
func benchmarkMetricToFingerprint(b *testing.B, ls LabelSet, e Fingerprint) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
if a := labelSetToFingerprint(ls); a != e {
|
||||
b.Fatalf("expected signature of %d for %s, got %d", e, ls, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMetricToFingerprintScalar(b *testing.B) {
|
||||
benchmarkMetricToFingerprint(b, nil, 14695981039346656037)
|
||||
}
|
||||
|
||||
func BenchmarkMetricToFingerprintSingle(b *testing.B) {
|
||||
benchmarkMetricToFingerprint(b, LabelSet{"first-label": "first-label-value"}, 5146282821936882169)
|
||||
}
|
||||
|
||||
func BenchmarkMetricToFingerprintDouble(b *testing.B) {
|
||||
benchmarkMetricToFingerprint(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value"}, 3195800080984914717)
|
||||
}
|
||||
|
||||
func BenchmarkMetricToFingerprintTriple(b *testing.B) {
|
||||
benchmarkMetricToFingerprint(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 13843036195897128121)
|
||||
}
|
||||
|
||||
func benchmarkMetricToFastFingerprint(b *testing.B, ls LabelSet, e Fingerprint) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
if a := labelSetToFastFingerprint(ls); a != e {
|
||||
b.Fatalf("expected signature of %d for %s, got %d", e, ls, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMetricToFastFingerprintScalar(b *testing.B) {
|
||||
benchmarkMetricToFastFingerprint(b, nil, 14695981039346656037)
|
||||
}
|
||||
|
||||
func BenchmarkMetricToFastFingerprintSingle(b *testing.B) {
|
||||
benchmarkMetricToFastFingerprint(b, LabelSet{"first-label": "first-label-value"}, 5147259542624943964)
|
||||
}
|
||||
|
||||
func BenchmarkMetricToFastFingerprintDouble(b *testing.B) {
|
||||
benchmarkMetricToFastFingerprint(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value"}, 18269973311206963528)
|
||||
}
|
||||
|
||||
func BenchmarkMetricToFastFingerprintTriple(b *testing.B) {
|
||||
benchmarkMetricToFastFingerprint(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676)
|
||||
}
|
||||
|
||||
func BenchmarkEmptyLabelSignature(b *testing.B) {
|
||||
input := []map[string]string{nil, {}}
|
||||
|
||||
var ms runtime.MemStats
|
||||
runtime.ReadMemStats(&ms)
|
||||
|
||||
alloc := ms.Alloc
|
||||
|
||||
for _, labels := range input {
|
||||
LabelsToSignature(labels)
|
||||
}
|
||||
|
||||
runtime.ReadMemStats(&ms)
|
||||
|
||||
if got := ms.Alloc; alloc != got {
|
||||
b.Fatal("expected LabelsToSignature with empty labels not to perform allocations")
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkMetricToFastFingerprintConc(b *testing.B, ls LabelSet, e Fingerprint, concLevel int) {
|
||||
var start, end sync.WaitGroup
|
||||
start.Add(1)
|
||||
end.Add(concLevel)
|
||||
|
||||
for i := 0; i < concLevel; i++ {
|
||||
go func() {
|
||||
start.Wait()
|
||||
for j := b.N / concLevel; j >= 0; j-- {
|
||||
if a := labelSetToFastFingerprint(ls); a != e {
|
||||
b.Fatalf("expected signature of %d for %s, got %d", e, ls, a)
|
||||
}
|
||||
}
|
||||
end.Done()
|
||||
}()
|
||||
}
|
||||
b.ResetTimer()
|
||||
start.Done()
|
||||
end.Wait()
|
||||
}
|
||||
|
||||
func BenchmarkMetricToFastFingerprintTripleConc1(b *testing.B) {
|
||||
benchmarkMetricToFastFingerprintConc(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 1)
|
||||
}
|
||||
|
||||
func BenchmarkMetricToFastFingerprintTripleConc2(b *testing.B) {
|
||||
benchmarkMetricToFastFingerprintConc(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 2)
|
||||
}
|
||||
|
||||
func BenchmarkMetricToFastFingerprintTripleConc4(b *testing.B) {
|
||||
benchmarkMetricToFastFingerprintConc(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 4)
|
||||
}
|
||||
|
||||
func BenchmarkMetricToFastFingerprintTripleConc8(b *testing.B) {
|
||||
benchmarkMetricToFastFingerprintConc(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 8)
|
||||
}
|
228
gateway/vendor/github.com/prometheus/common/model/silence_test.go
generated
vendored
Normal file
228
gateway/vendor/github.com/prometheus/common/model/silence_test.go
generated
vendored
Normal file
@ -0,0 +1,228 @@
|
||||
// Copyright 2015 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestMatcherValidate(t *testing.T) {
|
||||
var cases = []struct {
|
||||
matcher *Matcher
|
||||
err string
|
||||
}{
|
||||
{
|
||||
matcher: &Matcher{
|
||||
Name: "name",
|
||||
Value: "value",
|
||||
},
|
||||
},
|
||||
{
|
||||
matcher: &Matcher{
|
||||
Name: "name",
|
||||
Value: "value",
|
||||
IsRegex: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
matcher: &Matcher{
|
||||
Name: "name!",
|
||||
Value: "value",
|
||||
},
|
||||
err: "invalid name",
|
||||
},
|
||||
{
|
||||
matcher: &Matcher{
|
||||
Name: "",
|
||||
Value: "value",
|
||||
},
|
||||
err: "invalid name",
|
||||
},
|
||||
{
|
||||
matcher: &Matcher{
|
||||
Name: "name",
|
||||
Value: "value\xff",
|
||||
},
|
||||
err: "invalid value",
|
||||
},
|
||||
{
|
||||
matcher: &Matcher{
|
||||
Name: "name",
|
||||
Value: "",
|
||||
},
|
||||
err: "invalid value",
|
||||
},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
err := c.matcher.Validate()
|
||||
if err == nil {
|
||||
if c.err == "" {
|
||||
continue
|
||||
}
|
||||
t.Errorf("%d. Expected error %q but got none", i, c.err)
|
||||
continue
|
||||
}
|
||||
if c.err == "" && err != nil {
|
||||
t.Errorf("%d. Expected no error but got %q", i, err)
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(err.Error(), c.err) {
|
||||
t.Errorf("%d. Expected error to contain %q but got %q", i, c.err, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSilenceValidate(t *testing.T) {
|
||||
ts := time.Now()
|
||||
|
||||
var cases = []struct {
|
||||
sil *Silence
|
||||
err string
|
||||
}{
|
||||
{
|
||||
sil: &Silence{
|
||||
Matchers: []*Matcher{
|
||||
{Name: "name", Value: "value"},
|
||||
},
|
||||
StartsAt: ts,
|
||||
EndsAt: ts,
|
||||
CreatedAt: ts,
|
||||
CreatedBy: "name",
|
||||
Comment: "comment",
|
||||
},
|
||||
},
|
||||
{
|
||||
sil: &Silence{
|
||||
Matchers: []*Matcher{
|
||||
{Name: "name", Value: "value"},
|
||||
{Name: "name", Value: "value"},
|
||||
{Name: "name", Value: "value"},
|
||||
{Name: "name", Value: "value", IsRegex: true},
|
||||
},
|
||||
StartsAt: ts,
|
||||
EndsAt: ts,
|
||||
CreatedAt: ts,
|
||||
CreatedBy: "name",
|
||||
Comment: "comment",
|
||||
},
|
||||
},
|
||||
{
|
||||
sil: &Silence{
|
||||
Matchers: []*Matcher{
|
||||
{Name: "name", Value: "value"},
|
||||
},
|
||||
StartsAt: ts,
|
||||
EndsAt: ts.Add(-1 * time.Minute),
|
||||
CreatedAt: ts,
|
||||
CreatedBy: "name",
|
||||
Comment: "comment",
|
||||
},
|
||||
err: "start time must be before end time",
|
||||
},
|
||||
{
|
||||
sil: &Silence{
|
||||
Matchers: []*Matcher{
|
||||
{Name: "name", Value: "value"},
|
||||
},
|
||||
StartsAt: ts,
|
||||
CreatedAt: ts,
|
||||
CreatedBy: "name",
|
||||
Comment: "comment",
|
||||
},
|
||||
err: "end time missing",
|
||||
},
|
||||
{
|
||||
sil: &Silence{
|
||||
Matchers: []*Matcher{
|
||||
{Name: "name", Value: "value"},
|
||||
},
|
||||
EndsAt: ts,
|
||||
CreatedAt: ts,
|
||||
CreatedBy: "name",
|
||||
Comment: "comment",
|
||||
},
|
||||
err: "start time missing",
|
||||
},
|
||||
{
|
||||
sil: &Silence{
|
||||
Matchers: []*Matcher{
|
||||
{Name: "!name", Value: "value"},
|
||||
},
|
||||
StartsAt: ts,
|
||||
EndsAt: ts,
|
||||
CreatedAt: ts,
|
||||
CreatedBy: "name",
|
||||
Comment: "comment",
|
||||
},
|
||||
err: "invalid matcher",
|
||||
},
|
||||
{
|
||||
sil: &Silence{
|
||||
Matchers: []*Matcher{
|
||||
{Name: "name", Value: "value"},
|
||||
},
|
||||
StartsAt: ts,
|
||||
EndsAt: ts,
|
||||
CreatedAt: ts,
|
||||
CreatedBy: "name",
|
||||
},
|
||||
err: "comment missing",
|
||||
},
|
||||
{
|
||||
sil: &Silence{
|
||||
Matchers: []*Matcher{
|
||||
{Name: "name", Value: "value"},
|
||||
},
|
||||
StartsAt: ts,
|
||||
EndsAt: ts,
|
||||
CreatedBy: "name",
|
||||
Comment: "comment",
|
||||
},
|
||||
err: "creation timestamp missing",
|
||||
},
|
||||
{
|
||||
sil: &Silence{
|
||||
Matchers: []*Matcher{
|
||||
{Name: "name", Value: "value"},
|
||||
},
|
||||
StartsAt: ts,
|
||||
EndsAt: ts,
|
||||
CreatedAt: ts,
|
||||
Comment: "comment",
|
||||
},
|
||||
err: "creator information missing",
|
||||
},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
err := c.sil.Validate()
|
||||
if err == nil {
|
||||
if c.err == "" {
|
||||
continue
|
||||
}
|
||||
t.Errorf("%d. Expected error %q but got none", i, c.err)
|
||||
continue
|
||||
}
|
||||
if c.err == "" && err != nil {
|
||||
t.Errorf("%d. Expected no error but got %q", i, err)
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(err.Error(), c.err) {
|
||||
t.Errorf("%d. Expected error to contain %q but got %q", i, c.err, err)
|
||||
}
|
||||
}
|
||||
}
|
3
gateway/vendor/github.com/prometheus/common/model/time.go
generated
vendored
3
gateway/vendor/github.com/prometheus/common/model/time.go
generated
vendored
@ -214,6 +214,9 @@ func (d Duration) String() string {
|
||||
ms = int64(time.Duration(d) / time.Millisecond)
|
||||
unit = "ms"
|
||||
)
|
||||
if ms == 0 {
|
||||
return "0s"
|
||||
}
|
||||
factors := map[string]int64{
|
||||
"y": 1000 * 60 * 60 * 24 * 365,
|
||||
"w": 1000 * 60 * 60 * 24 * 7,
|
||||
|
132
gateway/vendor/github.com/prometheus/common/model/time_test.go
generated
vendored
Normal file
132
gateway/vendor/github.com/prometheus/common/model/time_test.go
generated
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright 2013 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestComparators(t *testing.T) {
|
||||
t1a := TimeFromUnix(0)
|
||||
t1b := TimeFromUnix(0)
|
||||
t2 := TimeFromUnix(2*second - 1)
|
||||
|
||||
if !t1a.Equal(t1b) {
|
||||
t.Fatalf("Expected %s to be equal to %s", t1a, t1b)
|
||||
}
|
||||
if t1a.Equal(t2) {
|
||||
t.Fatalf("Expected %s to not be equal to %s", t1a, t2)
|
||||
}
|
||||
|
||||
if !t1a.Before(t2) {
|
||||
t.Fatalf("Expected %s to be before %s", t1a, t2)
|
||||
}
|
||||
if t1a.Before(t1b) {
|
||||
t.Fatalf("Expected %s to not be before %s", t1a, t1b)
|
||||
}
|
||||
|
||||
if !t2.After(t1a) {
|
||||
t.Fatalf("Expected %s to be after %s", t2, t1a)
|
||||
}
|
||||
if t1b.After(t1a) {
|
||||
t.Fatalf("Expected %s to not be after %s", t1b, t1a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeConversions(t *testing.T) {
|
||||
unixSecs := int64(1136239445)
|
||||
unixNsecs := int64(123456789)
|
||||
unixNano := unixSecs*1e9 + unixNsecs
|
||||
|
||||
t1 := time.Unix(unixSecs, unixNsecs-unixNsecs%nanosPerTick)
|
||||
t2 := time.Unix(unixSecs, unixNsecs)
|
||||
|
||||
ts := TimeFromUnixNano(unixNano)
|
||||
if !ts.Time().Equal(t1) {
|
||||
t.Fatalf("Expected %s, got %s", t1, ts.Time())
|
||||
}
|
||||
|
||||
// Test available precision.
|
||||
ts = TimeFromUnixNano(t2.UnixNano())
|
||||
if !ts.Time().Equal(t1) {
|
||||
t.Fatalf("Expected %s, got %s", t1, ts.Time())
|
||||
}
|
||||
|
||||
if ts.UnixNano() != unixNano-unixNano%nanosPerTick {
|
||||
t.Fatalf("Expected %d, got %d", unixNano, ts.UnixNano())
|
||||
}
|
||||
}
|
||||
|
||||
func TestDuration(t *testing.T) {
|
||||
duration := time.Second + time.Minute + time.Hour
|
||||
goTime := time.Unix(1136239445, 0)
|
||||
|
||||
ts := TimeFromUnix(goTime.Unix())
|
||||
if !goTime.Add(duration).Equal(ts.Add(duration).Time()) {
|
||||
t.Fatalf("Expected %s to be equal to %s", goTime.Add(duration), ts.Add(duration))
|
||||
}
|
||||
|
||||
earlier := ts.Add(-duration)
|
||||
delta := ts.Sub(earlier)
|
||||
if delta != duration {
|
||||
t.Fatalf("Expected %s to be equal to %s", delta, duration)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseDuration(t *testing.T) {
|
||||
var cases = []struct {
|
||||
in string
|
||||
out time.Duration
|
||||
}{
|
||||
{
|
||||
in: "0s",
|
||||
out: 0,
|
||||
}, {
|
||||
in: "324ms",
|
||||
out: 324 * time.Millisecond,
|
||||
}, {
|
||||
in: "3s",
|
||||
out: 3 * time.Second,
|
||||
}, {
|
||||
in: "5m",
|
||||
out: 5 * time.Minute,
|
||||
}, {
|
||||
in: "1h",
|
||||
out: time.Hour,
|
||||
}, {
|
||||
in: "4d",
|
||||
out: 4 * 24 * time.Hour,
|
||||
}, {
|
||||
in: "3w",
|
||||
out: 3 * 7 * 24 * time.Hour,
|
||||
}, {
|
||||
in: "10y",
|
||||
out: 10 * 365 * 24 * time.Hour,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
d, err := ParseDuration(c.in)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error on input %q", c.in)
|
||||
}
|
||||
if time.Duration(d) != c.out {
|
||||
t.Errorf("Expected %v but got %v", c.out, d)
|
||||
}
|
||||
if d.String() != c.in {
|
||||
t.Errorf("Expected duration string %q but got %q", c.in, d.String())
|
||||
}
|
||||
}
|
||||
}
|
468
gateway/vendor/github.com/prometheus/common/model/value_test.go
generated
vendored
Normal file
468
gateway/vendor/github.com/prometheus/common/model/value_test.go
generated
vendored
Normal file
@ -0,0 +1,468 @@
|
||||
// Copyright 2013 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEqualValues(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
in1, in2 SampleValue
|
||||
want bool
|
||||
}{
|
||||
"equal floats": {
|
||||
in1: 3.14,
|
||||
in2: 3.14,
|
||||
want: true,
|
||||
},
|
||||
"unequal floats": {
|
||||
in1: 3.14,
|
||||
in2: 3.1415,
|
||||
want: false,
|
||||
},
|
||||
"positive inifinities": {
|
||||
in1: SampleValue(math.Inf(+1)),
|
||||
in2: SampleValue(math.Inf(+1)),
|
||||
want: true,
|
||||
},
|
||||
"negative inifinities": {
|
||||
in1: SampleValue(math.Inf(-1)),
|
||||
in2: SampleValue(math.Inf(-1)),
|
||||
want: true,
|
||||
},
|
||||
"different inifinities": {
|
||||
in1: SampleValue(math.Inf(+1)),
|
||||
in2: SampleValue(math.Inf(-1)),
|
||||
want: false,
|
||||
},
|
||||
"number and infinity": {
|
||||
in1: 42,
|
||||
in2: SampleValue(math.Inf(+1)),
|
||||
want: false,
|
||||
},
|
||||
"number and NaN": {
|
||||
in1: 42,
|
||||
in2: SampleValue(math.NaN()),
|
||||
want: false,
|
||||
},
|
||||
"NaNs": {
|
||||
in1: SampleValue(math.NaN()),
|
||||
in2: SampleValue(math.NaN()),
|
||||
want: true, // !!!
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
got := test.in1.Equal(test.in2)
|
||||
if got != test.want {
|
||||
t.Errorf("Comparing %s, %f and %f: got %t, want %t", name, test.in1, test.in2, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEqualSamples(t *testing.T) {
|
||||
testSample := &Sample{}
|
||||
|
||||
tests := map[string]struct {
|
||||
in1, in2 *Sample
|
||||
want bool
|
||||
}{
|
||||
"equal pointers": {
|
||||
in1: testSample,
|
||||
in2: testSample,
|
||||
want: true,
|
||||
},
|
||||
"different metrics": {
|
||||
in1: &Sample{Metric: Metric{"foo": "bar"}},
|
||||
in2: &Sample{Metric: Metric{"foo": "biz"}},
|
||||
want: false,
|
||||
},
|
||||
"different timestamp": {
|
||||
in1: &Sample{Timestamp: 0},
|
||||
in2: &Sample{Timestamp: 1},
|
||||
want: false,
|
||||
},
|
||||
"different value": {
|
||||
in1: &Sample{Value: 0},
|
||||
in2: &Sample{Value: 1},
|
||||
want: false,
|
||||
},
|
||||
"equal samples": {
|
||||
in1: &Sample{
|
||||
Metric: Metric{"foo": "bar"},
|
||||
Timestamp: 0,
|
||||
Value: 1,
|
||||
},
|
||||
in2: &Sample{
|
||||
Metric: Metric{"foo": "bar"},
|
||||
Timestamp: 0,
|
||||
Value: 1,
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
got := test.in1.Equal(test.in2)
|
||||
if got != test.want {
|
||||
t.Errorf("Comparing %s, %v and %v: got %t, want %t", name, test.in1, test.in2, got, test.want)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestSamplePairJSON(t *testing.T) {
|
||||
input := []struct {
|
||||
plain string
|
||||
value SamplePair
|
||||
}{
|
||||
{
|
||||
plain: `[1234.567,"123.1"]`,
|
||||
value: SamplePair{
|
||||
Value: 123.1,
|
||||
Timestamp: 1234567,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range input {
|
||||
b, err := json.Marshal(test.value)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if string(b) != test.plain {
|
||||
t.Errorf("encoding error: expected %q, got %q", test.plain, b)
|
||||
continue
|
||||
}
|
||||
|
||||
var sp SamplePair
|
||||
err = json.Unmarshal(b, &sp)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if sp != test.value {
|
||||
t.Errorf("decoding error: expected %v, got %v", test.value, sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSampleJSON(t *testing.T) {
|
||||
input := []struct {
|
||||
plain string
|
||||
value Sample
|
||||
}{
|
||||
{
|
||||
plain: `{"metric":{"__name__":"test_metric"},"value":[1234.567,"123.1"]}`,
|
||||
value: Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "test_metric",
|
||||
},
|
||||
Value: 123.1,
|
||||
Timestamp: 1234567,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range input {
|
||||
b, err := json.Marshal(test.value)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if string(b) != test.plain {
|
||||
t.Errorf("encoding error: expected %q, got %q", test.plain, b)
|
||||
continue
|
||||
}
|
||||
|
||||
var sv Sample
|
||||
err = json.Unmarshal(b, &sv)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(sv, test.value) {
|
||||
t.Errorf("decoding error: expected %v, got %v", test.value, sv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVectorJSON(t *testing.T) {
|
||||
input := []struct {
|
||||
plain string
|
||||
value Vector
|
||||
}{
|
||||
{
|
||||
plain: `[]`,
|
||||
value: Vector{},
|
||||
},
|
||||
{
|
||||
plain: `[{"metric":{"__name__":"test_metric"},"value":[1234.567,"123.1"]}]`,
|
||||
value: Vector{&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "test_metric",
|
||||
},
|
||||
Value: 123.1,
|
||||
Timestamp: 1234567,
|
||||
}},
|
||||
},
|
||||
{
|
||||
plain: `[{"metric":{"__name__":"test_metric"},"value":[1234.567,"123.1"]},{"metric":{"foo":"bar"},"value":[1.234,"+Inf"]}]`,
|
||||
value: Vector{
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "test_metric",
|
||||
},
|
||||
Value: 123.1,
|
||||
Timestamp: 1234567,
|
||||
},
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
"foo": "bar",
|
||||
},
|
||||
Value: SampleValue(math.Inf(1)),
|
||||
Timestamp: 1234,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range input {
|
||||
b, err := json.Marshal(test.value)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if string(b) != test.plain {
|
||||
t.Errorf("encoding error: expected %q, got %q", test.plain, b)
|
||||
continue
|
||||
}
|
||||
|
||||
var vec Vector
|
||||
err = json.Unmarshal(b, &vec)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(vec, test.value) {
|
||||
t.Errorf("decoding error: expected %v, got %v", test.value, vec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScalarJSON(t *testing.T) {
|
||||
input := []struct {
|
||||
plain string
|
||||
value Scalar
|
||||
}{
|
||||
{
|
||||
plain: `[123.456,"456"]`,
|
||||
value: Scalar{
|
||||
Timestamp: 123456,
|
||||
Value: 456,
|
||||
},
|
||||
},
|
||||
{
|
||||
plain: `[123123.456,"+Inf"]`,
|
||||
value: Scalar{
|
||||
Timestamp: 123123456,
|
||||
Value: SampleValue(math.Inf(1)),
|
||||
},
|
||||
},
|
||||
{
|
||||
plain: `[123123.456,"-Inf"]`,
|
||||
value: Scalar{
|
||||
Timestamp: 123123456,
|
||||
Value: SampleValue(math.Inf(-1)),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range input {
|
||||
b, err := json.Marshal(test.value)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if string(b) != test.plain {
|
||||
t.Errorf("encoding error: expected %q, got %q", test.plain, b)
|
||||
continue
|
||||
}
|
||||
|
||||
var sv Scalar
|
||||
err = json.Unmarshal(b, &sv)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if sv != test.value {
|
||||
t.Errorf("decoding error: expected %v, got %v", test.value, sv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringJSON(t *testing.T) {
|
||||
input := []struct {
|
||||
plain string
|
||||
value String
|
||||
}{
|
||||
{
|
||||
plain: `[123.456,"test"]`,
|
||||
value: String{
|
||||
Timestamp: 123456,
|
||||
Value: "test",
|
||||
},
|
||||
},
|
||||
{
|
||||
plain: `[123123.456,"台北"]`,
|
||||
value: String{
|
||||
Timestamp: 123123456,
|
||||
Value: "台北",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range input {
|
||||
b, err := json.Marshal(test.value)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if string(b) != test.plain {
|
||||
t.Errorf("encoding error: expected %q, got %q", test.plain, b)
|
||||
continue
|
||||
}
|
||||
|
||||
var sv String
|
||||
err = json.Unmarshal(b, &sv)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if sv != test.value {
|
||||
t.Errorf("decoding error: expected %v, got %v", test.value, sv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVectorSort(t *testing.T) {
|
||||
input := Vector{
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "A",
|
||||
},
|
||||
Timestamp: 1,
|
||||
},
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "A",
|
||||
},
|
||||
Timestamp: 2,
|
||||
},
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "C",
|
||||
},
|
||||
Timestamp: 1,
|
||||
},
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "C",
|
||||
},
|
||||
Timestamp: 2,
|
||||
},
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "B",
|
||||
},
|
||||
Timestamp: 1,
|
||||
},
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "B",
|
||||
},
|
||||
Timestamp: 2,
|
||||
},
|
||||
}
|
||||
|
||||
expected := Vector{
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "A",
|
||||
},
|
||||
Timestamp: 1,
|
||||
},
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "A",
|
||||
},
|
||||
Timestamp: 2,
|
||||
},
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "B",
|
||||
},
|
||||
Timestamp: 1,
|
||||
},
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "B",
|
||||
},
|
||||
Timestamp: 2,
|
||||
},
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "C",
|
||||
},
|
||||
Timestamp: 1,
|
||||
},
|
||||
&Sample{
|
||||
Metric: Metric{
|
||||
MetricNameLabel: "C",
|
||||
},
|
||||
Timestamp: 2,
|
||||
},
|
||||
}
|
||||
|
||||
sort.Sort(input)
|
||||
|
||||
for i, actual := range input {
|
||||
actualFp := actual.Metric.Fingerprint()
|
||||
expectedFp := expected[i].Metric.Fingerprint()
|
||||
|
||||
if actualFp != expectedFp {
|
||||
t.Fatalf("%d. Incorrect fingerprint. Got %s; want %s", i, actualFp.String(), expectedFp.String())
|
||||
}
|
||||
|
||||
if actual.Timestamp != expected[i].Timestamp {
|
||||
t.Fatalf("%d. Incorrect timestamp. Got %s; want %s", i, actual.Timestamp, expected[i].Timestamp)
|
||||
}
|
||||
}
|
||||
}
|
33
gateway/vendor/github.com/prometheus/common/promlog/flag/flag.go
generated
vendored
Normal file
33
gateway/vendor/github.com/prometheus/common/promlog/flag/flag.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2017 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package flag
|
||||
|
||||
import (
|
||||
"github.com/prometheus/common/promlog"
|
||||
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
// LevelFlagName is the canonical flag name to configure the allowed log level
|
||||
// within Prometheus projects.
|
||||
const LevelFlagName = "log.level"
|
||||
|
||||
// LevelFlagHelp is the help description for the log.level flag.
|
||||
const LevelFlagHelp = "Only log messages with the given severity or above. One of: [debug, info, warn, error]"
|
||||
|
||||
// AddFlags adds the flags used by this package to the Kingpin application.
|
||||
// To use the default Kingpin application, call AddFlags(kingpin.CommandLine)
|
||||
func AddFlags(a *kingpin.Application, logLevel *promlog.AllowedLevel) {
|
||||
a.Flag(LevelFlagName, LevelFlagHelp).
|
||||
Default("info").SetValue(logLevel)
|
||||
}
|
63
gateway/vendor/github.com/prometheus/common/promlog/log.go
generated
vendored
Normal file
63
gateway/vendor/github.com/prometheus/common/promlog/log.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
// Copyright 2017 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package promlog defines standardised ways to initialize Go kit loggers
|
||||
// across Prometheus components.
|
||||
// It should typically only ever be imported by main packages.
|
||||
package promlog
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/go-kit/kit/log"
|
||||
"github.com/go-kit/kit/log/level"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// AllowedLevel is a settable identifier for the minimum level a log entry
|
||||
// must be have.
|
||||
type AllowedLevel struct {
|
||||
s string
|
||||
o level.Option
|
||||
}
|
||||
|
||||
func (l *AllowedLevel) String() string {
|
||||
return l.s
|
||||
}
|
||||
|
||||
// Set updates the value of the allowed level.
|
||||
func (l *AllowedLevel) Set(s string) error {
|
||||
switch s {
|
||||
case "debug":
|
||||
l.o = level.AllowDebug()
|
||||
case "info":
|
||||
l.o = level.AllowInfo()
|
||||
case "warn":
|
||||
l.o = level.AllowWarn()
|
||||
case "error":
|
||||
l.o = level.AllowError()
|
||||
default:
|
||||
return errors.Errorf("unrecognized log level %q", s)
|
||||
}
|
||||
l.s = s
|
||||
return nil
|
||||
}
|
||||
|
||||
// New returns a new leveled oklog logger in the logfmt format. Each logged line will be annotated
|
||||
// with a timestamp. The output always goes to stderr.
|
||||
func New(al AllowedLevel) log.Logger {
|
||||
l := log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
|
||||
l = level.NewFilter(l, al.o)
|
||||
l = log.With(l, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
|
||||
return l
|
||||
}
|
100
gateway/vendor/github.com/prometheus/common/route/route.go
generated
vendored
Normal file
100
gateway/vendor/github.com/prometheus/common/route/route.go
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type param string
|
||||
|
||||
// Param returns param p for the context.
|
||||
func Param(ctx context.Context, p string) string {
|
||||
return ctx.Value(param(p)).(string)
|
||||
}
|
||||
|
||||
// WithParam returns a new context with param p set to v.
|
||||
func WithParam(ctx context.Context, p, v string) context.Context {
|
||||
return context.WithValue(ctx, param(p), v)
|
||||
}
|
||||
|
||||
// Router wraps httprouter.Router and adds support for prefixed sub-routers
|
||||
// and per-request context injections.
|
||||
type Router struct {
|
||||
rtr *httprouter.Router
|
||||
prefix string
|
||||
}
|
||||
|
||||
// New returns a new Router.
|
||||
func New() *Router {
|
||||
return &Router{
|
||||
rtr: httprouter.New(),
|
||||
}
|
||||
}
|
||||
|
||||
// WithPrefix returns a router that prefixes all registered routes with prefix.
|
||||
func (r *Router) WithPrefix(prefix string) *Router {
|
||||
return &Router{rtr: r.rtr, prefix: r.prefix + prefix}
|
||||
}
|
||||
|
||||
// handle turns a HandlerFunc into an httprouter.Handle.
|
||||
func (r *Router) handle(h http.HandlerFunc) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
|
||||
for _, p := range params {
|
||||
ctx = context.WithValue(ctx, param(p.Key), p.Value)
|
||||
}
|
||||
h(w, req.WithContext(ctx))
|
||||
}
|
||||
}
|
||||
|
||||
// Get registers a new GET route.
|
||||
func (r *Router) Get(path string, h http.HandlerFunc) {
|
||||
r.rtr.GET(r.prefix+path, r.handle(h))
|
||||
}
|
||||
|
||||
// Options registers a new OPTIONS route.
|
||||
func (r *Router) Options(path string, h http.HandlerFunc) {
|
||||
r.rtr.OPTIONS(r.prefix+path, r.handle(h))
|
||||
}
|
||||
|
||||
// Del registers a new DELETE route.
|
||||
func (r *Router) Del(path string, h http.HandlerFunc) {
|
||||
r.rtr.DELETE(r.prefix+path, r.handle(h))
|
||||
}
|
||||
|
||||
// Put registers a new PUT route.
|
||||
func (r *Router) Put(path string, h http.HandlerFunc) {
|
||||
r.rtr.PUT(r.prefix+path, r.handle(h))
|
||||
}
|
||||
|
||||
// Post registers a new POST route.
|
||||
func (r *Router) Post(path string, h http.HandlerFunc) {
|
||||
r.rtr.POST(r.prefix+path, r.handle(h))
|
||||
}
|
||||
|
||||
// Redirect takes an absolute path and sends an internal HTTP redirect for it,
|
||||
// prefixed by the router's path prefix. Note that this method does not include
|
||||
// functionality for handling relative paths or full URL redirects.
|
||||
func (r *Router) Redirect(w http.ResponseWriter, req *http.Request, path string, code int) {
|
||||
http.Redirect(w, req, r.prefix+path, code)
|
||||
}
|
||||
|
||||
// ServeHTTP implements http.Handler.
|
||||
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
r.rtr.ServeHTTP(w, req)
|
||||
}
|
||||
|
||||
// FileServe returns a new http.HandlerFunc that serves files from dir.
|
||||
// Using routes must provide the *filepath parameter.
|
||||
func FileServe(dir string) http.HandlerFunc {
|
||||
fs := http.FileServer(http.Dir(dir))
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
r.URL.Path = Param(r.Context(), "filepath")
|
||||
fs.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
44
gateway/vendor/github.com/prometheus/common/route/route_test.go
generated
vendored
Normal file
44
gateway/vendor/github.com/prometheus/common/route/route_test.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRedirect(t *testing.T) {
|
||||
router := New().WithPrefix("/test/prefix")
|
||||
w := httptest.NewRecorder()
|
||||
r, err := http.NewRequest("GET", "http://localhost:9090/foo", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Error building test request: %s", err)
|
||||
}
|
||||
|
||||
router.Redirect(w, r, "/some/endpoint", http.StatusFound)
|
||||
if w.Code != http.StatusFound {
|
||||
t.Fatalf("Unexpected redirect status code: got %d, want %d", w.Code, http.StatusFound)
|
||||
}
|
||||
|
||||
want := "/test/prefix/some/endpoint"
|
||||
got := w.Header()["Location"][0]
|
||||
if want != got {
|
||||
t.Fatalf("Unexpected redirect location: got %s, want %s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext(t *testing.T) {
|
||||
router := New()
|
||||
router.Get("/test/:foo/", func(w http.ResponseWriter, r *http.Request) {
|
||||
want := "bar"
|
||||
got := Param(r.Context(), "foo")
|
||||
if want != got {
|
||||
t.Fatalf("Unexpected context value: want %q, got %q", want, got)
|
||||
}
|
||||
})
|
||||
|
||||
r, err := http.NewRequest("GET", "http://localhost:9090/test/bar/", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Error building test request: %s", err)
|
||||
}
|
||||
router.ServeHTTP(nil, r)
|
||||
}
|
89
gateway/vendor/github.com/prometheus/common/version/info.go
generated
vendored
Normal file
89
gateway/vendor/github.com/prometheus/common/version/info.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright 2016 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package version
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// Build information. Populated at build-time.
|
||||
var (
|
||||
Version string
|
||||
Revision string
|
||||
Branch string
|
||||
BuildUser string
|
||||
BuildDate string
|
||||
GoVersion = runtime.Version()
|
||||
)
|
||||
|
||||
// NewCollector returns a collector which exports metrics about current version information.
|
||||
func NewCollector(program string) *prometheus.GaugeVec {
|
||||
buildInfo := prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Namespace: program,
|
||||
Name: "build_info",
|
||||
Help: fmt.Sprintf(
|
||||
"A metric with a constant '1' value labeled by version, revision, branch, and goversion from which %s was built.",
|
||||
program,
|
||||
),
|
||||
},
|
||||
[]string{"version", "revision", "branch", "goversion"},
|
||||
)
|
||||
buildInfo.WithLabelValues(Version, Revision, Branch, GoVersion).Set(1)
|
||||
return buildInfo
|
||||
}
|
||||
|
||||
// versionInfoTmpl contains the template used by Info.
|
||||
var versionInfoTmpl = `
|
||||
{{.program}}, version {{.version}} (branch: {{.branch}}, revision: {{.revision}})
|
||||
build user: {{.buildUser}}
|
||||
build date: {{.buildDate}}
|
||||
go version: {{.goVersion}}
|
||||
`
|
||||
|
||||
// Print returns version information.
|
||||
func Print(program string) string {
|
||||
m := map[string]string{
|
||||
"program": program,
|
||||
"version": Version,
|
||||
"revision": Revision,
|
||||
"branch": Branch,
|
||||
"buildUser": BuildUser,
|
||||
"buildDate": BuildDate,
|
||||
"goVersion": GoVersion,
|
||||
}
|
||||
t := template.Must(template.New("version").Parse(versionInfoTmpl))
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := t.ExecuteTemplate(&buf, "version", m); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return strings.TrimSpace(buf.String())
|
||||
}
|
||||
|
||||
// Info returns version, branch and revision information.
|
||||
func Info() string {
|
||||
return fmt.Sprintf("(version=%s, branch=%s, revision=%s)", Version, Branch, Revision)
|
||||
}
|
||||
|
||||
// BuildContext returns goVersion, buildUser and buildDate information.
|
||||
func BuildContext() string {
|
||||
return fmt.Sprintf("(go=%s, user=%s, date=%s)", GoVersion, BuildUser, BuildDate)
|
||||
}
|
Reference in New Issue
Block a user