From 849d859db4b883c7f40b220468d2cd15ca3a591c Mon Sep 17 00:00:00 2001 From: Bjoern Rabenstein Date: Tue, 27 Jan 2015 16:27:04 +0100 Subject: [PATCH] Add benchmarks to compare text and protobuf parsing. --- text/bench_test.go | 165 +++++++++++++++++++ text/testdata/protobuf | Bin 0 -> 8243 bytes text/testdata/protobuf.gz | Bin 0 -> 2053 bytes text/testdata/text | 322 ++++++++++++++++++++++++++++++++++++++ text/testdata/text.gz | Bin 0 -> 2595 bytes 5 files changed, 487 insertions(+) create mode 100644 text/bench_test.go create mode 100644 text/testdata/protobuf create mode 100644 text/testdata/protobuf.gz create mode 100644 text/testdata/text create mode 100644 text/testdata/text.gz diff --git a/text/bench_test.go b/text/bench_test.go new file mode 100644 index 0000000..806551e --- /dev/null +++ b/text/bench_test.go @@ -0,0 +1,165 @@ +// 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 text + +import ( + "bytes" + "compress/gzip" + "io" + "io/ioutil" + "testing" + + dto "github.com/prometheus/client_model/go" + + "github.com/matttproud/golang_protobuf_extensions/ext" +) + +// Benchmarks to show how much penalty text format parsing accually inflicts. +// +// Example results on Linux 3.13.0, Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz, go1.4. +// +// BenchmarkParseText 1000 1188535 ns/op 205085 B/op 6135 allocs/op +// BenchmarkParseTextGzip 1000 1376567 ns/op 246224 B/op 6151 allocs/op +// BenchmarkParseProto 10000 172790 ns/op 52258 B/op 1160 allocs/op +// BenchmarkParseProtoGzip 5000 324021 ns/op 94931 B/op 1211 allocs/op +// BenchmarkParseProtoMap 10000 187946 ns/op 58714 B/op 1203 allocs/op +// +// CONCLUSION: The overhead for the map is negligible. Text format needs ~5x more allocations. +// Without compression, it needs ~7x longer, but with compression (the more relevant scenario), +// the difference becomes less relevant, only ~4x. +// +// The test data contains 248 samples. + +// BenchmarkParseText benchmarks the parsing of a text-format scrape into metric +// family DTOs. +func BenchmarkParseText(b *testing.B) { + b.StopTimer() + data, err := ioutil.ReadFile("testdata/text") + if err != nil { + b.Fatal(err) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + if _, err := parser.TextToMetricFamilies(bytes.NewReader(data)); err != nil { + b.Fatal(err) + } + } +} + +// BenchmarkParseTextGzip benchmarks the parsing of a gzipped text-format scrape +// into metric family DTOs. +func BenchmarkParseTextGzip(b *testing.B) { + b.StopTimer() + data, err := ioutil.ReadFile("testdata/text.gz") + if err != nil { + b.Fatal(err) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + in, err := gzip.NewReader(bytes.NewReader(data)) + if err != nil { + b.Fatal(err) + } + if _, err := parser.TextToMetricFamilies(in); err != nil { + b.Fatal(err) + } + } +} + +// BenchmarkParseProto benchmarks the parsinge of a protobuf-format scrape into +// metric family DTOs. Note that this does not build a map of matric 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 := ext.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 := ext.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 := ext.ReadDelimited(in, family); err != nil { + if err == io.EOF { + break + } + b.Fatal(err) + } + families[family.GetName()] = family + } + } +} diff --git a/text/testdata/protobuf b/text/testdata/protobuf new file mode 100644 index 0000000000000000000000000000000000000000..df48256390c4f08c38e03f14d6cb90c8f5a96137 GIT binary patch literal 8243 zcmeHMO^h5z74BI(_G~#2yW`-+u|v5bcx}8h>yTg(;%u)Rln@dp!G?ewX!my4%rx86 z-RY{1cN`8I;J|?>NC=`JL@WgIATV3bDwzbDnzy0>C{Og^i>e$?oxx7`$?ZnPfvrjn4kB_G(A$Y7DOXWV?w7GQcs~hrL}f+`?;SD zre~vbXm=_7rtX0F+4O{e4c%G_Z+9t!%nhb!8q@e$ojX?|=S%KDLq1-M@Wo$8*do_>e}|zP}gJ57S3=}G@8Z?)f&$5RqmTt zIDYUyElcx;#hj0A;EZ@D$IN7av2UPTt1v@7mNGxKKYEt`hm&HsLUNq;42DDT&<{yx z&T{TYyU_L^4T-(&uEj;8e3yGgA3!@eJf@+&4NBntS-IQwN8PJ!G^e!F4C)v0DkyiT zf^zaL-hw%B<(OyXnCV#<+k!bB_wUzQTXd@0T>M|@6nEo0zj$vP=I(xZ9Ol}W_?Vdt z=#u*s`Y-@eKq&QstngIxroe7df?YuY>Yy{jbVL~$;!}@*5wmDWFwIE9cr&M#apc4Sa@!BF{l&Ji=rxqO3F5a(3AY7Of}T zhtVxs-q2t3deCLgKkBbV!(v!L

&=dr?eqNNA8p8B23&in{EcLc6snK3~Yf<;HG6 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 literal 0 HcmV?d00001 diff --git a/text/testdata/text b/text/testdata/text new file mode 100644 index 0000000..1b2b302 --- /dev/null +++ b/text/testdata/text @@ -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 process_goroutines Number of goroutines that currently exist. +# TYPE process_goroutines gauge +process_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 diff --git a/text/testdata/text.gz b/text/testdata/text.gz new file mode 100644 index 0000000000000000000000000000000000000000..46de5995ad79083b3e4a47f74936ac9382bc4ee5 GIT binary patch literal 2595 zcmV+;3f%P{iwFoRp~qAJ19WA0bO5zmU6Y$Q7Jctuq3U^=sZBg!8{0he!&D|!^Dvvr zZhE(Bo+ujBHWds6#H77l^WXPMh&CSrT?tPfk~HWXu8yRudj$Oh`R(KHpUH`_A}Hy% znpP}`>oR0Xo(1P5D)Wj)c@|gX@kGgQkB^^;Y(~hn1)FL(N;uct7JQ(8XU|9t=MTODRBN$JDAv-0l$BF+*5e=z};A%O07S&*nGuQO(j z>mWk-hgFMpQ_)zcr=+peP;yx+X@u_Lisa`rWn~iGK-4KN8)YZCY~}3`+G=b}F#to$ z@^TZI6-<^QtC$u@+|Vr$*n~g@4azV((%Xrw;#(rMl5eTtl60x;Ml=Hg7M4ePi_AR5 zWhuIvYk}Y`;R3PEC^}&Hxyn;oEiW7(g{&$T zOGz6lOF2!z9oUJ6#bPDLBo;y{NGx>}OqMblU^}Ra!R=`IYFF}DXsPD0l(QwXRMZT9 z1r}uvMcj$jioMF+IQ!Ll@7;uu%iOdxk_}6~P&?NkP;OYDNzoz`|$Y!B|ny zj%reuNgp&L4FZEROl#k@C-4^&Xc%S;&}O?m9I$#}oK6+6oP{ZQ6n|&+`H7Y!f9^S+ zik!okDveGH7f+_;o#NhWl*iERwd35sQ%b}ClgAJDu!kt)tP04Sbi$G~H#MGY%rG!z zqXsxvhKKo&h=>3i+chf&BMA|P4I`hz zdEunP01Z8x1s*LK%C+ePQyMV6TsWA4aWllCMbcU~oj@ZerWZ#K!MiszC|VYsf77Wl z^kaHav$XN*QGgD`PAaTJbBuMY-<^l{GCUqB&znByImP&6F7EmE+SM- zG~zI6k{C1#&h(r^E!3FXf6J?+xhl-@*c;Dt^g~d$@m8C|-tqi3{fDz3h6angWC5RM z?ff8L_@!p%fhI7K+r|)K7Ew}X$qS)H9-Zdqq=L8~tfGOt+OF4|-ND};Ham!RB;=n- z$?7oe_wT>WMVyREhJIkmCf;i6ZubY@h)3QL=l$J;%lU>F*wNp=&v19AS=VH;wR|< z-@2YDyw0vq){SG5#ZZ7{$KWYs(J5$t&FIpf4gZo0v=UiTG$bu<_=`zbn0|aQ&sJnn zW0LvYwv5idG2L=Lkr5YCG%3r8GOT)1XpqC*=1qVZ1-Edq2tU(b%|O@)2gek|0d>K2mV`aZrWlBBgViv1~zF z2&N}Wa_ufWf!jFSy}ss3GN|5?I4DY*=3zW~bFJu^YHI)jHOivo$`BSk}~3WQMl-poEuyZ_IjM|Hr)S#9?F8;~_e#+#M5@o&K<=yvPf zYP;Lm@ii5L1H-$T^%k=nvVz#-r--72keP8%NJs#-j+o%rO!WyAtW?t;b!v#o6xEgz zuy7am5LZwrG5RFbEPaiwm-)fo*N>i}-5iIAp|hVUfG42mFo8#AVHWYNSEfGkrbQuA zmb2tp)(Dl_r~cktB;R`Gr=pqIj>Kn1q(=iDDCdVk?T!_fc~QWY)oY~Omk`k?a-kkI zZ<7u2BOhyuw;&ihUj(MfWU8gn2O}(yYLq9}_$>QqbGb~fCu&~_)A$1DZ8VQXlDCqq6>I+Si%&LP2WB)_$3lw3ADGN z_NDAQ? z{(8`ap~;dXj