Live video on the AT Protocol
79
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v0.8.4 108 lines 2.5 kB view raw
1package proc 2 3import ( 4 "bufio" 5 "context" 6 "errors" 7 "fmt" 8 "io" 9 "os" 10 "os/exec" 11 "strings" 12 13 "golang.org/x/sync/errgroup" 14 "stream.place/streamplace/pkg/config" 15 "stream.place/streamplace/pkg/log" 16 "stream.place/streamplace/pkg/mist/mistconfig" 17) 18 19func RunMistServer(ctx context.Context, cli *config.CLI) error { 20 myself, err := os.Executable() 21 if err != nil { 22 return err 23 } 24 f, err := os.CreateTemp("", "mistconfig.json") 25 defer os.Remove(f.Name()) 26 if err != nil { 27 return err 28 } 29 conf, err := mistconfig.Generate(cli) 30 if err != nil { 31 return err 32 } 33 err = os.WriteFile(f.Name(), conf, 0644) 34 if err != nil { 35 return err 36 } 37 cmd := exec.CommandContext(ctx, myself, 38 "MistServer", 39 "-c", f.Name(), 40 "-i", "127.0.0.1", 41 "-p", fmt.Sprintf("%d", cli.MistAdminPort), 42 ) 43 cmd.Env = []string{ 44 "MIST_NO_PRETTY_LOGGING=true", 45 } 46 stdout, err := cmd.StdoutPipe() 47 if err != nil { 48 panic(err) 49 } 50 stderr, err := cmd.StderrPipe() 51 if err != nil { 52 panic(err) 53 } 54 group, ctx := errgroup.WithContext(ctx) 55 output := fmt.Println 56 for i, pipe := range []io.ReadCloser{stdout, stderr} { 57 func(i int, pipe io.ReadCloser) { 58 group.Go(func() error { 59 reader := bufio.NewReader(pipe) 60 61 for { 62 line, isPrefix, err := reader.ReadLine() 63 if err != nil { 64 if !errors.Is(err, io.EOF) { 65 _, _ = output(fmt.Sprintf("reader gave error, ending logging for fd=%d err=%s", i+1, err)) 66 } 67 line, _, err := reader.ReadLine() 68 if string(line) != "" { 69 _, _ = output(string(line)) 70 } 71 return err 72 } 73 if isPrefix { 74 _, _ = output("warning: preceding line exceeds 64k logging limit and was split") 75 } 76 if string(line) != "" { 77 level, procName, pid, path, streamName, msg, err := ParseMistLog(string(line)) 78 if err != nil { 79 log.Log(ctx, "badly formatted mist log", "message", string(line)) 80 } else { 81 log.Log(ctx, msg, 82 "level", level, 83 "procName", procName, 84 "pid", pid, 85 "streamName", streamName, 86 "caller", path, 87 ) 88 } 89 } 90 } 91 }) 92 }(i, pipe) 93 } 94 95 group.Go(func() error { 96 return cmd.Start() 97 }) 98 99 return group.Wait() 100} 101 102func ParseMistLog(str string) (string, string, string, string, string, string, error) { 103 parts := strings.Split(str, "|") 104 if len(parts) != 6 { 105 return "", "", "", "", "", "", fmt.Errorf("badly formatted mist string") 106 } 107 return parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], nil 108}