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 }