diff --git a/.idea/workspace.xml b/.idea/workspace.xml index bf78bbd..e17c851 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,7 +2,9 @@ + + diff --git a/reporter_darwin.go b/reporter_darwin.go new file mode 100644 index 0000000..d7deb4c --- /dev/null +++ b/reporter_darwin.go @@ -0,0 +1,96 @@ +package iperf + +import ( + "fmt" + "github.com/BGrewell/go-conversions" + "github.com/BGrewell/tail" + "log" + "strconv" + "strings" + "time" +) + +//TODO: This has not been tested on OS X ... my assumption is it is the exact same as linux but if it's not then the +// reporting will be broken + +func (r *Reporter) runLogProcessor() { + var err error + r.tailer, err = tail.TailFile(r.LogFile, tail.Config{ + Follow: true, + ReOpen: true, + Poll: false, // on linux we don't need to poll as the fsnotify works properly + MustExist: true, + }) + if err != nil { + log.Fatalf("failed to tail log file: %v", err) + } + + for { + select { + case line := <-r.tailer.Lines: + if line == nil { + continue + } + if len(line.Text) > 5 { + id := line.Text[1:4] + stream, err := strconv.Atoi(strings.TrimSpace(id)) + if err != nil { + continue + } + fields := strings.Fields(line.Text[5:]) + if len(fields) >= 9 { + if fields[0] == "local" { + continue + } + timeFields := strings.Split(fields[0], "-") + start, err := strconv.ParseFloat(timeFields[0], 32) + if err != nil { + log.Printf("failed to convert start time: %s\n", err) + } + end, err := strconv.ParseFloat(timeFields[1], 32) + transferedStr := fmt.Sprintf("%s%s", fields[2], fields[3]) + transferedBytes, err := conversions.StringBitRateToInt(transferedStr) + if err != nil { + log.Printf("failed to convert units: %s\n", err) + } + transferedBytes = transferedBytes / 8 + rateStr := fmt.Sprintf("%s%s", fields[4], fields[5]) + rate, err := conversions.StringBitRateToInt(rateStr) + if err != nil { + log.Printf("failed to convert units: %s\n", err) + } + retrans, err := strconv.Atoi(fields[6]) + if err != nil { + log.Printf("failed to convert units: %s\n", err) + } + cwndStr := fmt.Sprintf("%s%s", fields[7], fields[8]) + cwnd, err := conversions.StringBitRateToInt(cwndStr) + if err != nil { + log.Printf("failed to convert units: %s\n", err) + } + cwnd = cwnd / 8 + omitted := false + if len(fields) >= 10 && fields[9] == "(omitted)" { + omitted = true + } + report := &StreamIntervalReport{ + Socket: stream, + StartInterval: float32(start), + EndInterval: float32(end), + Seconds: float32(end - start), + Bytes: int(transferedBytes), + BitsPerSecond: float64(rate), + Retransmissions: retrans, + CongestionWindow: int(cwnd), + Omitted: omitted, + } + r.ReportingChannel <- report + } + } + case <-time.After(100 * time.Millisecond): + if !r.running { + return + } + } + } +}