1 // Copyright 2015 The Prometheus Authors
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
21 "github.com/golang/protobuf/proto"
22 "github.com/matttproud/golang_protobuf_extensions/pbutil"
23 "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg"
25 dto "github.com/prometheus/client_model/go"
28 // Encoder types encode metric families into an underlying wire protocol.
29 type Encoder interface {
30 Encode(*dto.MetricFamily) error
33 type encoder func(*dto.MetricFamily) error
35 func (e encoder) Encode(v *dto.MetricFamily) error {
39 // Negotiate returns the Content-Type based on the given Accept header.
40 // If no appropriate accepted type is found, FmtText is returned.
41 func Negotiate(h http.Header) Format {
42 for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) {
43 // Check for protocol buffer
44 if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol {
45 switch ac.Params["encoding"] {
51 return FmtProtoCompact
54 // Check for text format.
55 ver := ac.Params["version"]
56 if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") {
63 // NewEncoder returns a new encoder based on content type negotiation.
64 func NewEncoder(w io.Writer, format Format) Encoder {
67 return encoder(func(v *dto.MetricFamily) error {
68 _, err := pbutil.WriteDelimited(w, v)
72 return encoder(func(v *dto.MetricFamily) error {
73 _, err := fmt.Fprintln(w, v.String())
77 return encoder(func(v *dto.MetricFamily) error {
78 _, err := fmt.Fprintln(w, proto.MarshalTextString(v))
82 return encoder(func(v *dto.MetricFamily) error {
83 _, err := MetricFamilyToText(w, v)
87 panic("expfmt.NewEncoder: unknown format")