From 03369306e0224073b78b6bcf061b49669bb2742e Mon Sep 17 00:00:00 2001 From: "Matt T. Proud" Date: Wed, 26 Jun 2013 13:25:10 +0200 Subject: [PATCH] Provide Discriminator For Protocol Buf. Streams This commit introduces an incomplete processor that decodes varint record length-delimited streams of io.prometheus.client.MetricFamily Protocol Buffer messages. The Go client presently does not support generation of said messages, but this will unblock a number of Java changes. --- extraction/discriminator.go | 46 ++++++++++++++++++----------- extraction/discriminator_test.go | 15 ++++++++++ extraction/metricfamilyprocessor.go | 31 +++++++++++++++++++ extraction/processor0_0_2.go | 2 +- 4 files changed, 75 insertions(+), 19 deletions(-) create mode 100644 extraction/metricfamilyprocessor.go diff --git a/extraction/discriminator.go b/extraction/discriminator.go index 458d150..e0964d8 100644 --- a/extraction/discriminator.go +++ b/extraction/discriminator.go @@ -31,24 +31,34 @@ func ProcessorForRequestHeader(header http.Header) (Processor, error) { if err != nil { return nil, fmt.Errorf("Invalid Content-Type header %q: %s", header.Get("Content-Type"), err) } - if mediatype != "application/json" { + switch mediatype { + case "application/vnd.google.protobuf": + if params["proto"] != "io.prometheus.client.MetricFamily" { + return nil, fmt.Errorf("Unrecognized Protocol Message %s", params["proto"]) + } + if params["encoding"] != "varint record length-delimited" { + return nil, fmt.Errorf("Unsupported Encoding %s", params["encoding"]) + } + return MetricFamilyProcessor, nil + + case "application/json": + var prometheusApiVersion string + + if params["schema"] == "prometheus/telemetry" && params["version"] != "" { + prometheusApiVersion = params["version"] + } else { + prometheusApiVersion = header.Get("X-Prometheus-API-Version") + } + + switch prometheusApiVersion { + case "0.0.2": + return Processor002, nil + case "0.0.1": + return Processor001, nil + default: + return nil, fmt.Errorf("Unrecognized API version %s", prometheusApiVersion) + } + default: return nil, fmt.Errorf("Unsupported media type %q, expected %q", mediatype, "application/json") } - - var prometheusApiVersion string - - if params["schema"] == "prometheus/telemetry" && params["version"] != "" { - prometheusApiVersion = params["version"] - } else { - prometheusApiVersion = header.Get("X-Prometheus-API-Version") - } - - switch prometheusApiVersion { - case "0.0.2": - return Processor002, nil - case "0.0.1": - return Processor001, nil - default: - return nil, fmt.Errorf("Unrecognized API version %s", prometheusApiVersion) - } } diff --git a/extraction/discriminator_test.go b/extraction/discriminator_test.go index c7a0936..3e2e1a2 100644 --- a/extraction/discriminator_test.go +++ b/extraction/discriminator_test.go @@ -56,6 +56,21 @@ func testDiscriminatorHttpHeader(t test.Tester) { output: Processor002, err: nil, }, + { + input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="io.prometheus.client.MetricFamily"; encoding="varint record length-delimited"`}, + output: MetricFamilyProcessor, + err: nil, + }, + { + input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="illegal"; encoding="varint record length-delimited"`}, + output: nil, + err: fmt.Errorf("Unrecognized Protocol Message illegal"), + }, + { + input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="io.prometheus.client.MetricFamily"; encoding="illegal"`}, + output: nil, + err: fmt.Errorf("Unsupported Encoding illegal"), + }, } for i, scenario := range scenarios { diff --git a/extraction/metricfamilyprocessor.go b/extraction/metricfamilyprocessor.go new file mode 100644 index 0000000..ec54d5a --- /dev/null +++ b/extraction/metricfamilyprocessor.go @@ -0,0 +1,31 @@ +// Copyright 2013 Prometheus Team +// 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 extraction + +import ( + "io" +) + +type metricFamilyProcessor struct{} + +// MetricFamilyProcessor decodes varint encoded record length-delimited streams +// of io.prometheus.client.MetricFamily. +// +// See http://godoc.org/github.com/matttproud/golang_protobuf_extensions/ext for +// more details. +var MetricFamilyProcessor = new(metricFamilyProcessor) + +func (m *metricFamilyProcessor) ProcessSingle(io.Reader, chan<- *Result, *ProcessOptions) error { + panic("not implemented") +} diff --git a/extraction/processor0_0_2.go b/extraction/processor0_0_2.go index 42a94e7..2c7b566 100644 --- a/extraction/processor0_0_2.go +++ b/extraction/processor0_0_2.go @@ -23,7 +23,7 @@ import ( // Processor002 is responsible for decoding payloads from protocol version // 0.0.2. -var Processor002 = &processor002{} +var Processor002 = new(processor002) type histogram002 struct { Labels map[string]string `json:"labels"`