Skip to content

Commit

Permalink
feat: add print/printf/println (#12)
Browse files Browse the repository at this point in the history
* feat: add print funcs

* chore: unit tests

* chore: unit tests error
  • Loading branch information
shipengqi committed Oct 24, 2022
1 parent d7847b6 commit 34815d4
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 133 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/shipengqi/log
go 1.17

require (
github.com/shipengqi/errors v0.1.4
github.com/stretchr/testify v1.7.0
go.uber.org/zap v1.21.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
Expand Down
5 changes: 4 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/shipengqi/errors v0.1.4 h1:X7OU/yRKM9AAuSDH9xGspLFj0oI62IdT+9IpgcqvKTY=
github.com/shipengqi/errors v0.1.4/go.mod h1:xymtEu8M3i0SIEhhMyShYHZfn/e7tBQwjuLHyQ/UGCw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
Expand Down
85 changes: 19 additions & 66 deletions log.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
package log

import (
"errors"
"log"
"strings"

"go.uber.org/zap"
)
Expand All @@ -23,72 +21,12 @@ func L() *Logger {

// EncodedFilename returns the filename for logging when DisableFile is false.
func EncodedFilename() string {
return _globalL.encodedFilename
return _globalL.EncodedFilename()
}


// ErrSlice represents an error slice.
type ErrSlice struct {
errs []error
}

// NewErrSlice returns a new ErrSlice.
func NewErrSlice() ErrSlice {
return ErrSlice{
errs: make([]error, 0),
}
}

// Error implements error interface.
func (es ErrSlice) Error() string {
var b strings.Builder
if len(es.errs) == 0 {
return ""
}

b.WriteString(es.errs[0].Error())

for i := 1; i < len(es.errs); i++ {
b.WriteString(" : ")
b.WriteString(es.errs[i].Error())
}

return b.String()
}

// Len returns the length of slice.
func (es *ErrSlice) Len() int {
return len(es.errs)
}

// Append appends an error to the slice, nil error will be ignored.
func (es *ErrSlice) Append(err ...error) {
for i := range err {
if err[i] == nil {
continue
}
if v, ok := err[i].(ErrSlice); ok {
if v.Len() == 0 {
continue
}
}
if v, ok := err[i].(*ErrSlice); ok {
if v.Len() == 0 {
continue
}
}
es.errs = append(es.errs, err[i])
}
}

// AppendStr appends an error string to the slice, empty string will be ignored.
func (es *ErrSlice) AppendStr(err ...string) {
for i := range err {
if len(err[i]) == 0 {
continue
}
es.errs = append(es.errs, errors.New(err[i]))
}
// SugaredL returns global sugared logger.
func SugaredL() *zap.SugaredLogger {
return _globalL.Sugared()
}

// StdLogger returns logger of standard library which writes to supplied zap
Expand Down Expand Up @@ -250,6 +188,21 @@ func Fatal(msg string, keysAndValues ...interface{}) {
_globalL.Fatal(msg, keysAndValues...)
}

// Print logs a message at level Print.
func Print(args ...interface{}) {
_globalL.Print(args...)
}

// Println logs a message at level Print.
func Println(args ...interface{}) {
_globalL.Println(args...)
}

// Printf logs a message at level Print.
func Printf(format string, args ...interface{}) {
_globalL.Printf(format, args...)
}

// AtLevelt logs a message at Level.
func AtLevelt(level Level, msg string, fields ...Field) {
_globalL.AtLevelt(level, msg, fields...)
Expand Down
73 changes: 22 additions & 51 deletions log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package log
import (
"bufio"
"bytes"
"errors"
"io/ioutil"
"os"
"path/filepath"
Expand All @@ -30,17 +29,23 @@ func TestGlobalLogger(t *testing.T) {
str := "Hello, world!"
opts := NewOptions()
Configure(opts)

sugared := SugaredL()
assert.NotNil(t, sugared)

Debugf("Hello, %s", name+"1")
Infof("Hello, %s", name+"2")
Warnf("Hello, %s", name+"3")
Errorf("Hello, %s", name+"4")
Printf("Hello, %s", name+"5")

opts.ConsoleLevel = DebugLevel.String()
Configure(opts)
Debug(str)
Info(str)
Warn(str)
Error(str)
Print(str)

opts.DisableConsoleColor = true
Configure(opts)
Expand All @@ -49,19 +54,23 @@ func TestGlobalLogger(t *testing.T) {
L().Info(str)
L().Warn(str)
L().Error(str)
L().Println(str)

expected := []string{
"\x1b[34mINFO\x1b[0m Hello, world2",
"\x1b[33mWARN\x1b[0m Hello, world3",
"\x1b[31mERROR\x1b[0m Hello, world4",
"\x1b[34mINFO\x1b[0m Hello, world5",
"\x1b[35mDEBUG\x1b[0m Hello, world!",
"\x1b[34mINFO\x1b[0m Hello, world!",
"\x1b[33mWARN\x1b[0m Hello, world!",
"\x1b[31mERROR\x1b[0m Hello, world!",
"\x1b[34mINFO\x1b[0m Hello, world!",
"DEBUG Hello, world!",
"INFO Hello, world!",
"WARN Hello, world!",
"ERROR Hello, world!",
"INFO Hello, world!",
}
_ = w.Close()
stdout, _ := ioutil.ReadAll(r)
Expand Down Expand Up @@ -95,10 +104,10 @@ func TestGlobalLogger(t *testing.T) {
L().Warnf("Hello, %s", name+"3")
L().Errorf("Hello, %s", name+"4")
expected := []string{
"DEBUG log/log_test.go:93 Hello, world1",
"INFO log/log_test.go:94 Hello, world2",
"WARN log/log_test.go:95 Hello, world3",
"ERROR log/log_test.go:96 Hello, world4",
"DEBUG log/log_test.go:102 Hello, world1",
"INFO log/log_test.go:103 Hello, world2",
"WARN log/log_test.go:104 Hello, world3",
"ERROR log/log_test.go:105 Hello, world4",
}
_ = w.Close()
stdout, _ := ioutil.ReadAll(r)
Expand Down Expand Up @@ -131,10 +140,10 @@ func TestGlobalLogger(t *testing.T) {
L().Warnf("Hello, %s", name+"3")
L().Errorf("Hello, %s", name+"4")
expected := []string{
"debug log/log_test.go:129 Hello, world1",
"info log/log_test.go:130 Hello, world2",
"warn log/log_test.go:131 Hello, world3",
"error log/log_test.go:132 Hello, world4",
"debug log/log_test.go:138 Hello, world1",
"info log/log_test.go:139 Hello, world2",
"warn log/log_test.go:140 Hello, world3",
"error log/log_test.go:141 Hello, world4",
}
_ = w.Close()
stdout, _ := ioutil.ReadAll(r)
Expand Down Expand Up @@ -172,10 +181,10 @@ func TestGlobalLogger(t *testing.T) {
L().Warnf("Hello, %s", name+"3")
L().Errorf("Hello, %s", name+"4")
expected := []string{
"debug log/log_test.go:170 Hello, world1",
"info log/log_test.go:171 Hello, world2",
"warn log/log_test.go:172 Hello, world3",
"error log/log_test.go:173 Hello, world4",
"debug log/log_test.go:179 Hello, world1",
"info log/log_test.go:180 Hello, world2",
"warn log/log_test.go:181 Hello, world3",
"error log/log_test.go:182 Hello, world4",
}
_ = w.Close()
stdout, _ := ioutil.ReadAll(r)
Expand Down Expand Up @@ -306,43 +315,6 @@ func TestLoggerClose(t *testing.T) {
})
}

func TestErrSlice(t *testing.T) {
t.Run("Generic ErrSlice", func(t *testing.T) {
es := NewErrSlice()
assert.Equal(t, "", es.Error())
es.Append(errors.New("error1"))
assert.Equal(t, "error1", es.Error())

es.AppendStr("error2")
assert.Equal(t, "error1 : error2", es.Error())

es.Append(errors.New("error3"))
assert.Equal(t, "error1 : error2 : error3", es.Error())
})

t.Run("Append ErrSlice", func(t *testing.T) {
es := NewErrSlice()
es.Append(NewErrSlice())
assert.Equal(t, 0, es.Len())

es.Append(errors.New("error1"))
assert.Equal(t, 1, es.Len())

es2 := NewErrSlice()
es2.Append(errors.New("error1"))
es.Append(es2)
assert.Equal(t, 2, es.Len())
})

t.Run("Append *ErrSlice", func(t *testing.T) {
es := NewErrSlice()
es2 := NewErrSlice()
// es2.Append(errors.New("error1"))
es.Append(&es2)
assert.Equal(t, 0, es.Len())
})
}

func TestStdInfoLogger(t *testing.T) {
opts := NewOptions()
opts.DisableFile = true
Expand Down Expand Up @@ -385,7 +357,6 @@ func TestStdInfoLogger(t *testing.T) {
})
}


// fileWithLineNum return the file name and line number of the current file
func fileWithLineNum() string {
for i := 4; i < 15; i++ {
Expand Down
31 changes: 29 additions & 2 deletions logger.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package log

import (
"fmt"
"io"
"os"
"strings"

"github.com/shipengqi/errors"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
Expand All @@ -26,8 +28,8 @@ type Logger struct {

// New creates a new Logger.
func New(opts *Options, encoders ...Encoder) *Logger {
if errs := opts.Validate(); errs.Len() > 0 {
panic(errs)
if errs := opts.Validate(); len(errs) > 0 {
panic(errors.NewAggregate(errs))
}

l := &Logger{}
Expand Down Expand Up @@ -201,6 +203,21 @@ func (l *Logger) Fatal(msg string, keysAndValues ...interface{}) {
l.sugared.Fatalw(msg, keysAndValues...)
}

// Print logs a message at level Print.
func (l *Logger) Print(args ...interface{}) {
l.log.Info(fmt.Sprint(args...))
}

// Println logs a message at level Print.
func (l *Logger) Println(args ...interface{}) {
l.log.Info(fmt.Sprint(args...))
}

// Printf logs a message at level Print.
func (l *Logger) Printf(format string, args ...interface{}) {
l.log.Info(fmt.Sprintf(format, args...))
}

func (l *Logger) AtLevelt(level Level, msg string, fields ...Field) {
switch level {
case DebugLevel:
Expand Down Expand Up @@ -261,6 +278,13 @@ func (l *Logger) AtLevelf(level Level, msg string, args ...interface{}) {
}
}

// Sugared returns sugared logger.
func (l *Logger) Sugared() *zap.SugaredLogger {
return l.sugared
}

// WithValues creates a child logger and adds some Field of
// context to this logger.
func (l *Logger) WithValues(fields ...Field) *Logger {
newl := l.log.With(fields...)
return &Logger{
Expand All @@ -269,10 +293,13 @@ func (l *Logger) WithValues(fields ...Field) *Logger {
}
}

// Flush calls the underlying Core's Sync method, flushing any buffered
// log entries. Applications should take care to call Sync before exiting.
func (l *Logger) Flush() error {
return l.log.Sync()
}

// Close implements io.Closer, and closes the current logfile of default logger.
func (l *Logger) Close() error {
// https://github.com/uber-go/zap/issues/772
_ = l.Flush()
Expand Down
13 changes: 7 additions & 6 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,28 +60,29 @@ func NewOptions() *Options {
}

// Validate validates the options fields.
func (o *Options) Validate() ErrSlice {
var errs ErrSlice
func (o *Options) Validate() []error {
var errs []error
var level Level

if o.ConsoleLevel != "" {
if err := level.UnmarshalText([]byte(o.ConsoleLevel)); err != nil {
errs.Append(err)
errs = append(errs, err)
}
}

if o.FileLevel != "" {
if err := level.UnmarshalText([]byte(o.FileLevel)); err != nil {
errs.Append(err)
errs = append(errs, err)
}
}

if o.DisableConsole && o.DisableFile {
errs.Append(errors.New("no enabled logger"))
errs = append(errs, errors.New("no enabled logger, one or more of " +
"(DisableConsole, DisableFile) must be set to false"))
}

if !o.DisableFile && o.Output == "" {
errs.Append(errors.New("no log output"))
errs = append(errs, errors.New("no log output, 'Output' must be set"))
}
return errs
}
Loading

0 comments on commit 34815d4

Please sign in to comment.