|
|
|
|
@ -11,6 +11,8 @@ import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"net/http"
|
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"reflect"
|
|
|
|
|
"runtime"
|
|
|
|
|
"sort"
|
|
|
|
|
@ -189,7 +191,11 @@ func writePromExpVar(w io.Writer, prefix string, kv expvar.KeyValue) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if vs, ok := v.(string); ok && strings.HasSuffix(name, "version") {
|
|
|
|
|
fmt.Fprintf(w, "%s{version=%q} 1\n", name, vs)
|
|
|
|
|
if name == "version" {
|
|
|
|
|
fmt.Fprintf(w, "%s{version=%q,binary=%q} 1\n", name, vs, binaryName())
|
|
|
|
|
} else {
|
|
|
|
|
fmt.Fprintf(w, "%s{version=%q} 1\n", name, vs)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
switch v := v.(type) {
|
|
|
|
|
@ -308,6 +314,18 @@ func ExpvarDoHandler(expvarDoFunc func(f func(expvar.KeyValue))) func(http.Respo
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var binaryName = sync.OnceValue(func() string {
|
|
|
|
|
exe, err := os.Executable()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
exe2, err := filepath.EvalSymlinks(exe)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return filepath.Base(exe)
|
|
|
|
|
}
|
|
|
|
|
return filepath.Base(exe2)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// PrometheusMetricsReflectRooter is an optional interface that expvar.Var implementations
|
|
|
|
|
// can implement to indicate that they should be walked recursively with reflect to find
|
|
|
|
|
// sets of fields to export.
|
|
|
|
|
|