diff --git a/logger.go b/logger.go index 6433251..f044ecf 100644 --- a/logger.go +++ b/logger.go @@ -79,8 +79,9 @@ func (l *Logger) log(level Level, msg interface{}, keyvals ...interface{}) { } if msg != nil { - m := fmt.Sprint(msg) - kvs = append(kvs, MessageKey, m) + if m := fmt.Sprint(msg); m != "" { + kvs = append(kvs, MessageKey, m) + } } // append logger fields @@ -88,6 +89,7 @@ func (l *Logger) log(level Level, msg interface{}, keyvals ...interface{}) { if len(l.fields)%2 != 0 { kvs = append(kvs, ErrMissingValue) } + // append the rest kvs = append(kvs, keyvals...) if len(keyvals)%2 != 0 { diff --git a/text.go b/text.go index 301ebd0..2368172 100644 --- a/text.go +++ b/text.go @@ -143,38 +143,54 @@ func needsQuoting(str string) bool { } func (l *Logger) textFormatter(keyvals ...interface{}) { - for i := 0; i < len(keyvals); i += 2 { + lenKeyvals := len(keyvals) + firstElementOfLastKeyvalPair := lenKeyvals - 2 + + for i := 0; i < lenKeyvals; i += 2 { + firstKey := i == 0 + moreKeys := i < firstElementOfLastKeyvalPair switch keyvals[i] { case TimestampKey: if t, ok := keyvals[i+1].(time.Time); ok { ts := t.Format(l.timeFormat) ts = TimestampStyle.Renderer(l.re).Render(ts) + if !firstKey { + l.b.WriteByte(' ') + } l.b.WriteString(ts) - l.b.WriteByte(' ') } case LevelKey: if level, ok := keyvals[i+1].(Level); ok { lvl := levelStyle(level).Renderer(l.re).String() + if !firstKey { + l.b.WriteByte(' ') + } l.b.WriteString(lvl) - l.b.WriteByte(' ') } case CallerKey: if caller, ok := keyvals[i+1].(string); ok { caller = fmt.Sprintf("<%s>", caller) caller = CallerStyle.Renderer(l.re).Render(caller) + if !firstKey { + l.b.WriteByte(' ') + } l.b.WriteString(caller) - l.b.WriteByte(' ') } case PrefixKey: if prefix, ok := keyvals[i+1].(string); ok { prefix = PrefixStyle.Renderer(l.re).Render(prefix + ":") + if !firstKey { + l.b.WriteByte(' ') + } l.b.WriteString(prefix) - l.b.WriteByte(' ') } case MessageKey: if msg := keyvals[i+1]; msg != nil { m := fmt.Sprint(msg) m = MessageStyle.Renderer(l.re).Render(m) + if !firstKey { + l.b.WriteByte(' ') + } l.b.WriteString(m) } default: @@ -182,7 +198,6 @@ func (l *Logger) textFormatter(keyvals ...interface{}) { indentSep := indentSeparator sep = SeparatorStyle.Renderer(l.re).Render(sep) indentSep = SeparatorStyle.Renderer(l.re).Render(indentSep) - moreKeys := i < len(keyvals)-2 key := fmt.Sprint(keyvals[i]) val := fmt.Sprintf("%+v", keyvals[i+1]) raw := val == "" @@ -215,19 +230,19 @@ func (l *Logger) textFormatter(keyvals ...interface{}) { l.b.WriteString(key) l.b.WriteString(sep + "\n") l.writeIndent(&l.b, val, indentSep, moreKeys, actualKey) - // If there are more keyvals, separate them with a space. - if moreKeys { + } else if !raw && needsQuoting(val) { + if !firstKey { l.b.WriteByte(' ') } - } else if !raw && needsQuoting(val) { - l.b.WriteByte(' ') l.b.WriteString(key) l.b.WriteString(sep) l.b.WriteString(valueStyle.Renderer(l.re).Render(fmt.Sprintf(`"%s"`, escapeStringForOutput(val, true)))) } else { val = valueStyle.Renderer(l.re).Render(val) - l.b.WriteByte(' ') + if !firstKey { + l.b.WriteByte(' ') + } l.b.WriteString(key) l.b.WriteString(sep) l.b.WriteString(val)