@@ -1060,12 +1060,25 @@ func collectMetrics(done chan struct{}, cpumetricsChan chan CPUMetrics, gpumetri
10601060 cmd .SysProcAttr = & syscall.SysProcAttr {Setpgid : true }
10611061 stdout , err := cmd .StdoutPipe ()
10621062 if err != nil {
1063- log .Fatal (err )
1063+ stderrLogger .Fatal (err )
10641064 }
10651065 if err := cmd .Start (); err != nil {
1066- log .Fatal (err )
1066+ stderrLogger .Fatal (err )
10671067 }
1068- scanner := bufio .NewScanner (stdout )
1068+
1069+ defer func () {
1070+ if err := cmd .Process .Kill (); err != nil {
1071+ stderrLogger .Fatalf ("ERROR: Failed to kill powermetrics: %v" , err )
1072+ }
1073+ }()
1074+
1075+ // Create buffered reader with larger buffer
1076+ const bufferSize = 10 * 1024 * 1024 // 10MB
1077+ reader := bufio .NewReaderSize (stdout , bufferSize )
1078+
1079+ scanner := bufio .NewScanner (reader )
1080+ scanner .Buffer (make ([]byte , bufferSize ), bufferSize )
1081+
10691082 scanner .Split (func (data []byte , atEOF bool ) (advance int , token []byte , err error ) {
10701083 if atEOF && len (data ) == 0 {
10711084 return 0 , nil , nil
@@ -1080,27 +1093,36 @@ func collectMetrics(done chan struct{}, cpumetricsChan chan CPUMetrics, gpumetri
10801093 }
10811094 }
10821095 if atEOF {
1096+ if start >= 0 {
1097+ return len (data ), data [start :], nil
1098+ }
10831099 return len (data ), nil , nil
10841100 }
10851101 return 0 , nil , nil
10861102 })
1103+ retryCount := 0
1104+ maxRetries := 3
10871105 for scanner .Scan () {
1088- plistData := scanner .Text ()
1089- if ! strings .Contains (plistData , "<?xml" ) || ! strings .Contains (plistData , "</plist>" ) {
1090- continue
1091- }
1092- var data map [string ]interface {}
1093- err := plist .NewDecoder (strings .NewReader (plistData )).Decode (& data )
1094- if err != nil {
1095- log .Printf ("Error decoding plist: %v" , err )
1096- continue
1097- }
10981106 select {
10991107 case <- done :
1100- cmd .Process .Kill ()
11011108 return
11021109 default :
1103- // Send all metrics at once
1110+ plistData := scanner .Text ()
1111+ if ! strings .Contains (plistData , "<?xml" ) || ! strings .Contains (plistData , "</plist>" ) {
1112+ retryCount ++
1113+ if retryCount >= maxRetries {
1114+ retryCount = 0
1115+ continue
1116+ }
1117+ continue
1118+ }
1119+ retryCount = 0 // Reset retry counter on successful parse
1120+ var data map [string ]interface {}
1121+ err := plist .NewDecoder (strings .NewReader (plistData )).Decode (& data )
1122+ if err != nil {
1123+ stderrLogger .Printf ("Error decoding plist: %v" , err )
1124+ continue
1125+ }
11041126 cpuMetrics := parseCPUMetrics (data , NewCPUMetrics ())
11051127 gpuMetrics := parseGPUMetrics (data )
11061128 netdiskMetrics := parseNetDiskMetrics (data )
0 commit comments