Files
sing-box-extended-mirror/experimental/libbox/internal/runtimeinfo/runtimeinfo.go
T

75 lines
1.9 KiB
Go

package runtimeinfo
import (
"encoding/json"
"os"
"runtime/metrics"
)
type Report struct {
Metrics map[string]uint64 `json:"metrics"`
Goroutines *GoroutineReport `json:"goroutines,omitempty"`
Pools []PoolReport `json:"bufferPools,omitempty"`
}
type GoroutineReport struct {
Total int `json:"total"`
StackBytes uint64 `json:"stackBytes"`
Dead int `json:"dead"`
DeadStackBytes uint64 `json:"deadStackBytes"`
ByStatus map[string]int `json:"byStatus"`
ByFunction []GoroutineGroup `json:"byFunction"`
}
type GoroutineGroup struct {
Function string `json:"function"`
CreatedBy string `json:"createdBy,omitempty"`
Count int `json:"count"`
StackBytes uint64 `json:"stackBytes"`
MaxStackBytes uint64 `json:"maxStackBytes"`
MinStackBytes uint64 `json:"minStackBytes"`
}
type PoolReport struct {
Size int `json:"size"`
Cached int `json:"cached"`
Victim int `json:"victim"`
Bytes uint64 `json:"bytes"`
}
func Collect() Report {
return Report{
Metrics: collectMetrics(),
Goroutines: collectGoroutines(),
Pools: collectBufferPools(),
}
}
func WriteFile(path string) error {
content, err := json.MarshalIndent(Collect(), "", " ")
if err != nil {
return err
}
return os.WriteFile(path, content, 0o666)
}
func collectMetrics() map[string]uint64 {
descriptions := metrics.All()
samples := make([]metrics.Sample, 0, len(descriptions))
for _, description := range descriptions {
if description.Kind != metrics.KindUint64 {
continue
}
samples = append(samples, metrics.Sample{Name: description.Name})
}
metrics.Read(samples)
result := make(map[string]uint64, len(samples))
for _, sample := range samples {
if sample.Value.Kind() != metrics.KindUint64 {
continue
}
result[sample.Name] = sample.Value.Uint64()
}
return result
}