Merge pull request #172 from prometheus/move-to-common
Move from client_golang/text to common/expfmt
This commit is contained in:
commit
13985ab413
|
@ -33,12 +33,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"bitbucket.org/ww/goautoneg"
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
"github.com/prometheus/common/expfmt"
|
||||||
|
|
||||||
dto "github.com/prometheus/client_model/go"
|
dto "github.com/prometheus/client_model/go"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/text"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -345,7 +343,7 @@ func (r *registry) Push(job, instance, pushURL, method string) error {
|
||||||
}
|
}
|
||||||
buf := r.getBuf()
|
buf := r.getBuf()
|
||||||
defer r.giveBuf(buf)
|
defer r.giveBuf(buf)
|
||||||
if _, err := r.writePB(buf, text.WriteProtoDelimited); err != nil {
|
if err := r.writePB(expfmt.NewEncoder(buf, expfmt.FmtProtoDelim)); err != nil {
|
||||||
if r.panicOnCollectError {
|
if r.panicOnCollectError {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -368,11 +366,11 @@ func (r *registry) Push(job, instance, pushURL, method string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *registry) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (r *registry) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
enc, contentType := chooseEncoder(req)
|
contentType := expfmt.Negotiate(req.Header)
|
||||||
buf := r.getBuf()
|
buf := r.getBuf()
|
||||||
defer r.giveBuf(buf)
|
defer r.giveBuf(buf)
|
||||||
writer, encoding := decorateWriter(req, buf)
|
writer, encoding := decorateWriter(req, buf)
|
||||||
if _, err := r.writePB(writer, enc); err != nil {
|
if err := r.writePB(expfmt.NewEncoder(writer, contentType)); err != nil {
|
||||||
if r.panicOnCollectError {
|
if r.panicOnCollectError {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -383,7 +381,7 @@ func (r *registry) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
closer.Close()
|
closer.Close()
|
||||||
}
|
}
|
||||||
header := w.Header()
|
header := w.Header()
|
||||||
header.Set(contentTypeHeader, contentType)
|
header.Set(contentTypeHeader, string(contentType))
|
||||||
header.Set(contentLengthHeader, fmt.Sprint(buf.Len()))
|
header.Set(contentLengthHeader, fmt.Sprint(buf.Len()))
|
||||||
if encoding != "" {
|
if encoding != "" {
|
||||||
header.Set(contentEncodingHeader, encoding)
|
header.Set(contentEncodingHeader, encoding)
|
||||||
|
@ -391,7 +389,7 @@ func (r *registry) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
w.Write(buf.Bytes())
|
w.Write(buf.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *registry) writePB(w io.Writer, writeEncoded encoder) (int, error) {
|
func (r *registry) writePB(encoder expfmt.Encoder) error {
|
||||||
var metricHashes map[uint64]struct{}
|
var metricHashes map[uint64]struct{}
|
||||||
if r.collectChecksEnabled {
|
if r.collectChecksEnabled {
|
||||||
metricHashes = make(map[uint64]struct{})
|
metricHashes = make(map[uint64]struct{})
|
||||||
|
@ -443,7 +441,7 @@ func (r *registry) writePB(w io.Writer, writeEncoded encoder) (int, error) {
|
||||||
// TODO: Consider different means of error reporting so
|
// TODO: Consider different means of error reporting so
|
||||||
// that a single erroneous metric could be skipped
|
// that a single erroneous metric could be skipped
|
||||||
// instead of blowing up the whole collection.
|
// instead of blowing up the whole collection.
|
||||||
return 0, fmt.Errorf("error collecting metric %v: %s", desc, err)
|
return fmt.Errorf("error collecting metric %v: %s", desc, err)
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
case metricFamily.Type != nil:
|
case metricFamily.Type != nil:
|
||||||
|
@ -459,11 +457,11 @@ func (r *registry) writePB(w io.Writer, writeEncoded encoder) (int, error) {
|
||||||
case dtoMetric.Histogram != nil:
|
case dtoMetric.Histogram != nil:
|
||||||
metricFamily.Type = dto.MetricType_HISTOGRAM.Enum()
|
metricFamily.Type = dto.MetricType_HISTOGRAM.Enum()
|
||||||
default:
|
default:
|
||||||
return 0, fmt.Errorf("empty metric collected: %s", dtoMetric)
|
return fmt.Errorf("empty metric collected: %s", dtoMetric)
|
||||||
}
|
}
|
||||||
if r.collectChecksEnabled {
|
if r.collectChecksEnabled {
|
||||||
if err := r.checkConsistency(metricFamily, dtoMetric, desc, metricHashes); err != nil {
|
if err := r.checkConsistency(metricFamily, dtoMetric, desc, metricHashes); err != nil {
|
||||||
return 0, err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
metricFamily.Metric = append(metricFamily.Metric, dtoMetric)
|
metricFamily.Metric = append(metricFamily.Metric, dtoMetric)
|
||||||
|
@ -477,7 +475,7 @@ func (r *registry) writePB(w io.Writer, writeEncoded encoder) (int, error) {
|
||||||
if r.collectChecksEnabled {
|
if r.collectChecksEnabled {
|
||||||
for _, m := range mf.Metric {
|
for _, m := range mf.Metric {
|
||||||
if err := r.checkConsistency(mf, m, nil, metricHashes); err != nil {
|
if err := r.checkConsistency(mf, m, nil, metricHashes); err != nil {
|
||||||
return 0, err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -486,7 +484,7 @@ func (r *registry) writePB(w io.Writer, writeEncoded encoder) (int, error) {
|
||||||
for _, m := range mf.Metric {
|
for _, m := range mf.Metric {
|
||||||
if r.collectChecksEnabled {
|
if r.collectChecksEnabled {
|
||||||
if err := r.checkConsistency(existingMF, m, nil, metricHashes); err != nil {
|
if err := r.checkConsistency(existingMF, m, nil, metricHashes); err != nil {
|
||||||
return 0, err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
existingMF.Metric = append(existingMF.Metric, m)
|
existingMF.Metric = append(existingMF.Metric, m)
|
||||||
|
@ -507,15 +505,12 @@ func (r *registry) writePB(w io.Writer, writeEncoded encoder) (int, error) {
|
||||||
}
|
}
|
||||||
sort.Strings(names)
|
sort.Strings(names)
|
||||||
|
|
||||||
var written int
|
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
w, err := writeEncoded(w, metricFamiliesByName[name])
|
if err := encoder.Encode(metricFamiliesByName[name]); err != nil {
|
||||||
written += w
|
return err
|
||||||
if err != nil {
|
|
||||||
return written, err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return written, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *registry) checkConsistency(metricFamily *dto.MetricFamily, dtoMetric *dto.Metric, desc *Desc, metricHashes map[uint64]struct{}) error {
|
func (r *registry) checkConsistency(metricFamily *dto.MetricFamily, dtoMetric *dto.Metric, desc *Desc, metricHashes map[uint64]struct{}) error {
|
||||||
|
@ -685,34 +680,6 @@ func newDefaultRegistry() *registry {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func chooseEncoder(req *http.Request) (encoder, string) {
|
|
||||||
accepts := goautoneg.ParseAccept(req.Header.Get(acceptHeader))
|
|
||||||
for _, accept := range accepts {
|
|
||||||
switch {
|
|
||||||
case accept.Type == "application" &&
|
|
||||||
accept.SubType == "vnd.google.protobuf" &&
|
|
||||||
accept.Params["proto"] == "io.prometheus.client.MetricFamily":
|
|
||||||
switch accept.Params["encoding"] {
|
|
||||||
case "delimited":
|
|
||||||
return text.WriteProtoDelimited, DelimitedTelemetryContentType
|
|
||||||
case "text":
|
|
||||||
return text.WriteProtoText, ProtoTextTelemetryContentType
|
|
||||||
case "compact-text":
|
|
||||||
return text.WriteProtoCompactText, ProtoCompactTextTelemetryContentType
|
|
||||||
default:
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
case accept.Type == "text" &&
|
|
||||||
accept.SubType == "plain" &&
|
|
||||||
(accept.Params["version"] == "0.0.4" || accept.Params["version"] == ""):
|
|
||||||
return text.MetricFamilyToText, TextTelemetryContentType
|
|
||||||
default:
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return text.MetricFamilyToText, TextTelemetryContentType
|
|
||||||
}
|
|
||||||
|
|
||||||
// decorateWriter wraps a writer to handle gzip compression if requested. It
|
// decorateWriter wraps a writer to handle gzip compression if requested. It
|
||||||
// returns the decorated writer and the appropriate "Content-Encoding" header
|
// returns the decorated writer and the appropriate "Content-Encoding" header
|
||||||
// (which is empty if no compression is enabled).
|
// (which is empty if no compression is enabled).
|
||||||
|
|
Loading…
Reference in New Issue