From 08e74f3db7908d2cb34ecef68e4121a6cd696817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Pila=C5=99?= Date: Wed, 12 Jul 2017 14:57:53 +0200 Subject: [PATCH 1/6] WIP: Sketch out syslogLogger based on colorLogger --- log/syslog/syslog.go | 129 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 log/syslog/syslog.go diff --git a/log/syslog/syslog.go b/log/syslog/syslog.go new file mode 100644 index 000000000..19fccf968 --- /dev/null +++ b/log/syslog/syslog.go @@ -0,0 +1,129 @@ +package syslog + +import ( + gosyslog "log/syslog" + "io" + "github.com/go-kit/kit/log/level" + "github.com/go-kit/kit/log" + "bytes" + "sync" +) + +// @TODO +// 1. Wrap gosyslog.Writer +// 2. Provide dummy implementation for tests +// 3. Test that different levels are sent correctly with default selector +// 4. Test that all levels are sent with a custom exhaustive selector +// 5. Test default value +// 6. Extract bufLogger - colorLogger + +func NewLogger(defaultPriority gosyslog.Priority, tag string, newLogger func(io.Writer) log.Logger, options ...Option) (log.Logger, error) { + w, err := gosyslog.New(defaultPriority, tag) + if err != nil { + return nil, err + } + return NewSyslogLogger(w, newLogger, options...), nil +} + +type PrioritySelector func(keyvals ...interface{}) gosyslog.Priority + +func NewSyslogLogger(w gosyslog.Writer, newLogger func(io.Writer) log.Logger, options ...Option) log.Logger { + l := &syslogLogger{ + w: w, + newLogger: newLogger(w), + prioritySelector: defaultPrioritySelector, + bufPool: sync.Pool{New: func() interface{} { + return &loggerBuf{} + }}, + } + + for _, option := range options { + option(l) + } + + return l +} + +type syslogLogger struct { + w gosyslog.Writer + newLogger func(io.Writer) log.Logger + prioritySelector PrioritySelector + bufPool sync.Pool +} + +func (l *syslogLogger) Log(keyvals ...interface{}) error { + level := l.prioritySelector(keyvals...) + + lb := l.getLoggerBuf() + defer l.putLoggerBuf(lb) + if err := lb.logger.Log(keyvals...); err != nil { + return err + } + + switch level { + case gosyslog.LOG_EMERG: + return l.w.Emerg(lb.buf.String()) + case gosyslog.LOG_ALERT: + return l.w.Alert(lb.buf.String()) + case gosyslog.LOG_CRIT: + return l.w.Crit(lb.buf.String()) + case gosyslog.LOG_ERR: + return l.w.Err(lb.buf.String()) + case gosyslog.LOG_WARNING: + return l.w.Warning(lb.buf.String()) + case gosyslog.LOG_NOTICE: + return l.w.Notice(lb.buf.String()) + case gosyslog.LOG_INFO: + return l.w.Info(lb.buf.String()) + case gosyslog.LOG_DEBUG: + return l.w.Debug(lb.buf.String()) + default: + _, err := l.w.Write(lb.buf.Bytes()) + return err + } +} + +type loggerBuf struct { + buf *bytes.Buffer + logger log.Logger +} + +func (l *syslogLogger) getLoggerBuf() *loggerBuf { + lb := l.bufPool.Get().(*loggerBuf) + if lb.buf == nil { + lb.buf = &bytes.Buffer{} + lb.logger = l.newLogger(lb.buf) + } else { + lb.buf.Reset() + } + return lb +} + +func (l *syslogLogger) putLoggerBuf(cb *loggerBuf) { + l.bufPool.Put(cb) +} + +type Option func(*syslogLogger) + +func PrioritySelectorOption(selector PrioritySelector) Option { + return func (l *syslogLogger) { l.prioritySelector = selector } +} + +func defaultPrioritySelector(keyvals ...interface{}) gosyslog.Priority { + for i := 0; i < len(keyvals); i += 2 { + if v, ok := keyvals[i].(level.Value); ok { + switch v { + case level.DebugValue(): + return gosyslog.LOG_DEBUG + case level.InfoValue(): + return gosyslog.LOG_INFO + case level.WarnValue(): + return gosyslog.LOG_WARNING + case level.ErrorValue(): + return gosyslog.LOG_ERR + } + } + } + + return gosyslog.LOG_INFO +} From 1731cb408e981da8fff6baff68abd60344449a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Pila=C5=99?= Date: Wed, 12 Jul 2017 21:51:08 +0200 Subject: [PATCH 2/6] WIP: test syslog writer --- log/syslog/{syslog.go => syslog_logger.go} | 47 +++--- log/syslog/syslog_logger_test.go | 163 +++++++++++++++++++++ log/syslog/syslog_writer.go | 22 +++ 3 files changed, 206 insertions(+), 26 deletions(-) rename log/syslog/{syslog.go => syslog_logger.go} (67%) create mode 100644 log/syslog/syslog_logger_test.go create mode 100644 log/syslog/syslog_writer.go diff --git a/log/syslog/syslog.go b/log/syslog/syslog_logger.go similarity index 67% rename from log/syslog/syslog.go rename to log/syslog/syslog_logger.go index 19fccf968..f85963834 100644 --- a/log/syslog/syslog.go +++ b/log/syslog/syslog_logger.go @@ -10,27 +10,20 @@ import ( ) // @TODO -// 1. Wrap gosyslog.Writer -// 2. Provide dummy implementation for tests -// 3. Test that different levels are sent correctly with default selector -// 4. Test that all levels are sent with a custom exhaustive selector -// 5. Test default value +// 1. ~Wrap gosyslog.Writer~ +// 2. ~Provide dummy implementation for tests~ +// 3. ~Test that different levels are sent correctly with default selector~ +// 4. ~Test that all levels are sent with a custom exhaustive selector~ +// 5. ~Test default value~ // 6. Extract bufLogger - colorLogger -func NewLogger(defaultPriority gosyslog.Priority, tag string, newLogger func(io.Writer) log.Logger, options ...Option) (log.Logger, error) { - w, err := gosyslog.New(defaultPriority, tag) - if err != nil { - return nil, err - } - return NewSyslogLogger(w, newLogger, options...), nil -} type PrioritySelector func(keyvals ...interface{}) gosyslog.Priority -func NewSyslogLogger(w gosyslog.Writer, newLogger func(io.Writer) log.Logger, options ...Option) log.Logger { +func NewSyslogLogger(w SyslogWriter, newLogger func(io.Writer) log.Logger, options ...Option) log.Logger { l := &syslogLogger{ w: w, - newLogger: newLogger(w), + newLogger: newLogger, prioritySelector: defaultPrioritySelector, bufPool: sync.Pool{New: func() interface{} { return &loggerBuf{} @@ -45,7 +38,7 @@ func NewSyslogLogger(w gosyslog.Writer, newLogger func(io.Writer) log.Logger, op } type syslogLogger struct { - w gosyslog.Writer + w SyslogWriter newLogger func(io.Writer) log.Logger prioritySelector PrioritySelector bufPool sync.Pool @@ -59,7 +52,7 @@ func (l *syslogLogger) Log(keyvals ...interface{}) error { if err := lb.logger.Log(keyvals...); err != nil { return err } - +// @TODO - trim newline? switch level { case gosyslog.LOG_EMERG: return l.w.Emerg(lb.buf.String()) @@ -111,16 +104,18 @@ func PrioritySelectorOption(selector PrioritySelector) Option { func defaultPrioritySelector(keyvals ...interface{}) gosyslog.Priority { for i := 0; i < len(keyvals); i += 2 { - if v, ok := keyvals[i].(level.Value); ok { - switch v { - case level.DebugValue(): - return gosyslog.LOG_DEBUG - case level.InfoValue(): - return gosyslog.LOG_INFO - case level.WarnValue(): - return gosyslog.LOG_WARNING - case level.ErrorValue(): - return gosyslog.LOG_ERR + if keyvals[i] == level.Key() { + if v, ok := keyvals[i+1].(level.Value); ok { + switch v { + case level.DebugValue(): + return gosyslog.LOG_DEBUG + case level.InfoValue(): + return gosyslog.LOG_INFO + case level.WarnValue(): + return gosyslog.LOG_WARNING + case level.ErrorValue(): + return gosyslog.LOG_ERR + } } } } diff --git a/log/syslog/syslog_logger_test.go b/log/syslog/syslog_logger_test.go new file mode 100644 index 000000000..bb3e73157 --- /dev/null +++ b/log/syslog/syslog_logger_test.go @@ -0,0 +1,163 @@ +package syslog + +import ( + "fmt" + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + gosyslog "log/syslog" + "reflect" + "testing" +) + +func TestSyslogLoggerDefaultPrioritySelector(t *testing.T) { + w := &testSyslogWriter{} + l := NewSyslogLogger(w, log.NewLogfmtLogger) + + l.Log("level", level.WarnValue(), "msg", "one") + l.Log("level", "undefined", "msg", "two") + l.Log("level", level.InfoValue(), "msg", "three") + l.Log("level", level.ErrorValue(), "msg", "four") + l.Log("level", level.DebugValue(), "msg", "five") + + l.Log("msg", "six", "level", level.ErrorValue()) + l.Log("msg", "seven", "level", level.DebugValue()) + l.Log("msg", "eight", "level", level.InfoValue()) + l.Log("msg", "nine", "level", "undefined") + l.Log("msg", "ten", "level", level.WarnValue()) + + l.Log("level", level.ErrorValue(), "msg") + + want := []string{ + "warning: level=warn msg=one\n", + "info: level=undefined msg=two\n", + "info: level=info msg=three\n", + "err: level=error msg=four\n", + "debug: level=debug msg=five\n", + + "err: msg=six level=error\n", + "debug: msg=seven level=debug\n", + "info: msg=eight level=info\n", + "info: msg=nine level=undefined\n", + "warning: msg=ten level=warn\n", + + "err: level=error msg=null\n", + } + have := w.writes + if !reflect.DeepEqual(want, have) { + t.Errorf("wrong writes: want %s, have %s", want, have) + } +} + +func TestSyslogLoggerExhaustivePrioritySelector(t *testing.T) { + w := &testSyslogWriter{} + selector := func(keyvals ...interface{}) gosyslog.Priority { + for i := 0; i < len(keyvals); i += 2 { + if keyvals[i] == level.Key() { + if v, ok := keyvals[i+1].(string); ok { + switch v { + case "emergency": + return gosyslog.LOG_EMERG + case "alert": + return gosyslog.LOG_ALERT + case "critical": + return gosyslog.LOG_CRIT + case "error": + return gosyslog.LOG_ERR + case "warning": + return gosyslog.LOG_WARNING + case "notice": + return gosyslog.LOG_NOTICE + case "info": + return gosyslog.LOG_INFO + case "debug": + return gosyslog.LOG_DEBUG + } + return gosyslog.LOG_LOCAL0 + } + } + } + return gosyslog.LOG_LOCAL0 + } + l := NewSyslogLogger(w, log.NewLogfmtLogger, PrioritySelectorOption(selector)) + + l.Log("level", "warning", "msg", "one") + l.Log("level", "error", "msg", "two") + l.Log("level", "critical", "msg", "three") + l.Log("level", "debug", "msg", "four") + l.Log("level", "info", "msg", "five") + l.Log("level", "alert", "msg", "six") + l.Log("level", "emergency", "msg", "seven") + l.Log("level", "notice", "msg", "eight") + l.Log("level", "unknown", "msg", "nine") + + want := []string{ + "warning: level=warning msg=one\n", + "err: level=error msg=two\n", + "crit: level=critical msg=three\n", + "debug: level=debug msg=four\n", + "info: level=info msg=five\n", + "alert: level=alert msg=six\n", + "emerg: level=emergency msg=seven\n", + "notice: level=notice msg=eight\n", + "write: level=unknown msg=nine\n", + } + have := w.writes + if !reflect.DeepEqual(want, have) { + t.Errorf("wrong writes: want %s, have %s", want, have) + } +} + + +type testSyslogWriter struct { + writes []string +} + +func (w *testSyslogWriter) Write(b []byte) (int, error) { + msg := string(b) + w.writes = append(w.writes, fmt.Sprintf("write: %s", msg)) + return len(msg), nil +} + +func (w *testSyslogWriter) Close() error { + return nil +} + +func (w *testSyslogWriter) Emerg(msg string) error { + w.writes = append(w.writes, fmt.Sprintf("emerg: %s", msg)) + return nil +} + +func (w *testSyslogWriter) Alert(msg string) error { + w.writes = append(w.writes, fmt.Sprintf("alert: %s", msg)) + return nil +} + +func (w *testSyslogWriter) Crit(msg string) error { + w.writes = append(w.writes, fmt.Sprintf("crit: %s", msg)) + return nil +} + +func (w *testSyslogWriter) Err(msg string) error { + w.writes = append(w.writes, fmt.Sprintf("err: %s", msg)) + return nil +} + +func (w *testSyslogWriter) Warning(msg string) error { + w.writes = append(w.writes, fmt.Sprintf("warning: %s", msg)) + return nil +} + +func (w *testSyslogWriter) Notice(msg string) error { + w.writes = append(w.writes, fmt.Sprintf("notice: %s", msg)) + return nil +} + +func (w *testSyslogWriter) Info(msg string) error { + w.writes = append(w.writes, fmt.Sprintf("info: %s", msg)) + return nil +} + +func (w *testSyslogWriter) Debug(msg string) error { + w.writes = append(w.writes, fmt.Sprintf("debug: %s", msg)) + return nil +} diff --git a/log/syslog/syslog_writer.go b/log/syslog/syslog_writer.go new file mode 100644 index 000000000..4563dc0a1 --- /dev/null +++ b/log/syslog/syslog_writer.go @@ -0,0 +1,22 @@ +package syslog + +import ( + gosyslog "log/syslog" +) + +type SyslogWriter interface { + Write([]byte) (int, error) + Close() error + Emerg(string) error + Alert(string) error + Crit(string) error + Err(string) error + Warning(string) error + Notice(string) error + Info(string) error + Debug(string) error +} + +type syslogWriter struct { + gosyslog.Writer +} \ No newline at end of file From 8c940ee924393288e8451177273727ac84ccd1cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Pila=C5=99?= Date: Fri, 14 Jul 2017 20:30:17 +0200 Subject: [PATCH 3/6] WIP: Add documentation and an example --- log/syslog/example_test.go | 24 +++++++++++++++ log/syslog/syslog_logger.go | 58 ++++++++++++++++++------------------- log/syslog/syslog_writer.go | 1 + 3 files changed, 53 insertions(+), 30 deletions(-) create mode 100644 log/syslog/example_test.go diff --git a/log/syslog/example_test.go b/log/syslog/example_test.go new file mode 100644 index 000000000..79cb78bbe --- /dev/null +++ b/log/syslog/example_test.go @@ -0,0 +1,24 @@ +package syslog_test + +import ( + gosyslog "log/syslog" + "github.com/go-kit/kit/log/syslog" + "github.com/go-kit/kit/log" + "fmt" + "github.com/go-kit/kit/log/level" +) + + +func ExampleNewLogger_defaultPrioritySelector() { + // Normal syslog writer + w, err := gosyslog.New(gosyslog.LOG_INFO, "experiment") + if err != nil { + fmt.Println(err) + return + } + + // syslog logger with logfmt formatting + logger := syslog.NewSyslogLogger(w, log.NewLogfmtLogger) + logger.Log("msg", "info because of default") + logger.Log(level.Key(), level.DebugValue(), "msg", "debug because of explicit level") +} \ No newline at end of file diff --git a/log/syslog/syslog_logger.go b/log/syslog/syslog_logger.go index f85963834..4fa654156 100644 --- a/log/syslog/syslog_logger.go +++ b/log/syslog/syslog_logger.go @@ -9,17 +9,12 @@ import ( "sync" ) -// @TODO -// 1. ~Wrap gosyslog.Writer~ -// 2. ~Provide dummy implementation for tests~ -// 3. ~Test that different levels are sent correctly with default selector~ -// 4. ~Test that all levels are sent with a custom exhaustive selector~ -// 5. ~Test default value~ -// 6. Extract bufLogger - colorLogger - - +// PrioritySelector inspects list of keyvals and select a syslog priority type PrioritySelector func(keyvals ...interface{}) gosyslog.Priority +// NewSyslogLogger returns a new Logger which writes to syslog in syslog format. +// The body of the log message is the formatted output from the Logger returned +// by newLogger. func NewSyslogLogger(w SyslogWriter, newLogger func(io.Writer) log.Logger, options ...Option) log.Logger { l := &syslogLogger{ w: w, @@ -52,7 +47,7 @@ func (l *syslogLogger) Log(keyvals ...interface{}) error { if err := lb.logger.Log(keyvals...); err != nil { return err } -// @TODO - trim newline? + switch level { case gosyslog.LOG_EMERG: return l.w.Emerg(lb.buf.String()) @@ -76,28 +71,11 @@ func (l *syslogLogger) Log(keyvals ...interface{}) error { } } -type loggerBuf struct { - buf *bytes.Buffer - logger log.Logger -} - -func (l *syslogLogger) getLoggerBuf() *loggerBuf { - lb := l.bufPool.Get().(*loggerBuf) - if lb.buf == nil { - lb.buf = &bytes.Buffer{} - lb.logger = l.newLogger(lb.buf) - } else { - lb.buf.Reset() - } - return lb -} - -func (l *syslogLogger) putLoggerBuf(cb *loggerBuf) { - l.bufPool.Put(cb) -} - +// Option sets a parameter for syslog loggers. type Option func(*syslogLogger) +// PrioritySelectorOption sets priority selector function to choose syslog +// priority. func PrioritySelectorOption(selector PrioritySelector) Option { return func (l *syslogLogger) { l.prioritySelector = selector } } @@ -122,3 +100,23 @@ func defaultPrioritySelector(keyvals ...interface{}) gosyslog.Priority { return gosyslog.LOG_INFO } + +type loggerBuf struct { + buf *bytes.Buffer + logger log.Logger +} + +func (l *syslogLogger) getLoggerBuf() *loggerBuf { + lb := l.bufPool.Get().(*loggerBuf) + if lb.buf == nil { + lb.buf = &bytes.Buffer{} + lb.logger = l.newLogger(lb.buf) + } else { + lb.buf.Reset() + } + return lb +} + +func (l *syslogLogger) putLoggerBuf(cb *loggerBuf) { + l.bufPool.Put(cb) +} \ No newline at end of file diff --git a/log/syslog/syslog_writer.go b/log/syslog/syslog_writer.go index 4563dc0a1..2a3935d83 100644 --- a/log/syslog/syslog_writer.go +++ b/log/syslog/syslog_writer.go @@ -4,6 +4,7 @@ import ( gosyslog "log/syslog" ) +// SyslogWriter is an interface wrapping stdlib syslog Writer type SyslogWriter interface { Write([]byte) (int, error) Close() error From eafeb58d39e6a6e7f097b2a0bf1ae6511c619929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Pila=C5=99?= Date: Mon, 12 Feb 2018 20:27:32 +0100 Subject: [PATCH 4/6] WIP: Format and copy --- log/syslog/example_test.go | 9 +++++---- log/syslog/syslog_logger.go | 20 +++++++++++--------- log/syslog/syslog_logger_test.go | 9 +++++---- log/syslog/syslog_writer.go | 2 +- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/log/syslog/example_test.go b/log/syslog/example_test.go index 79cb78bbe..ff2220d00 100644 --- a/log/syslog/example_test.go +++ b/log/syslog/example_test.go @@ -1,14 +1,15 @@ package syslog_test import ( + "fmt" + gosyslog "log/syslog" - "github.com/go-kit/kit/log/syslog" + "github.com/go-kit/kit/log" - "fmt" "github.com/go-kit/kit/log/level" + "github.com/go-kit/kit/log/syslog" ) - func ExampleNewLogger_defaultPrioritySelector() { // Normal syslog writer w, err := gosyslog.New(gosyslog.LOG_INFO, "experiment") @@ -21,4 +22,4 @@ func ExampleNewLogger_defaultPrioritySelector() { logger := syslog.NewSyslogLogger(w, log.NewLogfmtLogger) logger.Log("msg", "info because of default") logger.Log(level.Key(), level.DebugValue(), "msg", "debug because of explicit level") -} \ No newline at end of file +} diff --git a/log/syslog/syslog_logger.go b/log/syslog/syslog_logger.go index 4fa654156..ee794620c 100644 --- a/log/syslog/syslog_logger.go +++ b/log/syslog/syslog_logger.go @@ -1,15 +1,17 @@ package syslog import ( - gosyslog "log/syslog" - "io" - "github.com/go-kit/kit/log/level" - "github.com/go-kit/kit/log" "bytes" + "io" "sync" + + gosyslog "log/syslog" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" ) -// PrioritySelector inspects list of keyvals and select a syslog priority +// PrioritySelector inspects the list of keyvals and selects a syslog priority type PrioritySelector func(keyvals ...interface{}) gosyslog.Priority // NewSyslogLogger returns a new Logger which writes to syslog in syslog format. @@ -17,8 +19,8 @@ type PrioritySelector func(keyvals ...interface{}) gosyslog.Priority // by newLogger. func NewSyslogLogger(w SyslogWriter, newLogger func(io.Writer) log.Logger, options ...Option) log.Logger { l := &syslogLogger{ - w: w, - newLogger: newLogger, + w: w, + newLogger: newLogger, prioritySelector: defaultPrioritySelector, bufPool: sync.Pool{New: func() interface{} { return &loggerBuf{} @@ -77,7 +79,7 @@ type Option func(*syslogLogger) // PrioritySelectorOption sets priority selector function to choose syslog // priority. func PrioritySelectorOption(selector PrioritySelector) Option { - return func (l *syslogLogger) { l.prioritySelector = selector } + return func(l *syslogLogger) { l.prioritySelector = selector } } func defaultPrioritySelector(keyvals ...interface{}) gosyslog.Priority { @@ -119,4 +121,4 @@ func (l *syslogLogger) getLoggerBuf() *loggerBuf { func (l *syslogLogger) putLoggerBuf(cb *loggerBuf) { l.bufPool.Put(cb) -} \ No newline at end of file +} diff --git a/log/syslog/syslog_logger_test.go b/log/syslog/syslog_logger_test.go index bb3e73157..9f7e59343 100644 --- a/log/syslog/syslog_logger_test.go +++ b/log/syslog/syslog_logger_test.go @@ -2,11 +2,13 @@ package syslog import ( "fmt" - "github.com/go-kit/kit/log" - "github.com/go-kit/kit/log/level" - gosyslog "log/syslog" "reflect" "testing" + + gosyslog "log/syslog" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" ) func TestSyslogLoggerDefaultPrioritySelector(t *testing.T) { @@ -107,7 +109,6 @@ func TestSyslogLoggerExhaustivePrioritySelector(t *testing.T) { } } - type testSyslogWriter struct { writes []string } diff --git a/log/syslog/syslog_writer.go b/log/syslog/syslog_writer.go index 2a3935d83..2354c25dc 100644 --- a/log/syslog/syslog_writer.go +++ b/log/syslog/syslog_writer.go @@ -20,4 +20,4 @@ type SyslogWriter interface { type syslogWriter struct { gosyslog.Writer -} \ No newline at end of file +} From a6dc69ee06352877fa9986fcb8645841fdb9c8db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Pila=C5=99?= Date: Tue, 13 Feb 2018 17:51:40 +0100 Subject: [PATCH 5/6] WIP: handle edge with level key as the last and odd keyval --- log/syslog/syslog_logger.go | 9 +++++++-- log/syslog/syslog_logger_test.go | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/log/syslog/syslog_logger.go b/log/syslog/syslog_logger.go index ee794620c..aaeb491ad 100644 --- a/log/syslog/syslog_logger.go +++ b/log/syslog/syslog_logger.go @@ -83,9 +83,14 @@ func PrioritySelectorOption(selector PrioritySelector) Option { } func defaultPrioritySelector(keyvals ...interface{}) gosyslog.Priority { - for i := 0; i < len(keyvals); i += 2 { + l := len(keyvals) + for i := 0; i < l; i += 2 { if keyvals[i] == level.Key() { - if v, ok := keyvals[i+1].(level.Value); ok { + var val interface{} + if i+1 < l { + val = keyvals[i+1] + } + if v, ok := val.(level.Value); ok { switch v { case level.DebugValue(): return gosyslog.LOG_DEBUG diff --git a/log/syslog/syslog_logger_test.go b/log/syslog/syslog_logger_test.go index 9f7e59343..aa9c2cb22 100644 --- a/log/syslog/syslog_logger_test.go +++ b/log/syslog/syslog_logger_test.go @@ -28,6 +28,7 @@ func TestSyslogLoggerDefaultPrioritySelector(t *testing.T) { l.Log("msg", "ten", "level", level.WarnValue()) l.Log("level", level.ErrorValue(), "msg") + l.Log("msg", "eleven", "level") want := []string{ "warning: level=warn msg=one\n", @@ -43,6 +44,7 @@ func TestSyslogLoggerDefaultPrioritySelector(t *testing.T) { "warning: msg=ten level=warn\n", "err: level=error msg=null\n", + "info: msg=eleven level=null\n", } have := w.writes if !reflect.DeepEqual(want, have) { From 7c423b4742c23b34e6b1ba12b34a4cdef236502c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Pila=C5=99?= Date: Tue, 13 Feb 2018 19:30:55 +0100 Subject: [PATCH 6/6] WIP: Shuffle code around --- log/syslog/{syslog_logger.go => syslog.go} | 58 ++++++++++++------- .../{syslog_logger_test.go => syslog_test.go} | 0 log/syslog/syslog_writer.go | 23 -------- 3 files changed, 36 insertions(+), 45 deletions(-) rename log/syslog/{syslog_logger.go => syslog.go} (88%) rename log/syslog/{syslog_logger_test.go => syslog_test.go} (100%) delete mode 100644 log/syslog/syslog_writer.go diff --git a/log/syslog/syslog_logger.go b/log/syslog/syslog.go similarity index 88% rename from log/syslog/syslog_logger.go rename to log/syslog/syslog.go index aaeb491ad..91c3f184a 100644 --- a/log/syslog/syslog_logger.go +++ b/log/syslog/syslog.go @@ -11,8 +11,19 @@ import ( "github.com/go-kit/kit/log/level" ) -// PrioritySelector inspects the list of keyvals and selects a syslog priority -type PrioritySelector func(keyvals ...interface{}) gosyslog.Priority +// SyslogWriter is an interface wrapping stdlib syslog Writer. +type SyslogWriter interface { + Write([]byte) (int, error) + Close() error + Emerg(string) error + Alert(string) error + Crit(string) error + Err(string) error + Warning(string) error + Notice(string) error + Info(string) error + Debug(string) error +} // NewSyslogLogger returns a new Logger which writes to syslog in syslog format. // The body of the log message is the formatted output from the Logger returned @@ -73,9 +84,32 @@ func (l *syslogLogger) Log(keyvals ...interface{}) error { } } +type loggerBuf struct { + buf *bytes.Buffer + logger log.Logger +} + +func (l *syslogLogger) getLoggerBuf() *loggerBuf { + lb := l.bufPool.Get().(*loggerBuf) + if lb.buf == nil { + lb.buf = &bytes.Buffer{} + lb.logger = l.newLogger(lb.buf) + } else { + lb.buf.Reset() + } + return lb +} + +func (l *syslogLogger) putLoggerBuf(lb *loggerBuf) { + l.bufPool.Put(lb) +} + // Option sets a parameter for syslog loggers. type Option func(*syslogLogger) +// PrioritySelector inspects the list of keyvals and selects a syslog priority. +type PrioritySelector func(keyvals ...interface{}) gosyslog.Priority + // PrioritySelectorOption sets priority selector function to choose syslog // priority. func PrioritySelectorOption(selector PrioritySelector) Option { @@ -107,23 +141,3 @@ func defaultPrioritySelector(keyvals ...interface{}) gosyslog.Priority { return gosyslog.LOG_INFO } - -type loggerBuf struct { - buf *bytes.Buffer - logger log.Logger -} - -func (l *syslogLogger) getLoggerBuf() *loggerBuf { - lb := l.bufPool.Get().(*loggerBuf) - if lb.buf == nil { - lb.buf = &bytes.Buffer{} - lb.logger = l.newLogger(lb.buf) - } else { - lb.buf.Reset() - } - return lb -} - -func (l *syslogLogger) putLoggerBuf(cb *loggerBuf) { - l.bufPool.Put(cb) -} diff --git a/log/syslog/syslog_logger_test.go b/log/syslog/syslog_test.go similarity index 100% rename from log/syslog/syslog_logger_test.go rename to log/syslog/syslog_test.go diff --git a/log/syslog/syslog_writer.go b/log/syslog/syslog_writer.go deleted file mode 100644 index 2354c25dc..000000000 --- a/log/syslog/syslog_writer.go +++ /dev/null @@ -1,23 +0,0 @@ -package syslog - -import ( - gosyslog "log/syslog" -) - -// SyslogWriter is an interface wrapping stdlib syslog Writer -type SyslogWriter interface { - Write([]byte) (int, error) - Close() error - Emerg(string) error - Alert(string) error - Crit(string) error - Err(string) error - Warning(string) error - Notice(string) error - Info(string) error - Debug(string) error -} - -type syslogWriter struct { - gosyslog.Writer -}