Skip to content

Commit ec2a21e

Browse files
authored
Add acccess log formatter (#3458)
This PR adds the ability to use a custom access log formatter. Currently, accessLogs can be configured in three ways: - If `AccessLogJSONEnabled` is defined, you can either pass a JSONFormatter, or have Skipper initialize one. - If `AccessLogJSONEnabled` is not defined, it uses a basic text formatter. There are cases (for example, when configuring NewRelic logrus integration, [see here](https://github.com/newrelic/go-agent/tree/master/v3/integrations/logcontext-v2/nrlogrus), that a custom formatter is needed, but current logger can't be configured. My initial approach was to change type on `AccessLogJsonFormatter` (typed parameter in Skipper options) to be able to pass any logrus.Formatter (interface), as it wouldn't break anything. But it would be weird to have something called `JSONFormatter` that may not be a JSON formatter. Signed-off-by: Xavi Ivars <[email protected]>
1 parent 6b448b1 commit ec2a21e

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

logging/log.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@ type Options struct {
4444

4545
// AccessLogJsonFormatter, when set and JSON logging is enabled, is passed along to to the underlying
4646
// Logrus logger for access logs. To enable structured logging, use AccessLogJSONEnabled.
47+
// Deprecated: use [AccessLogFormatter].
4748
AccessLogJsonFormatter *logrus.JSONFormatter
49+
50+
// AccessLogFormatter, when set is passed along to the underlying Logrus logger for access logs.
51+
AccessLogFormatter logrus.Formatter
4852
}
4953

5054
func (f *prefixFormatter) Format(e *logrus.Entry) ([]byte, error) {
@@ -74,7 +78,9 @@ func initApplicationLog(o Options) {
7478

7579
func initAccessLog(o Options) {
7680
l := logrus.New()
77-
if o.AccessLogJSONEnabled {
81+
if o.AccessLogFormatter != nil {
82+
l.Formatter = o.AccessLogFormatter
83+
} else if o.AccessLogJSONEnabled {
7884
if o.AccessLogJsonFormatter != nil {
7985
l.Formatter = o.AccessLogJsonFormatter
8086
} else {

logging/log_test.go

+25
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,28 @@ func TestApplicationLogJSONWithCustomFormatter(t *testing.T) {
121121
t.Errorf("unexpected field count")
122122
}
123123
}
124+
125+
type customFormatter struct {
126+
innerFormatter *log.JSONFormatter
127+
}
128+
129+
func (f *customFormatter) Format(entry *log.Entry) ([]byte, error) {
130+
originalBytes, err := f.innerFormatter.Format(entry)
131+
if err != nil {
132+
return nil, err
133+
}
134+
newBytes := bytes.NewBuffer(originalBytes)
135+
newBytes.WriteString(" - Custom Suffix")
136+
return newBytes.Bytes(), nil
137+
}
138+
139+
func TestAccessLogFormatterTakesPrecedence(t *testing.T) {
140+
var buf bytes.Buffer
141+
f := &customFormatter{innerFormatter: &log.JSONFormatter{}}
142+
Init(Options{AccessLogOutput: &buf, AccessLogFormatter: f})
143+
LogAccess(&AccessEntry{StatusCode: http.StatusTeapot}, nil)
144+
s := buf.String()
145+
if !strings.Contains(s, " - Custom Suffix") {
146+
t.Error("failed to use custom access log output")
147+
}
148+
}

skipper.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -619,10 +619,14 @@ type Options struct {
619619
// from the request URI in the access logs.
620620
AccessLogStripQuery bool
621621

622-
// AccessLogJsonFormatter, when set and JSON logging is enabled, is passed along to to the underlying
622+
// AccessLogJsonFormatter, when set and JSON logging is enabled, is passed along to the underlying
623623
// Logrus logger for access logs. To enable structured logging, use AccessLogJSONEnabled.
624+
// Deprecated: use [AccessLogFormatter].
624625
AccessLogJsonFormatter *log.JSONFormatter
625626

627+
// AccessLogFormatter, when set is passed along to the underlying Logrus logger for access logs.
628+
AccessLogFormatter log.Formatter
629+
626630
DebugListener string
627631

628632
// Path of certificate(s) when using TLS, multiple may be given comma separated
@@ -1177,6 +1181,7 @@ func initLog(o Options) error {
11771181
AccessLogJSONEnabled: o.AccessLogJSONEnabled,
11781182
AccessLogStripQuery: o.AccessLogStripQuery,
11791183
AccessLogJsonFormatter: o.AccessLogJsonFormatter,
1184+
AccessLogFormatter: o.AccessLogFormatter,
11801185
})
11811186

11821187
return nil

0 commit comments

Comments
 (0)