master
Charles Iliya Krempeaux 2021-02-04 17:19:59 -08:00
parent c0015e89c0
commit e690f00e18
20 changed files with 1211 additions and 0 deletions

78
default.go 100644
View File

@ -0,0 +1,78 @@
package flog
import (
"os"
)
var Default Logger
func init() {
Default = NewLogger(os.Stdout, "color")
}
func Debug(a ...interface{}) {
Default.Debug(a...)
}
func Debugf(format string, a ...interface{}) {
Default.Debugf(format, a...)
}
func Error(a ...interface{}) error {
return Default.Error(a...)
}
func Errorf(format string, a ...interface{}) error {
return Default.Errorf(format, a...)
}
func Fatal(a ...interface{}) {
Default.Fatal(a...)
}
func Fatalf(format string, a ...interface{}) {
Default.Fatalf(format, a...)
}
func Highlight(a ...interface{}) {
Default.Highlight(a...)
}
func Highlightf(format string, a ...interface{}) {
Default.Highlightf(format, a...)
}
func Inform(a ...interface{}) {
Default.Inform(a...)
}
func Informf(format string, a ...interface{}) {
Default.Informf(format, a...)
}
func Panic(a ...interface{}) {
Default.Panic(a...)
}
func Panicf(format string, a ...interface{}) {
Default.Panicf(format, a...)
}
func Trace(a ...interface{}) {
Default.Trace(a...)
}
func Tracef(format string, a ...interface{}) {
Default.Tracef(format, a...)
}
func Warn(a ...interface{}) {
Default.Warn(a...)
}
func Warnf(format string, a ...interface{}) {
Default.Warnf(format, a...)
}
func Prefix(a ...string) Logger {
return Default.Prefix(a...)
}

38
internal_logger.go 100644
View File

@ -0,0 +1,38 @@
package flog
import (
"io"
)
type internalLogger struct {
prefix string
style string
writer io.Writer
canNotLogDebug bool
canNotLogError bool
canNotLogFatal bool
canNotLogHighlight bool
canNotLogInform bool
canNotLogPanic bool
canNotLogTrace bool
canNotLogWarn bool
}
func NewLogger(writer io.Writer, parameters ...string) Logger {
logger := internalLogger{
writer:writer,
}
if 1 <= len(parameters) {
style := parameters[0]
switch style {
case "color","colour":
logger.style = "color"
default:
logger.style = ""
}
}
return logger
}

View File

@ -0,0 +1,62 @@
package flog
import (
"fmt"
"io"
"strings"
)
func (receiver internalLogger) CanLogDebug() bool {
return !receiver.canNotLogDebug
}
func (receiver internalLogger) Debug(a ...interface{}) {
if !receiver.CanLogDebug() {
return
}
if nil == receiver.writer {
return
}
s := fmt.Sprint(a...)
receiver.Debugf("%s", s)
}
func (receiver internalLogger) Debugf(format string, a ...interface{}) {
if !receiver.CanLogDebug() {
return
}
var writer io.Writer = receiver.writer
if nil == writer {
return
}
var newformat string
{
var buffer strings.Builder
switch receiver.style{
case"color":
buffer.WriteString("\x1b[48;2;1;1;1m")
buffer.WriteString("\x1b[38;2;44;181;233m")
case "":
buffer.WriteString("[debug] ")
}
buffer.WriteString(format)
switch receiver.style {
case "color":
buffer.WriteString("\x1b[0m")
buffer.WriteRune('\n')
case "":
buffer.WriteRune('\n')
}
newformat = buffer.String()
}
fmt.Fprintf(receiver.writer, newformat, a...)
}

View File

@ -0,0 +1,69 @@
package flog
import (
"bytes"
"testing"
)
func TestInternalLogger_Debugf(t *testing.T) {
tests := []struct{
Format string
Array []interface{}
Expected string
}{
{
Format: "",
Array: []interface{}(nil),
Expected: "[debug] \n",
},
{
Format: "",
Array: []interface{}{},
Expected: "[debug] \n",
},
{
Format: "hello world",
Array: []interface{}(nil),
Expected: "[debug] hello world\n",
},
{
Format: "hello world",
Array: []interface{}{},
Expected: "[debug] hello world\n",
},
{
Format: "hello %s",
Array: []interface{}{"Joe"},
Expected: "[debug] hello Joe\n",
},
{
Format: "hello %s %s",
Array: []interface{}{"Joe", "Blow"},
Expected: "[debug] hello Joe Blow\n",
},
}
for testNumber, test := range tests {
var buffer bytes.Buffer
logger := NewLogger(&buffer)
logger.Debugf(test.Format, test.Array...)
if expected, actual := test.Expected, buffer.String(); expected != actual {
t.Errorf("For tst #%d, the actual result is not what was expected.", testNumber)
t.Logf("EXPECTED: %q", expected)
t.Logf("ACTUAL: %q", actual)
continue
}
}
}

View File

@ -0,0 +1,59 @@
package flog
import (
"fmt"
"io"
"strings"
)
func (receiver internalLogger) CanLogError() bool {
return !receiver.canNotLogError
}
func (receiver internalLogger) Error(a ...interface{}) error {
s := fmt.Sprint(a...)
return receiver.Errorf("%s", s)
}
func (receiver internalLogger) Errorf(format string, a ...interface{}) error {
err := fmt.Errorf(format, a...)
if !receiver.CanLogError() {
return err
}
var writer io.Writer = receiver.writer
if nil == writer {
return err
}
var newformat string
{
var buffer strings.Builder
switch receiver.style{
case"color":
buffer.WriteString("\x1b[48;2;1;1;1m")
buffer.WriteString("\x1b[38;222;56;43;6m")
case "":
buffer.WriteString("[ERROR] ")
}
buffer.WriteString(format)
switch receiver.style {
case "color":
buffer.WriteString("\x1b[0m")
buffer.WriteRune('\n')
case "":
buffer.WriteRune('\n')
}
newformat = buffer.String()
}
fmt.Fprintf(receiver.writer, newformat, a...)
return err
}

View File

@ -0,0 +1,69 @@
package flog
import (
"bytes"
"testing"
)
func TestInternalLogger_Errorf(t *testing.T) {
tests := []struct{
Format string
Array []interface{}
Expected string
}{
{
Format: "",
Array: []interface{}(nil),
Expected: "[ERROR] \n",
},
{
Format: "",
Array: []interface{}{},
Expected: "[ERROR] \n",
},
{
Format: "hello world",
Array: []interface{}(nil),
Expected: "[ERROR] hello world\n",
},
{
Format: "hello world",
Array: []interface{}{},
Expected: "[ERROR] hello world\n",
},
{
Format: "hello %s",
Array: []interface{}{"Joe"},
Expected: "[ERROR] hello Joe\n",
},
{
Format: "hello %s %s",
Array: []interface{}{"Joe", "Blow"},
Expected: "[ERROR] hello Joe Blow\n",
},
}
for testNumber, test := range tests {
var buffer bytes.Buffer
logger := NewLogger(&buffer)
logger.Errorf(test.Format, test.Array...)
if expected, actual := test.Expected, buffer.String(); expected != actual {
t.Errorf("For tst #%d, the actual result is not what was expected.", testNumber)
t.Logf("EXPECTED: %q", expected)
t.Logf("ACTUAL: %q", actual)
continue
}
}
}

View File

@ -0,0 +1,60 @@
package flog
import (
"fmt"
"io"
"os"
"strings"
)
func (receiver internalLogger) CanLogFatal() bool {
return !receiver.canNotLogFatal
}
func (receiver internalLogger) Fatal(a ...interface{}) {
s := fmt.Sprint(a...)
receiver.Fatalf("%s", s)
}
func (receiver internalLogger) Fatalf(format string, a ...interface{}) {
if !receiver.CanLogFatal() {
os.Exit(1)
return
}
var writer io.Writer = receiver.writer
if nil == writer {
os.Exit(1)
return
}
var newformat string
{
var buffer strings.Builder
switch receiver.style{
case"color":
buffer.WriteString("\x1b[48;2;1;1;1m")
buffer.WriteString("\x1b[38;222;56;43;6m")
case "":
buffer.WriteString("[PANIC] ")
}
buffer.WriteString(format)
switch receiver.style {
case "color":
buffer.WriteString("\x1b[0m")
buffer.WriteRune('\n')
case "":
buffer.WriteRune('\n')
}
newformat = buffer.String()
}
fmt.Fprintf(receiver.writer, newformat, a...)
os.Exit(1)
}

View File

@ -0,0 +1,62 @@
package flog
import (
"fmt"
"io"
"strings"
)
func (receiver internalLogger) CanLogHighlight() bool {
return !receiver.canNotLogHighlight
}
func (receiver internalLogger) Highlight(a ...interface{}) {
if !receiver.CanLogHighlight() {
return
}
if nil == receiver.writer {
return
}
s := fmt.Sprint(a...)
receiver.Highlightf("%s", s)
}
func (receiver internalLogger) Highlightf(format string, a ...interface{}) {
if !receiver.CanLogHighlight() {
return
}
var writer io.Writer = receiver.writer
if nil == writer {
return
}
var newformat string
{
var buffer strings.Builder
switch receiver.style{
case"color":
buffer.WriteString("\x1b[48;2;153;0;17m")
buffer.WriteString("\x1b[38;2;252;246;245m")
case "":
buffer.WriteString("[HIGHLIGHT] ")
}
buffer.WriteString(format)
switch receiver.style {
case "color":
buffer.WriteString("\x1b[0m")
buffer.WriteRune('\n')
case "":
buffer.WriteRune('\n')
}
newformat = buffer.String()
}
fmt.Fprintf(receiver.writer, newformat, a...)
}

View File

@ -0,0 +1,69 @@
package flog
import (
"bytes"
"testing"
)
func TestInternalLogger_Highlightf(t *testing.T) {
tests := []struct{
Format string
Array []interface{}
Expected string
}{
{
Format: "",
Array: []interface{}(nil),
Expected: "[HIGHLIGHT] \n",
},
{
Format: "",
Array: []interface{}{},
Expected: "[HIGHLIGHT] \n",
},
{
Format: "hello world",
Array: []interface{}(nil),
Expected: "[HIGHLIGHT] hello world\n",
},
{
Format: "hello world",
Array: []interface{}{},
Expected: "[HIGHLIGHT] hello world\n",
},
{
Format: "hello %s",
Array: []interface{}{"Joe"},
Expected: "[HIGHLIGHT] hello Joe\n",
},
{
Format: "hello %s %s",
Array: []interface{}{"Joe", "Blow"},
Expected: "[HIGHLIGHT] hello Joe Blow\n",
},
}
for testNumber, test := range tests {
var buffer bytes.Buffer
logger := NewLogger(&buffer)
logger.Highlightf(test.Format, test.Array...)
if expected, actual := test.Expected, buffer.String(); expected != actual {
t.Errorf("For tst #%d, the actual result is not what was expected.", testNumber)
t.Logf("EXPECTED: %q", expected)
t.Logf("ACTUAL: %q", actual)
continue
}
}
}

View File

@ -0,0 +1,62 @@
package flog
import (
"fmt"
"io"
"strings"
)
func (receiver internalLogger) CanLogInform() bool {
return !receiver.canNotLogInform
}
func (receiver internalLogger) Inform(a ...interface{}) {
if !receiver.CanLogInform() {
return
}
if nil == receiver.writer {
return
}
s := fmt.Sprint(a...)
receiver.Informf("%s", s)
}
func (receiver internalLogger) Informf(format string, a ...interface{}) {
if !receiver.CanLogInform() {
return
}
var writer io.Writer = receiver.writer
if nil == writer {
return
}
var newformat string
{
var buffer strings.Builder
switch receiver.style{
case"color":
buffer.WriteString("\x1b[48;2;1;1;1m")
buffer.WriteString("\x1b[38;222;56;43;6m")
case "":
buffer.WriteString("[inform] ")
}
buffer.WriteString(format)
switch receiver.style {
case "color":
buffer.WriteString("\x1b[0m")
buffer.WriteRune('\n')
case "":
buffer.WriteRune('\n')
}
newformat = buffer.String()
}
fmt.Fprintf(receiver.writer, newformat, a...)
}

View File

@ -0,0 +1,69 @@
package flog
import (
"bytes"
"testing"
)
func TestInternalLogger_Informf(t *testing.T) {
tests := []struct{
Format string
Array []interface{}
Expected string
}{
{
Format: "",
Array: []interface{}(nil),
Expected: "[inform] \n",
},
{
Format: "",
Array: []interface{}{},
Expected: "[inform] \n",
},
{
Format: "hello world",
Array: []interface{}(nil),
Expected: "[inform] hello world\n",
},
{
Format: "hello world",
Array: []interface{}{},
Expected: "[inform] hello world\n",
},
{
Format: "hello %s",
Array: []interface{}{"Joe"},
Expected: "[inform] hello Joe\n",
},
{
Format: "hello %s %s",
Array: []interface{}{"Joe", "Blow"},
Expected: "[inform] hello Joe Blow\n",
},
}
for testNumber, test := range tests {
var buffer bytes.Buffer
logger := NewLogger(&buffer)
logger.Informf(test.Format, test.Array...)
if expected, actual := test.Expected, buffer.String(); expected != actual {
t.Errorf("For tst #%d, the actual result is not what was expected.", testNumber)
t.Logf("EXPECTED: %q", expected)
t.Logf("ACTUAL: %q", actual)
continue
}
}
}

View File

@ -0,0 +1,59 @@
package flog
import (
"fmt"
"io"
"strings"
)
func (receiver internalLogger) CanLogPanic() bool {
return !receiver.canNotLogPanic
}
func (receiver internalLogger) Panic(a ...interface{}) {
s := fmt.Sprint(a...)
receiver.Panicf("%s", s)
}
func (receiver internalLogger) Panicf(format string, a ...interface{}) {
err := fmt.Errorf(format, a...)
if !receiver.CanLogPanic() {
panic(err)
}
var writer io.Writer = receiver.writer
if nil == writer {
panic(err)
}
var newformat string
{
var buffer strings.Builder
switch receiver.style{
case"color":
buffer.WriteString("\x1b[48;2;1;1;1m")
buffer.WriteString("\x1b[38;222;56;43;6m")
case "":
buffer.WriteString("[PANIC] ")
}
buffer.WriteString(format)
switch receiver.style {
case "color":
buffer.WriteString("\x1b[0m")
buffer.WriteRune('\n')
case "":
buffer.WriteRune('\n')
}
newformat = buffer.String()
}
fmt.Fprintf(receiver.writer, newformat, a...)
panic(err)
}

View File

@ -0,0 +1,23 @@
package flog
import (
"strings"
)
func (receiver internalLogger) Prefix(newprefix ...string) Logger {
var buffer strings.Builder
buffer.WriteString(receiver.prefix)
for _, s := range newprefix {
buffer.WriteString(s)
buffer.WriteString(": ")
}
prefix := buffer.String()
var logger internalLogger = receiver
logger.prefix += prefix
return logger
}

View File

@ -0,0 +1,119 @@
package flog
import (
"bytes"
"fmt"
"testing"
)
func TestLoggerPrefix(t *testing.T) {
tests := []struct{
NewPrefix []string
Expected string
}{
{
NewPrefix: []string(nil),
Expected: "",
},
{
NewPrefix: []string{},
Expected: "",
},
{
NewPrefix: []string{""},
Expected: ": ",
},
{
NewPrefix: []string{"", ""},
Expected: ": : ",
},
{
NewPrefix: []string{"", "", ""},
Expected: ": : : ",
},
{
NewPrefix: []string{"", "", "", "", "", "", "", "", "", ""},
Expected: ": : : : : : : : : : ",
},
{
NewPrefix: []string{"ONE"},
Expected: "ONE: ",
},
{
NewPrefix: []string{"ONE", "TWO"},
Expected: "ONE: TWO: ",
},
{
NewPrefix: []string{"ONE", "TWO", "THREE"},
Expected: "ONE: TWO: THREE: ",
},
}
for testNumber, test := range tests {
var logger internalLogger
newLogger := logger.Prefix(test.NewPrefix...)
newInternalLogger, casted := newLogger.(internalLogger)
if !casted {
t.Errorf("For test #%d, could not cast to flog.internalLogger.", testNumber)
t.Logf("TYPE: %T", newLogger)
continue
}
if expected, actual := test.Expected, newInternalLogger.prefix; expected != actual {
t.Errorf("For test #%d, the actual prefix is not what was expected.", testNumber)
t.Log("EXPECTED:", expected)
t.Log("ACTUAL: ", actual)
continue
}
}
}
func TestLoggerPrefix_inform(t *testing.T) {
var buffer bytes.Buffer
log := NewLogger(&buffer).Prefix("one","two","three")
func(){
defer func(){
if r := recover(); nil != r {
fmt.Fprintf(&buffer, "RECOVER:%v\n",r)
}
}()
log.Panic("hello PANIC")
}()
log.Inform("hello INFORM")
log.Highlight("hello HIGHLIGHT")
log.Error("hello ERROR")
log.Warn("hello WARN")
log.Debug("hello DEBUG")
log.Trace("hello TRACE")
const expected = "[PANIC] hello PANIC" + "\n" +
"RECOVER:hello PANIC" + "\n" +
"[inform] hello INFORM" + "\n" +
"[HIGHLIGHT] hello HIGHLIGHT" + "\n" +
"[ERROR] hello ERROR" + "\n" +
"[warn] hello WARN" + "\n" +
"[debug] hello DEBUG" + "\n" +
"[trace] hello TRACE" + "\n"
if actual := buffer.String(); expected != actual {
t.Error("The actual logs is not what was expected.")
t.Log("EXPECTED:\n", expected)
t.Log("ACTUAL:\n", actual)
return
}
}

View File

@ -0,0 +1,62 @@
package flog
import (
"fmt"
"io"
"strings"
)
func (receiver internalLogger) CanLogTrace() bool {
return !receiver.canNotLogTrace
}
func (receiver internalLogger) Trace(a ...interface{}) {
if !receiver.CanLogTrace() {
return
}
if nil == receiver.writer {
return
}
s := fmt.Sprint(a...)
receiver.Tracef("%s", s)
}
func (receiver internalLogger) Tracef(format string, a ...interface{}) {
if !receiver.CanLogTrace() {
return
}
var writer io.Writer = receiver.writer
if nil == writer {
return
}
var newformat string
{
var buffer strings.Builder
switch receiver.style{
case"color":
buffer.WriteString("\x1b[48;2;1;1;1m")
buffer.WriteString("\x1b[38;2;255;199;6m")
case "":
buffer.WriteString("[trace] ")
}
buffer.WriteString(format)
switch receiver.style {
case "color":
buffer.WriteString("\x1b[0m")
buffer.WriteRune('\n')
case "":
buffer.WriteRune('\n')
}
newformat = buffer.String()
}
fmt.Fprintf(receiver.writer, newformat, a...)
}

View File

@ -0,0 +1,69 @@
package flog
import (
"bytes"
"testing"
)
func TestInternalLogger_Tracef(t *testing.T) {
tests := []struct{
Format string
Array []interface{}
Expected string
}{
{
Format: "",
Array: []interface{}(nil),
Expected: "[trace] \n",
},
{
Format: "",
Array: []interface{}{},
Expected: "[trace] \n",
},
{
Format: "hello world",
Array: []interface{}(nil),
Expected: "[trace] hello world\n",
},
{
Format: "hello world",
Array: []interface{}{},
Expected: "[trace] hello world\n",
},
{
Format: "hello %s",
Array: []interface{}{"Joe"},
Expected: "[trace] hello Joe\n",
},
{
Format: "hello %s %s",
Array: []interface{}{"Joe", "Blow"},
Expected: "[trace] hello Joe Blow\n",
},
}
for testNumber, test := range tests {
var buffer bytes.Buffer
logger := NewLogger(&buffer)
logger.Tracef(test.Format, test.Array...)
if expected, actual := test.Expected, buffer.String(); expected != actual {
t.Errorf("For tst #%d, the actual result is not what was expected.", testNumber)
t.Logf("EXPECTED: %q", expected)
t.Logf("ACTUAL: %q", actual)
continue
}
}
}

View File

@ -0,0 +1,62 @@
package flog
import (
"fmt"
"io"
"strings"
)
func (receiver internalLogger) CanLogWarn() bool {
return !receiver.canNotLogWarn
}
func (receiver internalLogger) Warn(a ...interface{}) {
if !receiver.CanLogWarn() {
return
}
if nil == receiver.writer {
return
}
s := fmt.Sprint(a...)
receiver.Warnf("%s", s)
}
func (receiver internalLogger) Warnf(format string, a ...interface{}) {
if !receiver.CanLogWarn() {
return
}
var writer io.Writer = receiver.writer
if nil == writer {
return
}
var newformat string
{
var buffer strings.Builder
switch receiver.style{
case"color":
buffer.WriteString("\x1b[48;2;1;1;1m")
buffer.WriteString("\x1b[38;222;56;43;6m")
case "":
buffer.WriteString("[warn] ")
}
buffer.WriteString(format)
switch receiver.style {
case "color":
buffer.WriteString("\x1b[0m")
buffer.WriteRune('\n')
case "":
buffer.WriteRune('\n')
}
newformat = buffer.String()
}
fmt.Fprintf(receiver.writer, newformat, a...)
}

View File

@ -0,0 +1,69 @@
package flog
import (
"bytes"
"testing"
)
func TestInternalLogger_Warnf(t *testing.T) {
tests := []struct{
Format string
Array []interface{}
Expected string
}{
{
Format: "",
Array: []interface{}(nil),
Expected: "[warn] \n",
},
{
Format: "",
Array: []interface{}{},
Expected: "[warn] \n",
},
{
Format: "hello world",
Array: []interface{}(nil),
Expected: "[warn] hello world\n",
},
{
Format: "hello world",
Array: []interface{}{},
Expected: "[warn] hello world\n",
},
{
Format: "hello %s",
Array: []interface{}{"Joe"},
Expected: "[warn] hello Joe\n",
},
{
Format: "hello %s %s",
Array: []interface{}{"Joe", "Blow"},
Expected: "[warn] hello Joe Blow\n",
},
}
for testNumber, test := range tests {
var buffer bytes.Buffer
logger := NewLogger(&buffer)
logger.Warnf(test.Format, test.Array...)
if expected, actual := test.Expected, buffer.String(); expected != actual {
t.Errorf("For tst #%d, the actual result is not what was expected.", testNumber)
t.Logf("EXPECTED: %q", expected)
t.Logf("ACTUAL: %q", actual)
continue
}
}
}

37
logger.go 100644
View File

@ -0,0 +1,37 @@
package flog
type Logger interface {
CanLogDebug() bool
Debug(...interface{})
Debugf(string, ...interface{})
CanLogError() bool
Error(...interface{}) error
Errorf(string, ...interface{}) error
CanLogFatal() bool
Fatal(...interface{})
Fatalf(string, ...interface{})
CanLogHighlight() bool
Highlight(...interface{})
Highlightf(string, ...interface{})
CanLogInform() bool
Inform(...interface{})
Informf(string, ...interface{})
CanLogPanic() bool
Panic(...interface{})
Panicf(string, ...interface{})
CanLogTrace() bool
Trace(...interface{})
Tracef(string, ...interface{})
CanLogWarn() bool
Warn(...interface{})
Warnf(string, ...interface{})
Prefix(...string) Logger
}

14
logger_test.go 100644
View File

@ -0,0 +1,14 @@
package flog
import (
"testing"
)
func TestInternalLoggerIsLogger(t *testing.T) {
var x Logger = internalLogger{} // THIS IS WHAT ACTUALLY MATTERS.
if nil == x {
t.Error("This should never happen.")
}
}