1 /* 2 Copyright 2019 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package metrics 18 19 import ( 20 "io" 21 "net/http" 22 "time" 23 24 "github.com/prometheus/client_golang/prometheus/promhttp" 25 ) 26 27 var ( 28 processStartedAt time.Time 29 ) 30 31 func init() { 32 processStartedAt = time.Now() 33 } 34 35 // These constants cause handlers serving metrics to behave as described if 36 // errors are encountered. 37 const ( 38 // HTTPErrorOnError serve an HTTP status code 500 upon the first error 39 // encountered. Report the error message in the body. 40 HTTPErrorOnError promhttp.HandlerErrorHandling = iota 41 42 // ContinueOnError ignore errors and try to serve as many metrics as possible. 43 // However, if no metrics can be served, serve an HTTP status code 500 and the 44 // last error message in the body. Only use this in deliberate "best 45 // effort" metrics collection scenarios. In this case, it is highly 46 // recommended to provide other means of detecting errors: By setting an 47 // ErrorLog in HandlerOpts, the errors are logged. By providing a 48 // Registry in HandlerOpts, the exposed metrics include an error counter 49 // "promhttp_metric_handler_errors_total", which can be used for 50 // alerts. 51 ContinueOnError 52 53 // PanicOnError panics upon the first error encountered (useful for "crash only" apps). 54 PanicOnError 55 ) 56 57 // HandlerOpts specifies options how to serve metrics via an http.Handler. The 58 // zero value of HandlerOpts is a reasonable default. 59 type HandlerOpts promhttp.HandlerOpts 60 61 func (ho *HandlerOpts) toPromhttpHandlerOpts() promhttp.HandlerOpts { 62 ho.ProcessStartTime = processStartedAt 63 return promhttp.HandlerOpts(*ho) 64 } 65 66 // HandlerFor returns an uninstrumented http.Handler for the provided 67 // Gatherer. The behavior of the Handler is defined by the provided 68 // HandlerOpts. Thus, HandlerFor is useful to create http.Handlers for custom 69 // Gatherers, with non-default HandlerOpts, and/or with custom (or no) 70 // instrumentation. Use the InstrumentMetricHandler function to apply the same 71 // kind of instrumentation as it is used by the Handler function. 72 func HandlerFor(reg Gatherer, opts HandlerOpts) http.Handler { 73 return promhttp.HandlerFor(reg, opts.toPromhttpHandlerOpts()) 74 } 75 76 // HandlerWithReset return an http.Handler with Reset 77 func HandlerWithReset(reg KubeRegistry, opts HandlerOpts) http.Handler { 78 defaultHandler := promhttp.HandlerFor(reg, opts.toPromhttpHandlerOpts()) 79 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 80 if r.Method == http.MethodDelete { 81 reg.Reset() 82 io.WriteString(w, "metrics reset\n") 83 return 84 } 85 defaultHandler.ServeHTTP(w, r) 86 }) 87 } 88