diff options
| author | Felix Hanley <felix@userspace.com.au> | 2017-11-28 04:05:50 +0000 |
|---|---|---|
| committer | Felix Hanley <felix@userspace.com.au> | 2017-11-28 04:06:25 +0000 |
| commit | aeaf184905c94143dacfc7d9e3b08f179121ba4d (patch) | |
| tree | 3adf5667b87d8083b3cacde3ef40c8607332726e | |
| parent | be3cf83fff7b64eb04146f9195de6abe71bbe5db (diff) | |
| download | logger-aeaf184905c94143dacfc7d9e3b08f179121ba4d.tar.gz logger-aeaf184905c94143dacfc7d9e3b08f179121ba4d.tar.bz2 | |
Update output to be more uniform, adding support for map arguments
| -rw-r--r-- | default.go | 3 | ||||
| -rw-r--r-- | level.go | 14 | ||||
| -rw-r--r-- | log.go | 70 | ||||
| -rw-r--r-- | logger.go | 1 | ||||
| -rw-r--r-- | logger_test.go | 18 | ||||
| -rw-r--r-- | outputs/json/json.go | 9 | ||||
| -rw-r--r-- | outputs/json/json_test.go | 16 | ||||
| -rw-r--r-- | outputs/keyvalue/keyvalue.go | 21 | ||||
| -rw-r--r-- | outputs/keyvalue/keyvalue_test.go | 16 |
9 files changed, 103 insertions, 65 deletions
@@ -20,8 +20,7 @@ func (dw DefaultWriter) Write(w io.Writer, m Message) { io.WriteString(w, prefix) if m.Name != "" { - io.WriteString(w, " ") - io.WriteString(w, m.Name) + io.WriteString(w, fmt.Sprintf(" %s:", m.Name)) } for _, f := range m.Fields { @@ -1,13 +1,19 @@ package logger +// Level defines the logger output level type Level int const ( + // NoLevel is prior to being defined NoLevel Level = 0 - Debug Level = 1 - Info Level = 2 - Warn Level = 3 - Error Level = 4 + // Debug is for development + Debug Level = 1 + // Info are for interesting runtime events + Info Level = 2 + // Warn is for almost errors + Warn Level = 3 + // Error is a runtime problem + Error Level = 4 ) func (lvl Level) String() string { @@ -17,6 +17,7 @@ type logger struct { out *bufio.Writer } +// New creates a new logger func New(opts *Options) Logger { if opts == nil { opts = &Options{} @@ -53,6 +54,7 @@ func New(opts *Options) Logger { return &l } +// Log is a generic logger function func (l logger) Log(lvl Level, args ...interface{}) { if lvl < l.level { return @@ -70,13 +72,27 @@ func (l logger) Log(lvl Level, args ...interface{}) { Fields: make([]interface{}, 0), } - offset := 0 - if len(args)%2 != 0 { - msg.Fields = append(msg.Fields, "message", args[0]) - offset = 1 - } - for i := offset; i < len(args); i = i + 2 { - msg.Fields = append(msg.Fields, ToString(args[i]), args[i+1]) + for _, f := range args { + switch c := f.(type) { + case map[string]string: + for k, v := range c { + msg.Fields = append(msg.Fields, k, v) + } + case map[string]int: + for k, v := range c { + msg.Fields = append(msg.Fields, k, v) + } + case map[int]string: + for k, v := range c { + msg.Fields = append(msg.Fields, k, v) + } + case map[string]interface{}: + for k, v := range c { + msg.Fields = append(msg.Fields, k, v) + } + default: + msg.Fields = append(msg.Fields, c) + } } l.formatter.Write(l.out, msg) @@ -84,39 +100,29 @@ func (l logger) Log(lvl Level, args ...interface{}) { l.out.Flush() } -func (l logger) Debug(args ...interface{}) { - l.Log(Debug, args...) -} - -func (l logger) Warn(args ...interface{}) { - l.Log(Warn, args...) -} - -func (l logger) Error(args ...interface{}) { - l.Log(Error, args...) -} - -func (l logger) Info(args ...interface{}) { - l.Log(Info, args...) -} - -func (l logger) IsLevel(lvl Level) bool { - return l.level <= lvl -} +// Convenience functions for logging at levels +func (l logger) Debug(args ...interface{}) { l.Log(Debug, args...) } +func (l logger) Warn(args ...interface{}) { l.Log(Warn, args...) } +func (l logger) Error(args ...interface{}) { l.Log(Error, args...) } +func (l logger) Info(args ...interface{}) { l.Log(Info, args...) } -func (l *logger) IsDebug() bool { return l.IsLevel(Debug) } -func (l *logger) IsInfo() bool { return l.IsLevel(Info) } -func (l *logger) IsWarn() bool { return l.IsLevel(Warn) } -func (l *logger) IsError() bool { return l.IsLevel(Error) } +// Test for current logging level +func (l logger) IsLevel(lvl Level) bool { return l.level <= lvl } +func (l *logger) IsDebug() bool { return l.IsLevel(Debug) } +func (l *logger) IsInfo() bool { return l.IsLevel(Info) } +func (l *logger) IsWarn() bool { return l.IsLevel(Warn) } +func (l *logger) IsError() bool { return l.IsLevel(Error) } +// WithFields sets the default fields for a new logger func (l *logger) WithFields(args ...interface{}) Logger { - var nl logger = *l + var nl = *l nl.fields = append(nl.fields, args...) return &nl } +// Named sets the name for a new logger func (l *logger) Named(name string) Logger { - var nl logger = *l + var nl = *l if nl.name != "" { nl.name = nl.name + "." + name } else { @@ -1,5 +1,6 @@ package logger +// Logger defines our methods type Logger interface { Log(level Level, args ...interface{}) Info(args ...interface{}) diff --git a/logger_test.go b/logger_test.go index cd51b8e..ec9b78c 100644 --- a/logger_test.go +++ b/logger_test.go @@ -12,23 +12,27 @@ func TestDefaultWriter(t *testing.T) { out string }{ { - in: []interface{}{"test message"}, - out: "[INFO ] test message test message", + in: []interface{}{"one"}, + out: "[INFO ] testlog: one", }, { - in: []interface{}{"test message", "name", "me"}, - out: "[INFO ] test message test message name me", + in: []interface{}{"one", "two", "2"}, + out: "[INFO ] testlog: one two 2", }, { - in: []interface{}{"test message", "name", "me", "number", 2}, - out: "[INFO ] test message test message name me number 2", + in: []interface{}{"one", "two", "2", "three", 3}, + out: "[INFO ] testlog: one two 2 three 3", + }, + { + in: []interface{}{"one", map[string]string{"two": "2", "three": "3"}}, + out: "[INFO ] testlog: one two 2 three 3", }, } for _, tt := range tests { var buf bytes.Buffer logger := New(&Options{ - Name: "test", + Name: "testlog", Output: &buf, }) diff --git a/outputs/json/json.go b/outputs/json/json.go index b170c2b..d7924ad 100644 --- a/outputs/json/json.go +++ b/outputs/json/json.go @@ -22,8 +22,13 @@ func (w Writer) Write(lw io.Writer, m logger.Message) { "@time": m.Time, } - for i := 0; i < len(m.Fields); i = i + 2 { - vals[m.Fields[i].(string)] = m.Fields[i+1] + offset := len(m.Fields) % 2 + if offset != 0 { + vals["message"] = logger.ToString(m.Fields[0]) + } + + for i := offset; i < len(m.Fields); i = i + 2 { + vals[logger.ToString(m.Fields[i])] = m.Fields[i+1] } err := json.NewEncoder(lw).Encode(vals) diff --git a/outputs/json/json_test.go b/outputs/json/json_test.go index d5f436e..8142fa9 100644 --- a/outputs/json/json_test.go +++ b/outputs/json/json_test.go @@ -14,16 +14,20 @@ func TestWriter(t *testing.T) { out map[string]interface{} }{ { - in: []interface{}{"test message"}, - out: map[string]interface{}{"@level": "info", "@name": "test", "message": "test message"}, + in: []interface{}{"one"}, + out: map[string]interface{}{"@level": "info", "@name": "test", "message": "one"}, }, { - in: []interface{}{"test message", "name", "me"}, - out: map[string]interface{}{"@level": "info", "@name": "test", "message": "test message", "name": "me"}, + in: []interface{}{"one", "two", "2"}, + out: map[string]interface{}{"@level": "info", "@name": "test", "message": "one", "two": "2"}, }, { - in: []interface{}{"test message", "name", "me", "number", 2}, - out: map[string]interface{}{"@level": "info", "@name": "test", "message": "test message", "name": "me", "number": float64(2)}, + in: []interface{}{"one", "two", "2", "three", 3}, + out: map[string]interface{}{"@level": "info", "@name": "test", "message": "one", "two": "2", "three": float64(3)}, + }, + { + in: []interface{}{"one", "two", "2", "three", 3, "fo ur", "# 4"}, + out: map[string]interface{}{"@level": "info", "@name": "test", "message": "one", "two": "2", "three": float64(3), "fo ur": "# 4"}, }, } diff --git a/outputs/keyvalue/keyvalue.go b/outputs/keyvalue/keyvalue.go index 5649f5e..234f29b 100644 --- a/outputs/keyvalue/keyvalue.go +++ b/outputs/keyvalue/keyvalue.go @@ -25,15 +25,24 @@ func (kv Writer) Write(w io.Writer, m logger.Message) { io.WriteString(w, ":") } - for i := 0; i < len(m.Fields); i = i + 2 { - io.WriteString(w, " ") - io.WriteString(w, maybeQuote(logger.ToString(m.Fields[i]))) - io.WriteString(w, "=") - s := logger.ToString(m.Fields[i+1]) - io.WriteString(w, maybeQuote(s)) + offset := len(m.Fields) % 2 + if offset != 0 { + io.WriteString(w, writeKV("message", m.Fields[0])) + } + + for i := offset; i < len(m.Fields); i = i + 2 { + io.WriteString(w, writeKV(m.Fields[i], m.Fields[i+1])) } } +func writeKV(k, v interface{}) string { + return fmt.Sprintf( + " %s=%s", + maybeQuote(logger.ToString(k)), + maybeQuote(logger.ToString(v)), + ) +} + func maybeQuote(s string) string { if strings.ContainsAny(s, " \t\n\r") { return fmt.Sprintf("%q", s) diff --git a/outputs/keyvalue/keyvalue_test.go b/outputs/keyvalue/keyvalue_test.go index 4ce6d90..7abe81e 100644 --- a/outputs/keyvalue/keyvalue_test.go +++ b/outputs/keyvalue/keyvalue_test.go @@ -13,16 +13,20 @@ func TestKeyValueWriter(t *testing.T) { out string }{ { - in: []interface{}{"test message"}, - out: "[INFO ] test: message=\"test message\"", + in: []interface{}{"one"}, + out: "[INFO ] test: message=one", }, { - in: []interface{}{"test message", "name", "me"}, - out: "[INFO ] test: message=\"test message\" name=me", + in: []interface{}{"one", "two", "2"}, + out: "[INFO ] test: message=one two=2", }, { - in: []interface{}{"test message", "name", "me", "number", 2}, - out: "[INFO ] test: message=\"test message\" name=me number=2", + in: []interface{}{"one", "two", "2", "three", 3}, + out: "[INFO ] test: message=one two=2 three=3", + }, + { + in: []interface{}{"one", "two", "2", "three", 3, "fo ur", "# 4"}, + out: "[INFO ] test: message=one two=2 three=3 \"fo ur\"=\"# 4\"", }, } |
