| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- package containers
- import (
- "bytes"
- "fmt"
- "path/filepath"
- "strconv"
- "time"
- "github.com/coroot/coroot-node-agent/common"
- "github.com/coroot/coroot-node-agent/proc"
- "github.com/prometheus/client_golang/prometheus"
- "github.com/xin053/hsperfdata"
- "k8s.io/klog/v2"
- )
- func isJvm(cmdline []byte) bool {
- idx := bytes.Index(cmdline, []byte{0})
- if idx < 0 {
- return false
- }
- return bytes.HasSuffix(cmdline[:idx], []byte("java"))
- }
- func jvmMetrics(pid uint32) (string, []prometheus.Metric) {
- p := proc.Path(pid, "root/tmp/hsperfdata_*/"+strconv.Itoa(int(proc.GetNsPid(pid))))
- files, _ := filepath.Glob(p)
- if len(files) != 1 {
- return "", nil
- }
- pd, err := readPerfData(files[0])
- if err != nil {
- if !common.IsNotExist(err) {
- klog.Warningln(err)
- }
- return "", nil
- }
- jvm := pd.getString("sun.rt.javaCommand")
- var res []prometheus.Metric
- res = append(res, gauge(metrics.JvmInfo, 1, jvm, pd.getString("java.property.java.version")))
- func() {
- size := float64(0)
- used := float64(0)
- for _, gen := range []int{0, 1} {
- spaces := pd.getInt64("sun.gc.generation.%d.spaces", gen)
- for s := 0; s < int(spaces); s++ {
- size += float64(pd.getInt64("sun.gc.generation.%d.space.%d.capacity", gen, s))
- used += float64(pd.getInt64("sun.gc.generation.%d.space.%d.used", gen, s))
- }
- }
- res = append(res, gauge(metrics.JvmHeapSize, size, jvm))
- res = append(res, gauge(metrics.JvmHeapUsed, used, jvm))
- }()
- gc := func(prefix string) {
- name := pd.getString(prefix + "name")
- if name == "" {
- return
- }
- res = append(res, counter(metrics.JvmGCTime, time.Duration(pd.getInt64(prefix+"time")).Seconds(), jvm, name))
- }
- gc("sun.gc.collector.0.")
- gc("sun.gc.collector.1.")
- gc("sun.gc.collector.2.")
- res = append(res, counter(metrics.JvmSafepointTime, time.Duration(pd.getInt64("sun.rt.safepointTime")).Seconds(), jvm))
- res = append(res, counter(metrics.JvmSafepointSyncTime, time.Duration(pd.getInt64("sun.rt.safepointSyncTime")).Seconds(), jvm))
- return jvm, res
- }
- type perfData struct {
- data map[string]interface{}
- }
- func readPerfData(p string) (*perfData, error) {
- data, err := hsperfdata.ReadPerfData(p, true)
- return &perfData{data: data}, err
- }
- func (pd *perfData) getString(key string) string {
- v, _ := pd.data[key].(string)
- return v
- }
- func (pd *perfData) getInt64(key string, a ...any) int64 {
- if len(a) > 0 {
- key = fmt.Sprintf(key, a...)
- }
- v, _ := pd.data[key].(int64)
- return v
- }
|