mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-10 07:34:04 -08:00
Vendor common/expfmt package
This commit is contained in:
parent
306e8468a0
commit
f237b0e2da
4
Godeps/Godeps.json
generated
4
Godeps/Godeps.json
generated
|
@ -58,6 +58,10 @@
|
|||
"ImportPath": "github.com/prometheus/client_golang/text",
|
||||
"Rev": "3a499bf7fc46bc58337ce612d0cbb29c550b8118"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/prometheus/common/expfmt",
|
||||
"Rev": "2502df85be1b9482ed669faa6b7cfe7f850eb08e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/prometheus/common/model",
|
||||
"Rev": "2502df85be1b9482ed669faa6b7cfe7f850eb08e"
|
||||
|
|
171
Godeps/_workspace/src/github.com/prometheus/common/expfmt/bench_test.go
generated
vendored
Normal file
171
Godeps/_workspace/src/github.com/prometheus/common/expfmt/bench_test.go
generated
vendored
Normal file
|
@ -0,0 +1,171 @@
|
|||
// 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.
|
||||
//
|
||||
// BenchmarkProcessor002ParseOnly in the extraction package is not quite
|
||||
// comparable to the benchmarks here, but it gives an idea: JSON parsing is even
|
||||
// slower than text parsing and needs a comparable amount of allocs.
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
388
Godeps/_workspace/src/github.com/prometheus/common/expfmt/decode.go
generated
vendored
Normal file
388
Godeps/_workspace/src/github.com/prometheus/common/expfmt/decode.go
generated
vendored
Normal file
|
@ -0,0 +1,388 @@
|
|||
// 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 (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"mime"
|
||||
"net/http"
|
||||
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
|
||||
"github.com/matttproud/golang_protobuf_extensions/pbutil"
|
||||
"github.com/prometheus/common/model"
|
||||
)
|
||||
|
||||
// Decoder types decode an input stream into metric families.
|
||||
type Decoder interface {
|
||||
Decode(*dto.MetricFamily) error
|
||||
}
|
||||
|
||||
type DecodeOptions struct {
|
||||
// Timestamp is added to each value from the stream that has no explicit timestamp set.
|
||||
Timestamp model.Time
|
||||
}
|
||||
|
||||
// NewDecor returns a new decoder based on the HTTP header.
|
||||
func NewDecoder(r io.Reader, h http.Header) (Decoder, error) {
|
||||
ct := h.Get(hdrContentType)
|
||||
|
||||
mediatype, params, err := mime.ParseMediaType(ct)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid Content-Type header %q: %s", ct, err)
|
||||
}
|
||||
|
||||
const (
|
||||
protoType = ProtoType + "/" + ProtoSubType
|
||||
textType = "text/plain"
|
||||
)
|
||||
|
||||
switch mediatype {
|
||||
case protoType:
|
||||
if p := params["proto"]; p != ProtoProtocol {
|
||||
return nil, fmt.Errorf("unrecognized protocol message %s", p)
|
||||
}
|
||||
if e := params["encoding"]; e != "delimited" {
|
||||
return nil, fmt.Errorf("unsupported encoding %s", e)
|
||||
}
|
||||
return &protoDecoder{r: r}, nil
|
||||
|
||||
case textType:
|
||||
if v, ok := params["version"]; ok && v != "0.0.4" {
|
||||
return nil, fmt.Errorf("unrecognized protocol version %s", v)
|
||||
}
|
||||
return &textDecoder{r: r}, nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported media type %q, expected %q or %q", mediatype, protoType, textType)
|
||||
}
|
||||
}
|
||||
|
||||
// protoDecoder implements the Decoder interface for protocol buffers.
|
||||
type protoDecoder struct {
|
||||
r io.Reader
|
||||
}
|
||||
|
||||
// Decode implements the Decoder interface.
|
||||
func (d *protoDecoder) Decode(v *dto.MetricFamily) error {
|
||||
_, err := pbutil.ReadDelimited(d.r, v)
|
||||
return err
|
||||
}
|
||||
|
||||
// textDecoder implements the Decoder interface for the text protcol.
|
||||
type textDecoder struct {
|
||||
r io.Reader
|
||||
p TextParser
|
||||
fams []*dto.MetricFamily
|
||||
}
|
||||
|
||||
// Decode implements the Decoder interface.
|
||||
func (d *textDecoder) Decode(v *dto.MetricFamily) error {
|
||||
// TODO(fabxc): Wrap this as a line reader to make streaming safer.
|
||||
if len(d.fams) == 0 {
|
||||
// No cached metric families, read everything and parse metrics.
|
||||
fams, err := d.p.TextToMetricFamilies(d.r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(fams) == 0 {
|
||||
return io.EOF
|
||||
}
|
||||
for _, f := range fams {
|
||||
d.fams = append(d.fams, f)
|
||||
}
|
||||
}
|
||||
*v = *d.fams[len(d.fams)-1]
|
||||
d.fams = d.fams[:len(d.fams)-1]
|
||||
return nil
|
||||
}
|
||||
|
||||
type SampleDecoder struct {
|
||||
Dec Decoder
|
||||
Opts *DecodeOptions
|
||||
|
||||
f dto.MetricFamily
|
||||
}
|
||||
|
||||
func (sd *SampleDecoder) Decode(s *model.Vector) error {
|
||||
if err := sd.Dec.Decode(&sd.f); err != nil {
|
||||
return err
|
||||
}
|
||||
*s = extractSamples(&sd.f, sd.Opts)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Extract samples builds a slice of samples from the provided metric families.
|
||||
func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) model.Vector {
|
||||
var all model.Vector
|
||||
for _, f := range fams {
|
||||
all = append(all, extractSamples(f, o)...)
|
||||
}
|
||||
return all
|
||||
}
|
||||
|
||||
func extractSamples(f *dto.MetricFamily, o *DecodeOptions) model.Vector {
|
||||
switch *f.Type {
|
||||
case dto.MetricType_COUNTER:
|
||||
return extractCounter(o, f)
|
||||
case dto.MetricType_GAUGE:
|
||||
return extractGauge(o, f)
|
||||
case dto.MetricType_SUMMARY:
|
||||
return extractSummary(o, f)
|
||||
case dto.MetricType_UNTYPED:
|
||||
return extractUntyped(o, f)
|
||||
case dto.MetricType_HISTOGRAM:
|
||||
return extractHistogram(o, f)
|
||||
}
|
||||
panic("expfmt.extractSamples: unknown metric family type")
|
||||
}
|
||||
|
||||
func extractCounter(o *DecodeOptions, f *dto.MetricFamily) model.Vector {
|
||||
samples := make(model.Vector, 0, len(f.Metric))
|
||||
|
||||
for _, m := range f.Metric {
|
||||
if m.Counter == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
lset := make(model.LabelSet, len(m.Label)+1)
|
||||
for _, p := range m.Label {
|
||||
lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
lset[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
||||
|
||||
smpl := &model.Sample{
|
||||
Metric: model.Metric(lset),
|
||||
Value: model.SampleValue(m.Counter.GetValue()),
|
||||
}
|
||||
|
||||
if m.TimestampMs != nil {
|
||||
smpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)
|
||||
} else {
|
||||
smpl.Timestamp = o.Timestamp
|
||||
}
|
||||
|
||||
samples = append(samples, smpl)
|
||||
}
|
||||
|
||||
return samples
|
||||
}
|
||||
|
||||
func extractGauge(o *DecodeOptions, f *dto.MetricFamily) model.Vector {
|
||||
samples := make(model.Vector, 0, len(f.Metric))
|
||||
|
||||
for _, m := range f.Metric {
|
||||
if m.Gauge == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
lset := make(model.LabelSet, len(m.Label)+1)
|
||||
for _, p := range m.Label {
|
||||
lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
lset[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
||||
|
||||
smpl := &model.Sample{
|
||||
Metric: model.Metric(lset),
|
||||
Value: model.SampleValue(m.Gauge.GetValue()),
|
||||
}
|
||||
|
||||
if m.TimestampMs != nil {
|
||||
smpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)
|
||||
} else {
|
||||
smpl.Timestamp = o.Timestamp
|
||||
}
|
||||
|
||||
samples = append(samples, smpl)
|
||||
}
|
||||
|
||||
return samples
|
||||
}
|
||||
|
||||
func extractUntyped(o *DecodeOptions, f *dto.MetricFamily) model.Vector {
|
||||
samples := make(model.Vector, 0, len(f.Metric))
|
||||
|
||||
for _, m := range f.Metric {
|
||||
if m.Untyped == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
lset := make(model.LabelSet, len(m.Label)+1)
|
||||
for _, p := range m.Label {
|
||||
lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
lset[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
||||
|
||||
smpl := &model.Sample{
|
||||
Metric: model.Metric(lset),
|
||||
Value: model.SampleValue(m.Untyped.GetValue()),
|
||||
}
|
||||
|
||||
if m.TimestampMs != nil {
|
||||
smpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)
|
||||
} else {
|
||||
smpl.Timestamp = o.Timestamp
|
||||
}
|
||||
|
||||
samples = append(samples, smpl)
|
||||
}
|
||||
|
||||
return samples
|
||||
}
|
||||
|
||||
func extractSummary(o *DecodeOptions, f *dto.MetricFamily) model.Vector {
|
||||
samples := make(model.Vector, 0, len(f.Metric))
|
||||
|
||||
for _, m := range f.Metric {
|
||||
if m.Summary == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
timestamp := o.Timestamp
|
||||
if m.TimestampMs != nil {
|
||||
timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)
|
||||
}
|
||||
|
||||
for _, q := range m.Summary.Quantile {
|
||||
lset := make(model.LabelSet, len(m.Label)+2)
|
||||
for _, p := range m.Label {
|
||||
lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
// BUG(matt): Update other names to "quantile".
|
||||
lset[model.LabelName(model.QuantileLabel)] = model.LabelValue(fmt.Sprint(q.GetQuantile()))
|
||||
lset[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
||||
|
||||
samples = append(samples, &model.Sample{
|
||||
Metric: model.Metric(lset),
|
||||
Value: model.SampleValue(q.GetValue()),
|
||||
Timestamp: timestamp,
|
||||
})
|
||||
}
|
||||
|
||||
if m.Summary.SampleSum != nil {
|
||||
lset := make(model.LabelSet, len(m.Label)+1)
|
||||
for _, p := range m.Label {
|
||||
lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum")
|
||||
|
||||
samples = append(samples, &model.Sample{
|
||||
Metric: model.Metric(lset),
|
||||
Value: model.SampleValue(m.Summary.GetSampleSum()),
|
||||
Timestamp: timestamp,
|
||||
})
|
||||
}
|
||||
|
||||
if m.Summary.SampleCount != nil {
|
||||
lset := make(model.LabelSet, len(m.Label)+1)
|
||||
for _, p := range m.Label {
|
||||
lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count")
|
||||
|
||||
samples = append(samples, &model.Sample{
|
||||
Metric: model.Metric(lset),
|
||||
Value: model.SampleValue(m.Summary.GetSampleCount()),
|
||||
Timestamp: timestamp,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return samples
|
||||
}
|
||||
|
||||
func extractHistogram(o *DecodeOptions, f *dto.MetricFamily) model.Vector {
|
||||
samples := make(model.Vector, 0, len(f.Metric))
|
||||
|
||||
for _, m := range f.Metric {
|
||||
if m.Histogram == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
timestamp := o.Timestamp
|
||||
if m.TimestampMs != nil {
|
||||
timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)
|
||||
}
|
||||
|
||||
infSeen := false
|
||||
|
||||
for _, q := range m.Histogram.Bucket {
|
||||
lset := make(model.LabelSet, len(m.Label)+2)
|
||||
for _, p := range m.Label {
|
||||
lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
lset[model.LabelName(model.BucketLabel)] = model.LabelValue(fmt.Sprint(q.GetUpperBound()))
|
||||
lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket")
|
||||
|
||||
if math.IsInf(q.GetUpperBound(), +1) {
|
||||
infSeen = true
|
||||
}
|
||||
|
||||
samples = append(samples, &model.Sample{
|
||||
Metric: model.Metric(lset),
|
||||
Value: model.SampleValue(q.GetCumulativeCount()),
|
||||
Timestamp: timestamp,
|
||||
})
|
||||
}
|
||||
|
||||
if m.Histogram.SampleSum != nil {
|
||||
lset := make(model.LabelSet, len(m.Label)+1)
|
||||
for _, p := range m.Label {
|
||||
lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum")
|
||||
|
||||
samples = append(samples, &model.Sample{
|
||||
Metric: model.Metric(lset),
|
||||
Value: model.SampleValue(m.Histogram.GetSampleSum()),
|
||||
Timestamp: timestamp,
|
||||
})
|
||||
}
|
||||
|
||||
if m.Histogram.SampleCount != nil {
|
||||
lset := make(model.LabelSet, len(m.Label)+1)
|
||||
for _, p := range m.Label {
|
||||
lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count")
|
||||
|
||||
count := &model.Sample{
|
||||
Metric: model.Metric(lset),
|
||||
Value: model.SampleValue(m.Histogram.GetSampleCount()),
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
samples = append(samples, count)
|
||||
|
||||
if !infSeen {
|
||||
// Append a infinity bucket sample.
|
||||
lset := make(model.LabelSet, len(m.Label)+2)
|
||||
for _, p := range m.Label {
|
||||
lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
lset[model.LabelName(model.BucketLabel)] = model.LabelValue("+Inf")
|
||||
lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket")
|
||||
|
||||
samples = append(samples, &model.Sample{
|
||||
Metric: model.Metric(lset),
|
||||
Value: count.Value,
|
||||
Timestamp: timestamp,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return samples
|
||||
}
|
327
Godeps/_workspace/src/github.com/prometheus/common/expfmt/decode_test.go
generated
vendored
Normal file
327
Godeps/_workspace/src/github.com/prometheus/common/expfmt/decode_test.go
generated
vendored
Normal file
|
@ -0,0 +1,327 @@
|
|||
// 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 (
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"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
|
||||
}{
|
||||
{
|
||||
in: "",
|
||||
},
|
||||
{
|
||||
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",
|
||||
"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",
|
||||
"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,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, 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 err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
all = append(all, smpls...)
|
||||
}
|
||||
sort.Sort(all)
|
||||
sort.Sort(scenario.expected)
|
||||
if !reflect.DeepEqual(all, scenario.expected) {
|
||||
t.Fatalf("output does not match")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testDiscriminatorHTTPHeader(t testing.TB) {
|
||||
var scenarios = []struct {
|
||||
input map[string]string
|
||||
output Decoder
|
||||
err error
|
||||
}{
|
||||
{
|
||||
input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="io.prometheus.client.MetricFamily"; encoding="delimited"`},
|
||||
output: &protoDecoder{},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="illegal"; encoding="delimited"`},
|
||||
output: nil,
|
||||
err: errors.New("unrecognized protocol message illegal"),
|
||||
},
|
||||
{
|
||||
input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="io.prometheus.client.MetricFamily"; encoding="illegal"`},
|
||||
output: nil,
|
||||
err: errors.New("unsupported encoding illegal"),
|
||||
},
|
||||
{
|
||||
input: map[string]string{"Content-Type": `text/plain; version=0.0.4`},
|
||||
output: &textDecoder{},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
input: map[string]string{"Content-Type": `text/plain`},
|
||||
output: &textDecoder{},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
input: map[string]string{"Content-Type": `text/plain; version=0.0.3`},
|
||||
output: nil,
|
||||
err: errors.New("unrecognized protocol version 0.0.3"),
|
||||
},
|
||||
}
|
||||
|
||||
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, err := NewDecoder(nil, header)
|
||||
|
||||
if scenario.err != err {
|
||||
if scenario.err != nil && err != nil {
|
||||
if scenario.err.Error() != err.Error() {
|
||||
t.Errorf("%d. expected %s, got %s", i, scenario.err, err)
|
||||
}
|
||||
} else if scenario.err != nil || err != nil {
|
||||
t.Errorf("%d. expected %s, got %s", i, scenario.err, err)
|
||||
}
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(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)
|
||||
}
|
||||
}
|
88
Godeps/_workspace/src/github.com/prometheus/common/expfmt/encode.go
generated
vendored
Normal file
88
Godeps/_workspace/src/github.com/prometheus/common/expfmt/encode.go
generated
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
// 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 (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"bitbucket.org/ww/goautoneg"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/matttproud/golang_protobuf_extensions/pbutil"
|
||||
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
)
|
||||
|
||||
// Encoder types encode metric families into an underlying wire protocol.
|
||||
type Encoder interface {
|
||||
Encode(*dto.MetricFamily) error
|
||||
}
|
||||
|
||||
type encoder func(*dto.MetricFamily) error
|
||||
|
||||
func (e encoder) Encode(v *dto.MetricFamily) error {
|
||||
return e(v)
|
||||
}
|
||||
|
||||
// Negotiate returns the Content-Type based on the given Accept header.
|
||||
// If no appropriate accepted type is found, FmtText is returned.
|
||||
func Negotiate(h http.Header) Format {
|
||||
for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) {
|
||||
// Check for protocol buffer
|
||||
if ac.Type == ProtoType && ac.SubType == ProtoSubType && ac.Params["proto"] == ProtoProtocol {
|
||||
switch ac.Params["encoding"] {
|
||||
case "delimited":
|
||||
return FmtProtoDelim
|
||||
case "text":
|
||||
return FmtProtoText
|
||||
case "compact-text":
|
||||
return FmtProtoCompact
|
||||
}
|
||||
}
|
||||
// Check for text format.
|
||||
ver := ac.Params["version"]
|
||||
if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") {
|
||||
return FmtText
|
||||
}
|
||||
}
|
||||
return FmtText
|
||||
}
|
||||
|
||||
// NewEncoder returns a new encoder based on content type negotiation.
|
||||
func NewEncoder(w io.Writer, format Format) Encoder {
|
||||
switch format {
|
||||
case FmtProtoDelim:
|
||||
return encoder(func(v *dto.MetricFamily) error {
|
||||
_, err := pbutil.WriteDelimited(w, v)
|
||||
return err
|
||||
})
|
||||
case FmtProtoCompact:
|
||||
return encoder(func(v *dto.MetricFamily) error {
|
||||
_, err := fmt.Fprintln(w, v.String())
|
||||
return err
|
||||
})
|
||||
case FmtProtoText:
|
||||
return encoder(func(v *dto.MetricFamily) error {
|
||||
_, err := fmt.Fprintln(w, proto.MarshalTextString(v))
|
||||
return err
|
||||
})
|
||||
case FmtText:
|
||||
return encoder(func(v *dto.MetricFamily) error {
|
||||
_, err := MetricFamilyToText(w, v)
|
||||
return err
|
||||
})
|
||||
}
|
||||
panic("expfmt.NewEncoder: unknown format")
|
||||
}
|
37
Godeps/_workspace/src/github.com/prometheus/common/expfmt/expfmt.go
generated
vendored
Normal file
37
Godeps/_workspace/src/github.com/prometheus/common/expfmt/expfmt.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
// 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.
|
||||
|
||||
// A package for reading and writing Prometheus metrics.
|
||||
package expfmt
|
||||
|
||||
type Format string
|
||||
|
||||
const (
|
||||
TextVersion = "0.0.4"
|
||||
|
||||
ProtoType = `application`
|
||||
ProtoSubType = `vnd.google.protobuf`
|
||||
ProtoProtocol = `io.prometheus.client.MetricFamily`
|
||||
ProtoFmt = ProtoType + "/" + ProtoSubType + "; proto=" + ProtoProtocol + ";"
|
||||
|
||||
// The Content-Type values for the different wire protocols.
|
||||
FmtText Format = `text/plain; version=` + TextVersion
|
||||
FmtProtoDelim Format = ProtoFmt + ` encoding=delimited`
|
||||
FmtProtoText Format = ProtoFmt + ` encoding=text`
|
||||
FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text`
|
||||
)
|
||||
|
||||
const (
|
||||
hdrContentType = "Content-Type"
|
||||
hdrAccept = "Accept"
|
||||
)
|
516
Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/protobuf
generated
vendored
Normal file
516
Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/protobuf
generated
vendored
Normal file
|
@ -0,0 +1,516 @@
|
|||
fc08 0a22 6874 7470 5f72 6571 7565 7374
|
||||
5f64 7572 6174 696f 6e5f 6d69 6372 6f73
|
||||
6563 6f6e 6473 122b 5468 6520 4854 5450
|
||||
2072 6571 7565 7374 206c 6174 656e 6369
|
||||
6573 2069 6e20 6d69 6372 6f73 6563 6f6e
|
||||
6473 2e18 0222 570a 0c0a 0768 616e 646c
|
||||
6572 1201 2f22 4708 0011 0000 0000 0000
|
||||
0000 1a12 0900 0000 0000 00e0 3f11 0000
|
||||
0000 0000 0000 1a12 09cd cccc cccc ccec
|
||||
3f11 0000 0000 0000 0000 1a12 09ae 47e1
|
||||
7a14 aeef 3f11 0000 0000 0000 0000 225d
|
||||
0a12 0a07 6861 6e64 6c65 7212 072f 616c
|
||||
6572 7473 2247 0800 1100 0000 0000 0000
|
||||
001a 1209 0000 0000 0000 e03f 1100 0000
|
||||
0000 0000 001a 1209 cdcc cccc cccc ec3f
|
||||
1100 0000 0000 0000 001a 1209 ae47 e17a
|
||||
14ae ef3f 1100 0000 0000 0000 0022 620a
|
||||
170a 0768 616e 646c 6572 120c 2f61 7069
|
||||
2f6d 6574 7269 6373 2247 0800 1100 0000
|
||||
0000 0000 001a 1209 0000 0000 0000 e03f
|
||||
1100 0000 0000 0000 001a 1209 cdcc cccc
|
||||
cccc ec3f 1100 0000 0000 0000 001a 1209
|
||||
ae47 e17a 14ae ef3f 1100 0000 0000 0000
|
||||
0022 600a 150a 0768 616e 646c 6572 120a
|
||||
2f61 7069 2f71 7565 7279 2247 0800 1100
|
||||
0000 0000 0000 001a 1209 0000 0000 0000
|
||||
e03f 1100 0000 0000 0000 001a 1209 cdcc
|
||||
cccc cccc ec3f 1100 0000 0000 0000 001a
|
||||
1209 ae47 e17a 14ae ef3f 1100 0000 0000
|
||||
0000 0022 660a 1b0a 0768 616e 646c 6572
|
||||
1210 2f61 7069 2f71 7565 7279 5f72 616e
|
||||
6765 2247 0800 1100 0000 0000 0000 001a
|
||||
1209 0000 0000 0000 e03f 1100 0000 0000
|
||||
0000 001a 1209 cdcc cccc cccc ec3f 1100
|
||||
0000 0000 0000 001a 1209 ae47 e17a 14ae
|
||||
ef3f 1100 0000 0000 0000 0022 620a 170a
|
||||
0768 616e 646c 6572 120c 2f61 7069 2f74
|
||||
6172 6765 7473 2247 0800 1100 0000 0000
|
||||
0000 001a 1209 0000 0000 0000 e03f 1100
|
||||
0000 0000 0000 001a 1209 cdcc cccc cccc
|
||||
ec3f 1100 0000 0000 0000 001a 1209 ae47
|
||||
e17a 14ae ef3f 1100 0000 0000 0000 0022
|
||||
600a 150a 0768 616e 646c 6572 120a 2f63
|
||||
6f6e 736f 6c65 732f 2247 0800 1100 0000
|
||||
0000 0000 001a 1209 0000 0000 0000 e03f
|
||||
1100 0000 0000 0000 001a 1209 cdcc cccc
|
||||
cccc ec3f 1100 0000 0000 0000 001a 1209
|
||||
ae47 e17a 14ae ef3f 1100 0000 0000 0000
|
||||
0022 5c0a 110a 0768 616e 646c 6572 1206
|
||||
2f67 7261 7068 2247 0800 1100 0000 0000
|
||||
0000 001a 1209 0000 0000 0000 e03f 1100
|
||||
0000 0000 0000 001a 1209 cdcc cccc cccc
|
||||
ec3f 1100 0000 0000 0000 001a 1209 ae47
|
||||
e17a 14ae ef3f 1100 0000 0000 0000 0022
|
||||
5b0a 100a 0768 616e 646c 6572 1205 2f68
|
||||
6561 7022 4708 0011 0000 0000 0000 0000
|
||||
1a12 0900 0000 0000 00e0 3f11 0000 0000
|
||||
0000 0000 1a12 09cd cccc cccc ccec 3f11
|
||||
0000 0000 0000 0000 1a12 09ae 47e1 7a14
|
||||
aeef 3f11 0000 0000 0000 0000 225e 0a13
|
||||
0a07 6861 6e64 6c65 7212 082f 7374 6174
|
||||
6963 2f22 4708 0011 0000 0000 0000 0000
|
||||
1a12 0900 0000 0000 00e0 3f11 0000 0000
|
||||
0000 0000 1a12 09cd cccc cccc ccec 3f11
|
||||
0000 0000 0000 0000 1a12 09ae 47e1 7a14
|
||||
aeef 3f11 0000 0000 0000 0000 2260 0a15
|
||||
0a07 6861 6e64 6c65 7212 0a70 726f 6d65
|
||||
7468 6575 7322 4708 3b11 5b8f c2f5 083f
|
||||
f440 1a12 0900 0000 0000 00e0 3f11 e17a
|
||||
14ae c7af 9340 1a12 09cd cccc cccc ccec
|
||||
3f11 2fdd 2406 81f0 9640 1a12 09ae 47e1
|
||||
7a14 aeef 3f11 3d0a d7a3 b095 a740 e608
|
||||
0a17 6874 7470 5f72 6571 7565 7374 5f73
|
||||
697a 655f 6279 7465 7312 2054 6865 2048
|
||||
5454 5020 7265 7175 6573 7420 7369 7a65
|
||||
7320 696e 2062 7974 6573 2e18 0222 570a
|
||||
0c0a 0768 616e 646c 6572 1201 2f22 4708
|
||||
0011 0000 0000 0000 0000 1a12 0900 0000
|
||||
0000 00e0 3f11 0000 0000 0000 0000 1a12
|
||||
09cd cccc cccc ccec 3f11 0000 0000 0000
|
||||
0000 1a12 09ae 47e1 7a14 aeef 3f11 0000
|
||||
0000 0000 0000 225d 0a12 0a07 6861 6e64
|
||||
6c65 7212 072f 616c 6572 7473 2247 0800
|
||||
1100 0000 0000 0000 001a 1209 0000 0000
|
||||
0000 e03f 1100 0000 0000 0000 001a 1209
|
||||
cdcc cccc cccc ec3f 1100 0000 0000 0000
|
||||
001a 1209 ae47 e17a 14ae ef3f 1100 0000
|
||||
0000 0000 0022 620a 170a 0768 616e 646c
|
||||
6572 120c 2f61 7069 2f6d 6574 7269 6373
|
||||
2247 0800 1100 0000 0000 0000 001a 1209
|
||||
0000 0000 0000 e03f 1100 0000 0000 0000
|
||||
001a 1209 cdcc cccc cccc ec3f 1100 0000
|
||||
0000 0000 001a 1209 ae47 e17a 14ae ef3f
|
||||
1100 0000 0000 0000 0022 600a 150a 0768
|
||||
616e 646c 6572 120a 2f61 7069 2f71 7565
|
||||
7279 2247 0800 1100 0000 0000 0000 001a
|
||||
1209 0000 0000 0000 e03f 1100 0000 0000
|
||||
0000 001a 1209 cdcc cccc cccc ec3f 1100
|
||||
0000 0000 0000 001a 1209 ae47 e17a 14ae
|
||||
ef3f 1100 0000 0000 0000 0022 660a 1b0a
|
||||
0768 616e 646c 6572 1210 2f61 7069 2f71
|
||||
7565 7279 5f72 616e 6765 2247 0800 1100
|
||||
0000 0000 0000 001a 1209 0000 0000 0000
|
||||
e03f 1100 0000 0000 0000 001a 1209 cdcc
|
||||
cccc cccc ec3f 1100 0000 0000 0000 001a
|
||||
1209 ae47 e17a 14ae ef3f 1100 0000 0000
|
||||
0000 0022 620a 170a 0768 616e 646c 6572
|
||||
120c 2f61 7069 2f74 6172 6765 7473 2247
|
||||
0800 1100 0000 0000 0000 001a 1209 0000
|
||||
0000 0000 e03f 1100 0000 0000 0000 001a
|
||||
1209 cdcc cccc cccc ec3f 1100 0000 0000
|
||||
0000 001a 1209 ae47 e17a 14ae ef3f 1100
|
||||
0000 0000 0000 0022 600a 150a 0768 616e
|
||||
646c 6572 120a 2f63 6f6e 736f 6c65 732f
|
||||
2247 0800 1100 0000 0000 0000 001a 1209
|
||||
0000 0000 0000 e03f 1100 0000 0000 0000
|
||||
001a 1209 cdcc cccc cccc ec3f 1100 0000
|
||||
0000 0000 001a 1209 ae47 e17a 14ae ef3f
|
||||
1100 0000 0000 0000 0022 5c0a 110a 0768
|
||||
616e 646c 6572 1206 2f67 7261 7068 2247
|
||||
0800 1100 0000 0000 0000 001a 1209 0000
|
||||
0000 0000 e03f 1100 0000 0000 0000 001a
|
||||
1209 cdcc cccc cccc ec3f 1100 0000 0000
|
||||
0000 001a 1209 ae47 e17a 14ae ef3f 1100
|
||||
0000 0000 0000 0022 5b0a 100a 0768 616e
|
||||
646c 6572 1205 2f68 6561 7022 4708 0011
|
||||
0000 0000 0000 0000 1a12 0900 0000 0000
|
||||
00e0 3f11 0000 0000 0000 0000 1a12 09cd
|
||||
cccc cccc ccec 3f11 0000 0000 0000 0000
|
||||
1a12 09ae 47e1 7a14 aeef 3f11 0000 0000
|
||||
0000 0000 225e 0a13 0a07 6861 6e64 6c65
|
||||
7212 082f 7374 6174 6963 2f22 4708 0011
|
||||
0000 0000 0000 0000 1a12 0900 0000 0000
|
||||
00e0 3f11 0000 0000 0000 0000 1a12 09cd
|
||||
cccc cccc ccec 3f11 0000 0000 0000 0000
|
||||
1a12 09ae 47e1 7a14 aeef 3f11 0000 0000
|
||||
0000 0000 2260 0a15 0a07 6861 6e64 6c65
|
||||
7212 0a70 726f 6d65 7468 6575 7322 4708
|
||||
3b11 0000 0000 40c4 d040 1a12 0900 0000
|
||||
0000 00e0 3f11 0000 0000 0030 7240 1a12
|
||||
09cd cccc cccc ccec 3f11 0000 0000 0030
|
||||
7240 1a12 09ae 47e1 7a14 aeef 3f11 0000
|
||||
0000 0030 7240 7c0a 1368 7474 705f 7265
|
||||
7175 6573 7473 5f74 6f74 616c 1223 546f
|
||||
7461 6c20 6e75 6d62 6572 206f 6620 4854
|
||||
5450 2072 6571 7565 7374 7320 6d61 6465
|
||||
2e18 0022 3e0a 0b0a 0463 6f64 6512 0332
|
||||
3030 0a15 0a07 6861 6e64 6c65 7212 0a70
|
||||
726f 6d65 7468 6575 730a 0d0a 066d 6574
|
||||
686f 6412 0367 6574 1a09 0900 0000 0000
|
||||
804d 40e8 080a 1868 7474 705f 7265 7370
|
||||
6f6e 7365 5f73 697a 655f 6279 7465 7312
|
||||
2154 6865 2048 5454 5020 7265 7370 6f6e
|
||||
7365 2073 697a 6573 2069 6e20 6279 7465
|
||||
732e 1802 2257 0a0c 0a07 6861 6e64 6c65
|
||||
7212 012f 2247 0800 1100 0000 0000 0000
|
||||
001a 1209 0000 0000 0000 e03f 1100 0000
|
||||
0000 0000 001a 1209 cdcc cccc cccc ec3f
|
||||
1100 0000 0000 0000 001a 1209 ae47 e17a
|
||||
14ae ef3f 1100 0000 0000 0000 0022 5d0a
|
||||
120a 0768 616e 646c 6572 1207 2f61 6c65
|
||||
7274 7322 4708 0011 0000 0000 0000 0000
|
||||
1a12 0900 0000 0000 00e0 3f11 0000 0000
|
||||
0000 0000 1a12 09cd cccc cccc ccec 3f11
|
||||
0000 0000 0000 0000 1a12 09ae 47e1 7a14
|
||||
aeef 3f11 0000 0000 0000 0000 2262 0a17
|
||||
0a07 6861 6e64 6c65 7212 0c2f 6170 692f
|
||||
6d65 7472 6963 7322 4708 0011 0000 0000
|
||||
0000 0000 1a12 0900 0000 0000 00e0 3f11
|
||||
0000 0000 0000 0000 1a12 09cd cccc cccc
|
||||
ccec 3f11 0000 0000 0000 0000 1a12 09ae
|
||||
47e1 7a14 aeef 3f11 0000 0000 0000 0000
|
||||
2260 0a15 0a07 6861 6e64 6c65 7212 0a2f
|
||||
6170 692f 7175 6572 7922 4708 0011 0000
|
||||
0000 0000 0000 1a12 0900 0000 0000 00e0
|
||||
3f11 0000 0000 0000 0000 1a12 09cd cccc
|
||||
cccc ccec 3f11 0000 0000 0000 0000 1a12
|
||||
09ae 47e1 7a14 aeef 3f11 0000 0000 0000
|
||||
0000 2266 0a1b 0a07 6861 6e64 6c65 7212
|
||||
102f 6170 692f 7175 6572 795f 7261 6e67
|
||||
6522 4708 0011 0000 0000 0000 0000 1a12
|
||||
0900 0000 0000 00e0 3f11 0000 0000 0000
|
||||
0000 1a12 09cd cccc cccc ccec 3f11 0000
|
||||
0000 0000 0000 1a12 09ae 47e1 7a14 aeef
|
||||
3f11 0000 0000 0000 0000 2262 0a17 0a07
|
||||
6861 6e64 6c65 7212 0c2f 6170 692f 7461
|
||||
7267 6574 7322 4708 0011 0000 0000 0000
|
||||
0000 1a12 0900 0000 0000 00e0 3f11 0000
|
||||
0000 0000 0000 1a12 09cd cccc cccc ccec
|
||||
3f11 0000 0000 0000 0000 1a12 09ae 47e1
|
||||
7a14 aeef 3f11 0000 0000 0000 0000 2260
|
||||
0a15 0a07 6861 6e64 6c65 7212 0a2f 636f
|
||||
6e73 6f6c 6573 2f22 4708 0011 0000 0000
|
||||
0000 0000 1a12 0900 0000 0000 00e0 3f11
|
||||
0000 0000 0000 0000 1a12 09cd cccc cccc
|
||||
ccec 3f11 0000 0000 0000 0000 1a12 09ae
|
||||
47e1 7a14 aeef 3f11 0000 0000 0000 0000
|
||||
225c 0a11 0a07 6861 6e64 6c65 7212 062f
|
||||
6772 6170 6822 4708 0011 0000 0000 0000
|
||||
0000 1a12 0900 0000 0000 00e0 3f11 0000
|
||||
0000 0000 0000 1a12 09cd cccc cccc ccec
|
||||
3f11 0000 0000 0000 0000 1a12 09ae 47e1
|
||||
7a14 aeef 3f11 0000 0000 0000 0000 225b
|
||||
0a10 0a07 6861 6e64 6c65 7212 052f 6865
|
||||
6170 2247 0800 1100 0000 0000 0000 001a
|
||||
1209 0000 0000 0000 e03f 1100 0000 0000
|
||||
0000 001a 1209 cdcc cccc cccc ec3f 1100
|
||||
0000 0000 0000 001a 1209 ae47 e17a 14ae
|
||||
ef3f 1100 0000 0000 0000 0022 5e0a 130a
|
||||
0768 616e 646c 6572 1208 2f73 7461 7469
|
||||
632f 2247 0800 1100 0000 0000 0000 001a
|
||||
1209 0000 0000 0000 e03f 1100 0000 0000
|
||||
0000 001a 1209 cdcc cccc cccc ec3f 1100
|
||||
0000 0000 0000 001a 1209 ae47 e17a 14ae
|
||||
ef3f 1100 0000 0000 0000 0022 600a 150a
|
||||
0768 616e 646c 6572 120a 7072 6f6d 6574
|
||||
6865 7573 2247 083b 1100 0000 00e0 b4fc
|
||||
401a 1209 0000 0000 0000 e03f 1100 0000
|
||||
0000 349f 401a 1209 cdcc cccc cccc ec3f
|
||||
1100 0000 0000 08a0 401a 1209 ae47 e17a
|
||||
14ae ef3f 1100 0000 0000 0aa0 405c 0a19
|
||||
7072 6f63 6573 735f 6370 755f 7365 636f
|
||||
6e64 735f 746f 7461 6c12 3054 6f74 616c
|
||||
2075 7365 7220 616e 6420 7379 7374 656d
|
||||
2043 5055 2074 696d 6520 7370 656e 7420
|
||||
696e 2073 6563 6f6e 6473 2e18 0022 0b1a
|
||||
0909 a470 3d0a d7a3 d03f 4f0a 1270 726f
|
||||
6365 7373 5f67 6f72 6f75 7469 6e65 7312
|
||||
2a4e 756d 6265 7220 6f66 2067 6f72 6f75
|
||||
7469 6e65 7320 7468 6174 2063 7572 7265
|
||||
6e74 6c79 2065 7869 7374 2e18 0122 0b12
|
||||
0909 0000 0000 0000 5140 4a0a 0f70 726f
|
||||
6365 7373 5f6d 6178 5f66 6473 1228 4d61
|
||||
7869 6d75 6d20 6e75 6d62 6572 206f 6620
|
||||
6f70 656e 2066 696c 6520 6465 7363 7269
|
||||
7074 6f72 732e 1801 220b 1209 0900 0000
|
||||
0000 00c0 4043 0a10 7072 6f63 6573 735f
|
||||
6f70 656e 5f66 6473 1220 4e75 6d62 6572
|
||||
206f 6620 6f70 656e 2066 696c 6520 6465
|
||||
7363 7269 7074 6f72 732e 1801 220b 1209
|
||||
0900 0000 0000 003d 404e 0a1d 7072 6f63
|
||||
6573 735f 7265 7369 6465 6e74 5f6d 656d
|
||||
6f72 795f 6279 7465 7312 1e52 6573 6964
|
||||
656e 7420 6d65 6d6f 7279 2073 697a 6520
|
||||
696e 2062 7974 6573 2e18 0122 0b12 0909
|
||||
0000 0000 004b 8841 630a 1a70 726f 6365
|
||||
7373 5f73 7461 7274 5f74 696d 655f 7365
|
||||
636f 6e64 7312 3653 7461 7274 2074 696d
|
||||
6520 6f66 2074 6865 2070 726f 6365 7373
|
||||
2073 696e 6365 2075 6e69 7820 6570 6f63
|
||||
6820 696e 2073 6563 6f6e 6473 2e18 0122
|
||||
0b12 0909 3d0a 172d e831 d541 4c0a 1c70
|
||||
726f 6365 7373 5f76 6972 7475 616c 5f6d
|
||||
656d 6f72 795f 6279 7465 7312 1d56 6972
|
||||
7475 616c 206d 656d 6f72 7920 7369 7a65
|
||||
2069 6e20 6279 7465 732e 1801 220b 1209
|
||||
0900 0000 0020 12c0 415f 0a27 7072 6f6d
|
||||
6574 6865 7573 5f64 6e73 5f73 645f 6c6f
|
||||
6f6b 7570 5f66 6169 6c75 7265 735f 746f
|
||||
7461 6c12 2554 6865 206e 756d 6265 7220
|
||||
6f66 2044 4e53 2d53 4420 6c6f 6f6b 7570
|
||||
2066 6169 6c75 7265 732e 1800 220b 1a09
|
||||
0900 0000 0000 0000 004f 0a1f 7072 6f6d
|
||||
6574 6865 7573 5f64 6e73 5f73 645f 6c6f
|
||||
6f6b 7570 735f 746f 7461 6c12 1d54 6865
|
||||
206e 756d 6265 7220 6f66 2044 4e53 2d53
|
||||
4420 6c6f 6f6b 7570 732e 1800 220b 1a09
|
||||
0900 0000 0000 0008 40cf 010a 2a70 726f
|
||||
6d65 7468 6575 735f 6576 616c 7561 746f
|
||||
725f 6475 7261 7469 6f6e 5f6d 696c 6c69
|
||||
7365 636f 6e64 7312 2c54 6865 2064 7572
|
||||
6174 696f 6e20 666f 7220 616c 6c20 6576
|
||||
616c 7561 7469 6f6e 7320 746f 2065 7865
|
||||
6375 7465 2e18 0222 7122 6f08 0b11 0000
|
||||
0000 0000 2240 1a12 097b 14ae 47e1 7a84
|
||||
3f11 0000 0000 0000 0000 1a12 099a 9999
|
||||
9999 99a9 3f11 0000 0000 0000 0000 1a12
|
||||
0900 0000 0000 00e0 3f11 0000 0000 0000
|
||||
0000 1a12 09cd cccc cccc ccec 3f11 0000
|
||||
0000 0000 f03f 1a12 09ae 47e1 7a14 aeef
|
||||
3f11 0000 0000 0000 f03f a301 0a39 7072
|
||||
6f6d 6574 6865 7573 5f6c 6f63 616c 5f73
|
||||
746f 7261 6765 5f63 6865 636b 706f 696e
|
||||
745f 6475 7261 7469 6f6e 5f6d 696c 6c69
|
||||
7365 636f 6e64 7312 5754 6865 2064 7572
|
||||
6174 696f 6e20 2869 6e20 6d69 6c6c 6973
|
||||
6563 6f6e 6473 2920 6974 2074 6f6f 6b20
|
||||
746f 2063 6865 636b 706f 696e 7420 696e
|
||||
2d6d 656d 6f72 7920 6d65 7472 6963 7320
|
||||
616e 6420 6865 6164 2063 6875 6e6b 732e
|
||||
1801 220b 1209 0900 0000 0000 0000 00f2
|
||||
010a 2870 726f 6d65 7468 6575 735f 6c6f
|
||||
6361 6c5f 7374 6f72 6167 655f 6368 756e
|
||||
6b5f 6f70 735f 746f 7461 6c12 3354 6865
|
||||
2074 6f74 616c 206e 756d 6265 7220 6f66
|
||||
2063 6875 6e6b 206f 7065 7261 7469 6f6e
|
||||
7320 6279 2074 6865 6972 2074 7970 652e
|
||||
1800 221b 0a0e 0a04 7479 7065 1206 6372
|
||||
6561 7465 1a09 0900 0000 0000 b880 4022
|
||||
1c0a 0f0a 0474 7970 6512 0770 6572 7369
|
||||
7374 1a09 0900 0000 0000 c05b 4022 180a
|
||||
0b0a 0474 7970 6512 0370 696e 1a09 0900
|
||||
0000 0000 807b 4022 1e0a 110a 0474 7970
|
||||
6512 0974 7261 6e73 636f 6465 1a09 0900
|
||||
0000 0000 a06b 4022 1a0a 0d0a 0474 7970
|
||||
6512 0575 6e70 696e 1a09 0900 0000 0000
|
||||
807b 40c4 010a 3c70 726f 6d65 7468 6575
|
||||
735f 6c6f 6361 6c5f 7374 6f72 6167 655f
|
||||
696e 6465 7869 6e67 5f62 6174 6368 5f6c
|
||||
6174 656e 6379 5f6d 696c 6c69 7365 636f
|
||||
6e64 7312 3751 7561 6e74 696c 6573 2066
|
||||
6f72 2062 6174 6368 2069 6e64 6578 696e
|
||||
6720 6c61 7465 6e63 6965 7320 696e 206d
|
||||
696c 6c69 7365 636f 6e64 732e 1802 2249
|
||||
2247 0801 1100 0000 0000 0000 001a 1209
|
||||
0000 0000 0000 e03f 1100 0000 0000 0000
|
||||
001a 1209 cdcc cccc cccc ec3f 1100 0000
|
||||
0000 0000 001a 1209 ae47 e17a 14ae ef3f
|
||||
1100 0000 0000 0000 00bf 010a 2d70 726f
|
||||
6d65 7468 6575 735f 6c6f 6361 6c5f 7374
|
||||
6f72 6167 655f 696e 6465 7869 6e67 5f62
|
||||
6174 6368 5f73 697a 6573 1241 5175 616e
|
||||
7469 6c65 7320 666f 7220 696e 6465 7869
|
||||
6e67 2062 6174 6368 2073 697a 6573 2028
|
||||
6e75 6d62 6572 206f 6620 6d65 7472 6963
|
||||
7320 7065 7220 6261 7463 6829 2e18 0222
|
||||
4922 4708 0111 0000 0000 0000 0040 1a12
|
||||
0900 0000 0000 00e0 3f11 0000 0000 0000
|
||||
0040 1a12 09cd cccc cccc ccec 3f11 0000
|
||||
0000 0000 0040 1a12 09ae 47e1 7a14 aeef
|
||||
3f11 0000 0000 0000 0040 660a 3070 726f
|
||||
6d65 7468 6575 735f 6c6f 6361 6c5f 7374
|
||||
6f72 6167 655f 696e 6465 7869 6e67 5f71
|
||||
7565 7565 5f63 6170 6163 6974 7912 2354
|
||||
6865 2063 6170 6163 6974 7920 6f66 2074
|
||||
6865 2069 6e64 6578 696e 6720 7175 6575
|
||||
652e 1801 220b 1209 0900 0000 0000 00d0
|
||||
406d 0a2e 7072 6f6d 6574 6865 7573 5f6c
|
||||
6f63 616c 5f73 746f 7261 6765 5f69 6e64
|
||||
6578 696e 675f 7175 6575 655f 6c65 6e67
|
||||
7468 122c 5468 6520 6e75 6d62 6572 206f
|
||||
6620 6d65 7472 6963 7320 7761 6974 696e
|
||||
6720 746f 2062 6520 696e 6465 7865 642e
|
||||
1801 220b 1209 0900 0000 0000 0000 0067
|
||||
0a2f 7072 6f6d 6574 6865 7573 5f6c 6f63
|
||||
616c 5f73 746f 7261 6765 5f69 6e67 6573
|
||||
7465 645f 7361 6d70 6c65 735f 746f 7461
|
||||
6c12 2554 6865 2074 6f74 616c 206e 756d
|
||||
6265 7220 6f66 2073 616d 706c 6573 2069
|
||||
6e67 6573 7465 642e 1800 220b 1a09 0900
|
||||
0000 0080 27cd 40c3 010a 3770 726f 6d65
|
||||
7468 6575 735f 6c6f 6361 6c5f 7374 6f72
|
||||
6167 655f 696e 7661 6c69 645f 7072 656c
|
||||
6f61 645f 7265 7175 6573 7473 5f74 6f74
|
||||
616c 1279 5468 6520 746f 7461 6c20 6e75
|
||||
6d62 6572 206f 6620 7072 656c 6f61 6420
|
||||
7265 7175 6573 7473 2072 6566 6572 7269
|
||||
6e67 2074 6f20 6120 6e6f 6e2d 6578 6973
|
||||
7465 6e74 2073 6572 6965 732e 2054 6869
|
||||
7320 6973 2061 6e20 696e 6469 6361 7469
|
||||
6f6e 206f 6620 6f75 7464 6174 6564 206c
|
||||
6162 656c 2069 6e64 6578 6573 2e18 0022
|
||||
0b1a 0909 0000 0000 0000 0000 6f0a 2a70
|
||||
726f 6d65 7468 6575 735f 6c6f 6361 6c5f
|
||||
7374 6f72 6167 655f 6d65 6d6f 7279 5f63
|
||||
6875 6e6b 6465 7363 7312 3254 6865 2063
|
||||
7572 7265 6e74 206e 756d 6265 7220 6f66
|
||||
2063 6875 6e6b 2064 6573 6372 6970 746f
|
||||
7273 2069 6e20 6d65 6d6f 7279 2e18 0122
|
||||
0b12 0909 0000 0000 0020 8f40 9c01 0a26
|
||||
7072 6f6d 6574 6865 7573 5f6c 6f63 616c
|
||||
5f73 746f 7261 6765 5f6d 656d 6f72 795f
|
||||
6368 756e 6b73 1263 5468 6520 6375 7272
|
||||
656e 7420 6e75 6d62 6572 206f 6620 6368
|
||||
756e 6b73 2069 6e20 6d65 6d6f 7279 2c20
|
||||
6578 636c 7564 696e 6720 636c 6f6e 6564
|
||||
2063 6875 6e6b 7320 2869 2e65 2e20 6368
|
||||
756e 6b73 2077 6974 686f 7574 2061 2064
|
||||
6573 6372 6970 746f 7229 2e18 0122 0b12
|
||||
0909 0000 0000 00e8 8d40 600a 2670 726f
|
||||
6d65 7468 6575 735f 6c6f 6361 6c5f 7374
|
||||
6f72 6167 655f 6d65 6d6f 7279 5f73 6572
|
||||
6965 7312 2754 6865 2063 7572 7265 6e74
|
||||
206e 756d 6265 7220 6f66 2073 6572 6965
|
||||
7320 696e 206d 656d 6f72 792e 1801 220b
|
||||
1209 0900 0000 0000 807a 40b7 010a 3570
|
||||
726f 6d65 7468 6575 735f 6c6f 6361 6c5f
|
||||
7374 6f72 6167 655f 7065 7273 6973 745f
|
||||
6c61 7465 6e63 795f 6d69 6372 6f73 6563
|
||||
6f6e 6473 1231 4120 7375 6d6d 6172 7920
|
||||
6f66 206c 6174 656e 6369 6573 2066 6f72
|
||||
2070 6572 7369 7374 696e 6720 6561 6368
|
||||
2063 6875 6e6b 2e18 0222 4922 4708 6f11
|
||||
1c2f dd24 e68c cc40 1a12 0900 0000 0000
|
||||
00e0 3f11 8d97 6e12 8360 3e40 1a12 09cd
|
||||
cccc cccc ccec 3f11 0ad7 a370 3d62 6b40
|
||||
1a12 09ae 47e1 7a14 aeef 3f11 7b14 ae47
|
||||
e1b6 7240 6a0a 2f70 726f 6d65 7468 6575
|
||||
735f 6c6f 6361 6c5f 7374 6f72 6167 655f
|
||||
7065 7273 6973 745f 7175 6575 655f 6361
|
||||
7061 6369 7479 1228 5468 6520 746f 7461
|
||||
6c20 6361 7061 6369 7479 206f 6620 7468
|
||||
6520 7065 7273 6973 7420 7175 6575 652e
|
||||
1801 220b 1209 0900 0000 0000 0090 407a
|
||||
0a2d 7072 6f6d 6574 6865 7573 5f6c 6f63
|
||||
616c 5f73 746f 7261 6765 5f70 6572 7369
|
||||
7374 5f71 7565 7565 5f6c 656e 6774 6812
|
||||
3a54 6865 2063 7572 7265 6e74 206e 756d
|
||||
6265 7220 6f66 2063 6875 6e6b 7320 7761
|
||||
6974 696e 6720 696e 2074 6865 2070 6572
|
||||
7369 7374 2071 7565 7565 2e18 0122 0b12
|
||||
0909 0000 0000 0000 0000 ac01 0a29 7072
|
||||
6f6d 6574 6865 7573 5f6c 6f63 616c 5f73
|
||||
746f 7261 6765 5f73 6572 6965 735f 6f70
|
||||
735f 746f 7461 6c12 3454 6865 2074 6f74
|
||||
616c 206e 756d 6265 7220 6f66 2073 6572
|
||||
6965 7320 6f70 6572 6174 696f 6e73 2062
|
||||
7920 7468 6569 7220 7479 7065 2e18 0022
|
||||
1b0a 0e0a 0474 7970 6512 0663 7265 6174
|
||||
651a 0909 0000 0000 0000 0040 222a 0a1d
|
||||
0a04 7479 7065 1215 6d61 696e 7465 6e61
|
||||
6e63 655f 696e 5f6d 656d 6f72 791a 0909
|
||||
0000 0000 0000 1440 d601 0a2d 7072 6f6d
|
||||
6574 6865 7573 5f6e 6f74 6966 6963 6174
|
||||
696f 6e73 5f6c 6174 656e 6379 5f6d 696c
|
||||
6c69 7365 636f 6e64 7312 584c 6174 656e
|
||||
6379 2071 7561 6e74 696c 6573 2066 6f72
|
||||
2073 656e 6469 6e67 2061 6c65 7274 206e
|
||||
6f74 6966 6963 6174 696f 6e73 2028 6e6f
|
||||
7420 696e 636c 7564 696e 6720 6472 6f70
|
||||
7065 6420 6e6f 7469 6669 6361 7469 6f6e
|
||||
7329 2e18 0222 4922 4708 0011 0000 0000
|
||||
0000 0000 1a12 0900 0000 0000 00e0 3f11
|
||||
0000 0000 0000 0000 1a12 09cd cccc cccc
|
||||
ccec 3f11 0000 0000 0000 0000 1a12 09ae
|
||||
47e1 7a14 aeef 3f11 0000 0000 0000 0000
|
||||
680a 2770 726f 6d65 7468 6575 735f 6e6f
|
||||
7469 6669 6361 7469 6f6e 735f 7175 6575
|
||||
655f 6361 7061 6369 7479 122e 5468 6520
|
||||
6361 7061 6369 7479 206f 6620 7468 6520
|
||||
616c 6572 7420 6e6f 7469 6669 6361 7469
|
||||
6f6e 7320 7175 6575 652e 1801 220b 1209
|
||||
0900 0000 0000 0059 4067 0a25 7072 6f6d
|
||||
6574 6865 7573 5f6e 6f74 6966 6963 6174
|
||||
696f 6e73 5f71 7565 7565 5f6c 656e 6774
|
||||
6812 2f54 6865 206e 756d 6265 7220 6f66
|
||||
2061 6c65 7274 206e 6f74 6966 6963 6174
|
||||
696f 6e73 2069 6e20 7468 6520 7175 6575
|
||||
652e 1801 220b 1209 0900 0000 0000 0000
|
||||
009e 020a 3070 726f 6d65 7468 6575 735f
|
||||
7275 6c65 5f65 7661 6c75 6174 696f 6e5f
|
||||
6475 7261 7469 6f6e 5f6d 696c 6c69 7365
|
||||
636f 6e64 7312 2354 6865 2064 7572 6174
|
||||
696f 6e20 666f 7220 6120 7275 6c65 2074
|
||||
6f20 6578 6563 7574 652e 1802 2260 0a15
|
||||
0a09 7275 6c65 5f74 7970 6512 0861 6c65
|
||||
7274 696e 6722 4708 3711 0000 0000 0000
|
||||
2840 1a12 0900 0000 0000 00e0 3f11 0000
|
||||
0000 0000 0000 1a12 09cd cccc cccc ccec
|
||||
3f11 0000 0000 0000 0000 1a12 09ae 47e1
|
||||
7a14 aeef 3f11 0000 0000 0000 0840 2261
|
||||
0a16 0a09 7275 6c65 5f74 7970 6512 0972
|
||||
6563 6f72 6469 6e67 2247 0837 1100 0000
|
||||
0000 002e 401a 1209 0000 0000 0000 e03f
|
||||
1100 0000 0000 0000 001a 1209 cdcc cccc
|
||||
cccc ec3f 1100 0000 0000 0000 001a 1209
|
||||
ae47 e17a 14ae ef3f 1100 0000 0000 0008
|
||||
4069 0a29 7072 6f6d 6574 6865 7573 5f72
|
||||
756c 655f 6576 616c 7561 7469 6f6e 5f66
|
||||
6169 6c75 7265 735f 746f 7461 6c12 2d54
|
||||
6865 2074 6f74 616c 206e 756d 6265 7220
|
||||
6f66 2072 756c 6520 6576 616c 7561 7469
|
||||
6f6e 2066 6169 6c75 7265 732e 1800 220b
|
||||
1a09 0900 0000 0000 0000 0060 0a21 7072
|
||||
6f6d 6574 6865 7573 5f73 616d 706c 6573
|
||||
5f71 7565 7565 5f63 6170 6163 6974 7912
|
||||
2c43 6170 6163 6974 7920 6f66 2074 6865
|
||||
2071 7565 7565 2066 6f72 2075 6e77 7269
|
||||
7474 656e 2073 616d 706c 6573 2e18 0122
|
||||
0b12 0909 0000 0000 0000 b040 da01 0a1f
|
||||
7072 6f6d 6574 6865 7573 5f73 616d 706c
|
||||
6573 5f71 7565 7565 5f6c 656e 6774 6812
|
||||
a701 4375 7272 656e 7420 6e75 6d62 6572
|
||||
206f 6620 6974 656d 7320 696e 2074 6865
|
||||
2071 7565 7565 2066 6f72 2075 6e77 7269
|
||||
7474 656e 2073 616d 706c 6573 2e20 4561
|
||||
6368 2069 7465 6d20 636f 6d70 7269 7365
|
||||
7320 616c 6c20 7361 6d70 6c65 7320 6578
|
||||
706f 7365 6420 6279 206f 6e65 2074 6172
|
||||
6765 7420 6173 206f 6e65 206d 6574 7269
|
||||
6320 6661 6d69 6c79 2028 692e 652e 206d
|
||||
6574 7269 6373 206f 6620 7468 6520 7361
|
||||
6d65 206e 616d 6529 2e18 0122 0b12 0909
|
||||
0000 0000 0000 0000 d902 0a29 7072 6f6d
|
||||
6574 6865 7573 5f74 6172 6765 745f 696e
|
||||
7465 7276 616c 5f6c 656e 6774 685f 7365
|
||||
636f 6e64 7312 2141 6374 7561 6c20 696e
|
||||
7465 7276 616c 7320 6265 7477 6565 6e20
|
||||
7363 7261 7065 732e 1802 2282 010a 0f0a
|
||||
0869 6e74 6572 7661 6c12 0331 3573 226f
|
||||
0804 1100 0000 0000 804d 401a 1209 7b14
|
||||
ae47 e17a 843f 1100 0000 0000 002c 401a
|
||||
1209 9a99 9999 9999 a93f 1100 0000 0000
|
||||
002c 401a 1209 0000 0000 0000 e03f 1100
|
||||
0000 0000 002e 401a 1209 cdcc cccc cccc
|
||||
ec3f 1100 0000 0000 002e 401a 1209 ae47
|
||||
e17a 14ae ef3f 1100 0000 0000 002e 4022
|
||||
8101 0a0e 0a08 696e 7465 7276 616c 1202
|
||||
3173 226f 083a 1100 0000 0000 003c 401a
|
||||
1209 7b14 ae47 e17a 843f 1100 0000 0000
|
||||
0000 001a 1209 9a99 9999 9999 a93f 1100
|
||||
0000 0000 0000 001a 1209 0000 0000 0000
|
||||
e03f 1100 0000 0000 0000 001a 1209 cdcc
|
||||
cccc cccc ec3f 1100 0000 0000 00f0 3f1a
|
||||
1209 ae47 e17a 14ae ef3f 1100 0000 0000
|
||||
00f0 3f
|
129
Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/protobuf.gz
generated
vendored
Normal file
129
Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/protobuf.gz
generated
vendored
Normal file
|
@ -0,0 +1,129 @@
|
|||
1f8b 0808 efa0 c754 0003 7072 6f74 6f62
|
||||
7566 00ed 594d 8c1c c515 9eb1 8d3d 5b86
|
||||
6037 265e 8c4d ca03 c4bb ceee cc9a 9f58
|
||||
01cc f6ca 4424 041b 8837 21c8 24ed daee
|
||||
9a99 cef6 1f55 d578 c7e4 b004 0e39 8088
|
||||
8448 048a 124b 4442 9110 e110 25b9 c54a
|
||||
9072 01c5 9724 4a24 2472 413e 448a 8592
|
||||
1b87 bcea aeda eeea 99d9 3530 49a4 68e7
|
||||
b0bb 5355 fdde abf7 bef7 bdf7 7a3f 6ca0
|
||||
664f 88c4 61f4 8994 72e1 7829 23c2 8f23
|
||||
27f4 5d16 73ea c691 c7ad cf2d f628 fed2
|
||||
e2e2 c358 9dc3 0111 3472 7dca b11f e1f2
|
||||
d9d6 e496 e6a3 e86a b4a3 4722 2fa0 ccaa
|
||||
b79b f737 6abb 6bea b3cf 9ac8 ff78 6fbe
|
||||
bcf6 cedb f2f3 7763 ed8d fbff 766e cf1b
|
||||
ff28 d69a df44 5621 7847 9bc0 2fc1 c727
|
||||
7e09 ed2d c45f dd26 89df 0ea9 60be 3b46
|
||||
1d67 d0f5 850e 94e9 008f b2fe f834 74d0
|
||||
8d85 865d 8506 8791 a84b ffa3 de12 8475
|
||||
e938 2352 f116 208c c701 e563 84d4 e368
|
||||
77a1 617b bbcb 48d2 1b9f f4d3 6857 21fd
|
||||
aa76 8f92 647c c2bf 85ae 2b84 37da 5c40
|
||||
e6ba 6374 8de9 fc84 c590 0c3d 9aca f0de
|
||||
bdfb f40b bffd 5763 fe9f 7659 8314 f0fb
|
||||
9fbf 6897 35b4 dfbd 65fb d397 7f60 9735
|
||||
1c43 7f7e f5cd 975e b3df 6fa0 bd06 fb70
|
||||
ff1c 7596 fa82 720b 0f50 8edc cce8 263b
|
||||
b0c9 339b 3cb3 c933 5afa ff2f cfc8 13f6
|
||||
5b17 ed01 0d73 cc1e d090 af99 1a60 ed3b
|
||||
e8ba 32cd 7047 c482 04d6 cd8b f217 8ed2
|
||||
7089 321c 770c bae1 3824 1e6d 4dd6 9af7
|
||||
a29d 689b 1b7b d4da 7adb dcdc 085b d135
|
||||
68bb fc33 f6ac ad00 cd7d 13b9 b5ab 27ec
|
||||
4b0d 34a9 b4f3 0470 45cb 2c77 b0c4 72f9
|
||||
ee26 cd7d 02ec 6cd2 dc26 cd7d 6ce1 ff73
|
||||
9a7b ef17 1f0e d2dc 1d3f 19a4 b9c6 f941
|
||||
9a43 e7ed c7d1 0d20 d5a5 9c3b 6e92 3a6a
|
||||
2053 6437 9793 5dca 81ea c006 ccfb 5cd0
|
||||
101f 7ff8 6b58 f821 d04e 4223 2169 676d
|
||||
8eab 3577 028d fd34 91dd dac5 f987 90a5
|
||||
8577 6316 a7c2 8f80 bf0e 9f5c 23cf 6215
|
||||
8b1e 11d8 4d19 0391 411f d315 9f8b d664
|
||||
bdb9 d352 b458 7bc4 7e00 5dab e585 64c5
|
||||
e9c0 9439 7582 acf8 611a 9618 3906 ab70
|
||||
c70f 28f6 2877 999f 8898 7153 d405 fb38
|
||||
daa5 45c9 f399 2c7c f2a3 c838 669f 4407
|
||||
b40c 6062 df03 cb9d 9086 31e4 79ce d437
|
||||
7d55 2de3 7c39 e3e9 124d 97c4 7de5 7b0b
|
||||
2eda a7c5 018e 9870 a48f 7544 accf 9f92
|
||||
6bb9 dfc1 4040 0156 a741 6ae4 529c 46fe
|
||||
0aa6 49ec f68c 88e4 3a8e a1bd b397 8efc
|
||||
71e1 41b4 5feb 78d2 6722 2581 69f1 81af
|
||||
e7ab 1b1a 8cad 0b0b 0e3a 5420 d2f1 22b0
|
||||
db73 8238 5e4e 13a7 43fc 2005 af28 24dd
|
||||
2a6b 5611 a2fb 4e9e 9a3d 751f cecf 627d
|
||||
56c3 47a3 ff21 f499 51f2 b5dc 03eb c8ad
|
||||
c86b d87f a8a3 c325 81f4 4912 a404 025b
|
||||
7e81 1104 bef6 f88c 94ad b770 2786 1c08
|
||||
02ac 9e82 25c0 6c0c 38a5 6e2a a82c b94f
|
||||
34e3 c64e 95ba 4d99 6c4f ed91 e9f6 ac91
|
||||
e2af bc2c 3f3f 9bff 88f4 7079 7e90 1e2e
|
||||
cfbf 5a47 5f28 5d28 885d 8827 871b 912e
|
||||
75dc 1e75 9793 d88f c488 fb3d 6adc 6f2a
|
||||
7b27 536c 4f63 1fd0 068e 94b7 2c64 0118
|
||||
6615 3654 5dce 9801 58d5 8353 69b4 5cc9
|
||||
925a ed83 3a9a 5ac7 4878 0432 50c7 f376
|
||||
6993 a8b4 58d9 2199 924c f97d a92f f1ef
|
||||
332c fa49 d66e dd88 3e85 b6c9 2fd6 7697
|
||||
5122 a88e faaf 57ed e67e 74ad dadc 0122
|
||||
38f0 8ade bd70 da6e 4eca 4e2d dbdd 9af8
|
||||
d15a 0ff6 94dd bc09 ca52 be33 21a0 6e73
|
||||
d9ce e9fd f3cb 7673 1ff4 6ff9 fe55 6964
|
||||
3efb 561d dd33 f2ce 7ee4 01bb 455d 6789
|
||||
08b7 e7e4 6fc5 fa66 6c8e 3e92 9248 00ff
|
||||
f00c 78d9 49ac 1fac be48 2b9e 9330 fc32
|
||||
d486 fa58 aacf 6fea 68f6 4a6f 9175 a0d6
|
||||
8269 f69a c1b9 fd79 973a 5504 5623 08c2
|
||||
921f 991e b8c0 6071 cbd7 aa17 182c 6eb0
|
||||
d641 731b db0f 8d59 0a40 2409 717d d187
|
||||
061f 10a8 bf69 a65d bb48 76d8 44f8 453b
|
||||
44ad 2b55 13d0 a82b 7a39 b50c fae1 2cf1
|
||||
85d4 0219 b7a4 9452 af9a 4f5d d45e 475b
|
||||
17c6 10ea 399c 8449 60b2 6f35 abd4 11ac
|
||||
9f29 b3e5 eaa1 77ec dfd5 d1d1 7514 010d
|
||||
fa9e 9330 1ac4 c4ab 4e49 fd61 0ad5 d962
|
||||
5862 b443 1953 1726 388a a3d9 acec cb82
|
||||
092d 07e0 bb85 177b 3e98 2849 46fa c377
|
||||
73b2 9215 3a15 1ea4 8107 c9b0 4403 e5ac
|
||||
8112 121b 8c6f de41 15be 8c5d 6495 e7d6
|
||||
6d59 ecf3 1e64 807f 4a8d 4096 76d9 d346
|
||||
70f0 0bf6 8fea e8b3 57a4 905b ee3a ca4a
|
||||
1a66 a0c4 b841 ea49 37b9 411c 51cd b3c0
|
||||
d82d dad2 5fce fa30 47a6 02dc 58d8 396d
|
||||
5877 e979 fbcc c6c6 e57e b70e 0d37 2edf
|
||||
1d71 fdd5 73f6 afea e8ce 911a 14f9 9608
|
||||
aff4 df82 230b 98a7 6148 5896 7305 c149
|
||||
1a51 0f4a 0f50 023c 925d 5933 45bc 7b7f
|
||||
fbdd 5bde 7fee 6d83 299e ff61 643d 73e6
|
||||
5e83 29a0 254d 8e2d 2d1b 4c91 95e8 5f32
|
||||
fbdb eb24 95b6 bb42 1453 05c6 ab74 a19e
|
||||
18c6 16df b7cf ad43 aaa6 2a45 1677 ad0b
|
||||
14cd 1910 930d 54d7 6aaf d7d1 f448 dd79
|
||||
6c4b b5f8 8ea1 ac91 23e0 6315 6360 e4e6
|
||||
6174 406d 5e1f 12e8 2768 44a0 7905 3e51
|
||||
005c 3bbb c7fe 9359 7ea2 58f8 1d45 007c
|
||||
78d5 fcc6 83f9 2adc be5c 8638 8db2 f4c9
|
||||
de55 6043 0e54 a358 f634 3ac3 3c16 2709
|
||||
a498 7168 ad2a 8d67 a8eb 196d b379 ad0a
|
||||
c65a c38a d1b0 6b0c 09f7 6376 17dd ba81
|
||||
2285 b0b6 598e 8629 50f0 1a0a ab1f 6f31
|
||||
ea2c 4b03 ea14 6df2 88ee f3e6 c1ee 1acb
|
||||
272b 4db5 1c80 2732 8919 681a 996d 1029
|
||||
88c6 51e5 d1a9 613d c215 46a3 6137 09fa
|
||||
7459 c304 0303 9967 aa68 7d22 15be 9175
|
||||
55f7 5426 a5d9 6159 9739 a678 66e4 c474
|
||||
061d 2c69 d24d 4005 5433 c72b 80ca f6b3
|
||||
10a4 d159 e60b c821 dd1d 98a1 7ed3 fe6b
|
||||
dd98 c94c 0d0a 4daf d58f 0f90 952f 6868
|
||||
8268 843e fc45 c9f0 f238 76e3 3061 8017
|
||||
9ecd 5dba 5da1 2b09 140d 4fd2 0e14 439c
|
||||
bfee c284 67df f246 0adc 0350 ebab 02a9
|
||||
9b2b 7559 9003 5887 1fd3 5518 ff65 8b11
|
||||
a75c b223 398a 81e7 d5ed d6e6 f183 0b6e
|
||||
3628 eb7d 2042 2ace 5279 1597 9124 7f0b
|
||||
fbdd 3acc 1e0d 7dc4 da7a e44e 0e43 e2b6
|
||||
1c19 ab27 860c 8933 f6e0 9038 3304 7dad
|
||||
214d 706b 4813 dcb2 9b4f d781 900b 23b6
|
||||
1c91 36dc a5f6 eff9 af0c aaff 06f1 48e5
|
||||
4433 2000 00
|
163
Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/test.gz
generated
vendored
Normal file
163
Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/test.gz
generated
vendored
Normal file
|
@ -0,0 +1,163 @@
|
|||
1f8b 0808 2aa1 c754 0003 7465 7874 00b5
|
||||
5b5d 939b 3816 7def 5fa1 ea79 99a9 4d3c
|
||||
601b db3c f4c3 5426 55f3 309b ca6e 7ab7
|
||||
6a9e 281a d436 150c 04c4 a4bd 5df3 dff7
|
||||
4a88 361f 025d 094f 1e92 34e8 1cae 8ea4
|
||||
ab7b 04fd 03f9 ede3 ef9f c989 b122 28e9
|
||||
b79a 562c 88eb 3264 499e 05e7 242a f38a
|
||||
4679 1657 e4f1 44c9 6f8f 8f9f 896c 46d2
|
||||
90d1 2c4a 6845 928c 749b aeee 7e20 8f7f
|
||||
7cfe 8861 adea f339 2c2f 77fa a6af a730
|
||||
8b53 5a3e dcff 7cff ee5b 1d66 2c49 e9c3
|
||||
bdb3 f2ee ff22 ce12 027f 3101 9621 80ee
|
||||
7659 90a8 28af 3366 8eeb 2042 f887 558b
|
||||
7553 d158 a8a7 a4b1 d450 7259 2a69 84ee
|
||||
e28a e4e7 3365 6512 dd40 d429 2e1b 6527
|
||||
b96c e5ed 10da 6a6c 4c31 0043 cbf2 7213
|
||||
9915 4c96 22ab 9816 48dc d02d 10d8 8440
|
||||
050d ca30 3bd2 db89 ace2 5b22 b592 6fa9
|
||||
e092 74a9 ec46 3403 0216 9647 7a8b cc3c
|
||||
c565 29ba 9a6b 81e0 2de1 02b1 cd28 3a60
|
||||
f8b9 ca53 5a2d 2f1c 2698 2c44 9e62 b294
|
||||
f84a 6729 b029 4107 7a2c c3e2 b458 5a05
|
||||
8b85 ac2a 164b 491b 2a4b 394d c01d d889
|
||||
86c5 6225 c724 1642 2a48 2c75 144c 9632
|
||||
1a60 3ba8 8ac1 ed68 f96a 57f2 5868 a9e6
|
||||
b194 b325 b354 d40c 7e05 1665 0e45 dc89
|
||||
d68a bdca dd38 fbd5 7aef dd84 90cb e21e
|
||||
bcc3 6ab7 59df 8690 336e 9cc3 7eb5 396c
|
||||
8df5 eeb0 425c 7bff 70d8 ad3c 47fe 712d
|
||||
46a0 4fe8 fa60 96c7 16bc 4afe 4783 a70b
|
||||
a30a dfcd ef09 cf2d eeab cd76 07af 74d8
|
||||
d7fb 26b6 1a81 524c 6a0c 6a16 a675 cd9d
|
||||
a67a abac 0c07 e98f d158 ac0c 5827 3c29
|
||||
c694 819d 9144 0fb1 34ba 6604 6889 4c2c
|
||||
edb4 4e73 2674 4e2c 1cce cab1 9ac0 4dd4
|
||||
427a d359 ad26 fca4 4629 2d6a 81f5 3427
|
||||
31d6 0c6b 32f5 ca4d 5942 8c7e 7aac a587
|
||||
3423 3051 0fed 1667 959b f477 1ad5 1038
|
||||
2b33 6802 c7aa 6560 fb26 b59a b16a 334a
|
||||
a150 c6ae 0e0b c5ea 83f4 6f93 da4c f8ae
|
||||
195d b408 537b 8644 6215 c119 b149 41d4
|
||||
0e6a 460f 1dc0 c267 e1c1 5851 d08e 6a52
|
||||
9749 1f34 230d 0283 334c 6bdf b527 f017
|
||||
1368 1866 0cd0 66bb 3d1c b07a 619c 4e15
|
||||
b09c 8529 7914 7f67 f5f9 8996 247f ee39
|
||||
9e8a 9cc3 982a 8d4e 0b17 4fa6 e59d e2de
|
||||
6b94 c7d0 edb5 e3dc bf53 4ac3 ff93 c70f
|
||||
f7b0 8728 e3ac 0ac8 9c74 c292 3537 359e
|
||||
6ccc 3030 65a3 0638 5786 87f9 96b0 79dc
|
||||
8c31 1bb7 9d73 6673 1169 ad99 2918 ad85
|
||||
de9c e914 195b 2dbd 2e08 8cb1 3fb3 62c0
|
||||
eb84 7368 5ab1 d456 0ba1 1812 6868 d22c
|
||||
f046 9269 6d1a 46b0 91e3 c2c9 a587 5939
|
||||
356b 1673 e1f4 5e0d 2ddf d870 1988 8800
|
||||
1bdb 352b 0623 0911 860d 239f c279 e1a4
|
||||
c300 0d3d 9b05 1e2d 19ca b5e9 0453 1a30
|
||||
bd5c 3898 8171 33c4 a245 d25a 379d 4023
|
||||
27a6 1747 0fc1 bb37 3328 5a16 9d7f d3a9
|
||||
32f4 637a 51b4 0823 0b67 8c46 2b83 3071
|
||||
3a71 148e 4caf 0f06 84f4 71ce d65f 4021
|
||||
7c98 e31d 9650 341c bb2d 52b1 9e27 5b6f
|
||||
f79d 7758 5ae1 a6fc 1c5c 8f68 05cd 8b3a
|
||||
685f 7a75 5d5d 5d81 a703 1252 5d2a 46cf
|
||||
e4c3 e7ff 1096 9cc1 3515 3463 dc35 0d3f
|
||||
1c9d 666c 8dde 740b 1819 6f18 d931 2ff3
|
||||
9a25 1938 af4f 6f16 b373 919d 4246 a2ba
|
||||
2c21 9ef4 42e8 4b52 b151 309d f6c7 b03e
|
||||
d23b c58d bd33 7cf4 397c 099e e38a fc33
|
||||
7c49 cef5 b963 7173 e83d 7986 7124 31ad
|
||||
a232 2958 5e8e 2568 f1fd 47b6 570f aebf
|
||||
1e3e 91f3 8a9b 9f0c 1ff5 06ec 3feb edf2
|
||||
7a34 e230 6992 1834 0bce f49c 432d d498
|
||||
db7f cbab a4b9 2acc f1d8 1bcf 73f4 4350
|
||||
b7f1 569b c3de f1fc 35fd 87b3 1f86 068b
|
||||
bc64 019f 66ed fc20 5ff8 a566 e681 2630
|
||||
91db c610 6116 5152 67c9 0ba1 451e 9de6
|
||||
e6a4 82b8 1fac a281 bbda aed7 9bdd c1df
|
||||
1e36 3b88 7624 e49f 49c9 ea30 edf7 efbf
|
||||
cd45 9c8c 4a86 7e60 ca26 de6a eb6e f707
|
||||
dfe5 2a1e 3a71 c9a5 1ec4 1974 290e d23c
|
||||
ff5a 17c1 7398 a435 0c47 bbc0 41c4 eb8c
|
||||
fef5 d397 f75f 7e25 4d53 d236 ed86 8a22
|
||||
edac 7154 7b47 1735 225a 7d94 d8e8 da76
|
||||
7b45 54f4 cf30 ad43 587c dd4f 05d2 34e9
|
||||
7e63 dfde 21cf 3964 cd34 2512 0497 2051
|
||||
e590 9c68 5433 aa8a 5747 df9e 3ae1 21af
|
||||
ddbd c671 c596 698b f696 a017 81c5 2725
|
||||
d660 5334 df70 89bb 3641 8839 45d6 1bc5
|
||||
9449 f308 966c 05d8 f048 83e8 44a3 af45
|
||||
9e64 0c33 837e 14bf 9871 bdfb 1349 20ff
|
||||
c12c e5f3 e84a 0549 e5bd cc31 f218 45ec
|
||||
d650 46c6 d0aa cebe 2a17 8761 606f a9c8
|
||||
12af 5ae4 430a 0815 76ab ee6a 6783 6365
|
||||
d186 6f87 a55c 504f 17be 1124 2561 9742
|
||||
b9a6 e69f a148 06b3 8057 fe98 87fb a8a4
|
||||
21e3 8706 9e7f 30c5 42ec 1594 27e2 6ba4
|
||||
ad31 38c9 00e8 af1d 5320 2bc3 ace2 27e9
|
||||
00df ba9e 29bc ceae 4fd6 8d63 92c5 5080
|
||||
65c7 e029 64d1 2968 7ecd e8d2 9f0d ff92
|
||||
0bb4 1259 5234 242d 6ef8 8b49 5798 7e7c
|
||||
31cf 5664 5163 92f9 dcb6 8cce bf31 dd72
|
||||
3e91 1117 5234 29d2 359d 3dcd 8b99 fe74
|
||||
799b 28cd bc69 9afc 784d 126d 1284 95d6
|
||||
34f9 c978 e234 9ca6 3345 a046 5363 bd00
|
||||
ef2f c55b 1088 d136 c518 0fef b79a d690
|
||||
6dc2 228c 1276 11c9 feed 0759 ddbf 8db3
|
||||
686b 3086 036e cdd6 3505 7377 fc7b 53c3
|
||||
0ea5 343b b2d3 a052 6d27 e4f7 3061 bc3f
|
||||
b07b 3fc9 eed1 d8b8 5ff2 1166 bd92 204c
|
||||
f63e 5270 f971 5085 e722 a573 9bb1 6c41
|
||||
5a08 a627 4a72 ed2e 3c81 db38 dbbd bee6
|
||||
4a32 a8de 9238 284a 9ae6 613c 7a73 ade8
|
||||
996c 7a7d 815d d267 5a96 72ec 4292 e5d9
|
||||
7b71 c8c0 5d72 454b d8ab 5640 9480 16bc
|
||||
f6e2 439b 444d 0dc7 dd7b cd62 4889 316c
|
||||
6c4f 3495 e38e dacc 6603 47a8 368b d7cf
|
||||
0569 3445 49c0 0f1e 9af2 549e b38c aab2
|
||||
ced1 84d8 b805 58df cbf1 4334 337b 0c70
|
||||
1dcf 37ea cc6c 473a d1bf 03b7 16a5 75cc
|
||||
073e 4af3 8cb6 0535 94e6 2bba 6a7f f89e
|
||||
b013 0c32 4c8c ab06 883d a71f 9141 af79
|
||||
8f11 8598 8434 f373 a2c7 f2a6 f978 4920
|
||||
2e6a d978 bbd6 e753 591e 778a 88ce 6f9b
|
||||
ffd2 6ec9 3cf4 6b99 c88b 0289 e323 4543
|
||||
a80a 8450 fade cc3e 4ebb ffcf a147 75c0
|
||||
c659 6df6 fb1b 9035 47c6 9b95 b7f1 6fc1
|
||||
26e8 76eb dd6a bbdb d8f1 3515 8303 c3bb
|
||||
9af5 16b3 1cb2 82d8 e3a7 88a2 8490 9971
|
||||
5048 4800 b68e 98e0 d74c f509 14ac 54d3
|
||||
1e75 6a88 c914 d596 12b0 7017 f710 5750
|
||||
2831 fa24 d42c 7d8d ad97 f9c1 ded7 8f9e
|
||||
a2dd 1c87 88a1 b39f 2980 27a0 e730 8147
|
||||
6661 16f1 ad57 a63e f1a6 4521 5296 b3e4
|
||||
59d6 0895 daa7 fede 5c24 df7a e6a7 a299
|
||||
d88e c467 46a4 4703 1e28 e787 41ed 8e15
|
||||
9779 51c0 96d5 6ba4 dc97 10d1 2872 a11e
|
||||
356f 930d f123 1f6b 8ab7 2018 3b5f 04a6
|
||||
c964 aaa5 d107 232c 906a 9427 d7f8 2cfb
|
||||
6875 cfb6 761d 6cf8 4ac3 a30a 5b66 2aa3
|
||||
e8a7 32d3 4c5b 55dc 659d d2e0 7a0c 8f3e
|
||||
bc27 1ca8 39b3 c771 2b56 0f0a f82a 5a35
|
||||
f945 880a eb5a f5ae fff6 bca3 c572 2bde
|
||||
d189 048a 58bc 0557 91ff 3538 aac7 b135
|
||||
6fc6 27f8 fa25 8c71 bf4b b854 c67f c340
|
||||
4d10 2f1f a929 62f1 8bb7 8b87 eaca 0eda
|
||||
9a4b 3b1e ab1e a1eb 2116 bce2 ade7 b004
|
||||
114b fd0a 997d fba9 a157 d41e 1a84 2a69
|
||||
b547 1d83 ccfc 61b0 4388 db22 5dd5 d9f7
|
||||
3261 b01f b507 33aa d027 5847 1976 a2dd
|
||||
d6f1 77da 5865 26fe 30aa 5d13 46cf fd8d
|
||||
6022 70f2 915b 38de 1cc4 3c17 25cc 854a
|
||||
bc4b 6d8f 9ce8 4b01 c621 e665 22b8 72d2
|
||||
7c8e 48c2 4afc d41c b7c1 08c2 34ba 48a7
|
||||
de1e c149 d580 07f6 2bf8 4b59 0e29 bba3
|
||||
9168 66fb 69a2 0b78 7558 c214 904d df3e
|
||||
2ef8 2512 5f09 b4b7 a1f6 a5ec 3be5 6a44
|
||||
6558 a887 5143 a9d8 6ee6 11af edf5 877b
|
||||
d71b 7ca2 245e 1bbb db1b 9179 3724 f346
|
||||
19c5 9ecb bf25 9729 9948 997d 42fe 7ad0
|
||||
84a1 c992 238e b55d 8f54 53c0 b90d d568
|
||||
1fb4 a6ba 1dd3 e813 017b 2643 aae1 c8f3
|
||||
41f3 168d 7bf3 71df feee ff2d f9e8 431a
|
||||
5200 00
|
322
Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/text
generated
vendored
Normal file
322
Godeps/_workspace/src/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
|
308
Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_create.go
generated
vendored
Normal file
308
Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_create.go
generated
vendored
Normal file
|
@ -0,0 +1,308 @@
|
|||
// 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"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"github.com/prometheus/common/model"
|
||||
)
|
||||
|
||||
// MetricFamilyToText converts a MetricFamily proto message into text format and
|
||||
// writes the resulting lines to 'out'. It returns the number of bytes written
|
||||
// and any error encountered. This function does not perform checks on the
|
||||
// content of the metric and label names, i.e. invalid metric or label names
|
||||
// will result in invalid text format output.
|
||||
// This method fulfills the type 'prometheus.encoder'.
|
||||
func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
|
||||
var written int
|
||||
|
||||
// Fail-fast checks.
|
||||
if len(in.Metric) == 0 {
|
||||
return written, fmt.Errorf("MetricFamily has no metrics: %s", in)
|
||||
}
|
||||
name := in.GetName()
|
||||
if name == "" {
|
||||
return written, fmt.Errorf("MetricFamily has no name: %s", in)
|
||||
}
|
||||
if in.Type == nil {
|
||||
return written, fmt.Errorf("MetricFamily has no type: %s", in)
|
||||
}
|
||||
|
||||
// Comments, first HELP, then TYPE.
|
||||
if in.Help != nil {
|
||||
n, err := fmt.Fprintf(
|
||||
out, "# HELP %s %s\n",
|
||||
name, escapeString(*in.Help, false),
|
||||
)
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
}
|
||||
metricType := in.GetType()
|
||||
n, err := fmt.Fprintf(
|
||||
out, "# TYPE %s %s\n",
|
||||
name, strings.ToLower(metricType.String()),
|
||||
)
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
|
||||
// Finally the samples, one line for each.
|
||||
for _, metric := range in.Metric {
|
||||
switch metricType {
|
||||
case dto.MetricType_COUNTER:
|
||||
if metric.Counter == nil {
|
||||
return written, fmt.Errorf(
|
||||
"expected counter in metric %s %s", name, metric,
|
||||
)
|
||||
}
|
||||
n, err = writeSample(
|
||||
name, metric, "", "",
|
||||
metric.Counter.GetValue(),
|
||||
out,
|
||||
)
|
||||
case dto.MetricType_GAUGE:
|
||||
if metric.Gauge == nil {
|
||||
return written, fmt.Errorf(
|
||||
"expected gauge in metric %s %s", name, metric,
|
||||
)
|
||||
}
|
||||
n, err = writeSample(
|
||||
name, metric, "", "",
|
||||
metric.Gauge.GetValue(),
|
||||
out,
|
||||
)
|
||||
case dto.MetricType_UNTYPED:
|
||||
if metric.Untyped == nil {
|
||||
return written, fmt.Errorf(
|
||||
"expected untyped in metric %s %s", name, metric,
|
||||
)
|
||||
}
|
||||
n, err = writeSample(
|
||||
name, metric, "", "",
|
||||
metric.Untyped.GetValue(),
|
||||
out,
|
||||
)
|
||||
case dto.MetricType_SUMMARY:
|
||||
if metric.Summary == nil {
|
||||
return written, fmt.Errorf(
|
||||
"expected summary in metric %s %s", name, metric,
|
||||
)
|
||||
}
|
||||
for _, q := range metric.Summary.Quantile {
|
||||
n, err = writeSample(
|
||||
name, metric,
|
||||
model.QuantileLabel, fmt.Sprint(q.GetQuantile()),
|
||||
q.GetValue(),
|
||||
out,
|
||||
)
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
}
|
||||
n, err = writeSample(
|
||||
name+"_sum", metric, "", "",
|
||||
metric.Summary.GetSampleSum(),
|
||||
out,
|
||||
)
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
written += n
|
||||
n, err = writeSample(
|
||||
name+"_count", metric, "", "",
|
||||
float64(metric.Summary.GetSampleCount()),
|
||||
out,
|
||||
)
|
||||
case dto.MetricType_HISTOGRAM:
|
||||
if metric.Histogram == nil {
|
||||
return written, fmt.Errorf(
|
||||
"expected histogram in metric %s %s", name, metric,
|
||||
)
|
||||
}
|
||||
infSeen := false
|
||||
for _, q := range metric.Histogram.Bucket {
|
||||
n, err = writeSample(
|
||||
name+"_bucket", metric,
|
||||
model.BucketLabel, fmt.Sprint(q.GetUpperBound()),
|
||||
float64(q.GetCumulativeCount()),
|
||||
out,
|
||||
)
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
if math.IsInf(q.GetUpperBound(), +1) {
|
||||
infSeen = true
|
||||
}
|
||||
}
|
||||
if !infSeen {
|
||||
n, err = writeSample(
|
||||
name+"_bucket", metric,
|
||||
model.BucketLabel, "+Inf",
|
||||
float64(metric.Histogram.GetSampleCount()),
|
||||
out,
|
||||
)
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
written += n
|
||||
}
|
||||
n, err = writeSample(
|
||||
name+"_sum", metric, "", "",
|
||||
metric.Histogram.GetSampleSum(),
|
||||
out,
|
||||
)
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
written += n
|
||||
n, err = writeSample(
|
||||
name+"_count", metric, "", "",
|
||||
float64(metric.Histogram.GetSampleCount()),
|
||||
out,
|
||||
)
|
||||
default:
|
||||
return written, fmt.Errorf(
|
||||
"unexpected type in metric %s %s", name, metric,
|
||||
)
|
||||
}
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
}
|
||||
return written, nil
|
||||
}
|
||||
|
||||
// writeSample writes a single sample in text format to out, given the metric
|
||||
// name, the metric proto message itself, optionally an additional label name
|
||||
// and value (use empty strings if not required), and the value. The function
|
||||
// returns the number of bytes written and any error encountered.
|
||||
func writeSample(
|
||||
name string,
|
||||
metric *dto.Metric,
|
||||
additionalLabelName, additionalLabelValue string,
|
||||
value float64,
|
||||
out io.Writer,
|
||||
) (int, error) {
|
||||
var written int
|
||||
n, err := fmt.Fprint(out, name)
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
n, err = labelPairsToText(
|
||||
metric.Label,
|
||||
additionalLabelName, additionalLabelValue,
|
||||
out,
|
||||
)
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
n, err = fmt.Fprintf(out, " %v", value)
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
if metric.TimestampMs != nil {
|
||||
n, err = fmt.Fprintf(out, " %v", *metric.TimestampMs)
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
}
|
||||
n, err = out.Write([]byte{'\n'})
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
return written, nil
|
||||
}
|
||||
|
||||
// labelPairsToText converts a slice of LabelPair proto messages plus the
|
||||
// explicitly given additional label pair into text formatted as required by the
|
||||
// text format and writes it to 'out'. An empty slice in combination with an
|
||||
// empty string 'additionalLabelName' results in nothing being
|
||||
// written. Otherwise, the label pairs are written, escaped as required by the
|
||||
// text format, and enclosed in '{...}'. The function returns the number of
|
||||
// bytes written and any error encountered.
|
||||
func labelPairsToText(
|
||||
in []*dto.LabelPair,
|
||||
additionalLabelName, additionalLabelValue string,
|
||||
out io.Writer,
|
||||
) (int, error) {
|
||||
if len(in) == 0 && additionalLabelName == "" {
|
||||
return 0, nil
|
||||
}
|
||||
var written int
|
||||
separator := '{'
|
||||
for _, lp := range in {
|
||||
n, err := fmt.Fprintf(
|
||||
out, `%c%s="%s"`,
|
||||
separator, lp.GetName(), escapeString(lp.GetValue(), true),
|
||||
)
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
separator = ','
|
||||
}
|
||||
if additionalLabelName != "" {
|
||||
n, err := fmt.Fprintf(
|
||||
out, `%c%s="%s"`,
|
||||
separator, additionalLabelName,
|
||||
escapeString(additionalLabelValue, true),
|
||||
)
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
}
|
||||
n, err := out.Write([]byte{'}'})
|
||||
written += n
|
||||
if err != nil {
|
||||
return written, err
|
||||
}
|
||||
return written, nil
|
||||
}
|
||||
|
||||
// escapeString replaces '\' by '\\', new line character by '\n', and - if
|
||||
// includeDoubleQuote is true - '"' by '\"'.
|
||||
func escapeString(v string, includeDoubleQuote bool) string {
|
||||
result := bytes.NewBuffer(make([]byte, 0, len(v)))
|
||||
for _, c := range v {
|
||||
switch {
|
||||
case c == '\\':
|
||||
result.WriteString(`\\`)
|
||||
case includeDoubleQuote && c == '"':
|
||||
result.WriteString(`\"`)
|
||||
case c == '\n':
|
||||
result.WriteString(`\n`)
|
||||
default:
|
||||
result.WriteRune(c)
|
||||
}
|
||||
}
|
||||
return result.String()
|
||||
}
|
440
Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_create_test.go
generated
vendored
Normal file
440
Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_create_test.go
generated
vendored
Normal file
|
@ -0,0 +1,440 @@
|
|||
// 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
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
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: No metric type.
|
||||
{
|
||||
in: &dto.MetricFamily{
|
||||
Name: proto.String("name"),
|
||||
Help: proto.String("doc string"),
|
||||
Metric: []*dto.Metric{
|
||||
&dto.Metric{
|
||||
Untyped: &dto.Untyped{
|
||||
Value: proto.Float64(math.Inf(-1)),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "MetricFamily has no type",
|
||||
},
|
||||
// 3: 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)
|
||||
}
|
||||
}
|
746
Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_parse.go
generated
vendored
Normal file
746
Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_parse.go
generated
vendored
Normal file
|
@ -0,0 +1,746 @@
|
|||
// 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 (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/prometheus/common/model"
|
||||
)
|
||||
|
||||
// A stateFn is a function that represents a state in a state machine. By
|
||||
// executing it, the state is progressed to the next state. The stateFn returns
|
||||
// another stateFn, which represents the new state. The end state is represented
|
||||
// by nil.
|
||||
type stateFn func() stateFn
|
||||
|
||||
// ParseError signals errors while parsing the simple and flat text-based
|
||||
// exchange format.
|
||||
type ParseError struct {
|
||||
Line int
|
||||
Msg string
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e ParseError) Error() string {
|
||||
return fmt.Sprintf("text format parsing error in line %d: %s", e.Line, e.Msg)
|
||||
}
|
||||
|
||||
// TextParser is used to parse the simple and flat text-based exchange format. Its
|
||||
// nil value is ready to use.
|
||||
type TextParser struct {
|
||||
metricFamiliesByName map[string]*dto.MetricFamily
|
||||
buf *bufio.Reader // Where the parsed input is read through.
|
||||
err error // Most recent error.
|
||||
lineCount int // Tracks the line count for error messages.
|
||||
currentByte byte // The most recent byte read.
|
||||
currentToken bytes.Buffer // Re-used each time a token has to be gathered from multiple bytes.
|
||||
currentMF *dto.MetricFamily
|
||||
currentMetric *dto.Metric
|
||||
currentLabelPair *dto.LabelPair
|
||||
|
||||
// The remaining member variables are only used for summaries/histograms.
|
||||
currentLabels map[string]string // All labels including '__name__' but excluding 'quantile'/'le'
|
||||
// Summary specific.
|
||||
summaries map[uint64]*dto.Metric // Key is created with LabelsToSignature.
|
||||
currentQuantile float64
|
||||
// Histogram specific.
|
||||
histograms map[uint64]*dto.Metric // Key is created with LabelsToSignature.
|
||||
currentBucket float64
|
||||
// These tell us if the currently processed line ends on '_count' or
|
||||
// '_sum' respectively and belong to a summary/histogram, representing the sample
|
||||
// count and sum of that summary/histogram.
|
||||
currentIsSummaryCount, currentIsSummarySum bool
|
||||
currentIsHistogramCount, currentIsHistogramSum bool
|
||||
}
|
||||
|
||||
// TextToMetricFamilies reads 'in' as the simple and flat text-based exchange
|
||||
// format and creates MetricFamily proto messages. It returns the MetricFamily
|
||||
// proto messages in a map where the metric names are the keys, along with any
|
||||
// error encountered.
|
||||
//
|
||||
// If the input contains duplicate metrics (i.e. lines with the same metric name
|
||||
// and exactly the same label set), the resulting MetricFamily will contain
|
||||
// duplicate Metric proto messages. Similar is true for duplicate label
|
||||
// names. Checks for duplicates have to be performed separately, if required.
|
||||
// Also note that neither the metrics within each MetricFamily are sorted nor
|
||||
// the label pairs within each Metric. Sorting is not required for the most
|
||||
// frequent use of this method, which is sample ingestion in the Prometheus
|
||||
// server. However, for presentation purposes, you might want to sort the
|
||||
// metrics, and in some cases, you must sort the labels, e.g. for consumption by
|
||||
// the metric family injection hook of the Prometheus registry.
|
||||
//
|
||||
// Summaries and histograms are rather special beasts. You would probably not
|
||||
// use them in the simple text format anyway. This method can deal with
|
||||
// summaries and histograms if they are presented in exactly the way the
|
||||
// text.Create function creates them.
|
||||
//
|
||||
// This method must not be called concurrently. If you want to parse different
|
||||
// input concurrently, instantiate a separate Parser for each goroutine.
|
||||
func (p *TextParser) TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricFamily, error) {
|
||||
p.reset(in)
|
||||
for nextState := p.startOfLine; nextState != nil; nextState = nextState() {
|
||||
// Magic happens here...
|
||||
}
|
||||
// Get rid of empty metric families.
|
||||
for k, mf := range p.metricFamiliesByName {
|
||||
if len(mf.GetMetric()) == 0 {
|
||||
delete(p.metricFamiliesByName, k)
|
||||
}
|
||||
}
|
||||
return p.metricFamiliesByName, p.err
|
||||
}
|
||||
|
||||
func (p *TextParser) reset(in io.Reader) {
|
||||
p.metricFamiliesByName = map[string]*dto.MetricFamily{}
|
||||
if p.buf == nil {
|
||||
p.buf = bufio.NewReader(in)
|
||||
} else {
|
||||
p.buf.Reset(in)
|
||||
}
|
||||
p.err = nil
|
||||
p.lineCount = 0
|
||||
if p.summaries == nil || len(p.summaries) > 0 {
|
||||
p.summaries = map[uint64]*dto.Metric{}
|
||||
}
|
||||
if p.histograms == nil || len(p.histograms) > 0 {
|
||||
p.histograms = map[uint64]*dto.Metric{}
|
||||
}
|
||||
p.currentQuantile = math.NaN()
|
||||
p.currentBucket = math.NaN()
|
||||
}
|
||||
|
||||
// startOfLine represents the state where the next byte read from p.buf is the
|
||||
// start of a line (or whitespace leading up to it).
|
||||
func (p *TextParser) startOfLine() stateFn {
|
||||
p.lineCount++
|
||||
if p.skipBlankTab(); p.err != nil {
|
||||
// End of input reached. This is the only case where
|
||||
// that is not an error but a signal that we are done.
|
||||
p.err = nil
|
||||
return nil
|
||||
}
|
||||
switch p.currentByte {
|
||||
case '#':
|
||||
return p.startComment
|
||||
case '\n':
|
||||
return p.startOfLine // Empty line, start the next one.
|
||||
}
|
||||
return p.readingMetricName
|
||||
}
|
||||
|
||||
// startComment represents the state where the next byte read from p.buf is the
|
||||
// start of a comment (or whitespace leading up to it).
|
||||
func (p *TextParser) startComment() stateFn {
|
||||
if p.skipBlankTab(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
if p.currentByte == '\n' {
|
||||
return p.startOfLine
|
||||
}
|
||||
if p.readTokenUntilWhitespace(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
// If we have hit the end of line already, there is nothing left
|
||||
// to do. This is not considered a syntax error.
|
||||
if p.currentByte == '\n' {
|
||||
return p.startOfLine
|
||||
}
|
||||
keyword := p.currentToken.String()
|
||||
if keyword != "HELP" && keyword != "TYPE" {
|
||||
// Generic comment, ignore by fast forwarding to end of line.
|
||||
for p.currentByte != '\n' {
|
||||
if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
}
|
||||
return p.startOfLine
|
||||
}
|
||||
// There is something. Next has to be a metric name.
|
||||
if p.skipBlankTab(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
if p.readTokenAsMetricName(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
if p.currentByte == '\n' {
|
||||
// At the end of the line already.
|
||||
// Again, this is not considered a syntax error.
|
||||
return p.startOfLine
|
||||
}
|
||||
if !isBlankOrTab(p.currentByte) {
|
||||
p.parseError("invalid metric name in comment")
|
||||
return nil
|
||||
}
|
||||
p.setOrCreateCurrentMF()
|
||||
if p.skipBlankTab(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
if p.currentByte == '\n' {
|
||||
// At the end of the line already.
|
||||
// Again, this is not considered a syntax error.
|
||||
return p.startOfLine
|
||||
}
|
||||
switch keyword {
|
||||
case "HELP":
|
||||
return p.readingHelp
|
||||
case "TYPE":
|
||||
return p.readingType
|
||||
}
|
||||
panic(fmt.Sprintf("code error: unexpected keyword %q", keyword))
|
||||
}
|
||||
|
||||
// readingMetricName represents the state where the last byte read (now in
|
||||
// p.currentByte) is the first byte of a metric name.
|
||||
func (p *TextParser) readingMetricName() stateFn {
|
||||
if p.readTokenAsMetricName(); p.err != nil {
|
||||
return nil
|
||||
}
|
||||
if p.currentToken.Len() == 0 {
|
||||
p.parseError("invalid metric name")
|
||||
return nil
|
||||
}
|
||||
p.setOrCreateCurrentMF()
|
||||
// Now is the time to fix the type if it hasn't happened yet.
|
||||
if p.currentMF.Type == nil {
|
||||
p.currentMF.Type = dto.MetricType_UNTYPED.Enum()
|
||||
}
|
||||
p.currentMetric = &dto.Metric{}
|
||||
// Do not append the newly created currentMetric to
|
||||
// currentMF.Metric right now. First wait if this is a summary,
|
||||
// and the metric exists already, which we can only know after
|
||||
// having read all the labels.
|
||||
if p.skipBlankTabIfCurrentBlankTab(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
return p.readingLabels
|
||||
}
|
||||
|
||||
// readingLabels represents the state where the last byte read (now in
|
||||
// p.currentByte) is either the first byte of the label set (i.e. a '{'), or the
|
||||
// first byte of the value (otherwise).
|
||||
func (p *TextParser) readingLabels() stateFn {
|
||||
// Summaries/histograms are special. We have to reset the
|
||||
// currentLabels map, currentQuantile and currentBucket before starting to
|
||||
// read labels.
|
||||
if p.currentMF.GetType() == dto.MetricType_SUMMARY || p.currentMF.GetType() == dto.MetricType_HISTOGRAM {
|
||||
p.currentLabels = map[string]string{}
|
||||
p.currentLabels[string(model.MetricNameLabel)] = p.currentMF.GetName()
|
||||
p.currentQuantile = math.NaN()
|
||||
p.currentBucket = math.NaN()
|
||||
}
|
||||
if p.currentByte != '{' {
|
||||
return p.readingValue
|
||||
}
|
||||
return p.startLabelName
|
||||
}
|
||||
|
||||
// startLabelName represents the state where the next byte read from p.buf is
|
||||
// the start of a label name (or whitespace leading up to it).
|
||||
func (p *TextParser) startLabelName() stateFn {
|
||||
if p.skipBlankTab(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
if p.currentByte == '}' {
|
||||
if p.skipBlankTab(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
return p.readingValue
|
||||
}
|
||||
if p.readTokenAsLabelName(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
if p.currentToken.Len() == 0 {
|
||||
p.parseError(fmt.Sprintf("invalid label name for metric %q", p.currentMF.GetName()))
|
||||
return nil
|
||||
}
|
||||
p.currentLabelPair = &dto.LabelPair{Name: proto.String(p.currentToken.String())}
|
||||
if p.currentLabelPair.GetName() == string(model.MetricNameLabel) {
|
||||
p.parseError(fmt.Sprintf("label name %q is reserved", model.MetricNameLabel))
|
||||
return nil
|
||||
}
|
||||
// Special summary/histogram treatment. Don't add 'quantile' and 'le'
|
||||
// labels to 'real' labels.
|
||||
if !(p.currentMF.GetType() == dto.MetricType_SUMMARY && p.currentLabelPair.GetName() == model.QuantileLabel) &&
|
||||
!(p.currentMF.GetType() == dto.MetricType_HISTOGRAM && p.currentLabelPair.GetName() == model.BucketLabel) {
|
||||
p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPair)
|
||||
}
|
||||
if p.skipBlankTabIfCurrentBlankTab(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
if p.currentByte != '=' {
|
||||
p.parseError(fmt.Sprintf("expected '=' after label name, found %q", p.currentByte))
|
||||
return nil
|
||||
}
|
||||
return p.startLabelValue
|
||||
}
|
||||
|
||||
// startLabelValue represents the state where the next byte read from p.buf is
|
||||
// the start of a (quoted) label value (or whitespace leading up to it).
|
||||
func (p *TextParser) startLabelValue() stateFn {
|
||||
if p.skipBlankTab(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
if p.currentByte != '"' {
|
||||
p.parseError(fmt.Sprintf("expected '\"' at start of label value, found %q", p.currentByte))
|
||||
return nil
|
||||
}
|
||||
if p.readTokenAsLabelValue(); p.err != nil {
|
||||
return nil
|
||||
}
|
||||
p.currentLabelPair.Value = proto.String(p.currentToken.String())
|
||||
// Special treatment of summaries:
|
||||
// - Quantile labels are special, will result in dto.Quantile later.
|
||||
// - Other labels have to be added to currentLabels for signature calculation.
|
||||
if p.currentMF.GetType() == dto.MetricType_SUMMARY {
|
||||
if p.currentLabelPair.GetName() == model.QuantileLabel {
|
||||
if p.currentQuantile, p.err = strconv.ParseFloat(p.currentLabelPair.GetValue(), 64); p.err != nil {
|
||||
// Create a more helpful error message.
|
||||
p.parseError(fmt.Sprintf("expected float as value for 'quantile' label, got %q", p.currentLabelPair.GetValue()))
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
p.currentLabels[p.currentLabelPair.GetName()] = p.currentLabelPair.GetValue()
|
||||
}
|
||||
}
|
||||
// Similar special treatment of histograms.
|
||||
if p.currentMF.GetType() == dto.MetricType_HISTOGRAM {
|
||||
if p.currentLabelPair.GetName() == model.BucketLabel {
|
||||
if p.currentBucket, p.err = strconv.ParseFloat(p.currentLabelPair.GetValue(), 64); p.err != nil {
|
||||
// Create a more helpful error message.
|
||||
p.parseError(fmt.Sprintf("expected float as value for 'le' label, got %q", p.currentLabelPair.GetValue()))
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
p.currentLabels[p.currentLabelPair.GetName()] = p.currentLabelPair.GetValue()
|
||||
}
|
||||
}
|
||||
if p.skipBlankTab(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
switch p.currentByte {
|
||||
case ',':
|
||||
return p.startLabelName
|
||||
|
||||
case '}':
|
||||
if p.skipBlankTab(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
return p.readingValue
|
||||
default:
|
||||
p.parseError(fmt.Sprintf("unexpected end of label value %q", p.currentLabelPair.Value))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// readingValue represents the state where the last byte read (now in
|
||||
// p.currentByte) is the first byte of the sample value (i.e. a float).
|
||||
func (p *TextParser) readingValue() stateFn {
|
||||
// When we are here, we have read all the labels, so for the
|
||||
// special case of a summary/histogram, we can finally find out
|
||||
// if the metric already exists.
|
||||
if p.currentMF.GetType() == dto.MetricType_SUMMARY {
|
||||
signature := model.LabelsToSignature(p.currentLabels)
|
||||
if summary := p.summaries[signature]; summary != nil {
|
||||
p.currentMetric = summary
|
||||
} else {
|
||||
p.summaries[signature] = p.currentMetric
|
||||
p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric)
|
||||
}
|
||||
} else if p.currentMF.GetType() == dto.MetricType_HISTOGRAM {
|
||||
signature := model.LabelsToSignature(p.currentLabels)
|
||||
if histogram := p.histograms[signature]; histogram != nil {
|
||||
p.currentMetric = histogram
|
||||
} else {
|
||||
p.histograms[signature] = p.currentMetric
|
||||
p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric)
|
||||
}
|
||||
} else {
|
||||
p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric)
|
||||
}
|
||||
if p.readTokenUntilWhitespace(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
value, err := strconv.ParseFloat(p.currentToken.String(), 64)
|
||||
if err != nil {
|
||||
// Create a more helpful error message.
|
||||
p.parseError(fmt.Sprintf("expected float as value, got %q", p.currentToken.String()))
|
||||
return nil
|
||||
}
|
||||
switch p.currentMF.GetType() {
|
||||
case dto.MetricType_COUNTER:
|
||||
p.currentMetric.Counter = &dto.Counter{Value: proto.Float64(value)}
|
||||
case dto.MetricType_GAUGE:
|
||||
p.currentMetric.Gauge = &dto.Gauge{Value: proto.Float64(value)}
|
||||
case dto.MetricType_UNTYPED:
|
||||
p.currentMetric.Untyped = &dto.Untyped{Value: proto.Float64(value)}
|
||||
case dto.MetricType_SUMMARY:
|
||||
// *sigh*
|
||||
if p.currentMetric.Summary == nil {
|
||||
p.currentMetric.Summary = &dto.Summary{}
|
||||
}
|
||||
switch {
|
||||
case p.currentIsSummaryCount:
|
||||
p.currentMetric.Summary.SampleCount = proto.Uint64(uint64(value))
|
||||
case p.currentIsSummarySum:
|
||||
p.currentMetric.Summary.SampleSum = proto.Float64(value)
|
||||
case !math.IsNaN(p.currentQuantile):
|
||||
p.currentMetric.Summary.Quantile = append(
|
||||
p.currentMetric.Summary.Quantile,
|
||||
&dto.Quantile{
|
||||
Quantile: proto.Float64(p.currentQuantile),
|
||||
Value: proto.Float64(value),
|
||||
},
|
||||
)
|
||||
}
|
||||
case dto.MetricType_HISTOGRAM:
|
||||
// *sigh*
|
||||
if p.currentMetric.Histogram == nil {
|
||||
p.currentMetric.Histogram = &dto.Histogram{}
|
||||
}
|
||||
switch {
|
||||
case p.currentIsHistogramCount:
|
||||
p.currentMetric.Histogram.SampleCount = proto.Uint64(uint64(value))
|
||||
case p.currentIsHistogramSum:
|
||||
p.currentMetric.Histogram.SampleSum = proto.Float64(value)
|
||||
case !math.IsNaN(p.currentBucket):
|
||||
p.currentMetric.Histogram.Bucket = append(
|
||||
p.currentMetric.Histogram.Bucket,
|
||||
&dto.Bucket{
|
||||
UpperBound: proto.Float64(p.currentBucket),
|
||||
CumulativeCount: proto.Uint64(uint64(value)),
|
||||
},
|
||||
)
|
||||
}
|
||||
default:
|
||||
p.err = fmt.Errorf("unexpected type for metric name %q", p.currentMF.GetName())
|
||||
}
|
||||
if p.currentByte == '\n' {
|
||||
return p.startOfLine
|
||||
}
|
||||
return p.startTimestamp
|
||||
}
|
||||
|
||||
// startTimestamp represents the state where the next byte read from p.buf is
|
||||
// the start of the timestamp (or whitespace leading up to it).
|
||||
func (p *TextParser) startTimestamp() stateFn {
|
||||
if p.skipBlankTab(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
if p.readTokenUntilWhitespace(); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
timestamp, err := strconv.ParseInt(p.currentToken.String(), 10, 64)
|
||||
if err != nil {
|
||||
// Create a more helpful error message.
|
||||
p.parseError(fmt.Sprintf("expected integer as timestamp, got %q", p.currentToken.String()))
|
||||
return nil
|
||||
}
|
||||
p.currentMetric.TimestampMs = proto.Int64(timestamp)
|
||||
if p.readTokenUntilNewline(false); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
if p.currentToken.Len() > 0 {
|
||||
p.parseError(fmt.Sprintf("spurious string after timestamp: %q", p.currentToken.String()))
|
||||
return nil
|
||||
}
|
||||
return p.startOfLine
|
||||
}
|
||||
|
||||
// readingHelp represents the state where the last byte read (now in
|
||||
// p.currentByte) is the first byte of the docstring after 'HELP'.
|
||||
func (p *TextParser) readingHelp() stateFn {
|
||||
if p.currentMF.Help != nil {
|
||||
p.parseError(fmt.Sprintf("second HELP line for metric name %q", p.currentMF.GetName()))
|
||||
return nil
|
||||
}
|
||||
// Rest of line is the docstring.
|
||||
if p.readTokenUntilNewline(true); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
p.currentMF.Help = proto.String(p.currentToken.String())
|
||||
return p.startOfLine
|
||||
}
|
||||
|
||||
// readingType represents the state where the last byte read (now in
|
||||
// p.currentByte) is the first byte of the type hint after 'HELP'.
|
||||
func (p *TextParser) readingType() stateFn {
|
||||
if p.currentMF.Type != nil {
|
||||
p.parseError(fmt.Sprintf("second TYPE line for metric name %q, or TYPE reported after samples", p.currentMF.GetName()))
|
||||
return nil
|
||||
}
|
||||
// Rest of line is the type.
|
||||
if p.readTokenUntilNewline(false); p.err != nil {
|
||||
return nil // Unexpected end of input.
|
||||
}
|
||||
metricType, ok := dto.MetricType_value[strings.ToUpper(p.currentToken.String())]
|
||||
if !ok {
|
||||
p.parseError(fmt.Sprintf("unknown metric type %q", p.currentToken.String()))
|
||||
return nil
|
||||
}
|
||||
p.currentMF.Type = dto.MetricType(metricType).Enum()
|
||||
return p.startOfLine
|
||||
}
|
||||
|
||||
// parseError sets p.err to a ParseError at the current line with the given
|
||||
// message.
|
||||
func (p *TextParser) parseError(msg string) {
|
||||
p.err = ParseError{
|
||||
Line: p.lineCount,
|
||||
Msg: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// skipBlankTab reads (and discards) bytes from p.buf until it encounters a byte
|
||||
// that is neither ' ' nor '\t'. That byte is left in p.currentByte.
|
||||
func (p *TextParser) skipBlankTab() {
|
||||
for {
|
||||
if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil || !isBlankOrTab(p.currentByte) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// skipBlankTabIfCurrentBlankTab works exactly as skipBlankTab but doesn't do
|
||||
// anything if p.currentByte is neither ' ' nor '\t'.
|
||||
func (p *TextParser) skipBlankTabIfCurrentBlankTab() {
|
||||
if isBlankOrTab(p.currentByte) {
|
||||
p.skipBlankTab()
|
||||
}
|
||||
}
|
||||
|
||||
// readTokenUntilWhitespace copies bytes from p.buf into p.currentToken. The
|
||||
// first byte considered is the byte already read (now in p.currentByte). The
|
||||
// first whitespace byte encountered is still copied into p.currentByte, but not
|
||||
// into p.currentToken.
|
||||
func (p *TextParser) readTokenUntilWhitespace() {
|
||||
p.currentToken.Reset()
|
||||
for p.err == nil && !isBlankOrTab(p.currentByte) && p.currentByte != '\n' {
|
||||
p.currentToken.WriteByte(p.currentByte)
|
||||
p.currentByte, p.err = p.buf.ReadByte()
|
||||
}
|
||||
}
|
||||
|
||||
// readTokenUntilNewline copies bytes from p.buf into p.currentToken. The first
|
||||
// byte considered is the byte already read (now in p.currentByte). The first
|
||||
// newline byte encountered is still copied into p.currentByte, but not into
|
||||
// p.currentToken. If recognizeEscapeSequence is true, two escape sequences are
|
||||
// recognized: '\\' tranlates into '\', and '\n' into a line-feed character. All
|
||||
// other escape sequences are invalid and cause an error.
|
||||
func (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) {
|
||||
p.currentToken.Reset()
|
||||
escaped := false
|
||||
for p.err == nil {
|
||||
if recognizeEscapeSequence && escaped {
|
||||
switch p.currentByte {
|
||||
case '\\':
|
||||
p.currentToken.WriteByte(p.currentByte)
|
||||
case 'n':
|
||||
p.currentToken.WriteByte('\n')
|
||||
default:
|
||||
p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte))
|
||||
return
|
||||
}
|
||||
escaped = false
|
||||
} else {
|
||||
switch p.currentByte {
|
||||
case '\n':
|
||||
return
|
||||
case '\\':
|
||||
escaped = true
|
||||
default:
|
||||
p.currentToken.WriteByte(p.currentByte)
|
||||
}
|
||||
}
|
||||
p.currentByte, p.err = p.buf.ReadByte()
|
||||
}
|
||||
}
|
||||
|
||||
// readTokenAsMetricName copies a metric name from p.buf into p.currentToken.
|
||||
// The first byte considered is the byte already read (now in p.currentByte).
|
||||
// The first byte not part of a metric name is still copied into p.currentByte,
|
||||
// but not into p.currentToken.
|
||||
func (p *TextParser) readTokenAsMetricName() {
|
||||
p.currentToken.Reset()
|
||||
if !isValidMetricNameStart(p.currentByte) {
|
||||
return
|
||||
}
|
||||
for {
|
||||
p.currentToken.WriteByte(p.currentByte)
|
||||
p.currentByte, p.err = p.buf.ReadByte()
|
||||
if p.err != nil || !isValidMetricNameContinuation(p.currentByte) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// readTokenAsLabelName copies a label name from p.buf into p.currentToken.
|
||||
// The first byte considered is the byte already read (now in p.currentByte).
|
||||
// The first byte not part of a label name is still copied into p.currentByte,
|
||||
// but not into p.currentToken.
|
||||
func (p *TextParser) readTokenAsLabelName() {
|
||||
p.currentToken.Reset()
|
||||
if !isValidLabelNameStart(p.currentByte) {
|
||||
return
|
||||
}
|
||||
for {
|
||||
p.currentToken.WriteByte(p.currentByte)
|
||||
p.currentByte, p.err = p.buf.ReadByte()
|
||||
if p.err != nil || !isValidLabelNameContinuation(p.currentByte) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// readTokenAsLabelValue copies a label value from p.buf into p.currentToken.
|
||||
// In contrast to the other 'readTokenAs...' functions, which start with the
|
||||
// last read byte in p.currentByte, this method ignores p.currentByte and starts
|
||||
// with reading a new byte from p.buf. The first byte not part of a label value
|
||||
// is still copied into p.currentByte, but not into p.currentToken.
|
||||
func (p *TextParser) readTokenAsLabelValue() {
|
||||
p.currentToken.Reset()
|
||||
escaped := false
|
||||
for {
|
||||
if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil {
|
||||
return
|
||||
}
|
||||
if escaped {
|
||||
switch p.currentByte {
|
||||
case '"', '\\':
|
||||
p.currentToken.WriteByte(p.currentByte)
|
||||
case 'n':
|
||||
p.currentToken.WriteByte('\n')
|
||||
default:
|
||||
p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte))
|
||||
return
|
||||
}
|
||||
escaped = false
|
||||
continue
|
||||
}
|
||||
switch p.currentByte {
|
||||
case '"':
|
||||
return
|
||||
case '\n':
|
||||
p.parseError(fmt.Sprintf("label value %q contains unescaped new-line", p.currentToken.String()))
|
||||
return
|
||||
case '\\':
|
||||
escaped = true
|
||||
default:
|
||||
p.currentToken.WriteByte(p.currentByte)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *TextParser) setOrCreateCurrentMF() {
|
||||
p.currentIsSummaryCount = false
|
||||
p.currentIsSummarySum = false
|
||||
p.currentIsHistogramCount = false
|
||||
p.currentIsHistogramSum = false
|
||||
name := p.currentToken.String()
|
||||
if p.currentMF = p.metricFamiliesByName[name]; p.currentMF != nil {
|
||||
return
|
||||
}
|
||||
// Try out if this is a _sum or _count for a summary/histogram.
|
||||
summaryName := summaryMetricName(name)
|
||||
if p.currentMF = p.metricFamiliesByName[summaryName]; p.currentMF != nil {
|
||||
if p.currentMF.GetType() == dto.MetricType_SUMMARY {
|
||||
if isCount(name) {
|
||||
p.currentIsSummaryCount = true
|
||||
}
|
||||
if isSum(name) {
|
||||
p.currentIsSummarySum = true
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
histogramName := histogramMetricName(name)
|
||||
if p.currentMF = p.metricFamiliesByName[histogramName]; p.currentMF != nil {
|
||||
if p.currentMF.GetType() == dto.MetricType_HISTOGRAM {
|
||||
if isCount(name) {
|
||||
p.currentIsHistogramCount = true
|
||||
}
|
||||
if isSum(name) {
|
||||
p.currentIsHistogramSum = true
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
p.currentMF = &dto.MetricFamily{Name: proto.String(name)}
|
||||
p.metricFamiliesByName[name] = p.currentMF
|
||||
}
|
||||
|
||||
func isValidLabelNameStart(b byte) bool {
|
||||
return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_'
|
||||
}
|
||||
|
||||
func isValidLabelNameContinuation(b byte) bool {
|
||||
return isValidLabelNameStart(b) || (b >= '0' && b <= '9')
|
||||
}
|
||||
|
||||
func isValidMetricNameStart(b byte) bool {
|
||||
return isValidLabelNameStart(b) || b == ':'
|
||||
}
|
||||
|
||||
func isValidMetricNameContinuation(b byte) bool {
|
||||
return isValidLabelNameContinuation(b) || b == ':'
|
||||
}
|
||||
|
||||
func isBlankOrTab(b byte) bool {
|
||||
return b == ' ' || b == '\t'
|
||||
}
|
||||
|
||||
func isCount(name string) bool {
|
||||
return len(name) > 6 && name[len(name)-6:] == "_count"
|
||||
}
|
||||
|
||||
func isSum(name string) bool {
|
||||
return len(name) > 4 && name[len(name)-4:] == "_sum"
|
||||
}
|
||||
|
||||
func isBucket(name string) bool {
|
||||
return len(name) > 7 && name[len(name)-7:] == "_bucket"
|
||||
}
|
||||
|
||||
func summaryMetricName(name string) string {
|
||||
switch {
|
||||
case isCount(name):
|
||||
return name[:len(name)-6]
|
||||
case isSum(name):
|
||||
return name[:len(name)-4]
|
||||
default:
|
||||
return name
|
||||
}
|
||||
}
|
||||
|
||||
func histogramMetricName(name string) string {
|
||||
switch {
|
||||
case isCount(name):
|
||||
return name[:len(name)-6]
|
||||
case isSum(name):
|
||||
return name[:len(name)-4]
|
||||
case isBucket(name):
|
||||
return name[:len(name)-7]
|
||||
default:
|
||||
return name
|
||||
}
|
||||
}
|
586
Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_parse_test.go
generated
vendored
Normal file
586
Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_parse_test.go
generated
vendored
Normal file
|
@ -0,0 +1,586 @@
|
|||
// 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`,
|
||||
err: "EOF",
|
||||
},
|
||||
// 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",
|
||||
},
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue