forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
1package engine 2 3import ( 4 "fmt" 5 "io" 6 "os" 7 "path/filepath" 8) 9 10type StepLogger struct { 11 stderr *os.File 12 stdout *os.File 13} 14 15func NewStepLogger(baseDir, workflowID string, stepIdx int) (*StepLogger, error) { 16 dir := filepath.Join(baseDir, workflowID) 17 if err := os.MkdirAll(dir, 0755); err != nil { 18 return nil, fmt.Errorf("creating log dir: %w", err) 19 } 20 21 stdoutPath := logFilePath(baseDir, workflowID, "stdout", stepIdx) 22 stderrPath := logFilePath(baseDir, workflowID, "stderr", stepIdx) 23 24 stdoutFile, err := os.Create(stdoutPath) 25 if err != nil { 26 return nil, fmt.Errorf("creating stdout log file: %w", err) 27 } 28 29 stderrFile, err := os.Create(stderrPath) 30 if err != nil { 31 stdoutFile.Close() 32 return nil, fmt.Errorf("creating stderr log file: %w", err) 33 } 34 35 return &StepLogger{ 36 stdout: stdoutFile, 37 stderr: stderrFile, 38 }, nil 39} 40 41func (l *StepLogger) Stdout() io.Writer { 42 return l.stdout 43} 44 45func (l *StepLogger) Stderr() io.Writer { 46 return l.stderr 47} 48 49func (l *StepLogger) Close() error { 50 err1 := l.stdout.Close() 51 err2 := l.stderr.Close() 52 if err1 != nil { 53 return err1 54 } 55 return err2 56} 57 58func ReadStepLog(baseDir, workflowID, stream string, stepIdx int) (string, error) { 59 logPath := logFilePath(baseDir, workflowID, stream, stepIdx) 60 61 data, err := os.ReadFile(logPath) 62 if err != nil { 63 return "", fmt.Errorf("error reading log file: %w", err) 64 } 65 66 return string(data), nil 67} 68 69func logFilePath(baseDir, workflowID, stream string, stepIdx int) string { 70 logFilePath := filepath.Join(baseDir, workflowID, fmt.Sprintf("%d-%s.log", stepIdx, stream)) 71 return logFilePath 72}