Merge branch 'master' into sparsehistogram
This commit is contained in:
commit
5b19c553c3
|
@ -1,7 +1,7 @@
|
|||
version: 2.1
|
||||
orbs:
|
||||
go: circleci/go@0.2.0
|
||||
prometheus: prometheus/prometheus@0.11.0
|
||||
prometheus: prometheus/prometheus@0.15.0
|
||||
jobs:
|
||||
test:
|
||||
parameters:
|
||||
|
@ -63,6 +63,8 @@ workflows:
|
|||
name: go-1-16
|
||||
go_version: "1.16"
|
||||
run_lint: true
|
||||
# Style and unused/missing packages are only checked against
|
||||
# the latest supported Go version.
|
||||
- test:
|
||||
name: go-1-17
|
||||
go_version: "1.17"
|
||||
run_lint: true
|
||||
run_style_and_unused: true
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
name: golangci-lint
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "go.sum"
|
||||
- "go.mod"
|
||||
- "**.go"
|
||||
- "scripts/errcheck_excludes.txt"
|
||||
- ".github/workflows/golangci-lint.yml"
|
||||
- ".golangci.yml"
|
||||
pull_request:
|
||||
paths:
|
||||
- "go.sum"
|
||||
- "go.mod"
|
||||
- "**.go"
|
||||
- "scripts/errcheck_excludes.txt"
|
||||
- ".github/workflows/golangci-lint.yml"
|
||||
- ".golangci.yml"
|
||||
|
||||
jobs:
|
||||
golangci:
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@v2
|
||||
with:
|
||||
version: v1.42.0
|
|
@ -78,17 +78,23 @@ ifneq ($(shell which gotestsum),)
|
|||
endif
|
||||
endif
|
||||
|
||||
PROMU_VERSION ?= 0.12.0
|
||||
PROMU_VERSION ?= 0.13.0
|
||||
PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz
|
||||
|
||||
GOLANGCI_LINT :=
|
||||
GOLANGCI_LINT_OPTS ?=
|
||||
GOLANGCI_LINT_VERSION ?= v1.39.0
|
||||
GOLANGCI_LINT_VERSION ?= v1.42.0
|
||||
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64.
|
||||
# windows isn't included here because of the path separator being different.
|
||||
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))
|
||||
ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386))
|
||||
GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint
|
||||
# If we're in CI and there is an Actions file, that means the linter
|
||||
# is being run in Actions, so we don't need to run it here.
|
||||
ifeq (,$(CIRCLE_JOB))
|
||||
GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint
|
||||
else ifeq (,$(wildcard .github/workflows/golangci-lint.yml))
|
||||
GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -154,7 +160,7 @@ endif
|
|||
update-go-deps:
|
||||
@echo ">> updating Go dependencies"
|
||||
@for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \
|
||||
$(GO) get $$m; \
|
||||
$(GO) get -d $$m; \
|
||||
done
|
||||
GO111MODULE=$(GO111MODULE) $(GO) mod tidy
|
||||
ifneq (,$(wildcard vendor))
|
||||
|
|
|
@ -139,6 +139,7 @@ const (
|
|||
epBuildinfo = apiPrefix + "/status/buildinfo"
|
||||
epRuntimeinfo = apiPrefix + "/status/runtimeinfo"
|
||||
epTSDB = apiPrefix + "/status/tsdb"
|
||||
epWalReplay = apiPrefix + "/status/walreplay"
|
||||
)
|
||||
|
||||
// AlertState models the state of an alert.
|
||||
|
@ -261,6 +262,8 @@ type API interface {
|
|||
Metadata(ctx context.Context, metric string, limit string) (map[string][]Metadata, error)
|
||||
// TSDB returns the cardinality statistics.
|
||||
TSDB(ctx context.Context) (TSDBResult, error)
|
||||
// WalReplay returns the current replay status of the wal.
|
||||
WalReplay(ctx context.Context) (WalReplayStatus, error)
|
||||
}
|
||||
|
||||
// AlertsResult contains the result from querying the alerts endpoint.
|
||||
|
@ -303,8 +306,6 @@ type RuntimeinfoResult struct {
|
|||
CWD string `json:"CWD"`
|
||||
ReloadConfigSuccess bool `json:"reloadConfigSuccess"`
|
||||
LastConfigTime time.Time `json:"lastConfigTime"`
|
||||
ChunkCount int `json:"chunkCount"`
|
||||
TimeSeriesCount int `json:"timeSeriesCount"`
|
||||
CorruptionCount int `json:"corruptionCount"`
|
||||
GoroutineCount int `json:"goroutineCount"`
|
||||
GOMAXPROCS int `json:"GOMAXPROCS"`
|
||||
|
@ -431,10 +432,27 @@ type queryResult struct {
|
|||
|
||||
// TSDBResult contains the result from querying the tsdb endpoint.
|
||||
type TSDBResult struct {
|
||||
SeriesCountByMetricName []Stat `json:"seriesCountByMetricName"`
|
||||
LabelValueCountByLabelName []Stat `json:"labelValueCountByLabelName"`
|
||||
MemoryInBytesByLabelName []Stat `json:"memoryInBytesByLabelName"`
|
||||
SeriesCountByLabelValuePair []Stat `json:"seriesCountByLabelValuePair"`
|
||||
HeadStats TSDBHeadStats `json:"headStats"`
|
||||
SeriesCountByMetricName []Stat `json:"seriesCountByMetricName"`
|
||||
LabelValueCountByLabelName []Stat `json:"labelValueCountByLabelName"`
|
||||
MemoryInBytesByLabelName []Stat `json:"memoryInBytesByLabelName"`
|
||||
SeriesCountByLabelValuePair []Stat `json:"seriesCountByLabelValuePair"`
|
||||
}
|
||||
|
||||
// TSDBHeadStats contains TSDB stats
|
||||
type TSDBHeadStats struct {
|
||||
NumSeries int `json:"numSeries"`
|
||||
NumLabelPairs int `json:"numLabelPairs"`
|
||||
ChunkCount int `json:"chunkCount"`
|
||||
MinTime int `json:"minTime"`
|
||||
MaxTime int `json:"maxTime"`
|
||||
}
|
||||
|
||||
// WalReplayStatus represents the wal replay status.
|
||||
type WalReplayStatus struct {
|
||||
Min int `json:"min"`
|
||||
Max int `json:"max"`
|
||||
Current int `json:"current"`
|
||||
}
|
||||
|
||||
// Stat models information about statistic value.
|
||||
|
@ -984,6 +1002,23 @@ func (h *httpAPI) TSDB(ctx context.Context) (TSDBResult, error) {
|
|||
return res, json.Unmarshal(body, &res)
|
||||
}
|
||||
|
||||
func (h *httpAPI) WalReplay(ctx context.Context) (WalReplayStatus, error) {
|
||||
u := h.client.URL(epWalReplay, nil)
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||
if err != nil {
|
||||
return WalReplayStatus{}, err
|
||||
}
|
||||
|
||||
_, body, _, err := h.client.Do(ctx, req)
|
||||
if err != nil {
|
||||
return WalReplayStatus{}, err
|
||||
}
|
||||
|
||||
var res WalReplayStatus
|
||||
return res, json.Unmarshal(body, &res)
|
||||
}
|
||||
|
||||
func (h *httpAPI) QueryExemplars(ctx context.Context, query string, startTime time.Time, endTime time.Time) ([]ExemplarQueryResult, error) {
|
||||
u := h.client.URL(epQueryExemplars, nil)
|
||||
q := u.Query()
|
||||
|
|
|
@ -230,6 +230,13 @@ func TestAPIs(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
doWalReply := func() func() (interface{}, Warnings, error) {
|
||||
return func() (interface{}, Warnings, error) {
|
||||
v, err := promAPI.WalReplay(context.Background())
|
||||
return v, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
doQueryExemplars := func(query string, startTime time.Time, endTime time.Time) func() (interface{}, Warnings, error) {
|
||||
return func() (interface{}, Warnings, error) {
|
||||
v, err := promAPI.QueryExemplars(context.Background(), query, startTime, endTime)
|
||||
|
@ -696,8 +703,6 @@ func TestAPIs(t *testing.T) {
|
|||
"CWD": "/prometheus",
|
||||
"reloadConfigSuccess": true,
|
||||
"lastConfigTime": "2020-05-18T15:52:56Z",
|
||||
"chunkCount": 72692,
|
||||
"timeSeriesCount": 18476,
|
||||
"corruptionCount": 0,
|
||||
"goroutineCount": 217,
|
||||
"GOMAXPROCS": 2,
|
||||
|
@ -710,8 +715,6 @@ func TestAPIs(t *testing.T) {
|
|||
CWD: "/prometheus",
|
||||
ReloadConfigSuccess: true,
|
||||
LastConfigTime: time.Date(2020, 5, 18, 15, 52, 56, 0, time.UTC),
|
||||
ChunkCount: 72692,
|
||||
TimeSeriesCount: 18476,
|
||||
CorruptionCount: 0,
|
||||
GoroutineCount: 217,
|
||||
GOMAXPROCS: 2,
|
||||
|
@ -1145,6 +1148,13 @@ func TestAPIs(t *testing.T) {
|
|||
reqMethod: "GET",
|
||||
reqPath: "/api/v1/status/tsdb",
|
||||
inRes: map[string]interface{}{
|
||||
"headStats": map[string]interface{}{
|
||||
"numSeries": 18476,
|
||||
"numLabelPairs": 4301,
|
||||
"chunkCount": 72692,
|
||||
"minTime": 1634644800304,
|
||||
"maxTime": 1634650590304,
|
||||
},
|
||||
"seriesCountByMetricName": []interface{}{
|
||||
map[string]interface{}{
|
||||
"name": "kubelet_http_requests_duration_seconds_bucket",
|
||||
|
@ -1171,6 +1181,13 @@ func TestAPIs(t *testing.T) {
|
|||
},
|
||||
},
|
||||
res: TSDBResult{
|
||||
HeadStats: TSDBHeadStats{
|
||||
NumSeries: 18476,
|
||||
NumLabelPairs: 4301,
|
||||
ChunkCount: 72692,
|
||||
MinTime: 1634644800304,
|
||||
MaxTime: 1634650590304,
|
||||
},
|
||||
SeriesCountByMetricName: []Stat{
|
||||
{
|
||||
Name: "kubelet_http_requests_duration_seconds_bucket",
|
||||
|
@ -1198,6 +1215,30 @@ func TestAPIs(t *testing.T) {
|
|||
},
|
||||
},
|
||||
|
||||
{
|
||||
do: doWalReply(),
|
||||
reqMethod: "GET",
|
||||
reqPath: "/api/v1/status/walreplay",
|
||||
inErr: fmt.Errorf("some error"),
|
||||
err: fmt.Errorf("some error"),
|
||||
},
|
||||
|
||||
{
|
||||
do: doWalReply(),
|
||||
reqMethod: "GET",
|
||||
reqPath: "/api/v1/status/walreplay",
|
||||
inRes: map[string]interface{}{
|
||||
"min": 2,
|
||||
"max": 5,
|
||||
"current": 40,
|
||||
},
|
||||
res: WalReplayStatus{
|
||||
Min: 2,
|
||||
Max: 5,
|
||||
Current: 40,
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
do: doQueryExemplars("tns_request_duration_seconds_bucket", testTime.Add(-1*time.Minute), testTime),
|
||||
reqMethod: "GET",
|
||||
|
|
|
@ -29,48 +29,46 @@ import (
|
|||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
var (
|
||||
addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.")
|
||||
uniformDomain = flag.Float64("uniform.domain", 0.0002, "The domain for the uniform distribution.")
|
||||
normDomain = flag.Float64("normal.domain", 0.0002, "The domain for the normal distribution.")
|
||||
normMean = flag.Float64("normal.mean", 0.00001, "The mean for the normal distribution.")
|
||||
oscillationPeriod = flag.Duration("oscillation-period", 10*time.Minute, "The duration of the rate oscillation period.")
|
||||
)
|
||||
|
||||
var (
|
||||
// Create a summary to track fictional interservice RPC latencies for three
|
||||
// distinct services with different latency distributions. These services are
|
||||
// differentiated via a "service" label.
|
||||
rpcDurations = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Name: "rpc_durations_seconds",
|
||||
Help: "RPC latency distributions.",
|
||||
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||
},
|
||||
[]string{"service"},
|
||||
func main() {
|
||||
var (
|
||||
addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.")
|
||||
uniformDomain = flag.Float64("uniform.domain", 0.0002, "The domain for the uniform distribution.")
|
||||
normDomain = flag.Float64("normal.domain", 0.0002, "The domain for the normal distribution.")
|
||||
normMean = flag.Float64("normal.mean", 0.00001, "The mean for the normal distribution.")
|
||||
oscillationPeriod = flag.Duration("oscillation-period", 10*time.Minute, "The duration of the rate oscillation period.")
|
||||
)
|
||||
|
||||
flag.Parse()
|
||||
|
||||
var (
|
||||
// Create a summary to track fictional interservice RPC latencies for three
|
||||
// distinct services with different latency distributions. These services are
|
||||
// differentiated via a "service" label.
|
||||
rpcDurations = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Name: "rpc_durations_seconds",
|
||||
Help: "RPC latency distributions.",
|
||||
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||
},
|
||||
[]string{"service"},
|
||||
)
|
||||
// The same as above, but now as a histogram, and only for the normal
|
||||
// distribution. The buckets are targeted to the parameters of the
|
||||
// normal distribution, with 20 buckets centered on the mean, each
|
||||
// half-sigma wide.
|
||||
rpcDurationsHistogram = prometheus.NewHistogram(prometheus.HistogramOpts{
|
||||
Name: "rpc_durations_histogram_seconds",
|
||||
Help: "RPC latency distributions.",
|
||||
Buckets: prometheus.LinearBuckets(*normMean-5**normDomain, .5**normDomain, 20),
|
||||
SparseBucketsFactor: 1.1,
|
||||
})
|
||||
)
|
||||
// The same as above, but now as a histogram, and only for the normal
|
||||
// distribution. The buckets are targeted to the parameters of the
|
||||
// normal distribution, with 20 buckets centered on the mean, each
|
||||
// half-sigma wide.
|
||||
rpcDurationsHistogram = prometheus.NewHistogram(prometheus.HistogramOpts{
|
||||
Name: "rpc_durations_histogram_seconds",
|
||||
Help: "RPC latency distributions.",
|
||||
Buckets: prometheus.LinearBuckets(*normMean-5**normDomain, .5**normDomain, 20),
|
||||
SparseBucketsFactor: 1.1,
|
||||
})
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Register the summary and the histogram with Prometheus's default registry.
|
||||
prometheus.MustRegister(rpcDurations)
|
||||
prometheus.MustRegister(rpcDurationsHistogram)
|
||||
// Add Go module build info.
|
||||
prometheus.MustRegister(prometheus.NewBuildInfoCollector())
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
start := time.Now()
|
||||
|
||||
|
|
2
go.mod
2
go.mod
|
@ -2,7 +2,7 @@ module github.com/prometheus/client_golang
|
|||
|
||||
require (
|
||||
github.com/beorn7/perks v1.0.1
|
||||
github.com/cespare/xxhash/v2 v2.1.1
|
||||
github.com/cespare/xxhash/v2 v2.1.2
|
||||
github.com/golang/protobuf v1.4.3
|
||||
github.com/json-iterator/go v1.1.11
|
||||
github.com/prometheus/client_model v0.2.1-0.20210624201024-61b6c1aac064
|
||||
|
|
3
go.sum
3
go.sum
|
@ -43,8 +43,9 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
|
|||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build go1.15
|
||||
// +build go1.15
|
||||
|
||||
package collectors
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !go1.15
|
||||
// +build !go1.15
|
||||
|
||||
package collectors
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package prometheus
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package prometheus
|
||||
|
|
|
@ -199,7 +199,7 @@ func TestPush(t *testing.T) {
|
|||
Collector(metric1).
|
||||
Collector(metric2).
|
||||
Push(); err == nil {
|
||||
t.Error("push with empty job succeded")
|
||||
t.Error("push with empty job succeeded")
|
||||
} else {
|
||||
if got, want := err, errJobEmpty; got != want {
|
||||
t.Errorf("got error %q, want %q", got, want)
|
||||
|
|
Loading…
Reference in New Issue