github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/cmd/logtool/watch.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "strconv" 8 "strings" 9 10 "github.com/Cloud-Foundations/Dominator/lib/errors" 11 "github.com/Cloud-Foundations/Dominator/lib/log" 12 "github.com/Cloud-Foundations/Dominator/lib/srpc" 13 proto "github.com/Cloud-Foundations/Dominator/proto/logger" 14 ) 15 16 func watchSubcommand(args []string, logger log.DebugLogger) error { 17 level, err := strconv.ParseInt(args[0], 10, 16) 18 if err != nil { 19 return fmt.Errorf("Error parsing level: %s", err) 20 } 21 clients, addrs, err := dial(true) 22 if err != nil { 23 return err 24 } 25 if err := watchAll(clients, addrs, int16(level)); err != nil { 26 return fmt.Errorf("Error watching: %s", err) 27 } 28 return nil 29 } 30 31 func watchAll(clients []*srpc.Client, addrs []string, level int16) error { 32 if len(clients) == 1 { 33 return watchOne(clients[0], level, "") 34 } 35 maxWidth := 0 36 for _, addr := range addrs { 37 if len(addr) > maxWidth { 38 maxWidth = len(addr) 39 } 40 } 41 errors := make(chan error, 1) 42 for index, client := range clients { 43 prefix := addrs[index] 44 if len(prefix) < maxWidth { 45 prefix += strings.Repeat(" ", maxWidth-len(prefix)) 46 } 47 go func(client *srpc.Client, level int16, prefix string) { 48 errors <- watchOne(client, level, prefix) 49 }(client, level, prefix) 50 } 51 for range clients { 52 if err := <-errors; err != nil { 53 return err 54 } 55 } 56 return nil 57 } 58 59 func watchOne(client *srpc.Client, level int16, prefix string) error { 60 request := proto.WatchRequest{ 61 ExcludeRegex: *excludeRegex, 62 IncludeRegex: *includeRegex, 63 Name: *loggerName, 64 DebugLevel: level, 65 } 66 if conn, err := client.Call("Logger.Watch"); err != nil { 67 return err 68 } else { 69 defer conn.Close() 70 if err := conn.Encode(request); err != nil { 71 return err 72 } 73 if err := conn.Flush(); err != nil { 74 return err 75 } 76 var response proto.WatchResponse 77 if err := conn.Decode(&response); err != nil { 78 return fmt.Errorf("error decoding: %s", err) 79 } 80 if response.Error != "" { 81 return errors.New(response.Error) 82 } 83 if prefix == "" { 84 _, err := io.Copy(os.Stdout, conn) 85 return err 86 } 87 for { 88 line, err := conn.ReadString('\n') 89 if len(line) > 0 { 90 if prefix != "" { 91 line = prefix + " " + line 92 } 93 if _, err := os.Stdout.Write([]byte(line)); err != nil { 94 return err 95 } 96 } 97 if err != nil { 98 if err == io.EOF { 99 return nil 100 } 101 return err 102 } 103 } 104 } 105 }