Skip to content

Commit 2966db0

Browse files
committed
fix(log): properly set logrus level (#327)
(cherry picked from commit 8b9ec59)
1 parent 23d086e commit 2966db0

File tree

5 files changed

+183
-51
lines changed

5 files changed

+183
-51
lines changed

envbuilder.go

+12-4
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,13 @@ func Run(ctx context.Context, opts options.Options) error {
278278
}
279279
}
280280

281-
HijackLogrus(func(entry *logrus.Entry) {
281+
lvl := log.LevelInfo
282+
if opts.Verbose {
283+
lvl = log.LevelDebug
284+
}
285+
log.HijackLogrus(lvl, func(entry *logrus.Entry) {
282286
for _, line := range strings.Split(entry.Message, "\r") {
283-
opts.Logger(log.LevelInfo, "#%d: %s", stageNumber, color.HiBlackString(line))
287+
opts.Logger(log.FromLogrus(entry.Level), "#%d: %s", stageNumber, color.HiBlackString(line))
284288
}
285289
})
286290

@@ -1050,9 +1054,13 @@ func RunCacheProbe(ctx context.Context, opts options.Options) (v1.Image, error)
10501054
return nil, fmt.Errorf("no Dockerfile or devcontainer.json found")
10511055
}
10521056

1053-
HijackLogrus(func(entry *logrus.Entry) {
1057+
lvl := log.LevelInfo
1058+
if opts.Verbose {
1059+
lvl = log.LevelDebug
1060+
}
1061+
log.HijackLogrus(lvl, func(entry *logrus.Entry) {
10541062
for _, line := range strings.Split(entry.Message, "\r") {
1055-
opts.Logger(log.LevelInfo, "#%d: %s", stageNumber, color.HiBlackString(line))
1063+
opts.Logger(log.FromLogrus(entry.Level), "#%d: %s", stageNumber, color.HiBlackString(line))
10561064
}
10571065
})
10581066

log.go

-28
This file was deleted.

log/logrus.go

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package log
2+
3+
import (
4+
"io"
5+
6+
"github.com/sirupsen/logrus"
7+
)
8+
9+
// HijackLogrus hijacks the logrus logger and calls the callback for each log entry.
10+
// This is an abuse of logrus, the package that Kaniko uses, but it exposes
11+
// no other way to obtain the log entries.
12+
func HijackLogrus(lvl Level, callback func(entry *logrus.Entry)) {
13+
logrus.StandardLogger().SetOutput(io.Discard)
14+
logrus.StandardLogger().SetLevel(ToLogrus(lvl))
15+
logrus.StandardLogger().SetFormatter(&logrusFormatter{
16+
callback: callback,
17+
empty: []byte{},
18+
})
19+
}
20+
21+
type logrusFormatter struct {
22+
callback func(entry *logrus.Entry)
23+
empty []byte
24+
}
25+
26+
func (f *logrusFormatter) Format(entry *logrus.Entry) ([]byte, error) {
27+
f.callback(entry)
28+
return f.empty, nil
29+
}
30+
31+
func ToLogrus(lvl Level) logrus.Level {
32+
switch lvl {
33+
case LevelTrace:
34+
return logrus.TraceLevel
35+
case LevelDebug:
36+
return logrus.DebugLevel
37+
case LevelInfo:
38+
return logrus.InfoLevel
39+
case LevelWarn:
40+
return logrus.WarnLevel
41+
case LevelError:
42+
return logrus.ErrorLevel
43+
default:
44+
return logrus.InfoLevel
45+
}
46+
}
47+
48+
func FromLogrus(lvl logrus.Level) Level {
49+
switch lvl {
50+
case logrus.TraceLevel:
51+
return LevelTrace
52+
case logrus.DebugLevel:
53+
return LevelDebug
54+
case logrus.InfoLevel:
55+
return LevelInfo
56+
case logrus.WarnLevel:
57+
return LevelWarn
58+
default: // Error, Fatal, Panic
59+
return LevelError
60+
}
61+
}

log/logrus_test.go

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package log_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
8+
"github.com/coder/envbuilder/log"
9+
"github.com/sirupsen/logrus"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestHijackLogrus_Info(t *testing.T) {
14+
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
15+
t.Cleanup(cancel)
16+
messages := make(chan *logrus.Entry)
17+
18+
logf := func(entry *logrus.Entry) {
19+
t.Logf("got msg level: %s msg: %q", entry.Level, entry.Message)
20+
messages <- entry
21+
}
22+
23+
log.HijackLogrus(log.LevelInfo, logf)
24+
25+
done := make(chan struct{})
26+
go func() {
27+
defer close(done)
28+
// The following should be filtered out.
29+
logrus.Trace("Tracing!")
30+
logrus.Debug("Debugging!")
31+
// We should receive the below.
32+
logrus.Info("Testing!")
33+
logrus.Warn("Warning!")
34+
logrus.Error("Error!")
35+
}()
36+
37+
require.Equal(t, "Testing!", rcvCtx(ctx, t, messages).Message)
38+
require.Equal(t, "Warning!", rcvCtx(ctx, t, messages).Message)
39+
require.Equal(t, "Error!", rcvCtx(ctx, t, messages).Message)
40+
<-done
41+
}
42+
43+
func TestHijackLogrus_Debug(t *testing.T) {
44+
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
45+
t.Cleanup(cancel)
46+
messages := make(chan *logrus.Entry)
47+
48+
logf := func(entry *logrus.Entry) {
49+
t.Logf("got msg level: %s msg: %q", entry.Level, entry.Message)
50+
messages <- entry
51+
}
52+
53+
log.HijackLogrus(log.LevelDebug, logf)
54+
55+
done := make(chan struct{})
56+
go func() {
57+
defer close(done)
58+
// The following should be filtered out.
59+
logrus.Trace("Tracing!")
60+
// We should receive the below.
61+
logrus.Debug("Debugging!")
62+
logrus.Info("Testing!")
63+
logrus.Warn("Warning!")
64+
logrus.Error("Error!")
65+
}()
66+
67+
require.Equal(t, "Debugging!", rcvCtx(ctx, t, messages).Message)
68+
require.Equal(t, "Testing!", rcvCtx(ctx, t, messages).Message)
69+
require.Equal(t, "Warning!", rcvCtx(ctx, t, messages).Message)
70+
require.Equal(t, "Error!", rcvCtx(ctx, t, messages).Message)
71+
<-done
72+
}
73+
74+
func TestHijackLogrus_Error(t *testing.T) {
75+
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
76+
t.Cleanup(cancel)
77+
messages := make(chan *logrus.Entry)
78+
79+
logf := func(entry *logrus.Entry) {
80+
t.Logf("got msg level: %s msg: %q", entry.Level, entry.Message)
81+
messages <- entry
82+
}
83+
84+
log.HijackLogrus(log.LevelError, logf)
85+
86+
done := make(chan struct{})
87+
go func() {
88+
defer close(done)
89+
// The following should be filtered out.
90+
logrus.Trace("Tracing!")
91+
logrus.Debug("Debugging!")
92+
logrus.Info("Testing!")
93+
logrus.Warn("Warning!")
94+
// We should receive the below.
95+
logrus.Error("Error!")
96+
}()
97+
98+
require.Equal(t, "Error!", rcvCtx(ctx, t, messages).Message)
99+
<-done
100+
}
101+
102+
func rcvCtx[T any](ctx context.Context, t *testing.T, ch <-chan T) (v T) {
103+
t.Helper()
104+
select {
105+
case <-ctx.Done():
106+
t.Fatal("timeout")
107+
case v = <-ch:
108+
}
109+
return v
110+
}

log_test.go

-19
This file was deleted.

0 commit comments

Comments
 (0)