package expfmt
import (
"fmt"
"io"
"net/http"
"google.golang.org/protobuf/encoding/protodelim"
"google.golang.org/protobuf/encoding/prototext"
"github.com/prometheus/common/model"
"github.com/munnerz/goautoneg"
dto "github.com/prometheus/client_model/go"
)
type Encoder interface {
Encode (*dto .MetricFamily ) error
}
type Closer interface {
Close () error
}
type encoderCloser struct {
encode func (*dto .MetricFamily ) error
close func () error
}
func (ec encoderCloser ) Encode (v *dto .MetricFamily ) error {
return ec .encode (v )
}
func (ec encoderCloser ) Close () error {
return ec .close ()
}
func Negotiate (h http .Header ) Format {
escapingScheme := Format (fmt .Sprintf ("; escaping=%s" , Format (model .NameEscapingScheme .String ())))
for _ , ac := range goautoneg .ParseAccept (h .Get (hdrAccept )) {
if escapeParam := ac .Params [model .EscapingKey ]; escapeParam != "" {
switch Format (escapeParam ) {
case model .AllowUTF8 , model .EscapeUnderscores , model .EscapeDots , model .EscapeValues :
escapingScheme = Format ("; escaping=" + escapeParam )
default :
}
}
ver := ac .Params ["version" ]
if ac .Type +"/" +ac .SubType == ProtoType && ac .Params ["proto" ] == ProtoProtocol {
switch ac .Params ["encoding" ] {
case "delimited" :
return FmtProtoDelim + escapingScheme
case "text" :
return FmtProtoText + escapingScheme
case "compact-text" :
return FmtProtoCompact + escapingScheme
}
}
if ac .Type == "text" && ac .SubType == "plain" && (ver == TextVersion || ver == "" ) {
return FmtText + escapingScheme
}
}
return FmtText + escapingScheme
}
func NegotiateIncludingOpenMetrics (h http .Header ) Format {
escapingScheme := Format (fmt .Sprintf ("; escaping=%s" , Format (model .NameEscapingScheme .String ())))
for _ , ac := range goautoneg .ParseAccept (h .Get (hdrAccept )) {
if escapeParam := ac .Params [model .EscapingKey ]; escapeParam != "" {
switch Format (escapeParam ) {
case model .AllowUTF8 , model .EscapeUnderscores , model .EscapeDots , model .EscapeValues :
escapingScheme = Format ("; escaping=" + escapeParam )
default :
}
}
ver := ac .Params ["version" ]
if ac .Type +"/" +ac .SubType == ProtoType && ac .Params ["proto" ] == ProtoProtocol {
switch ac .Params ["encoding" ] {
case "delimited" :
return FmtProtoDelim + escapingScheme
case "text" :
return FmtProtoText + escapingScheme
case "compact-text" :
return FmtProtoCompact + escapingScheme
}
}
if ac .Type == "text" && ac .SubType == "plain" && (ver == TextVersion || ver == "" ) {
return FmtText + escapingScheme
}
if ac .Type +"/" +ac .SubType == OpenMetricsType && (ver == OpenMetricsVersion_0_0_1 || ver == OpenMetricsVersion_1_0_0 || ver == "" ) {
switch ver {
case OpenMetricsVersion_1_0_0 :
return FmtOpenMetrics_1_0_0 + escapingScheme
default :
return FmtOpenMetrics_0_0_1 + escapingScheme
}
}
}
return FmtText + escapingScheme
}
func NewEncoder (w io .Writer , format Format , options ...EncoderOption ) Encoder {
escapingScheme := format .ToEscapingScheme ()
switch format .FormatType () {
case TypeProtoDelim :
return encoderCloser {
encode : func (v *dto .MetricFamily ) error {
_ , err := protodelim .MarshalTo (w , v )
return err
},
close : func () error { return nil },
}
case TypeProtoCompact :
return encoderCloser {
encode : func (v *dto .MetricFamily ) error {
_ , err := fmt .Fprintln (w , model .EscapeMetricFamily (v , escapingScheme ).String ())
return err
},
close : func () error { return nil },
}
case TypeProtoText :
return encoderCloser {
encode : func (v *dto .MetricFamily ) error {
_ , err := fmt .Fprintln (w , prototext .Format (model .EscapeMetricFamily (v , escapingScheme )))
return err
},
close : func () error { return nil },
}
case TypeTextPlain :
return encoderCloser {
encode : func (v *dto .MetricFamily ) error {
_ , err := MetricFamilyToText (w , model .EscapeMetricFamily (v , escapingScheme ))
return err
},
close : func () error { return nil },
}
case TypeOpenMetrics :
return encoderCloser {
encode : func (v *dto .MetricFamily ) error {
_ , err := MetricFamilyToOpenMetrics (w , model .EscapeMetricFamily (v , escapingScheme ), options ...)
return err
},
close : func () error {
_ , err := FinalizeOpenMetrics (w )
return err
},
}
}
panic (fmt .Errorf ("expfmt.NewEncoder: unknown format %q" , format ))
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .