123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- package main
- import (
- "bufio"
- "bytes"
- "fmt"
- "log"
- "runtime"
- "strings"
- )
- var buffer []byte
- var output *bytes.Buffer
- const DEBUG_THIS bool = false
- func GStatusMapper(status []byte) byte {
- switch status[0] {
- case 'c':
- if status[1] == 'o' {
- return 'C'
- }
- switch status[5] {
- case 'r':
- return '<'
- case 's':
- return '>'
- }
- return '?'
- case 'd':
- return 'D'
- case 'i':
- return 'I'
- case 'p':
- return 'P'
- case 'r':
- switch status[4] {
- case 'a':
- return 'r'
- case 'i':
- return 'R'
- }
- return '?'
- case 's':
- switch status[1] {
- case 'y':
- return 's'
- case 'l':
- return 'S'
- case 'e':
- return 's'
- }
- return '?'
- case 'w':
- return 'W'
- default:
- return '?'
- }
- }
- func GoRoutinesStatus() []byte {
- if output == nil {
- log.Println("new bytes.Buffer{}")
- output = &bytes.Buffer{}
- }
- output.Reset()
-
-
-
- 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()
- }
- var buff []byte = buffer[:read]
-
-
- var pos, lineend int
- var slice []byte
- var space, spaceend int
- var status []byte
- var count int
- for pos != -1 {
- if DEBUG_THIS {
- log.Printf("POS: %d (%d)\n", pos, len(buff))
- }
- lineend = bytes.Index(buff[pos:], []byte("\n"))
- if DEBUG_THIS {
- log.Printf("LineEnd: %d\n", lineend)
- }
- if lineend != -1 {
- lineend += pos
- slice = buff[pos:lineend]
- pos = lineend + 1
- } else {
- slice = buffer[pos:]
- pos = -1
- }
-
- if bytes.HasPrefix(slice, []byte("goroutine ")) {
- if DEBUG_THIS {
- log.Printf("GoRoutine %d [%s]\n", count, slice)
- count++
- }
-
- space = bytes.Index(slice, []byte{'['})
- spaceend = bytes.Index(slice[space+1:], []byte{']'})
- if spaceend == -1 {
- status = slice[space+1:]
- } else {
- spaceend += space + 1
-
- status = slice[space+1 : spaceend]
- }
-
- if DEBUG_THIS {
- log.Printf("Status: [%s]\n", status)
- }
- space = bytes.Index(status, []byte{','})
- if space != -1 {
- status = status[:space]
-
- }
- rstatus := GStatusMapper(status)
-
- output.WriteByte(rstatus)
-
- }
- }
- if false {
- var reader = bytes.NewReader(buffer[0:read])
- var scanner = bufio.NewScanner(reader)
- for scanner.Scan() {
- var text = scanner.Text()
- if strings.HasPrefix(text, "goroutine ") {
-
-
-
-
-
- parts := strings.SplitN(text, " ", 3)
-
- status := parts[2][1 : len(parts[2])-2]
- if strings.Contains(status, ",") {
- status = strings.Split(status, ",")[0]
- }
-
- }
- }
- }
- return output.Bytes()
- }
- func ReprMem(size uint64, output *bytes.Buffer) {
- if output == nil {
- return
- }
- output.Reset()
- var value float64 = float64(size)
- var units byte = ' '
- if value > 1024 {
-
- units = 'K'
- value /= 1024
- }
- if value > 1024 {
-
- units = 'M'
- value /= 1024
- }
- if value > 1024 {
-
- units = 'G'
- value /= 1024
- }
- fmt.Fprintf(output, "%0.2f", value)
- if output.Len() > 4 {
- output.Reset()
- fmt.Fprintf(output, "%0.1f", value)
- }
- if output.Len() > 4 {
- output.Reset()
- fmt.Fprintf(output, "%0.0f", value)
- }
- if units != ' ' {
- output.WriteByte(units)
- }
- }
- func Memory(result *map[string]*bytes.Buffer) {
- var memstats runtime.MemStats
- runtime.ReadMemStats(&memstats)
- if (*result)["Sys"] == nil {
- (*result)["Sys"] = &bytes.Buffer{}
- }
- ReprMem(memstats.Sys, (*result)["Sys"])
-
-
- if (*result)["Heap"] == nil {
- (*result)["Heap"] = &bytes.Buffer{}
- }
- ReprMem(memstats.HeapAlloc, (*result)["Heap"])
- if (*result)["HeapSys"] == nil {
- (*result)["HeapSys"] = &bytes.Buffer{}
- }
- ReprMem(memstats.HeapSys, (*result)["MeapSys"])
- if (*result)["StackSys"] == nil {
- (*result)["StackSys"] = &bytes.Buffer{}
- }
- ReprMem(memstats.StackSys, (*result)["StackSys"])
-
- if (*result)["NumGC"] == nil {
- (*result)["NumGC"] = &bytes.Buffer{}
- }
- (*result)["NumGC"].Reset()
- fmt.Fprintf((*result)["NumGC"], "%d", memstats.NumGC)
-
-
- }
|