2022-07-21 18:49:52 +02:00
|
|
|
package appmetrics
|
2019-05-22 23:16:55 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
2020-11-03 13:10:42 +01:00
|
|
|
"regexp"
|
2019-05-22 23:16:55 +02:00
|
|
|
"strings"
|
2021-02-16 13:54:34 +01:00
|
|
|
"sync"
|
|
|
|
"sync/atomic"
|
2019-05-22 23:16:55 +02:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/buildinfo"
|
2021-02-16 13:54:34 +01:00
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
2021-03-10 11:01:18 +01:00
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/cgroup"
|
2020-09-16 21:34:01 +02:00
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
|
2019-05-22 23:16:55 +02:00
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/memory"
|
|
|
|
"github.com/VictoriaMetrics/metrics"
|
|
|
|
)
|
|
|
|
|
2021-09-21 22:07:56 +02:00
|
|
|
var versionRe = regexp.MustCompile(`v\d+\.\d+\.\d+(?:-enterprise)?(?:-cluster)?`)
|
2020-11-03 13:10:42 +01:00
|
|
|
|
2020-08-07 09:56:50 +02:00
|
|
|
// WritePrometheusMetrics writes all the registered metrics to w in Prometheus exposition format.
|
|
|
|
func WritePrometheusMetrics(w io.Writer) {
|
2021-02-16 13:54:34 +01:00
|
|
|
currentTime := time.Now()
|
|
|
|
metricsCacheLock.Lock()
|
|
|
|
if currentTime.Sub(metricsCacheLastUpdateTime) > time.Second {
|
|
|
|
var bb bytesutil.ByteBuffer
|
|
|
|
writePrometheusMetrics(&bb)
|
|
|
|
metricsCache.Store(&bb)
|
|
|
|
metricsCacheLastUpdateTime = currentTime
|
|
|
|
}
|
|
|
|
metricsCacheLock.Unlock()
|
|
|
|
|
2023-07-20 02:37:49 +02:00
|
|
|
bb := metricsCache.Load()
|
2021-02-16 21:05:00 +01:00
|
|
|
_, _ = w.Write(bb.B)
|
2021-02-16 13:54:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
metricsCacheLock sync.Mutex
|
|
|
|
metricsCacheLastUpdateTime time.Time
|
2023-07-20 02:37:49 +02:00
|
|
|
metricsCache atomic.Pointer[bytesutil.ByteBuffer]
|
2021-02-16 13:54:34 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
func writePrometheusMetrics(w io.Writer) {
|
2019-05-22 23:16:55 +02:00
|
|
|
metrics.WritePrometheus(w, true)
|
2021-02-04 15:33:07 +01:00
|
|
|
metrics.WriteFDMetrics(w)
|
2019-05-22 23:16:55 +02:00
|
|
|
|
2020-11-03 13:10:42 +01:00
|
|
|
fmt.Fprintf(w, "vm_app_version{version=%q, short_version=%q} 1\n", buildinfo.Version,
|
|
|
|
versionRe.FindString(buildinfo.Version))
|
2019-05-22 23:16:55 +02:00
|
|
|
fmt.Fprintf(w, "vm_allowed_memory_bytes %d\n", memory.Allowed())
|
2021-03-10 11:01:18 +01:00
|
|
|
fmt.Fprintf(w, "vm_available_memory_bytes %d\n", memory.Allowed()+memory.Remaining())
|
|
|
|
fmt.Fprintf(w, "vm_available_cpu_cores %d\n", cgroup.AvailableCPUs())
|
2021-07-05 11:31:26 +02:00
|
|
|
fmt.Fprintf(w, "vm_gogc %d\n", cgroup.GetGOGC())
|
2019-05-22 23:16:55 +02:00
|
|
|
|
|
|
|
// Export start time and uptime in seconds
|
|
|
|
fmt.Fprintf(w, "vm_app_start_timestamp %d\n", startTime.Unix())
|
|
|
|
fmt.Fprintf(w, "vm_app_uptime_seconds %d\n", int(time.Since(startTime).Seconds()))
|
|
|
|
|
|
|
|
// Export flags as metrics.
|
2021-07-13 14:07:59 +02:00
|
|
|
isSetMap := make(map[string]bool)
|
|
|
|
flag.Visit(func(f *flag.Flag) {
|
|
|
|
isSetMap[f.Name] = true
|
|
|
|
})
|
2019-05-22 23:16:55 +02:00
|
|
|
flag.VisitAll(func(f *flag.Flag) {
|
|
|
|
lname := strings.ToLower(f.Name)
|
|
|
|
value := f.Value.String()
|
2020-09-16 21:34:01 +02:00
|
|
|
if flagutil.IsSecretFlag(lname) {
|
2019-05-22 23:16:55 +02:00
|
|
|
// Do not expose passwords and keys to prometheus.
|
|
|
|
value = "secret"
|
|
|
|
}
|
2021-07-13 14:07:59 +02:00
|
|
|
isSet := "false"
|
|
|
|
if isSetMap[f.Name] {
|
|
|
|
isSet = "true"
|
|
|
|
}
|
|
|
|
fmt.Fprintf(w, "flag{name=%q, value=%q, is_set=%q} 1\n", f.Name, value, isSet)
|
2019-05-22 23:16:55 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
var startTime = time.Now()
|