at master 102 lines 2.4 kB view raw
1package models 2 3import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "os" 8 "path/filepath" 9 "strings" 10) 11 12type WorkflowLogger interface { 13 Close() error 14 DataWriter(idx int, stream string) io.Writer 15 ControlWriter(idx int, step Step, stepStatus StepStatus) io.Writer 16} 17 18type NullLogger struct{} 19 20func (l NullLogger) Close() error { return nil } 21func (l NullLogger) DataWriter(idx int, stream string) io.Writer { return io.Discard } 22func (l NullLogger) ControlWriter(idx int, step Step, stepStatus StepStatus) io.Writer { 23 return io.Discard 24} 25 26type FileWorkflowLogger struct { 27 file *os.File 28 encoder *json.Encoder 29 mask *SecretMask 30} 31 32func NewFileWorkflowLogger(baseDir string, wid WorkflowId, secretValues []string) (WorkflowLogger, error) { 33 path := LogFilePath(baseDir, wid) 34 file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) 35 if err != nil { 36 return nil, fmt.Errorf("creating log file: %w", err) 37 } 38 return &FileWorkflowLogger{ 39 file: file, 40 encoder: json.NewEncoder(file), 41 mask: NewSecretMask(secretValues), 42 }, nil 43} 44 45func LogFilePath(baseDir string, workflowID WorkflowId) string { 46 logFilePath := filepath.Join(baseDir, fmt.Sprintf("%s.log", workflowID.String())) 47 return logFilePath 48} 49 50func (l *FileWorkflowLogger) Close() error { 51 return l.file.Close() 52} 53 54func (l *FileWorkflowLogger) DataWriter(idx int, stream string) io.Writer { 55 return &dataWriter{ 56 logger: l, 57 idx: idx, 58 stream: stream, 59 } 60} 61 62func (l *FileWorkflowLogger) ControlWriter(idx int, step Step, stepStatus StepStatus) io.Writer { 63 return &controlWriter{ 64 logger: l, 65 idx: idx, 66 step: step, 67 stepStatus: stepStatus, 68 } 69} 70 71type dataWriter struct { 72 logger *FileWorkflowLogger 73 idx int 74 stream string 75} 76 77func (w *dataWriter) Write(p []byte) (int, error) { 78 line := strings.TrimRight(string(p), "\r\n") 79 if w.logger.mask != nil { 80 line = w.logger.mask.Mask(line) 81 } 82 entry := NewDataLogLine(w.idx, line, w.stream) 83 if err := w.logger.encoder.Encode(entry); err != nil { 84 return 0, err 85 } 86 return len(p), nil 87} 88 89type controlWriter struct { 90 logger *FileWorkflowLogger 91 idx int 92 step Step 93 stepStatus StepStatus 94} 95 96func (w *controlWriter) Write(_ []byte) (int, error) { 97 entry := NewControlLogLine(w.idx, w.step, w.stepStatus) 98 if err := w.logger.encoder.Encode(entry); err != nil { 99 return 0, err 100 } 101 return len(w.step.Name()), nil 102}