Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions cmd/prom2json/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,18 @@ Examples:
`

func main() {
cert := kingpin.Flag("cert", "client certificate file").String()
key := kingpin.Flag("key", "client certificate's key file").String()
cert := kingpin.Flag("cert", "client certificate file").PlaceHolder("FILE").String()
key := kingpin.Flag("key", "client certificate's key file").PlaceHolder("FILE").String()
skipServerCertCheck := kingpin.Flag("accept-invalid-cert", "Accept any certificate during TLS handshake. Insecure, use only for testing.").Bool()
escapingScheme := kingpin.Flag("escaping", "Sets an escaping scheme in content negotiation. Use 'allow-utf-8' for full UTF-8 character support.").
PlaceHolder("SCHEME").
Enum(
"allow-utf-8",
"underscores",
"dots",
"values",
)

kingpin.CommandLine.UsageWriter(os.Stderr)
kingpin.Version(version.Print("prom2json"))
kingpin.HelpFlag.Short('h')
Expand Down Expand Up @@ -88,8 +97,7 @@ func main() {
os.Exit(1)
}
go func() {
err := prom2json.FetchMetricFamilies(*arg, mfChan, transport)
if err != nil {
if err := prom2json.FetchMetricFamiliesWithEscapingScheme(*arg, mfChan, transport, *escapingScheme); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
Expand Down
23 changes: 21 additions & 2 deletions prom2json.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,15 @@ import (
"github.com/prometheus/prom2json/histogram"
)

const acceptHeader = `application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited;q=0.7,text/plain;version=0.0.4;q=0.3`
const (
acceptHeader = `application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited;q=0.7,text/plain;version=1.0.0;q=0.2,text/plain;version=0.0.4;q=0.1`
// acceptHeaderTemplate takes the escaping scheme as its single
// parameter. Note that we even add the parameter to
// text/plain;version=0.0.4. This version officially does not support
// escaping scheme selection, but some targets implement it anyway, so
// no harm in trying.
acceptHeaderTemplate = `application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited;escaping=%[1]s;q=0.7,text/plain;version=1.0.0;escaping=%[1]s;q=0.2,text/plain;version=0.0.4;escaping=%[1]s;q=0.1`
)

// Family mirrors the MetricFamily proto message.
type Family struct {
Expand Down Expand Up @@ -177,12 +185,23 @@ func makeBuckets(m *dto.Metric) map[string]string {
// returns after all MetricFamilies have been sent. The provided transport
// may be nil (in which case the default Transport is used).
func FetchMetricFamilies(url string, ch chan<- *dto.MetricFamily, transport http.RoundTripper) error {
return FetchMetricFamiliesWithEscapingScheme(url, ch, transport, "")
}

// FetchMetricFamiliesWithEscapingScheme works like FetchMetricFamilies but adds
// the provided string as the value of the additional 'escaping' parameter in
// the accept header.
func FetchMetricFamiliesWithEscapingScheme(url string, ch chan<- *dto.MetricFamily, transport http.RoundTripper, escapingScheme string) error {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
close(ch)
return fmt.Errorf("creating GET request for URL %q failed: %w", url, err)
}
req.Header.Add("Accept", acceptHeader)
if escapingScheme != "" {
req.Header.Add("Accept", fmt.Sprintf(acceptHeaderTemplate, escapingScheme))
} else {
req.Header.Add("Accept", acceptHeader)
}
client := http.Client{Transport: transport}
resp, err := client.Do(req)
if err != nil {
Expand Down