Skip to content

Commit d7aec30

Browse files
authored
Merge pull request #539 from marle3003/develop
Develop
2 parents 4d5930a + 5e1fdeb commit d7aec30

File tree

19 files changed

+440
-71
lines changed

19 files changed

+440
-71
lines changed

docs/resources/blogs/debugging-mokapi-scripts.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ In this case, because the handler returns true, Mokapi will:
7070
This visibility is incredibly helpful when debugging complex request flows, especially if you have
7171
multiple handlers reacting to a single request.
7272

73+
<img src="/dashboard-event-handler-debugging.png" alt="Mokapi dashboard displaying event handler logs for a specific HTTP request." class="image shadow">
74+
7375
## Best Practices for Debugging
7476

7577
- Use console.log freely during development to trace values and decisions inside your scripts.

engine/common/host.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ type Logger interface {
5151
Warn(args ...interface{})
5252
Error(args ...interface{})
5353
Debug(args ...interface{})
54+
IsLevelEnabled(level string) bool
5455
}
5556

5657
type KafkaClient interface {

engine/engine.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func New(reader dynamic.Reader, app *runtime.App, config *static.Config, paralle
2727
return &Engine{
2828
scripts: make(map[string]*scriptHost),
2929
scheduler: NewDefaultScheduler(),
30-
logger: log.StandardLogger(),
30+
logger: newLogger(log.StandardLogger()),
3131
reader: reader,
3232
kafkaClient: NewKafkaClient(app),
3333
parallel: parallel,
@@ -39,7 +39,7 @@ func NewEngine(opts ...Options) *Engine {
3939
e := &Engine{
4040
scripts: make(map[string]*scriptHost),
4141
scheduler: NewDefaultScheduler(),
42-
logger: log.StandardLogger(),
42+
logger: newLogger(log.StandardLogger()),
4343
}
4444
for _, opt := range opts {
4545
opt(e)
@@ -134,3 +134,7 @@ func (e *Engine) Scripts() int {
134134
defer e.m.Unlock()
135135
return len(e.scripts)
136136
}
137+
138+
func (e *Engine) IsLevelEnabled(level string) bool {
139+
return e.logger.IsLevelEnabled(level)
140+
}

engine/enginetest/host.go

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,20 @@ import (
1010
)
1111

1212
type Host struct {
13-
OpenFileFunc func(file, hint string) (string, string, error)
14-
OpenFunc func(file, hint string) (*dynamic.Config, error)
15-
InfoFunc func(args ...interface{})
16-
WarnFunc func(args ...interface{})
17-
ErrorFunc func(args ...interface{})
18-
DebugFunc func(args ...interface{})
19-
HttpClientTest *HttpClient
20-
KafkaClientTest *KafkaClient
21-
EveryFunc func(every string, do func(), opt common.JobOptions)
22-
CronFunc func(every string, do func(), opt common.JobOptions)
23-
OnFunc func(event string, do func(args ...interface{}) (bool, error), tags map[string]string)
24-
FindFakerNodeFunc func(name string) *common.FakerTree
25-
m sync.Mutex
13+
OpenFileFunc func(file, hint string) (string, string, error)
14+
OpenFunc func(file, hint string) (*dynamic.Config, error)
15+
InfoFunc func(args ...interface{})
16+
WarnFunc func(args ...interface{})
17+
ErrorFunc func(args ...interface{})
18+
DebugFunc func(args ...interface{})
19+
IsLevelEnabledFunc func(level string) bool
20+
HttpClientTest *HttpClient
21+
KafkaClientTest *KafkaClient
22+
EveryFunc func(every string, do func(), opt common.JobOptions)
23+
CronFunc func(every string, do func(), opt common.JobOptions)
24+
OnFunc func(event string, do func(args ...interface{}) (bool, error), tags map[string]string)
25+
FindFakerNodeFunc func(name string) *common.FakerTree
26+
m sync.Mutex
2627
}
2728

2829
type HttpClient struct {
@@ -58,6 +59,13 @@ func (h *Host) Debug(args ...interface{}) {
5859
}
5960
}
6061

62+
func (h *Host) IsLevelEnabled(level string) bool {
63+
if h.IsLevelEnabledFunc == nil {
64+
return true
65+
}
66+
return h.IsLevelEnabledFunc(level)
67+
}
68+
6169
func (h *Host) OpenFile(file, hint string) (*dynamic.Config, error) {
6270
if h.OpenFileFunc != nil {
6371
p, src, err := h.OpenFileFunc(file, hint)

engine/enginetest/logger.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package enginetest
22

33
type Logger struct {
4-
InfoFunc func(args ...interface{})
5-
WarnFunc func(args ...interface{})
6-
ErrorFunc func(args ...interface{})
7-
DebugFunc func(args ...interface{})
4+
InfoFunc func(args ...interface{})
5+
WarnFunc func(args ...interface{})
6+
ErrorFunc func(args ...interface{})
7+
DebugFunc func(args ...interface{})
8+
IsLevelEnabledFunc func(level string) bool
89
}
910

1011
func (l *Logger) Info(args ...interface{}) {
@@ -34,3 +35,10 @@ func (l *Logger) Debug(args ...interface{}) {
3435
}
3536
l.DebugFunc(args...)
3637
}
38+
39+
func (l *Logger) IsLevelEnabled(level string) bool {
40+
if l.IsLevelEnabledFunc == nil {
41+
return true
42+
}
43+
return l.IsLevelEnabledFunc(level)
44+
}

engine/eventhandler_test.go

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package engine_test
22

33
import (
44
"github.com/stretchr/testify/require"
5+
"mokapi/engine"
56
"mokapi/engine/common"
67
"mokapi/engine/enginetest"
78
"testing"
@@ -11,6 +12,7 @@ func TestEventHandler(t *testing.T) {
1112
testcases := []struct {
1213
name string
1314
script string
15+
logger *enginetest.Logger
1416
run func(evt common.EventEmitter) []*common.Action
1517
test func(t *testing.T, actions []*common.Action, err error)
1618
}{
@@ -50,6 +52,48 @@ export default () => {
5052
require.Len(t, actions, 1)
5153
require.Len(t, actions[0].Logs, 1)
5254
require.Equal(t, "a log message from event handler", actions[0].Logs[0].Message)
55+
require.Equal(t, "log", actions[0].Logs[0].Level)
56+
},
57+
},
58+
{
59+
name: "console.warn",
60+
script: `import { on } from 'mokapi'
61+
export default () => {
62+
on('http', () => {
63+
console.warn('a log message from event handler')
64+
return true
65+
})
66+
}
67+
`,
68+
run: func(evt common.EventEmitter) []*common.Action {
69+
return evt.Emit("http")
70+
},
71+
test: func(t *testing.T, actions []*common.Action, err error) {
72+
require.NoError(t, err)
73+
require.Len(t, actions, 1)
74+
require.Len(t, actions[0].Logs, 1)
75+
require.Equal(t, "a log message from event handler", actions[0].Logs[0].Message)
76+
require.Equal(t, "warn", actions[0].Logs[0].Level)
77+
},
78+
},
79+
{
80+
name: "console.warn but not match log level",
81+
script: `import { on } from 'mokapi'
82+
export default () => {
83+
on('http', () => {
84+
console.warn('a log message from event handler')
85+
return true
86+
})
87+
}
88+
`,
89+
logger: &enginetest.Logger{IsLevelEnabledFunc: func(level string) bool { return false }},
90+
run: func(evt common.EventEmitter) []*common.Action {
91+
return evt.Emit("http")
92+
},
93+
test: func(t *testing.T, actions []*common.Action, err error) {
94+
require.NoError(t, err)
95+
require.Len(t, actions, 1)
96+
require.Len(t, actions[0].Logs, 0)
5397
},
5498
},
5599
{
@@ -110,7 +154,12 @@ export default () => {
110154
t.Run(tc.name, func(t *testing.T) {
111155
t.Parallel()
112156

113-
e := enginetest.NewEngine()
157+
var opts []engine.Options
158+
if tc.logger != nil {
159+
opts = append(opts, engine.WithLogger(tc.logger))
160+
}
161+
162+
e := enginetest.NewEngine(opts...)
114163
err := e.AddScript(newScript("test.js", tc.script))
115164

116165
var actions []*common.Action

engine/host.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,32 +188,36 @@ func (sh *scriptHost) close() {
188188

189189
func (sh *scriptHost) Info(args ...interface{}) {
190190
sh.engine.logger.Info(args...)
191-
if sh.actionLogger != nil {
191+
if sh.actionLogger != nil && sh.IsLevelEnabled("info") {
192192
sh.actionLogger("log", fmt.Sprint(args...))
193193
}
194194
}
195195

196196
func (sh *scriptHost) Warn(args ...interface{}) {
197197
sh.engine.logger.Warn(args...)
198-
if sh.actionLogger != nil {
198+
if sh.actionLogger != nil && sh.IsLevelEnabled("warn") {
199199
sh.actionLogger("warn", fmt.Sprint(args...))
200200
}
201201
}
202202

203203
func (sh *scriptHost) Error(args ...interface{}) {
204204
sh.engine.logger.Error(args...)
205-
if sh.actionLogger != nil {
205+
if sh.actionLogger != nil && sh.IsLevelEnabled("error") {
206206
sh.actionLogger("error", fmt.Sprint(args...))
207207
}
208208
}
209209

210210
func (sh *scriptHost) Debug(args ...interface{}) {
211211
sh.engine.logger.Debug(args...)
212-
if sh.actionLogger != nil {
212+
if sh.actionLogger != nil && sh.IsLevelEnabled("debug") {
213213
sh.actionLogger("debug", fmt.Sprint(args...))
214214
}
215215
}
216216

217+
func (e *scriptHost) IsLevelEnabled(level string) bool {
218+
return e.engine.IsLevelEnabled(level)
219+
}
220+
217221
func (sh *scriptHost) OpenFile(path string, hint string) (*dynamic.Config, error) {
218222
u, err := url.Parse(path)
219223
if err != nil || len(u.Scheme) == 0 || len(u.Opaque) > 0 {

engine/kafka_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func TestKafkaClient_Produce_Empty_Parameter(t *testing.T) {
4242
app := runtime.New(&static.Config{})
4343
e := enginetest.NewEngine(
4444
engine.WithKafkaClient(engine.NewKafkaClient(app)),
45-
engine.WithLogger(logrus.StandardLogger()),
45+
engine.WithDefaultLogger(),
4646
)
4747

4848
info, err := app.Kafka.Add(getConfig(config), e)
@@ -345,7 +345,7 @@ func TestKafkaClient_Produce(t *testing.T) {
345345
app := runtime.New(&static.Config{})
346346
e := enginetest.NewEngine(
347347
engine.WithKafkaClient(engine.NewKafkaClient(app)),
348-
engine.WithLogger(logrus.StandardLogger()),
348+
engine.WithDefaultLogger(),
349349
)
350350

351351
info, err := app.Kafka.Add(getConfig(config), e)

engine/logger.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package engine
2+
3+
import log "github.com/sirupsen/logrus"
4+
5+
type logger struct {
6+
logger *log.Logger
7+
}
8+
9+
func newLogger(l *log.Logger) *logger {
10+
return &logger{logger: l}
11+
}
12+
13+
func (l *logger) Debug(args ...interface{}) {
14+
l.logger.Debug(args...)
15+
}
16+
17+
func (l *logger) Info(args ...interface{}) {
18+
l.logger.Info(args...)
19+
}
20+
21+
func (l *logger) Error(args ...interface{}) {
22+
l.logger.Error(args...)
23+
}
24+
25+
func (l *logger) Warn(args ...interface{}) {
26+
l.logger.Warn(args...)
27+
}
28+
29+
func (l *logger) IsLevelEnabled(level string) bool {
30+
lvl, err := log.ParseLevel(level)
31+
if err != nil {
32+
return false
33+
}
34+
return l.logger.IsLevelEnabled(lvl)
35+
}

engine/options.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package engine
22

33
import (
4+
"github.com/sirupsen/logrus"
45
"mokapi/config/dynamic"
56
"mokapi/engine/common"
67
)
@@ -29,6 +30,12 @@ func WithScheduler(scheduler Scheduler) Options {
2930
}
3031
}
3132

33+
func WithDefaultLogger() Options {
34+
return func(e *Engine) {
35+
e.logger = newLogger(logrus.StandardLogger())
36+
}
37+
}
38+
3239
func WithLogger(logger common.Logger) Options {
3340
return func(e *Engine) {
3441
e.logger = logger

0 commit comments

Comments
 (0)