Skip to content

Instantly share code, notes, and snippets.

@ostcar
Created November 12, 2022 12:23
Show Gist options
  • Save ostcar/60f6f544de140d7ff0947e9621ef7328 to your computer and use it in GitHub Desktop.
Save ostcar/60f6f544de140d7ff0947e9621ef7328 to your computer and use it in GitHub Desktop.
Show memory usage in go services
// From https://github.com/dustin/go-humanize
func intToByte(s uint64) string {
sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"}
base := 1000.0
logn := func(n, b float64) float64 {
return math.Log(n) / math.Log(b)
}
if s < 10 {
return fmt.Sprintf("%d B", s)
}
e := math.Floor(logn(float64(s), base))
suffix := sizes[int(e)]
val := math.Floor(float64(s)/math.Pow(base, e)*10+0.5) / 10
f := "%.0f %s"
if val < 10 {
f = "%.1f %s"
}
return fmt.Sprintf(f, val, suffix)
}
func init() {
// fn, err := os.Create("memory.log")
// if err != nil {
// panic(err)
// }
fn := os.Stdout
type keyFunc struct {
key string
f func(metrics.Value) any
}
metricKeys := []keyFunc{
{"/memory/classes/heap/free:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/heap/objects:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/heap/released:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/heap/stacks:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/heap/unused:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/metadata/mcache/free:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/metadata/mcache/inuse:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/metadata/mspan/free:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/metadata/mspan/inuse:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/metadata/other:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/os-stacks:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/other:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/profiling/buckets:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/memory/classes/total:bytes", func(v metrics.Value) any { return intToByte(v.Uint64()) }},
{"/gc/cycles/total:gc-cycles", func(v metrics.Value) any { return v.Uint64() }},
}
sampleList := make([]metrics.Sample, len(metricKeys))
for i, kf := range metricKeys {
sampleList[i].Name = kf.key
}
go func() {
for {
// Sample the metric.
metrics.Read(sampleList)
fmt.Fprintln(fn, time.Now())
for i, sample := range sampleList {
key := sample.Name
value := metricKeys[i].f(sample.Value)
fmt.Fprintf(fn, "%s\t\t\t%v\n", key, value)
}
fmt.Fprintln(fn)
time.Sleep(time.Second)
}
}()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment