github.com/matrixorigin/matrixone@v1.2.0/pkg/util/debug/goroutine/parser.go (about) 1 // Copyright 2023 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package goroutine 16 17 import ( 18 "bufio" 19 "bytes" 20 "strings" 21 22 "github.com/fagongzi/util/format" 23 ) 24 25 var ( 26 goroutineTokenLen = len("goroutine") 27 blockedMinutesTokenLen = len(" minutes]:") 28 ) 29 30 func parse(data []byte) []Goroutine { 31 var gs []Goroutine 32 var g Goroutine 33 scanner := bufio.NewScanner(bytes.NewReader(data)) 34 for scanner.Scan() { 35 line := strings.TrimSpace(scanner.Text()) 36 if strings.HasPrefix(line, "goroutine") { 37 if !g.IsEmpty() { 38 gs = append(gs, g) 39 } 40 g = Goroutine{} 41 readGoroutineLine(line, &g) 42 } else if line == "" { 43 continue 44 } else if strings.Contains(line, ":") { 45 g.files = append(g.files, line) 46 } else { 47 g.methods = append(g.methods, line) 48 } 49 } 50 if !g.IsEmpty() { 51 gs = append(gs, g) 52 } 53 return gs 54 } 55 56 // format: goroutine 628 [IO wait, 8 minutes]: 57 func readGoroutineLine( 58 line string, 59 g *Goroutine) { 60 g.rawState = line 61 62 // goroutine 628 [IO wait, 8 minutes]: 63 // ^ offset 64 offset := goroutineTokenLen + 1 65 66 idx := strings.Index(line[offset:], " ") 67 g.ID = format.MustParseStringInt(line[offset : offset+idx]) 68 69 // goroutine 628 [IO wait, 8 minutes]: 70 // ^ offset 71 offset += idx + 2 72 idx = strings.Index(line[offset:], ",") 73 if idx == -1 { 74 g.State = line[offset : len(line)-2] 75 return 76 } 77 78 g.State = line[offset : offset+idx] 79 80 // goroutine 628 [IO wait, 8 minutes]: 81 // ^ offset 82 offset += idx + 2 83 g.BlockedMinutes = format.MustParseStringInt(line[offset : len(line)-blockedMinutesTokenLen]) 84 }