From 4792177b11dd47521ef61ff89b45b363e685c100 Mon Sep 17 00:00:00 2001 From: Jean-Laurent de Morlhon Date: Mon, 7 Dec 2015 12:29:24 +0100 Subject: [PATCH] Logrus Machine Logger Signed-off-by: Jean-Laurent de Morlhon --- commands/env.go | 2 +- .../drivers/plugin/localbinary/plugin_test.go | 4 +- libmachine/log/interface.go | 18 ----- libmachine/log/log.go | 24 +++--- libmachine/log/log_test.go | 9 +++ libmachine/log/logrus_machine_logger.go | 79 +++++++++++++++++++ libmachine/log/logrus_machine_logger_test.go | 77 ++++++++++++++++++ ...chineFormatter.go => machine_formatter.go} | 4 +- libmachine/log/machine_formatter_test.go | 17 ++++ libmachine/log/machine_logger.go | 28 +++++++ 10 files changed, 225 insertions(+), 37 deletions(-) delete mode 100644 libmachine/log/interface.go create mode 100644 libmachine/log/log_test.go create mode 100644 libmachine/log/logrus_machine_logger.go create mode 100644 libmachine/log/logrus_machine_logger_test.go rename libmachine/log/{machineFormatter.go => machine_formatter.go} (64%) create mode 100644 libmachine/log/machine_formatter_test.go create mode 100644 libmachine/log/machine_logger.go diff --git a/commands/env.go b/commands/env.go index bd5e79a8cc..1aff42ae10 100644 --- a/commands/env.go +++ b/commands/env.go @@ -244,7 +244,7 @@ func detectShell() (string, error) { if shell == "" { // check for windows env and not bash (i.e. msysgit, etc) if runtime.GOOS == "windows" { - log.Infof("On Windows, please specify either 'cmd' or 'powershell' with the --shell flag.\n\n") + log.Info("On Windows, please specify either 'cmd' or 'powershell' with the --shell flag.\n\n") } return "", ErrUnknownShell diff --git a/libmachine/drivers/plugin/localbinary/plugin_test.go b/libmachine/drivers/plugin/localbinary/plugin_test.go index 6a838a1287..1f38d874e7 100644 --- a/libmachine/drivers/plugin/localbinary/plugin_test.go +++ b/libmachine/drivers/plugin/localbinary/plugin_test.go @@ -83,11 +83,11 @@ func TestExecServer(t *testing.T) { logReader, logWriter := io.Pipe() - log.GetStandardLogger().Out = logWriter + log.SetOutput(logWriter) defer func() { log.SetDebug(false) - log.GetStandardLogger().Out = os.Stderr + log.SetOutput(os.Stderr) }() stdoutReader, stdoutWriter := io.Pipe() diff --git a/libmachine/log/interface.go b/libmachine/log/interface.go deleted file mode 100644 index 19597c4649..0000000000 --- a/libmachine/log/interface.go +++ /dev/null @@ -1,18 +0,0 @@ -package log - -type MachineLogger interface { - Debug(...interface{}) - Debugf(string, ...interface{}) - - Info(...interface{}) - Infof(string, ...interface{}) - - Warn(...interface{}) - Warnf(string, ...interface{}) - - Error(...interface{}) - Errorf(string, ...interface{}) - - Fatal(...interface{}) - Fatalf(string, ...interface{}) -} diff --git a/libmachine/log/log.go b/libmachine/log/log.go index d969ac985f..1ef5a552aa 100644 --- a/libmachine/log/log.go +++ b/libmachine/log/log.go @@ -1,20 +1,16 @@ package log -import ( - "github.com/Sirupsen/logrus" -) +import "io" -var logger *logrus.Logger +var logger MachineLogger func init() { - logger = logrus.New() - logger.Level = logrus.InfoLevel - logger.Formatter = new(machineFormatter) + logger = NewMachineLogger() } // RedirectStdOutToStdErr prevents any log from corrupting the output func RedirectStdOutToStdErr() { - logger.Level = logrus.ErrorLevel + logger.RedirectStdOutToStdErr() } func Debug(args ...interface{}) { @@ -57,14 +53,14 @@ func Warnf(fmtString string, args ...interface{}) { logger.Warnf(fmtString, args...) } -func GetStandardLogger() *logrus.Logger { +func Logger() interface{} { return logger } func SetDebug(debug bool) { - if debug { - logger.Level = logrus.DebugLevel - } else { - logger.Level = logrus.InfoLevel - } + logger.SetDebug(debug) +} + +func SetOutput(out io.Writer) { + logger.SetOutput(out) } diff --git a/libmachine/log/log_test.go b/libmachine/log/log_test.go new file mode 100644 index 0000000000..cb7505bb84 --- /dev/null +++ b/libmachine/log/log_test.go @@ -0,0 +1,9 @@ +package log + +import ( + "testing" +) + +func TestFormatterIsSet(t *testing.T) { + +} diff --git a/libmachine/log/logrus_machine_logger.go b/libmachine/log/logrus_machine_logger.go new file mode 100644 index 0000000000..df2d45bc96 --- /dev/null +++ b/libmachine/log/logrus_machine_logger.go @@ -0,0 +1,79 @@ +package log + +import ( + "io" + + "github.com/Sirupsen/logrus" +) + +type LogrusMachineLogger struct { + logger *logrus.Logger +} + +func NewMachineLogger() MachineLogger { + logrusLogger := logrus.New() + logrusLogger.Level = logrus.InfoLevel + logrusLogger.Formatter = new(MachineFormatter) + return LogrusMachineLogger{logrusLogger} +} + +// RedirectStdOutToStdErr prevents any log from corrupting the output +func (ml LogrusMachineLogger) RedirectStdOutToStdErr() { + ml.logger.Level = logrus.ErrorLevel +} + +func (ml LogrusMachineLogger) SetDebug(debug bool) { + if debug { + ml.logger.Level = logrus.DebugLevel + } else { + ml.logger.Level = logrus.InfoLevel + } +} + +func (ml LogrusMachineLogger) SetOutput(out io.Writer) { + ml.logger.Out = out +} + +func (ml LogrusMachineLogger) Logger() interface{} { + return ml.logger +} + +func (ml LogrusMachineLogger) Debug(args ...interface{}) { + ml.logger.Debug(args...) +} + +func (ml LogrusMachineLogger) Debugf(fmtString string, args ...interface{}) { + ml.logger.Debugf(fmtString, args...) +} + +func (ml LogrusMachineLogger) Error(args ...interface{}) { + ml.logger.Error(args...) +} + +func (ml LogrusMachineLogger) Errorf(fmtString string, args ...interface{}) { + ml.logger.Errorf(fmtString, args...) +} + +func (ml LogrusMachineLogger) Info(args ...interface{}) { + ml.logger.Info(args...) +} + +func (ml LogrusMachineLogger) Infof(fmtString string, args ...interface{}) { + ml.logger.Infof(fmtString, args...) +} + +func (ml LogrusMachineLogger) Fatal(args ...interface{}) { + ml.logger.Fatal(args...) +} + +func (ml LogrusMachineLogger) Fatalf(fmtString string, args ...interface{}) { + ml.logger.Fatalf(fmtString, args...) +} + +func (ml LogrusMachineLogger) Warn(args ...interface{}) { + ml.logger.Warn(args...) +} + +func (ml LogrusMachineLogger) Warnf(fmtString string, args ...interface{}) { + ml.logger.Warnf(fmtString, args...) +} diff --git a/libmachine/log/logrus_machine_logger_test.go b/libmachine/log/logrus_machine_logger_test.go new file mode 100644 index 0000000000..7bbe4dd4fc --- /dev/null +++ b/libmachine/log/logrus_machine_logger_test.go @@ -0,0 +1,77 @@ +package log + +import ( + "testing" + + "bufio" + "io" + + "github.com/Sirupsen/logrus" + "github.com/stretchr/testify/assert" +) + +func TestDefaultLevelIsInfo(t *testing.T) { + testLogger := NewMachineLogger() + assert.Equal(t, testLogger.Logger().(*logrus.Logger).Level, logrus.InfoLevel) +} + +func TestSetDebugToTrue(t *testing.T) { + testLogger := NewMachineLogger() + testLogger.SetDebug(true) + assert.Equal(t, testLogger.Logger().(*logrus.Logger).Level, logrus.DebugLevel) +} + +func TestSetDebugToFalse(t *testing.T) { + testLogger := NewMachineLogger() + testLogger.SetDebug(true) + testLogger.SetDebug(false) + assert.Equal(t, testLogger.Logger().(*logrus.Logger).Level, logrus.InfoLevel) +} + +func TestSetSilenceOutput(t *testing.T) { + testLogger := NewMachineLogger() + testLogger.RedirectStdOutToStdErr() + assert.Equal(t, testLogger.Logger().(*logrus.Logger).Level, logrus.ErrorLevel) +} + +func TestDebug(t *testing.T) { + testLogger := NewMachineLogger() + testLogger.SetDebug(true) + + result := captureOutput(testLogger, func() { testLogger.Debug("debug") }) + + assert.Equal(t, result, "debug") +} + +func TestInfo(t *testing.T) { + testLogger := NewMachineLogger() + + result := captureOutput(testLogger, func() { testLogger.Info("info") }) + + assert.Equal(t, result, "info") +} + +func TestWarn(t *testing.T) { + testLogger := NewMachineLogger() + + result := captureOutput(testLogger, func() { testLogger.Warn("warn") }) + + assert.Equal(t, result, "warn") +} + +func TestError(t *testing.T) { + testLogger := NewMachineLogger() + + result := captureOutput(testLogger, func() { testLogger.Error("error") }) + + assert.Equal(t, result, "error") +} + +func captureOutput(testLogger MachineLogger, lambda func()) string { + pipeReader, pipeWriter := io.Pipe() + scanner := bufio.NewScanner(pipeReader) + testLogger.SetOutput(pipeWriter) + go lambda() + scanner.Scan() + return scanner.Text() +} diff --git a/libmachine/log/machineFormatter.go b/libmachine/log/machine_formatter.go similarity index 64% rename from libmachine/log/machineFormatter.go rename to libmachine/log/machine_formatter.go index 21970efd5d..e159918bb4 100644 --- a/libmachine/log/machineFormatter.go +++ b/libmachine/log/machine_formatter.go @@ -6,10 +6,10 @@ import ( "github.com/Sirupsen/logrus" ) -type machineFormatter struct { +type MachineFormatter struct { } -func (d *machineFormatter) Format(entry *logrus.Entry) ([]byte, error) { +func (d *MachineFormatter) Format(entry *logrus.Entry) ([]byte, error) { b := &bytes.Buffer{} b.WriteString(entry.Message) diff --git a/libmachine/log/machine_formatter_test.go b/libmachine/log/machine_formatter_test.go new file mode 100644 index 0000000000..357f4068b1 --- /dev/null +++ b/libmachine/log/machine_formatter_test.go @@ -0,0 +1,17 @@ +package log + +import ( + "testing" + + "github.com/Sirupsen/logrus" + "github.com/stretchr/testify/assert" +) + +func TestWrite(t *testing.T) { + entry := logrus.NewEntry(logrus.New()) + entry.Message = "foobar" + formatter := MachineFormatter{} + bytes, err := formatter.Format(entry) + assert.Nil(t, err) + assert.Equal(t, string(bytes[:]), "foobar\n") +} diff --git a/libmachine/log/machine_logger.go b/libmachine/log/machine_logger.go new file mode 100644 index 0000000000..4ef5adb922 --- /dev/null +++ b/libmachine/log/machine_logger.go @@ -0,0 +1,28 @@ +package log + +import "io" + +type MachineLogger interface { + RedirectStdOutToStdErr() + + SetDebug(debug bool) + + SetOutput(io.Writer) + + Debug(args ...interface{}) + Debugf(fmtString string, args ...interface{}) + + Error(args ...interface{}) + Errorf(fmtString string, args ...interface{}) + + Info(args ...interface{}) + Infof(fmtString string, args ...interface{}) + + Fatal(args ...interface{}) + Fatalf(fmtString string, args ...interface{}) + + Warn(args ...interface{}) + Warnf(fmtString string, args ...interface{}) + + Logger() interface{} +}