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