123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- package main
- import (
- "bufio"
- "bytes"
- "fmt"
- "log"
- "runtime"
- "strings"
- )
- // reused by GoRuntinesStatus()
- var buffer []byte
- // Get Go Routines and map the Status. See GStatus.
- func GoRoutinesStatus() string {
- var result string
- // Map status to letter.
- var GStatus = map[string]string{
- "idle": "I",
- "runnable": "r",
- "running": "R",
- "syscall": "s",
- "waiting": "W",
- "dead": "D",
- "copystack": "C",
- "preempted": "P",
- "sleep": "S",
- "select": "s", // missing
- "chan receive": "<", // missing
- "chan send": ">", // missing
- }
- // 2K works, we don't have to grow any more.
- if buffer == nil {
- buffer = make([]byte, 2048)
- }
- read := runtime.Stack(buffer, true)
- if read == cap(buffer) {
- log.Printf("Increasing buffer from (%d bytes)\n", cap(buffer))
- buffer = make([]byte, cap(buffer)+1024)
- return GoRoutinesStatus()
- }
- // fmt.Println(string(buffer[0:read]))
- var reader = bytes.NewReader(buffer[0:read])
- var scanner = bufio.NewScanner(reader)
- for scanner.Scan() {
- var text = scanner.Text()
- if strings.HasPrefix(text, "goroutine ") {
- // fmt.Println(text)
- // goroutine 20 [runnable]:
- // goroutine 1 [select, 1 minutes]:
- // goroutine 17 [chan receive]:
- // Get ID and get Status.
- parts := strings.SplitN(text, " ", 3)
- /*
- gid, err := strconv.Atoi(parts[1])
- if err != nil {
- continue
- }
- */
- status := parts[2][1 : len(parts[2])-2]
- if strings.Contains(status, ",") {
- status = strings.Split(status, ",")[0]
- }
- rstatus, ok := GStatus[status]
- if ok {
- result += rstatus
- } else {
- log.Printf("Status %s not found.\n[%s]\n", rstatus, text)
- }
- }
- }
- return result
- }
- // Return a nicely formatted string representing memory usage.
- func ReprMem(size uint64) string {
- var value float64 = float64(size)
- var units string = ""
- if value > 1024 {
- // In KB
- units = "K"
- value /= 1024
- }
- if value > 1024 {
- // In MB
- units = "M"
- value /= 1024
- }
- if value > 1024 {
- // Im GB
- units = "G"
- value /= 1024
- }
- var test = fmt.Sprintf("%0.2f", value)
- if len(test) > 4 {
- test = fmt.Sprintf("%0.1f", value)
- }
- if len(test) > 4 {
- test = fmt.Sprintf("%0.0f", value)
- }
- return test + units
- }
- // Return array of memory usage information
- func Memory() map[string]string {
- var memstats runtime.MemStats
- var result map[string]string = make(map[string]string, 7)
- runtime.ReadMemStats(&memstats)
- result["Heap"] = ReprMem(memstats.HeapAlloc)
- result["HeapInUse"] = ReprMem(memstats.HeapInuse)
- result["HeapSys"] = ReprMem(memstats.HeapSys)
- result["Sys"] = ReprMem(memstats.Sys)
- result["StackInUse"] = ReprMem(memstats.StackInuse)
- result["StackSys"] = ReprMem(memstats.StackSys)
- result["GCSys"] = ReprMem(memstats.GCSys)
- return result
- }
|