diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f5f2bd8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.idea*
+.idea/*
\ No newline at end of file
diff --git a/README.md b/README.md
index 02cbd79..6eb9e79 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,53 @@
-# logger
+# Kris Nóva Logger
-Ported from it's [original location](https://github.com/kubicorn/kubicorn/tree/master/pkg/logger) in the Kubicorn code base.
+## History
+
+- [2017] Originally ported from it's [original location](https://github.com/kubicorn/kubicorn/tree/master/pkg/logger) in the Kubicorn code base.
+- [2021] Refactored to support custom `io.Writer`'s
-# Rainbow logs
+
+## Install
+
+```bash
+go get github.com/kris-nova/logger
+```
+
+## Basic Usage
+
+```go
+package main
+
+import (
+ "github.com/kris-nova/logger"
+ "os"
+)
+
+func main() {
+ // Options
+ logger.Writer = os.Stdout // This is not needed
+ logger.BitwiseLevel = logger.LogCritical | logger.LogWarning // Customize your levels
+ logger.BitwiseLevel = logger.LogEverything // Turn everything on
+ logger.BitwiseLevel = logger.LogAlways // Only log Always()
+ logger.BitwiseLevel = logger.LogEverything // Turn everything back on
+ //
+
+ // Log lines
+ logger.Debug("Check this out %d", 123)
+ logger.Info("Cool!")
+ logger.Success("Hooray!")
+ logger.Always("Hello!")
+ logger.Critical("Oh No!")
+ logger.Warning("Beware...")
+ logger.Deprecated("Don't do this!")
+ //
+}
+
+```
+
+
+## Rainbow logs
```go
@@ -12,74 +55,21 @@ package main
import (
"github.com/kris-nova/logger"
- "fmt"
- "os"
+ lol "github.com/kris-nova/lolgopher"
)
func main(){
+ //
+ logger.Writer = lol.NewLolWriter() // Sometimes this will work better
+ logger.Writer = lol.NewTruecolorLolWriter() // Comment one of these out
+ //
- logger.Fabulous = true
- logger.Color = false
- logger.Level = 4
-
- err := fmt.Errorf("New error")
-
- logger.Always("This is always printed")
-
- logger.Success("Hooray a good thing happened!")
-
- logger.Info("we found an error: %v", err)
-
- logger.Debug("this is a useful message for software enigneers")
-
- logger.Warning("something bad happened but the software can still run")
-
- // Notice this does *NOT* exit!
- logger.Critical("the software should stop running, this is bad")
-
- // Now we have to exit
- os.Exit(123)
+ logger.BitwiseLevel = logger.LogEverything
+ logger.Always("Rainbow logging")
+ logger.Always("Rainbow logging")
+ logger.Always("Rainbow logging")
+ logger.Always("Rainbow logging")
}
-```
-
-# Simple golang logger
-
-```go
-package main
-
-import (
- "github.com/kris-nova/logger"
- "fmt"
- "os"
-)
-
-
-func main(){
-
- // Most Verbose
- //logger.Level = 4
-
- // Normal
- // No info or debug messages, only warnings and criticals
- logger.Level = 2
-
- // Off
- //logger.Level = 0
-
- err := fmt.Errorf("New error")
- logger.Info("we found an error: %v", err)
-
- logger.Debug("this is a useful message for software enigneers")
-
- logger.Warning("something bad happened but the software can still run")
-
- // Notice this does *NOT* exit!
- logger.Critical("the software should stop running, this is bad")
-
- // Now we have to exit
- os.Exit(123)
-}
-
-```
+```
\ No newline at end of file
diff --git a/example/example.go b/example/example.go
deleted file mode 100644
index ca27826..0000000
--- a/example/example.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package main
-
-import (
- "github.com/kris-nova/logger"
- "fmt"
- "os"
-)
-
-
-func main(){
-
- // Most Verbose
- //logger.Level = 4
-
- // Normal
- // No info or debug messages, only warnings and criticals
- logger.Level = 2
-
- // Off
- //logger.Level = 0
-
- logger.Always("This is always printed")
-
- logger.Success("Hooray a good thing happened!")
-
- err := fmt.Errorf("New error")
- logger.Info("we found an error: %v", err)
-
- logger.Debug("this is a useful message for software enigneers")
-
- logger.Warning("something bad happened but the software can still run")
-
- // Notice this does *NOT* exit!
- logger.Critical("the software should stop running, this is bad")
-
- // Now we have to exit
- os.Exit(123)
-}
diff --git a/example/fabulous.go b/example/fabulous.go
deleted file mode 100644
index 9c6a305..0000000
--- a/example/fabulous.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package main
-
-import (
- "github.com/kris-nova/logger"
- "fmt"
- "os"
-)
-
-
-func main(){
-
- logger.Fabulous = true
- logger.Color = false
- logger.Level = 4
-
- err := fmt.Errorf("New error")
-
- logger.Always("This is always printed")
-
- logger.Success("Hooray a good thing happened!")
-
- logger.Info("we found an error: %v", err)
-
- logger.Debug("this is a useful message for software enigneers")
-
- logger.Warning("something bad happened but the software can still run")
-
- // Notice this does *NOT* exit!
- logger.Critical("the software should stop running, this is bad")
-
- // Now we have to exit
- os.Exit(123)
-}
diff --git a/examples/legacy.go b/examples/legacy.go
new file mode 100644
index 0000000..56eb4f8
--- /dev/null
+++ b/examples/legacy.go
@@ -0,0 +1,26 @@
+// Copyright © 2021 Kris Nóva
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import "github.com/kris-nova/novaarchive/logger"
+
+func main() {
+
+ logger.Level = 4
+ logger.Always("Always logging")
+ logger.Info("Info logging")
+ logger.Debug("Debug logging")
+
+}
diff --git a/examples/rainbow.go b/examples/rainbow.go
new file mode 100644
index 0000000..bb58f43
--- /dev/null
+++ b/examples/rainbow.go
@@ -0,0 +1,57 @@
+// Copyright © 2021 Kris Nóva
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+ "github.com/kris-nova/logger"
+ lol "github.com/kris-nova/lolgopher"
+)
+
+func main() {
+ //
+ logger.Writer = lol.NewLolWriter() // Sometimes this will work better
+ logger.Writer = lol.NewTruecolorLolWriter() // Comment one of these out
+ //
+
+ logger.BitwiseLevel = logger.LogEverything
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Always(".....................")
+ logger.Debug("Debug logging")
+ logger.Critical("Stderr logging")
+}
diff --git a/examples/simple.go b/examples/simple.go
new file mode 100644
index 0000000..3c9eba0
--- /dev/null
+++ b/examples/simple.go
@@ -0,0 +1,32 @@
+// Copyright © 2021 Kris Nóva
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+ "os"
+
+ "github.com/kris-nova/novaarchive/logger"
+)
+
+func main() {
+
+ logger.BitwiseLevel = logger.LogEverything
+ logger.Always("Always logging")
+ logger.Always("Always logging")
+ logger.Debug("Debug logging")
+
+ logger.Writer = os.Stderr
+ logger.Critical("Stderr logging")
+}
diff --git a/go.mod b/go.mod
deleted file mode 100644
index 831c64b..0000000
--- a/go.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-module github.com/kris-nova/logger
-
-go 1.14
-
-require (
- github.com/fatih/color v1.9.0
- github.com/kris-nova/lolgopher v0.0.0-20180921204813-313b3abb0d9b
-)
diff --git a/go.sum b/go.sum
deleted file mode 100644
index fff877b..0000000
--- a/go.sum
+++ /dev/null
@@ -1,12 +0,0 @@
-github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
-github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
-github.com/kris-nova/lolgopher v0.0.0-20180921204813-313b3abb0d9b h1:xYEM2oBUhBEhQjrV+KJ9lEWDWYZoNVZUaBF++Wyljq4=
-github.com/kris-nova/lolgopher v0.0.0-20180921204813-313b3abb0d9b/go.mod h1:V0HF/ZBlN86HqewcDC/cVxMmYDiRukWjSrgKLUAn9Js=
-github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
-github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
-github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
-golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/logger.go b/logger.go
index 5c21b5e..29b5c12 100644
--- a/logger.go
+++ b/logger.go
@@ -1,4 +1,4 @@
-// Copyright © 2017
+// Copyright © 2021 Kris Nóva
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -20,172 +20,167 @@ import (
"os"
"strings"
"time"
-
- "github.com/fatih/color"
- lol "github.com/kris-nova/lolgopher"
)
-type Logger func(format string, a ...interface{})
+type LoggerFunc func(format string, a ...interface{})
+
+//type Logger interface {
+// LineBytes(prefix, format string, a ...interface{}) []byte
+// Line(prefix, format string, a ...interface{}) string
+// Always(format string, a ...interface{})
+// Success(format string, a ...interface{})
+// Debug(format string, a ...interface{})
+// Info(format string, a ...interface{})
+// Warning(format string, a ...interface{})
+// Critical(format string, a ...interface{})
+//}
const (
- AlwaysLabel = "✿"
- CriticalLabel = "✖"
- DebugLabel = "▶"
- InfoLabel = "ℹ"
- SuccessLabel = "✔"
- WarningLabel = "!"
+ // [Log Constants]
+ //
+ // These are the bitwise values for the
+ // various log options.
+ //
+ // Also these are the string prefixes
+ // for the log lines.
+ LogAlways = 1
+ PreAlways = "Always "
+ LogSuccess = 2
+ PreSuccess = "Success "
+ LogCritical = 4
+ PreCritical = "Critical "
+ LogWarning = 8
+ PreWarning = "Warning "
+ LogInfo = 16
+ PreInfo = "Info "
+ LogDebug = 32
+ PreDebug = "Debug "
+ LogDeprecated = 64
+ PreDeprecated = "Deprecated"
+
+ LogLegacyLevel2 = LogAlways | LogSuccess | LogCritical | LogWarning | LogInfo
+ LogLegacyLevel2Deprecated = LogLegacyLevel2 | LogDeprecated
+
+ // Enable all Logging levels
+ // [127]
+ LogEverything = LogAlways | LogSuccess | LogDebug | LogInfo | LogWarning | LogCritical | LogDeprecated
)
+type WriterMode int
+
var (
- Level = 2
- Color = true
- Fabulous = false
- FabulousWriter = lol.NewLolWriter()
- FabulousTrueWriter = lol.NewTruecolorLolWriter()
- TestMode = false
- Timestamps = true
+
+ // BitwiseLevel is the preferred
+ // way of managing log levels.
+ //
+ // ----- [ Bitwise Chart ] ------
+ //
+ // LogEverything (All Levels)
+ // LogAlways
+ // LogSuccess
+ // LogCritical
+ // LogWarning
+ // LogInfo
+ // LogDebug
+ // LogDeprecated
+ //
+ // TODO @kris-nova In the next release flip to LogEverything
+ // BitwiseLevel = LogEverything
+ BitwiseLevel = LogLegacyLevel2Deprecated
+
+ // A custom io.Writer to use regardless of Mode
+ Writer io.Writer = os.Stdout
+
+ // Layout is the time layout string to use
+ Layout string = time.RFC3339
)
-func Always(format string, a ...interface{}) {
- a, w := extractLoggerArgs(format, a...)
- s := fmt.Sprintf(label(format, AlwaysLabel), a...)
-
- if !TestMode {
- if Color {
- w = color.Output
- s = color.GreenString(s)
- } else if Fabulous {
- w = FabulousWriter
- }
- }
-
- fmt.Fprint(w, s)
+// LineBytes will format a log line, and return
+// a slice of bytes []byte
+func LineBytes(prefix, format string, a ...interface{}) []byte {
+ return []byte(Line(prefix, format, a...))
}
-func Critical(format string, a ...interface{}) {
- if Level >= 1 {
- a, w := extractLoggerArgs(format, a...)
- s := fmt.Sprintf(label(format, CriticalLabel), a...)
-
- if !TestMode {
- if Color {
- w = color.Output
- s = color.RedString(s)
- } else if Fabulous {
- w = FabulousWriter
- }
- }
-
- fmt.Fprint(w, s)
+// Line will format a log line, and return a string
+func Line(prefix, format string, a ...interface{}) string {
+ if !strings.Contains(format, "\n") {
+ format = fmt.Sprintf("%s%s", format, "\n")
}
-}
-
-func Info(format string, a ...interface{}) {
- if Level >= 3 {
- a, w := extractLoggerArgs(format, a...)
- s := fmt.Sprintf(label(format, InfoLabel), a...)
-
- if !TestMode {
- if Color {
- w = color.Output
- s = color.CyanString(s)
- } else if Fabulous {
- w = FabulousWriter
- }
- }
-
- fmt.Fprint(w, s)
- }
-}
-
-func Success(format string, a ...interface{}) {
- if Level >= 3 {
- a, w := extractLoggerArgs(format, a...)
- s := fmt.Sprintf(label(format, SuccessLabel), a...)
-
- if !TestMode {
- if Color {
- w = color.Output
- s = color.CyanString(s)
- } else if Fabulous {
- w = FabulousWriter
- }
- }
-
- fmt.Fprint(w, s)
- }
-}
-
-func Debug(format string, a ...interface{}) {
- if Level >= 4 {
- a, w := extractLoggerArgs(format, a...)
- s := fmt.Sprintf(label(format, DebugLabel), a...)
-
- if !TestMode {
- if Color {
- w = color.Output
- s = color.GreenString(s)
- } else if Fabulous {
- w = FabulousWriter
- }
- }
-
- fmt.Fprint(w, s)
- }
-}
-
-func Warning(format string, a ...interface{}) {
- if Level >= 2 {
- a, w := extractLoggerArgs(format, a...)
- s := fmt.Sprintf(label(format, WarningLabel), a...)
-
- if !TestMode {
- if Color {
- w = color.Output
- s = color.GreenString(s)
- } else if Fabulous {
- w = FabulousWriter
- }
- }
-
- fmt.Fprint(w, s)
- }
-}
-
-func extractLoggerArgs(format string, a ...interface{}) ([]interface{}, io.Writer) {
- var w io.Writer = os.Stdout
-
- if n := len(a); n > 0 {
- // extract an io.Writer at the end of a
- if value, ok := a[n-1].(io.Writer); ok {
- w = value
- a = a[0 : n-1]
- }
- }
-
- return a, w
-}
-
-func label(format, label string) string {
if Timestamps {
- return labelWithTime(format, label)
+ now := time.Now()
+ fNow := now.Format(Layout)
+ prefix = fmt.Sprintf("%s [%s]", fNow, prefix)
} else {
- return labelWithoutTime(format, label)
+ prefix = fmt.Sprintf("[%s]", prefix)
+ }
+ return fmt.Sprintf("%s %s", prefix, fmt.Sprintf(format, a...))
+}
+
+// Always
+func Always(format string, a ...interface{}) {
+ d()
+ a = legacyFindWriter(a...)
+ if BitwiseLevel&LogAlways != 0 {
+ fmt.Fprint(Writer, Line(PreAlways, format, a...))
}
}
-func labelWithTime(format, label string) string {
- t := time.Now()
- rfct := t.Format(time.RFC3339)
- if !strings.Contains(format, "\n") {
- format = fmt.Sprintf("%s%s", format, "\n")
+// Success
+func Success(format string, a ...interface{}) {
+ d()
+ a = legacyFindWriter(a...)
+ if BitwiseLevel&LogSuccess != 0 {
+ fmt.Fprint(Writer, Line(PreSuccess, format, a...))
}
- return fmt.Sprintf("%s [%s] %s", rfct, label, format)
}
-func labelWithoutTime(format, label string) string {
- if !strings.Contains(format, "\n") {
- format = fmt.Sprintf("%s%s", format, "\n")
+// Debug
+func Debug(format string, a ...interface{}) {
+ d()
+ a = legacyFindWriter(a...)
+ if BitwiseLevel&LogDebug != 0 {
+ fmt.Fprint(Writer, Line(PreDebug, format, a...))
}
- return fmt.Sprintf("[%s] %s", label, format)
+}
+
+// Info
+func Info(format string, a ...interface{}) {
+ d()
+ a = legacyFindWriter(a...)
+ if BitwiseLevel&LogInfo != 0 {
+ fmt.Fprint(Writer, Line(PreInfo, format, a...))
+ }
+}
+
+// Warning
+func Warning(format string, a ...interface{}) {
+ d()
+ a = legacyFindWriter(a...)
+ if BitwiseLevel&LogWarning != 0 {
+ fmt.Fprint(Writer, Line(PreWarning, format, a...))
+ }
+}
+
+// Critical
+func Critical(format string, a ...interface{}) {
+ d()
+ a = legacyFindWriter(a...)
+ if BitwiseLevel&LogCritical != 0 {
+ fmt.Fprint(Writer, Line(PreCritical, format, a...))
+ }
+}
+
+// Used to show deprecated log lines
+func Deprecated(format string, a ...interface{}) {
+ a = legacyFindWriter(a...)
+ if BitwiseLevel&LogDeprecated != 0 {
+ fmt.Fprint(Writer, Line(PreDeprecated, format, a...))
+ }
+}
+
+// d is used by every function
+// and is an easy way to add
+// global logic/state to the logger
+func d() {
+ checkDeprecatedValues()
}
diff --git a/logger_legacy.go b/logger_legacy.go
new file mode 100644
index 0000000..ea3b711
--- /dev/null
+++ b/logger_legacy.go
@@ -0,0 +1,108 @@
+// Copyright © 2021 Kris Nóva
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package logger
+
+import (
+ "io"
+ "sync"
+)
+
+// Legacy Logic for 0.1.0
+//
+// Here we store the legacy (0.1.0) compatible configuration options
+// that will eventually be deprecated.
+//
+var (
+
+ // Timestamps are used to toggle timestamps
+ // deprecated
+ Timestamps = true
+
+ // TestMode is used for running
+ // the regression tests.
+ // deprecated
+ TestMode = false
+
+ // Color is no longer used
+ // deprecated
+ Color = true
+
+ // Level is the legacy log level
+ //
+ // 0 (Least verbose)
+ // 1
+ // 2
+ // 3
+ // 4 (Most verbose)
+ //
+ // deprecated
+ Level = -1
+)
+
+var (
+ testRaceMutex = sync.Mutex{}
+ annoyed = false
+)
+
+// checkDeprecatedValues is a singleton
+// that will only execute once.
+// This will convert the legacy logger.Level
+// to the new logger.BitwiseLevel
+//
+// LogEverything =
+func checkDeprecatedValues() {
+ testRaceMutex.Lock()
+ defer testRaceMutex.Unlock()
+ if Level != -1 {
+ if !annoyed {
+ Deprecated("********")
+ Deprecated("***")
+ Deprecated("*")
+ Deprecated("logger.Level is deprecated. Use logger.BitwiseLevel")
+ Deprecated("*")
+ Deprecated("***")
+ Deprecated("********")
+ annoyed = true
+ }
+ if Level == 4 {
+ BitwiseLevel = LogDeprecated | LogAlways | LogSuccess | LogCritical | LogWarning | LogInfo | LogDebug
+ } else if Level == 3 {
+ BitwiseLevel = LogDeprecated | LogAlways | LogSuccess | LogCritical | LogWarning | LogInfo
+ } else if Level == 2 {
+ BitwiseLevel = LogDeprecated | LogAlways | LogSuccess | LogCritical | LogWarning
+ } else if Level == 1 {
+ BitwiseLevel = LogDeprecated | LogAlways | LogSuccess | LogCritical
+ } else if Level == 0 {
+ BitwiseLevel = LogDeprecated | LogAlways | LogSuccess
+ } else {
+ BitwiseLevel = LogDeprecated | LogEverything
+ }
+ }
+}
+
+// legacyFindWriter will check if there is an io.Writer
+// appended to the end of the arguments passed to the logger.
+//
+// deprecated
+func legacyFindWriter(a ...interface{}) []interface{} {
+ if n := len(a); n > 0 {
+ // extract an io.Writer at the end of a
+ if newWriter, ok := a[n-1].(io.Writer); ok {
+ Writer = newWriter
+ a = a[0 : n-1]
+ }
+ }
+ return a
+}
diff --git a/logger_legacy_test.go b/logger_legacy_test.go
new file mode 100644
index 0000000..1ac038b
--- /dev/null
+++ b/logger_legacy_test.go
@@ -0,0 +1,158 @@
+// Copyright © 2021 Kris Nóva
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// ----------------------------------------------------------------------------
+//
+// Legacy Regression tests for 0.1.0
+//
+// Note: @christopherhein added these tests and I am unsure if Amazon
+// is still using the old io.Writer append() convention.
+// Either way, I am keeping legacy (deprecated) support for it.
+//
+// All of these regression tests should still pass.
+//
+// ----------------------------------------------------------------------------
+
+package logger
+
+import (
+ "bytes"
+ "fmt"
+ "regexp"
+ "testing"
+)
+
+const (
+ format = "%v, %v, %v, all eyes on me!"
+ formatExp = `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.* \[%s\] \d, \d, \d, all eyes on me!`
+ formatWOTimeExp = `\[%s\] \d, \d, \d, all eyes on me!`
+)
+
+var (
+ a = []interface{}{1, 2, 3}
+)
+
+func TestMain(m *testing.M) {
+ TestMode = true
+ m.Run()
+}
+
+func TestAlwaysLegacy(t *testing.T) {
+ e, err := regexp.Compile(fmt.Sprintf(formatExp, PreAlways))
+ g := captureLoggerOutput(Always, format, a)
+
+ if err != nil {
+ t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
+ }
+
+ if !e.MatchString(g) {
+ t.Fatalf("Always should produce a pattern '%v' but produces: %v", e.String(), g)
+ }
+}
+
+func TestCriticalLegacy(t *testing.T) {
+ Level = 1
+
+ e, err := regexp.Compile(fmt.Sprintf(formatExp, PreCritical))
+ g := captureLoggerOutput(Critical, format, a)
+
+ if err != nil {
+ t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
+ }
+
+ if !e.MatchString(g) {
+ t.Fatalf("Critical should produce a pattern '%v' but produces: %v", e.String(), g)
+ }
+}
+
+func TestInfoLegacy(t *testing.T) {
+ Level = 3
+
+ e, err := regexp.Compile(fmt.Sprintf(formatExp, PreInfo))
+ g := captureLoggerOutput(Info, format, a)
+
+ if err != nil {
+ t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
+ }
+
+ if !e.MatchString(g) {
+ t.Fatalf("Info should produce a pattern '%v' but produces: %v", e.String(), g)
+ }
+}
+
+func TestSuccessLegacy(t *testing.T) {
+ Level = 3
+
+ e, err := regexp.Compile(fmt.Sprintf(formatExp, PreSuccess))
+ g := captureLoggerOutput(Success, format, a)
+
+ if err != nil {
+ t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
+ }
+
+ if !e.MatchString(g) {
+ t.Fatalf("Success should produce a pattern '%v' but produces: %v", e.String(), g)
+ }
+}
+
+func TestDebugLegacy(t *testing.T) {
+ Level = 4
+
+ e, err := regexp.Compile(fmt.Sprintf(formatExp, PreDebug))
+ g := captureLoggerOutput(Debug, format, a)
+
+ if err != nil {
+ t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
+ }
+
+ if !e.MatchString(g) {
+ t.Fatalf("Info should produce a pattern '%v' but produces: %v", e.String(), g)
+ }
+}
+
+func TestWarningLegacy(t *testing.T) {
+ Level = 2
+
+ e, err := regexp.Compile(fmt.Sprintf(formatExp, PreWarning))
+ g := captureLoggerOutput(Warning, format, a)
+
+ if err != nil {
+ t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
+ }
+
+ if !e.MatchString(g) {
+ t.Fatalf("Info should produce a pattern '%v' but produces: %v", e.String(), g)
+ }
+}
+
+func TestWithoutTimestampsLegacy(t *testing.T) {
+ Timestamps = false
+ e, err := regexp.Compile(fmt.Sprintf(formatWOTimeExp, PreAlways))
+ g := captureLoggerOutput(Always, format, a)
+
+ if err != nil {
+ t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
+ }
+
+ if !e.MatchString(g) {
+ t.Fatalf("Always should produce a pattern '%v' but produces: %v", e.String(), g)
+ }
+}
+
+// captureLoggerOutput is used to test the log functions
+func captureLoggerOutput(l LoggerFunc, format string, a []interface{}) string {
+ b := new(bytes.Buffer)
+ l(format, append(a, b)...)
+ return b.String()
+}
diff --git a/logger_test.go b/logger_test.go
index eb4861f..6846c54 100644
--- a/logger_test.go
+++ b/logger_test.go
@@ -1,4 +1,4 @@
-// Copyright © 2017 The Kubicorn Authors
+// Copyright © 2021 Kris Nóva
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,130 +17,192 @@ package logger
import (
"bytes"
"fmt"
- "regexp"
"testing"
)
const (
- format = "%v, %v, %v, all eyes on me!"
- formatExp = `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.* \[%s\] \d, \d, \d, all eyes on me!`
- formatWOTimeExp = `\[%s\] \d, \d, \d, all eyes on me!`
+ TestFormat = "%s %s %s money, success, fame glamour"
)
var (
- a = []interface{}{1, 2, 3}
+ testA = []interface{}{"1", "2", "3"}
)
-func TestMain(m *testing.M) {
- TestMode = true
-
- m.Run()
-}
-
-func TestAlways(t *testing.T) {
- e, err := regexp.Compile(fmt.Sprintf(formatExp, AlwaysLabel))
- g := captureLoggerOutput(Always, format, a)
-
- if err != nil {
- t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
- }
-
- if !e.MatchString(g) {
- t.Fatalf("Always should produce a pattern '%v' but produces: %v", e.String(), g)
+func TestAlwaysOnly(t *testing.T) {
+ Level = -1
+ BitwiseLevel = LogAlways
+ buffer := new(bytes.Buffer)
+ Writer = buffer
+ expected := Line(PreAlways, TestFormat, testA...)
+ Deprecated(TestFormat, testA...)
+ Debug(TestFormat, testA...)
+ Info(TestFormat, testA...)
+ Warning(TestFormat, testA...)
+ Critical(TestFormat, testA...)
+ Success(TestFormat, testA...)
+ Always(TestFormat, testA...)
+ actual := buffer.String()
+ if expected != actual {
+ t.Errorf("Expected (%s) Actual (%s)", expected, actual)
}
}
-func TestCritical(t *testing.T) {
- Level = 1
-
- e, err := regexp.Compile(fmt.Sprintf(formatExp, CriticalLabel))
- g := captureLoggerOutput(Critical, format, a)
-
- if err != nil {
- t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
- }
-
- if !e.MatchString(g) {
- t.Fatalf("Critical should produce a pattern '%v' but produces: %v", e.String(), g)
+func TestSuccessOnly(t *testing.T) {
+ Level = -1
+ BitwiseLevel = LogSuccess
+ buffer := new(bytes.Buffer)
+ Writer = buffer
+ expected := Line(PreSuccess, TestFormat, testA...)
+ Deprecated(TestFormat, testA...)
+ Debug(TestFormat, testA...)
+ Info(TestFormat, testA...)
+ Warning(TestFormat, testA...)
+ Critical(TestFormat, testA...)
+ Success(TestFormat, testA...)
+ Always(TestFormat, testA...)
+ actual := buffer.String()
+ if expected != actual {
+ t.Errorf("Expected (%s) Actual (%s)", expected, actual)
}
}
-func TestInfo(t *testing.T) {
- Level = 3
-
- e, err := regexp.Compile(fmt.Sprintf(formatExp, InfoLabel))
- g := captureLoggerOutput(Info, format, a)
-
- if err != nil {
- t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
- }
-
- if !e.MatchString(g) {
- t.Fatalf("Info should produce a pattern '%v' but produces: %v", e.String(), g)
+func TestDebugOnly(t *testing.T) {
+ Level = -1
+ BitwiseLevel = LogDebug
+ buffer := new(bytes.Buffer)
+ Writer = buffer
+ expected := Line(PreDebug, TestFormat, testA...)
+ Deprecated(TestFormat, testA...)
+ Debug(TestFormat, testA...)
+ Info(TestFormat, testA...)
+ Warning(TestFormat, testA...)
+ Critical(TestFormat, testA...)
+ Success(TestFormat, testA...)
+ Always(TestFormat, testA...)
+ actual := buffer.String()
+ if expected != actual {
+ t.Errorf("Expected (%s) Actual (%s)", expected, actual)
}
}
-func TestSuccess(t *testing.T) {
- Level = 3
-
- e, err := regexp.Compile(fmt.Sprintf(formatExp, SuccessLabel))
- g := captureLoggerOutput(Success, format, a)
-
- if err != nil {
- t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
- }
-
- if !e.MatchString(g) {
- t.Fatalf("Success should produce a pattern '%v' but produces: %v", e.String(), g)
+func TestInfoOnly(t *testing.T) {
+ Level = -1
+ BitwiseLevel = LogInfo
+ buffer := new(bytes.Buffer)
+ Writer = buffer
+ expected := Line(PreInfo, TestFormat, testA...)
+ Deprecated(TestFormat, testA...)
+ Debug(TestFormat, testA...)
+ Info(TestFormat, testA...)
+ Warning(TestFormat, testA...)
+ Critical(TestFormat, testA...)
+ Success(TestFormat, testA...)
+ Always(TestFormat, testA...)
+ actual := buffer.String()
+ if expected != actual {
+ t.Errorf("Expected (%s) Actual (%s)", expected, actual)
}
}
-func TestDebug(t *testing.T) {
- Level = 4
-
- e, err := regexp.Compile(fmt.Sprintf(formatExp, DebugLabel))
- g := captureLoggerOutput(Debug, format, a)
-
- if err != nil {
- t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
- }
-
- if !e.MatchString(g) {
- t.Fatalf("Info should produce a pattern '%v' but produces: %v", e.String(), g)
+func TestWarningOnly(t *testing.T) {
+ Level = -1
+ BitwiseLevel = LogWarning
+ buffer := new(bytes.Buffer)
+ Writer = buffer
+ expected := Line(PreWarning, TestFormat, testA...)
+ Deprecated(TestFormat, testA...)
+ Debug(TestFormat, testA...)
+ Info(TestFormat, testA...)
+ Warning(TestFormat, testA...)
+ Critical(TestFormat, testA...)
+ Success(TestFormat, testA...)
+ Always(TestFormat, testA...)
+ actual := buffer.String()
+ if expected != actual {
+ t.Errorf("Expected (%s) Actual (%s)", expected, actual)
}
}
-func TestWarning(t *testing.T) {
- Level = 2
-
- e, err := regexp.Compile(fmt.Sprintf(formatExp, WarningLabel))
- g := captureLoggerOutput(Warning, format, a)
-
- if err != nil {
- t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
- }
-
- if !e.MatchString(g) {
- t.Fatalf("Info should produce a pattern '%v' but produces: %v", e.String(), g)
+func TestCriticalOnly(t *testing.T) {
+ Level = -1
+ BitwiseLevel = LogCritical
+ buffer := new(bytes.Buffer)
+ Writer = buffer
+ expected := Line(PreCritical, TestFormat, testA...)
+ Deprecated(TestFormat, testA...)
+ Debug(TestFormat, testA...)
+ Info(TestFormat, testA...)
+ Warning(TestFormat, testA...)
+ Critical(TestFormat, testA...)
+ Success(TestFormat, testA...)
+ Always(TestFormat, testA...)
+ actual := buffer.String()
+ if expected != actual {
+ t.Errorf("Expected (%s) Actual (%s)", expected, actual)
}
}
-func TestWithoutTimestamps(t *testing.T) {
- Timestamps = false
- e, err := regexp.Compile(fmt.Sprintf(formatWOTimeExp, AlwaysLabel))
- g := captureLoggerOutput(Always, format, a)
-
- if err != nil {
- t.Fatalf("Failed to compile regexp '%v': %v", e.String(), err)
- }
-
- if !e.MatchString(g) {
- t.Fatalf("Always should produce a pattern '%v' but produces: %v", e.String(), g)
+func TestDeprecatedOnly(t *testing.T) {
+ Level = -1
+ BitwiseLevel = LogDeprecated
+ buffer := new(bytes.Buffer)
+ Writer = buffer
+ expected := Line(PreDeprecated, TestFormat, testA...)
+ Deprecated(TestFormat, testA...)
+ Debug(TestFormat, testA...)
+ Info(TestFormat, testA...)
+ Warning(TestFormat, testA...)
+ Critical(TestFormat, testA...)
+ Success(TestFormat, testA...)
+ Always(TestFormat, testA...)
+ actual := buffer.String()
+ if expected != actual {
+ t.Errorf("Expected (%s) Actual (%s)", expected, actual)
}
}
-func captureLoggerOutput(l Logger, format string, a []interface{}) string {
- b := new(bytes.Buffer)
- l(format, append(a, b)...)
- return b.String()
+func TestEverything(t *testing.T) {
+ Level = -1
+ BitwiseLevel = LogEverything
+ buffer := new(bytes.Buffer)
+ Writer = buffer
+ cases := []string{PreDeprecated, PreDebug, PreInfo, PreWarning, PreCritical, PreSuccess, PreAlways}
+ expected := ""
+ for _, c := range cases {
+ expected = fmt.Sprintf("%s%s", expected, Line(c, TestFormat, testA...))
+ }
+ Deprecated(TestFormat, testA...)
+ Debug(TestFormat, testA...)
+ Info(TestFormat, testA...)
+ Warning(TestFormat, testA...)
+ Critical(TestFormat, testA...)
+ Success(TestFormat, testA...)
+ Always(TestFormat, testA...)
+ actual := buffer.String()
+ if expected != actual {
+ t.Errorf("Expected (%s) Actual (%s)", expected, actual)
+ }
+}
+
+func TestAlwaysCriticalDebugOnly(t *testing.T) {
+ Level = -1
+ BitwiseLevel = LogAlways | LogCritical | LogDebug
+ buffer := new(bytes.Buffer)
+ Writer = buffer
+ cases := []string{PreDebug, PreCritical, PreAlways}
+ expected := ""
+ for _, c := range cases {
+ expected = fmt.Sprintf("%s%s", expected, Line(c, TestFormat, testA...))
+ }
+ Deprecated(TestFormat, testA...)
+ Debug(TestFormat, testA...)
+ Info(TestFormat, testA...)
+ Warning(TestFormat, testA...)
+ Critical(TestFormat, testA...)
+ Success(TestFormat, testA...)
+ Always(TestFormat, testA...)
+ actual := buffer.String()
+ if expected != actual {
+ t.Errorf("Expected (%s) Actual (%s)", expected, actual)
+ }
}
diff --git a/screenshot.png b/screenshot.png
index 3aee64d..af9043c 100644
Binary files a/screenshot.png and b/screenshot.png differ