From a7afc248895dc717960bcf20685e041f9bb45d34 Mon Sep 17 00:00:00 2001 From: soh335 Date: Fri, 23 Mar 2018 18:34:14 +0900 Subject: [PATCH 1/2] Add DisableEscapeHTML option for json logger --- log/json_logger.go | 23 ++++++++++++++++++++--- log/json_logger_test.go | 13 +++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/log/json_logger.go b/log/json_logger.go index 66094b4dd..5da47c37e 100644 --- a/log/json_logger.go +++ b/log/json_logger.go @@ -10,14 +10,29 @@ import ( type jsonLogger struct { io.Writer + disableEscapeHTML bool } // NewJSONLogger returns a Logger that encodes keyvals to the Writer as a // single JSON object. Each log event produces no more than one call to // w.Write. The passed Writer must be safe for concurrent use by multiple // goroutines if the returned Logger will be used concurrently. -func NewJSONLogger(w io.Writer) Logger { - return &jsonLogger{w} +func NewJSONLogger(w io.Writer, options ...JSONLoggerOption) Logger { + l := &jsonLogger{ + Writer: w, + } + for _, option := range options { + option(l) + } + return l +} + +// JSONLoggerOption sets a parameter for json logger +type JSONLoggerOption func(*jsonLogger) + +// DisableEscapeHTML disable to escape &, <, >. +func DisableEscapeHTML(v bool) JSONLoggerOption { + return func(j *jsonLogger) { j.disableEscapeHTML = v } } func (l *jsonLogger) Log(keyvals ...interface{}) error { @@ -31,7 +46,9 @@ func (l *jsonLogger) Log(keyvals ...interface{}) error { } merge(m, k, v) } - return json.NewEncoder(l.Writer).Encode(m) + enc := json.NewEncoder(l.Writer) + enc.SetEscapeHTML(!l.disableEscapeHTML) + return enc.Encode(m) } func merge(dst map[string]interface{}, k, v interface{}) { diff --git a/log/json_logger_test.go b/log/json_logger_test.go index e3e309090..83a68fb3c 100644 --- a/log/json_logger_test.go +++ b/log/json_logger_test.go @@ -73,6 +73,19 @@ func TestJSONLoggerNilErrorValue(t *testing.T) { } } +func TestJSONLoggerWithDisableHTMLEscapeOption(t *testing.T) { + t.Parallel() + + buf := &bytes.Buffer{} + logger := log.NewJSONLogger(buf, log.DisableEscapeHTML(true)) + if err := logger.Log("a", "<&>"); err != nil { + t.Fatal(err) + } + if want, have := `{"a":"<&>"}`+"\n", buf.String(); want != have { + t.Errorf("\nwant %#v\nhave %#v", want, have) + } +} + // aller implements json.Marshaler, encoding.TextMarshaler, and fmt.Stringer. type aller struct{} From 4b65eab7730cb51f6a2f1b1b06356f464b3c5f49 Mon Sep 17 00:00:00 2001 From: soh335 Date: Thu, 29 Mar 2018 10:59:48 +0900 Subject: [PATCH 2/2] DisableEscapeHTML -> SetEscapeHTML --- log/json_logger.go | 10 +++++----- log/json_logger_test.go | 21 ++++++++++++++------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/log/json_logger.go b/log/json_logger.go index 5da47c37e..1886d5374 100644 --- a/log/json_logger.go +++ b/log/json_logger.go @@ -10,7 +10,7 @@ import ( type jsonLogger struct { io.Writer - disableEscapeHTML bool + escapeHTML bool } // NewJSONLogger returns a Logger that encodes keyvals to the Writer as a @@ -30,9 +30,9 @@ func NewJSONLogger(w io.Writer, options ...JSONLoggerOption) Logger { // JSONLoggerOption sets a parameter for json logger type JSONLoggerOption func(*jsonLogger) -// DisableEscapeHTML disable to escape &, <, >. -func DisableEscapeHTML(v bool) JSONLoggerOption { - return func(j *jsonLogger) { j.disableEscapeHTML = v } +// SetEscapeHTML escape &, <, > inside JSON quoted strings. +func SetEscapeHTML(v bool) JSONLoggerOption { + return func(j *jsonLogger) { j.escapeHTML = v } } func (l *jsonLogger) Log(keyvals ...interface{}) error { @@ -47,7 +47,7 @@ func (l *jsonLogger) Log(keyvals ...interface{}) error { merge(m, k, v) } enc := json.NewEncoder(l.Writer) - enc.SetEscapeHTML(!l.disableEscapeHTML) + enc.SetEscapeHTML(l.escapeHTML) return enc.Encode(m) } diff --git a/log/json_logger_test.go b/log/json_logger_test.go index 83a68fb3c..bae8c5f1b 100644 --- a/log/json_logger_test.go +++ b/log/json_logger_test.go @@ -73,17 +73,24 @@ func TestJSONLoggerNilErrorValue(t *testing.T) { } } -func TestJSONLoggerWithDisableHTMLEscapeOption(t *testing.T) { +func TestJSONLoggerWithSetHTMLEscapeOption(t *testing.T) { t.Parallel() buf := &bytes.Buffer{} - logger := log.NewJSONLogger(buf, log.DisableEscapeHTML(true)) - if err := logger.Log("a", "<&>"); err != nil { - t.Fatal(err) - } - if want, have := `{"a":"<&>"}`+"\n", buf.String(); want != have { - t.Errorf("\nwant %#v\nhave %#v", want, have) + for b, want := range map[bool]string{ + false: `{"a":"<&>"}` + "\n", + true: `{"a":"\u003c\u0026\u003e"}` + "\n", + } { + buf.Reset() + logger := log.NewJSONLogger(buf, log.SetEscapeHTML(b)) + if err := logger.Log("a", "<&>"); err != nil { + t.Fatal(err) + } + if have := buf.String(); want != have { + t.Errorf("\nwant %#v\nhave %#v", want, have) + } } + } // aller implements json.Marshaler, encoding.TextMarshaler, and fmt.Stringer.