at master 1.9 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 struct { 13 file *os.File 14 encoder *json.Encoder 15 mask *SecretMask 16} 17 18func NewWorkflowLogger(baseDir string, wid WorkflowId, secretValues []string) (*WorkflowLogger, error) { 19 path := LogFilePath(baseDir, wid) 20 21 file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) 22 if err != nil { 23 return nil, fmt.Errorf("creating log file: %w", err) 24 } 25 26 return &WorkflowLogger{ 27 file: file, 28 encoder: json.NewEncoder(file), 29 mask: NewSecretMask(secretValues), 30 }, nil 31} 32 33func LogFilePath(baseDir string, workflowID WorkflowId) string { 34 logFilePath := filepath.Join(baseDir, fmt.Sprintf("%s.log", workflowID.String())) 35 return logFilePath 36} 37 38func (l *WorkflowLogger) Close() error { 39 return l.file.Close() 40} 41 42func (l *WorkflowLogger) DataWriter(idx int, stream string) io.Writer { 43 return &dataWriter{ 44 logger: l, 45 idx: idx, 46 stream: stream, 47 } 48} 49 50func (l *WorkflowLogger) ControlWriter(idx int, step Step, stepStatus StepStatus) io.Writer { 51 return &controlWriter{ 52 logger: l, 53 idx: idx, 54 step: step, 55 stepStatus: stepStatus, 56 } 57} 58 59type dataWriter struct { 60 logger *WorkflowLogger 61 idx int 62 stream string 63} 64 65func (w *dataWriter) Write(p []byte) (int, error) { 66 line := strings.TrimRight(string(p), "\r\n") 67 if w.logger.mask != nil { 68 line = w.logger.mask.Mask(line) 69 } 70 entry := NewDataLogLine(w.idx, line, w.stream) 71 if err := w.logger.encoder.Encode(entry); err != nil { 72 return 0, err 73 } 74 return len(p), nil 75} 76 77type controlWriter struct { 78 logger *WorkflowLogger 79 idx int 80 step Step 81 stepStatus StepStatus 82} 83 84func (w *controlWriter) Write(_ []byte) (int, error) { 85 entry := NewControlLogLine(w.idx, w.step, w.stepStatus) 86 if err := w.logger.encoder.Encode(entry); err != nil { 87 return 0, err 88 } 89 return len(w.step.Name()), nil 90}