-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgo_step_logger.go
143 lines (117 loc) · 3.29 KB
/
go_step_logger.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package gosteps
import (
"io"
"os"
// "strings"
"github.com/rs/zerolog"
)
type LogLevel zerolog.Level
var (
// defaultLogOut is the default output for the logger
defaultLogOut = os.Stdout
// stateToLevelMap maps the StepState to the log level
stateToLevelMap = map[StepState]zerolog.Level{
StepStateComplete: zerolog.InfoLevel,
StepStateFailed: zerolog.WarnLevel,
StepStateSkipped: zerolog.DebugLevel,
StepStatePending: zerolog.DebugLevel,
StepStateError: zerolog.ErrorLevel,
}
// Log Level of GoSteps Logger implementation of zerolog.Level
DebugLevel = LogLevel(zerolog.DebugLevel)
InfoLevel = LogLevel(zerolog.InfoLevel)
WarnLevel = LogLevel(zerolog.WarnLevel)
ErrorLevel = LogLevel(zerolog.ErrorLevel)
)
type goStepsLogger struct {
config *LoggerOpts
logger zerolog.Logger
}
type LoggerOpts struct {
StepLoggingEnabled bool
}
// NewGoStepsLogger returns a new instance of the GoStepsLogger
//
// output: is of type io.Writer, example os.Stdout, for more options refer
// to zerolog documentation: https://github.com/rs/zerolog?tab=readme-ov-file#multiple-log-output
//
// loggerOpts: is of type *LoggerOpts, if nil, default options are used
// to enable step level logging, set StepLoggingEnabled to true
func NewGoStepsLogger(out io.Writer, loggerOpts *LoggerOpts) goStepsLogger {
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
if out == nil {
out = defaultLogOut
}
if loggerOpts == nil {
loggerOpts = &LoggerOpts{
StepLoggingEnabled: false,
}
}
return goStepsLogger{
config: loggerOpts,
logger: zerolog.New(out).With().Timestamp().Logger(),
}
}
type stepLogStruct struct {
Name string
State string
Message *string
Error error
RunCount int
MaxRun int
}
// getStepLogStruct returns the loggable struct for the step
func (step *Step) getStepLogStruct() stepLogStruct {
var stepError error
if step.stepResult.StepError != nil {
stepError = step.stepResult.StepError
}
return stepLogStruct{
Name: string(step.Name),
State: string(step.stepResult.StepState),
Message: step.stepResult.StepMessage,
Error: stepError,
RunCount: step.stepRunProgress.runCount,
MaxRun: step.StepOpts.MaxRunAttempts,
}
}
// loggableFormat returns the loggable format for the step
func (s stepLogStruct) loggableFormat() map[string]interface{} {
loggableFields := map[string]interface{}{
"maxRun": s.MaxRun,
}
if s.Error != nil {
loggableFields["error"] = s.Error
}
if s.Message != nil {
loggableFields["message"] = s.Message
}
return loggableFields
}
// log logs the step with the step name, state, run count and the log fields
// it is only used by the step if the step logging is enabled
func (c *GoStepsCtx) log(step *Step) {
lStruct := step.getStepLogStruct()
c.logger.logger.WithLevel(
stateToLevelMap[step.stepResult.StepState],
).Str(
"step", string(lStruct.Name),
).Str(
"state", lStruct.State,
).Int(
"runCount", lStruct.RunCount,
).Fields(
lStruct.loggableFormat(),
).Msg("")
}
// Log logs the message with the step name and the log level, if provided.
// The log level is the first argument in the args.
func (c *GoStepsCtx) Log(message string, levels ...LogLevel) {
ll := InfoLevel
if len(levels) > 0 {
ll = levels[0]
}
c.logger.logger.WithLevel(zerolog.Level(ll)).Str(
"step", string(c.currentStep),
).Msg(message)
}