Skip to content

Commit 2a50d8a

Browse files
fzipitheseionCopilot
authored
feat: add new formatter log output for github (#59)
--------- Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org> Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent c7080a6 commit 2a50d8a

3 files changed

Lines changed: 178 additions & 17 deletions

File tree

go.sum

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ github.com/cli/shurcooL-graphql v0.0.4 h1:6MogPnQJLjKkaXPyGqPRXOI2qCsQdqNfUY1QSJ
2727
github.com/cli/shurcooL-graphql v0.0.4/go.mod h1:3waN4u02FiZivIV+p1y4d0Jo1jc6BViMA73C+sZo2fk=
2828
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
2929
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
30-
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
3130
github.com/coreruleset/wnram v0.1.0 h1:9tNgUX67h8E1WorbiU9OOlgKUJClYjunjBfb7cXPUas=
3231
github.com/coreruleset/wnram v0.1.0/go.mod h1:EeNpPR2NxOfy4x4yQtEQR+Tenn0Qpqcld+kZAzwc5dc=
3332
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
@@ -56,15 +55,8 @@ github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDz
5655
github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY=
5756
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
5857
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
59-
github.com/go-git/go-git/v5 v5.17.0 h1:AbyI4xf+7DsjINHMu35quAh4wJygKBKBuXVjV/pxesM=
60-
github.com/go-git/go-git/v5 v5.17.0/go.mod h1:f82C4YiLx+Lhi8eHxltLeGC5uBTXSFa6PC5WW9o4SjI=
61-
github.com/go-git/go-git/v5 v5.17.1 h1:WnljyxIzSj9BRRUlnmAU35ohDsjRK0EKmL0evDqi5Jk=
62-
github.com/go-git/go-git/v5 v5.17.1/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo=
63-
github.com/go-git/go-git/v5 v5.17.2 h1:B+nkdlxdYrvyFK4GPXVU8w1U+YkbsgciIR7f2sZJ104=
64-
github.com/go-git/go-git/v5 v5.17.2/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo=
6558
github.com/go-git/go-git/v5 v5.18.0 h1:O831KI+0PR51hM2kep6T8k+w0/LIAD490gvqMCvL5hM=
6659
github.com/go-git/go-git/v5 v5.18.0/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo=
67-
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
6860
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
6961
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
7062
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -115,12 +107,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
115107
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
116108
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
117109
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
118-
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
119-
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
120110
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
121111
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
122-
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
123-
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
124112
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
125113
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
126114
github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
@@ -141,9 +129,6 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
141129
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
142130
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
143131
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
144-
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
145-
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
146-
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
147132
github.com/rs/zerolog v1.35.0 h1:VD0ykx7HMiMJytqINBsKcbLS+BJ4WYjz+05us+LRTdI=
148133
github.com/rs/zerolog v1.35.0/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw=
149134
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -194,9 +179,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
194179
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
195180
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
196181
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
197-
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
198182
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
199-
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
200183
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
201184
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
202185
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=

logger/logger.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package logger
55

66
import (
7+
"fmt"
8+
"io"
79
"os"
810

911
"github.com/rs/zerolog"
@@ -16,3 +18,40 @@ func init() {
1618
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: "03:04:05"}).With().Caller().Logger()
1719
zerolog.SetGlobalLevel(DefaultLogLevel)
1820
}
21+
22+
func SetGithubOutput(w io.Writer) zerolog.Logger {
23+
ghOutput := zerolog.ConsoleWriter{Out: w, TimeFormat: "03:04:05"}
24+
ghOutput.FormatLevel = func(i interface{}) string {
25+
var l string
26+
if ll, ok := i.(string); ok {
27+
switch ll {
28+
case zerolog.LevelTraceValue, zerolog.LevelDebugValue:
29+
l = "debug"
30+
case zerolog.LevelInfoValue:
31+
l = "notice"
32+
case zerolog.LevelWarnValue:
33+
l = "warn"
34+
case zerolog.LevelErrorValue, zerolog.LevelFatalValue, zerolog.LevelPanicValue:
35+
l = "error "
36+
default:
37+
l = "???"
38+
}
39+
} else {
40+
if i == nil {
41+
l = "???"
42+
}
43+
}
44+
return fmt.Sprintf("::%s", l)
45+
}
46+
ghOutput.FormatMessage = func(i interface{}) string {
47+
return fmt.Sprintf("::%s\n", i)
48+
}
49+
ghOutput.PartsExclude = []string{zerolog.TimestampFieldName, zerolog.CallerFieldName}
50+
ghOutput.PartsOrder = []string{
51+
zerolog.LevelFieldName,
52+
zerolog.MessageFieldName,
53+
}
54+
ghOutput.NoColor = true
55+
56+
return log.Output(ghOutput).With().Caller().Logger()
57+
}

logger/logger_test.go

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// Copyright 2024 OWASP ModSecurity Core Rule Set Project
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package logger
5+
6+
import (
7+
"bytes"
8+
"testing"
9+
10+
"github.com/rs/zerolog"
11+
"github.com/stretchr/testify/suite"
12+
)
13+
14+
type loggerTestSuite struct {
15+
suite.Suite
16+
out *bytes.Buffer
17+
logger zerolog.Logger
18+
}
19+
20+
func TestRunLoggerTestSuite(t *testing.T) {
21+
suite.Run(t, new(loggerTestSuite))
22+
}
23+
24+
var testJsonBase = []struct {
25+
name string
26+
text string
27+
logLevel zerolog.Level
28+
want string
29+
}{
30+
{
31+
name: "JsonBaseOutput",
32+
text: "hello",
33+
logLevel: zerolog.InfoLevel,
34+
want: "message\":\"hello\"",
35+
},
36+
}
37+
38+
var testConsoleBase = []struct {
39+
name string
40+
text string
41+
logLevel zerolog.Level
42+
want string
43+
}{
44+
{
45+
name: "BaseConsoleOutput",
46+
text: "hello",
47+
logLevel: zerolog.InfoLevel,
48+
want: "INF hello component=parser-test",
49+
},
50+
}
51+
52+
var testGithub = []struct {
53+
name string
54+
text string
55+
logLevel zerolog.Level
56+
want string
57+
}{
58+
{
59+
name: "TestGithubInfoOutput",
60+
text: "this is an info message",
61+
logLevel: zerolog.InfoLevel,
62+
want: "::notice ::this is an info message",
63+
},
64+
{
65+
name: "TestGithubWarningOutput",
66+
text: "this is a warning message",
67+
logLevel: zerolog.WarnLevel,
68+
want: "::warn ::this is a warning message",
69+
},
70+
{
71+
name: "TestGithubTraceOutput",
72+
text: "this is a trace message that will show as debug",
73+
logLevel: zerolog.TraceLevel,
74+
want: "::debug ::this is a trace message that will show as debug",
75+
},
76+
{
77+
name: "TestGithubDebugOutput",
78+
text: "this is a debug message",
79+
logLevel: zerolog.DebugLevel,
80+
want: "::debug ::this is a debug message",
81+
},
82+
{
83+
name: "TestGithubErrorOutput",
84+
text: "this is an error message",
85+
logLevel: zerolog.ErrorLevel,
86+
want: "::error ::this is an error message",
87+
},
88+
{
89+
name: "TestGithubFatalOutput",
90+
text: "this is a fatal message",
91+
logLevel: zerolog.FatalLevel,
92+
want: "::error ::this is a fatal message",
93+
},
94+
{
95+
name: "TestGithubPanicOutput",
96+
text: "this is a panic message",
97+
logLevel: zerolog.PanicLevel,
98+
want: "::error ::this is a panic message",
99+
},
100+
}
101+
102+
func (s *loggerTestSuite) SetupTest() {
103+
// reset logger
104+
s.out = &bytes.Buffer{}
105+
s.logger = zerolog.New(s.out).With().Str("component", "parser-test").Logger()
106+
zerolog.SetGlobalLevel(zerolog.TraceLevel)
107+
}
108+
109+
func (s *loggerTestSuite) TestJsonOutput() {
110+
for _, t := range testJsonBase {
111+
s.Run(t.name, func() {
112+
s.logger.WithLevel(t.logLevel).Msg(t.text)
113+
s.Contains(s.out.String(), t.want)
114+
s.out.Reset()
115+
})
116+
}
117+
}
118+
119+
func (s *loggerTestSuite) TestConsoleOutput() {
120+
s.logger = s.logger.Output(zerolog.ConsoleWriter{Out: s.out, NoColor: true, TimeFormat: "03:04:05"})
121+
for _, t := range testConsoleBase {
122+
s.Run(t.name, func() {
123+
s.logger.WithLevel(t.logLevel).Msg(t.text)
124+
s.Contains(s.out.String(), t.want)
125+
s.out.Reset()
126+
})
127+
}
128+
}
129+
130+
func (s *loggerTestSuite) TestSetGithubOutput() {
131+
logger := SetGithubOutput(s.out)
132+
for _, t := range testGithub {
133+
s.Run(t.name, func() {
134+
logger.WithLevel(t.logLevel).Msg(t.text)
135+
s.Contains(s.out.String(), t.want)
136+
s.out.Reset()
137+
})
138+
}
139+
}

0 commit comments

Comments
 (0)