Skip to content

Commit c2c6fd2

Browse files
committed
Fix PR comments
Signed-off-by: glefloch <[email protected]>
1 parent fdf4cbc commit c2c6fd2

File tree

1 file changed

+48
-32
lines changed

1 file changed

+48
-32
lines changed

prometheus/promhttp/http.go

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ var gzipPool = sync.Pool{
5959
},
6060
}
6161

62+
var bufPool = sync.Pool{
63+
New: func() interface{} {
64+
return &bytes.Buffer{}
65+
},
66+
}
67+
6268
// Handler returns an http.Handler for the prometheus.DefaultGatherer, using
6369
// default HandlerOpts, i.e. it reports the first error as an HTTP error, it has
6470
// no error logging, and it applies compression if requested by the client.
@@ -103,7 +109,6 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
103109
return
104110
}
105111
}
106-
107112
mfs, err := reg.Gather()
108113
if err != nil {
109114
if opts.ErrorLog != nil {
@@ -124,9 +129,12 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
124129
}
125130

126131
contentType := expfmt.Negotiate(req.Header)
127-
buf := &bytes.Buffer{}
132+
buf := bufPool.Get().(*bytes.Buffer)
133+
buf.Reset()
128134
enc := expfmt.NewEncoder(buf, contentType)
129135

136+
defer bufPool.Put(buf)
137+
130138
var lastErr error
131139
for _, mf := range mfs {
132140
if err := enc.Encode(mf); err != nil {
@@ -150,45 +158,30 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
150158
http.Error(w, "No metrics encoded, last error:\n\n"+lastErr.Error(), http.StatusInternalServerError)
151159
return
152160
}
161+
header := w.Header()
162+
header.Set(contentTypeHeader, string(contentType))
163+
header.Set(contentLengthHeader, fmt.Sprint(buf.Len()))
153164

154-
w.Header().Set(contentTypeHeader, string(contentType))
165+
if !opts.DisableCompression && gzipAccepted(req.Header) {
166+
header.Set(contentEncodingHeader, "gzip")
167+
gz := gzipPool.Get().(*gzip.Writer)
168+
defer gzipPool.Put(gz)
155169

156-
if _, err := w.Write(buf.Bytes()); err != nil && opts.ErrorLog != nil {
157-
opts.ErrorLog.Println("error while sending encoded metrics:", err)
158-
}
159-
// TODO(beorn7): Consider streaming serving of metrics.
160-
})
170+
gz.Reset(w)
171+
defer gz.Close()
161172

162-
gzipHandler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
163-
if opts.DisableCompression {
164-
h.ServeHTTP(w, req)
173+
zipWriter := gzipResponseWriter{gz, w}
174+
writeResult(zipWriter, buf, opts)
165175
return
166176
}
167-
header := req.Header.Get(acceptEncodingHeader)
168-
parts := strings.Split(header, ",")
169-
for _, part := range parts {
170-
part = strings.TrimSpace(part)
171-
if part == "gzip" || strings.HasPrefix(part, "gzip;") {
172-
173-
w.Header().Set(contentEncodingHeader, "gzip")
174-
gz := gzipPool.Get().(*gzip.Writer)
175-
defer gzipPool.Put(gz)
176-
177-
gz.Reset(w)
178-
defer gz.Close()
179-
180-
h.ServeHTTP(gzipResponseWriter{gz, w}, req)
181-
return
182-
}
183-
}
184-
h.ServeHTTP(w, req)
185-
return
177+
writeResult(w, buf, opts)
178+
// TODO(beorn7): Consider streaming serving of metrics.
186179
})
187180

188181
if opts.Timeout <= 0 {
189-
return gzipHandler
182+
return h
190183
}
191-
return http.TimeoutHandler(gzipHandler, opts.Timeout, fmt.Sprintf(
184+
return http.TimeoutHandler(h, opts.Timeout, fmt.Sprintf(
192185
"Exceeded configured timeout of %v.\n",
193186
opts.Timeout,
194187
))
@@ -313,3 +306,26 @@ type gzipResponseWriter struct {
313306
func (w gzipResponseWriter) Write(b []byte) (int, error) {
314307
return w.Writer.Write(b)
315308
}
309+
310+
// writeResult to buf using http.ResponseWriter.
311+
// If ErrorLog is enabled, err is logged in.
312+
func writeResult(w http.ResponseWriter, buf *bytes.Buffer, opts HandlerOpts) {
313+
if _, err := w.Write(buf.Bytes()); err != nil && opts.ErrorLog != nil {
314+
opts.ErrorLog.Println("error while sending encoded metrics:", err)
315+
}
316+
}
317+
318+
// gzipHandler return a http.HandlerFunc in charge of compressing the content
319+
// of the given http.HandlerFunc
320+
func gzipAccepted(header http.Header) bool {
321+
322+
a := header.Get(acceptEncodingHeader)
323+
parts := strings.Split(a, ",")
324+
for _, part := range parts {
325+
part = strings.TrimSpace(part)
326+
if part == "gzip" || strings.HasPrefix(part, "gzip;") {
327+
return true
328+
}
329+
}
330+
return false
331+
}

0 commit comments

Comments
 (0)