-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: allow external loggers to be used with glog as default
- Loading branch information
Showing
3 changed files
with
127 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package ginoauth2 | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"os" | ||
|
||
"github.com/golang/glog" | ||
) | ||
|
||
// Logger is the interface used by GinOAuth2 to log messages. | ||
type Logger interface { | ||
Errorf(format string, args ...interface{}) | ||
Infof(format string, args ...interface{}) | ||
Debugf(format string, args ...interface{}) | ||
} | ||
|
||
type glogLogger struct { | ||
output io.Writer | ||
} | ||
|
||
// DefaultLogger is the default logger used by GinOAuth2 if no other logger is provided. | ||
// To use a different logger, set the DefaultLogger variable to a logger of your choice. | ||
// Replacement loggers must implement the Logger interface. | ||
// | ||
// Example: | ||
// | ||
// import "github.com/zalando/gin-oauth2" | ||
// | ||
// ginoauth2.DefaultLogger = &logrusLogger{} // use logrus | ||
var DefaultLogger Logger = &glogLogger{output: os.Stderr} | ||
|
||
func maskLogArgs(args ...interface{}) []interface{} { | ||
for i := range args { | ||
args[i] = maskAccessToken(args[i]) | ||
} | ||
|
||
return args | ||
} | ||
|
||
// SetOutput sets the output destination for the logger | ||
func (gl *glogLogger) setOutput(w io.Writer) { | ||
gl.output = w | ||
} | ||
|
||
// Errorf is a logging function using glog.Errorf | ||
func (gl *glogLogger) Errorf(f string, args ...interface{}) { | ||
glog.ErrorDepth(1, fmt.Sprintf(f, args...)) | ||
if gl.output != nil { | ||
fmt.Fprintf(gl.output, f+"\n", args...) | ||
} | ||
} | ||
|
||
// Infof is a logging function using glog.Infof | ||
func (gl *glogLogger) Infof(f string, args ...interface{}) { | ||
glog.InfoDepth(1, fmt.Sprintf(f, args...)) | ||
if gl.output != nil { | ||
fmt.Fprintf(gl.output, f+"\n", args...) | ||
} | ||
} | ||
|
||
// Debugf is a verbose logging function using glog.V(2) | ||
func (gl *glogLogger) Debugf(f string, args ...interface{}) { | ||
if glog.V(2) { | ||
glog.InfoDepth(1, fmt.Sprintf(f, args...)) | ||
} | ||
if gl.output != nil { | ||
fmt.Fprintf(gl.output, f+"\n", args...) | ||
} | ||
} | ||
|
||
func errorf(f string, args ...interface{}) { | ||
DefaultLogger.Errorf(f, maskLogArgs(args...)...) | ||
} | ||
|
||
func infof(f string, args ...interface{}) { | ||
DefaultLogger.Infof(f, maskLogArgs(args...)...) | ||
} | ||
|
||
func infofv2(f string, args ...interface{}) { | ||
DefaultLogger.Debugf(f, maskLogArgs(args...)...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package ginoauth2 | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
type mockLogger struct{ buffer bytes.Buffer } | ||
|
||
func (m *mockLogger) Errorf(format string, args ...interface{}) { | ||
m.buffer.WriteString(fmt.Sprintf("ERROR: "+format, args...)) | ||
} | ||
func (m *mockLogger) Infof(format string, args ...interface{}) { | ||
m.buffer.WriteString(fmt.Sprintf("INFO: "+format, args...)) | ||
} | ||
func (m *mockLogger) Debugf(format string, args ...interface{}) { | ||
m.buffer.WriteString(fmt.Sprintf("DEBUG: "+format, args...)) | ||
} | ||
|
||
func TestLogWithMaskedAccessToken(t *testing.T) { | ||
mockLog := &mockLogger{} | ||
DefaultLogger = mockLog | ||
tests := []struct{ name, input, expected string }{ | ||
{"With access token", "&access_token=abcdefghijklmnop&", "INFO: <MASK>&"}, | ||
{"Without access token", "no_token_here", "INFO: no_token_here"}, | ||
{"Empty string", "", "INFO: "}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
mockLog.buffer.Reset() | ||
|
||
infof("%s", tt.input) | ||
|
||
logOutput := mockLog.buffer.String() | ||
if logOutput != tt.expected { | ||
t.Errorf("Expected log to contain %q, got %q", tt.expected, logOutput) | ||
} | ||
if strings.Contains(logOutput, "abcdefghijklmnop") { | ||
t.Errorf("Log should not contain the original token") | ||
} | ||
}) | ||
} | ||
} |