initial commit

master
Bel LaPointe 2019-12-17 15:20:40 -07:00
commit 17a762ffb0
4 changed files with 294 additions and 0 deletions

63
level.go Normal file
View File

@ -0,0 +1,63 @@
package logb
import (
"sync"
)
const (
cError = iota
cWarn
cInfo
cDebug
cVerbose
)
var (
ERROR = Level{Level: cError}
WARN = Level{Level: cWarn}
INFO = Level{Level: cInfo}
DEBUG = Level{Level: cDebug}
VERBOSE = Level{Level: cVerbose}
)
type Level struct {
Level int
Lock sync.Mutex
}
func NewLevel() *Level {
return &Level{
Level: cInfo,
}
}
func (l *Level) Set(v Level) {
l.Lock.Lock()
defer l.Lock.Unlock()
l.Level = v.Level
}
func (l *Level) Get(v Level) int {
return l.Level
}
func (l Level) Should(v Level) bool {
return l.Level >= v.Level
}
func (l Level) String() string {
s := "undefined"
switch l.Level {
case ERROR.Level:
s = "ERROR"
case WARN.Level:
s = "WARN"
case INFO.Level:
s = "INFO"
case DEBUG.Level:
s = "DEBUG"
case VERBOSE.Level:
s = "VERBOSE"
}
return s
}

71
level_test.go Normal file
View File

@ -0,0 +1,71 @@
package logb
import (
"sync"
"testing"
"time"
)
func TestNewLevel(t *testing.T) {
NewLevel()
}
func TestConsts(t *testing.T) {
for _, c := range []int{
cInfo,
cWarn,
cError,
cDebug,
cVerbose,
} {
l := Level{Level: c}
if l.String() == "undefined" {
t.Error(l)
}
}
}
func TestLevelLock(t *testing.T) {
l := NewLevel()
doLock := &sync.WaitGroup{}
doLock.Add(1)
didLock := make(chan struct{})
go func() {
doLock.Wait()
l.Lock.Lock()
didLock <- struct{}{}
}()
l.Lock.Lock()
doLock.Done()
select {
case <-didLock:
t.Error("did a lock while locked")
case <-time.After(time.Millisecond * 50):
l.Lock.Unlock()
<-didLock
}
}
func TestLevelShould(t *testing.T) {
levels := []Level{
ERROR,
WARN,
INFO,
DEBUG,
VERBOSE,
}
for i := range levels {
okayed := 0
for j := range levels {
should := levels[i].Should(levels[j])
if should {
okayed += 1
}
}
if okayed != i+1 {
t.Error(levels[i])
}
}
}

79
logb.go Normal file
View File

@ -0,0 +1,79 @@
package logb
import (
"fmt"
"io"
"os"
)
var level Level = INFO
var writer io.Writer = os.Stderr
func Set(l ...Level) {
if len(l) < 1 {
l = []Level{INFO}
}
level.Set(l[0])
}
func SetWriter(w io.Writer) {
writer = w
}
func Info(args ...interface{}) {
log(INFO, args...)
}
func Warn(args ...interface{}) {
log(WARN, args...)
}
func Error(args ...interface{}) {
log(ERROR, args...)
}
func Debug(args ...interface{}) {
log(DEBUG, args...)
}
func Verbose(args ...interface{}) {
log(VERBOSE, args...)
}
func Infof(form string, args ...interface{}) {
logf(INFO, form, args...)
}
func Warnf(form string, args ...interface{}) {
logf(WARN, form, args...)
}
func Errorf(form string, args ...interface{}) {
logf(ERROR, form, args...)
}
func Debugf(form string, args ...interface{}) {
logf(DEBUG, form, args...)
}
func Verbosef(form string, args ...interface{}) {
logf(VERBOSE, form, args...)
}
func log(lvl Level, args ...interface{}) {
v := ""
if len(args) > 0 {
args = append([]interface{}{}, args...)
v = fmt.Sprint(args)
v = v[1 : len(v)-1]
}
logf(lvl, "%s", v)
}
func logf(lvl Level, form string, args ...interface{}) {
if !level.Should(lvl) {
return
}
form = fmt.Sprintf("[%v] %s\n", lvl.String()[:3], form)
fmt.Fprintf(writer, form, args...)
}

81
logb_test.go Normal file
View File

@ -0,0 +1,81 @@
package logb
import (
"bytes"
"fmt"
"testing"
)
func TestSet(t *testing.T) {
Set()
if level != INFO {
t.Error(level, INFO)
}
Set(VERBOSE)
if level != VERBOSE {
t.Error(level, VERBOSE)
}
}
func TestLogf(t *testing.T) {
cases := map[string]struct {
foo func(...interface{})
in []interface{}
out string
}{
"info empty": {
foo: Info,
in: []interface{}{},
out: "[INF] ",
},
"info args": {
foo: Info,
in: []interface{}{"hello", "info"},
out: "[INF] hello info",
},
"debug empty": {
foo: Debug,
in: []interface{}{},
out: "[DEB] ",
},
"debug args": {
foo: Debug,
in: []interface{}{"hello", "debug"},
out: "[DEB] hello debug",
},
"error empty": {
foo: Error,
in: []interface{}{},
out: "[ERR] ",
},
"error args": {
foo: Error,
in: []interface{}{"hello", "error"},
out: "[ERR] hello error",
},
"verbose empty": {
foo: Verbose,
in: []interface{}{},
out: "[VER] ",
},
"verbose args": {
foo: Verbose,
in: []interface{}{"hello", "verbose"},
out: "[VER] hello verbose",
},
}
for i, c := range cases {
w := bytes.NewBuffer(nil)
SetWriter(w)
Set(VERBOSE)
c.foo(c.in...)
out := fmt.Sprintf("%s", w.Bytes())
if out != c.out+"\n" {
t.Errorf("[%s]: %v => %q, want %q", i, c.in, out, c.out)
}
}
}
func TestLog(t *testing.T) {
}