Skip to content

Commit

Permalink
✨ feat: handler - refactoring some handler create logic, support use …
Browse files Browse the repository at this point in the history
…max level or levels
  • Loading branch information
inhere committed Jul 5, 2023
1 parent fabaca0 commit 3a54534
Show file tree
Hide file tree
Showing 16 changed files with 390 additions and 292 deletions.
89 changes: 68 additions & 21 deletions handler/buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,8 @@ func NewBufferedHandler(w io.WriteCloser, bufSize int, levels ...slog.Level) *Fl
levels = slog.AllLevels
}

return &FlushCloseHandler{
Output: bufwrite.NewBufIOWriterSize(w, bufSize),
// log levels
LevelFormattable: slog.NewLvsFormatter(levels),
}
out := bufwrite.NewBufIOWriterSize(w, bufSize)
return FlushCloserWithLevels(out, levels)
}

// LineBufferedFile handler
Expand All @@ -35,16 +32,11 @@ func LineBufferedFile(logfile string, bufSize int, levels []slog.Level) (slog.Ha
WithBuffMode(BuffModeLine),
)

output, err := cfg.CreateWriter()
out, err := cfg.CreateWriter()
if err != nil {
return nil, err
}

return &SyncCloseHandler{
Output: output,
// init log levels
LevelFormattable: slog.NewLvsFormatter(cfg.Levels),
}, nil
return SyncCloserWithLevels(out, levels), nil
}

// LineBuffOsFile handler
Expand All @@ -53,11 +45,8 @@ func LineBuffOsFile(f *os.File, bufSize int, levels []slog.Level) slog.Handler {
panic("slog: the os file cannot be nil")
}

return &SyncCloseHandler{
Output: bufwrite.NewLineWriterSize(f, bufSize),
// init log levels
LevelFormattable: slog.NewLvsFormatter(levels),
}
out := bufwrite.NewLineWriterSize(f, bufSize)
return SyncCloserWithLevels(out, levels)
}

// LineBuffWriter handler
Expand All @@ -66,9 +55,67 @@ func LineBuffWriter(w io.Writer, bufSize int, levels []slog.Level) slog.Handler
panic("slog: the io writer cannot be nil")
}

return &IOWriterHandler{
Output: bufwrite.NewLineWriterSize(w, bufSize),
// init log levels
LevelFormattable: slog.NewLvsFormatter(levels),
out := bufwrite.NewLineWriterSize(w, bufSize)
return IOWriterWithLevels(out, levels)
}

//
// --------- wrap a handler with buffer ---------
//

// FormatWriterHandler interface
type FormatWriterHandler interface {
slog.Handler
// Formatter record formatter
Formatter() slog.Formatter
// Writer the output writer
Writer() io.Writer
}

// bufferWrapper struct
type bufferWrapper struct {
buffer FlushWriter
handler FormatWriterHandler
}

// BufferWrapper new instance.
//
// Deprecated: use `NewBufferedHandler` instead, will remove this func at v1.0
func BufferWrapper(h FormatWriterHandler, buffSize int) slog.Handler {
return &bufferWrapper{
handler: h,
buffer: bufwrite.NewBufIOWriterSize(h.Writer(), buffSize),
}
}

// IsHandling Check if the current level can be handling
func (w *bufferWrapper) IsHandling(level slog.Level) bool {
return w.handler.IsHandling(level)
}

// Flush all buffers to the `h.fcWriter.Writer()`
func (w *bufferWrapper) Flush() error {
if err := w.buffer.Flush(); err != nil {
return err
}
return w.handler.Flush()
}

// Close log records
func (w *bufferWrapper) Close() error {
if err := w.Flush(); err != nil {
return err
}
return w.handler.Close()
}

// Handle log record
func (w *bufferWrapper) Handle(record *slog.Record) error {
bts, err := w.handler.Formatter().Format(record)
if err != nil {
return err
}

_, err = w.buffer.Write(bts)
return err
}
13 changes: 7 additions & 6 deletions handler/buffer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,22 @@ func TestBufferWrapper(t *testing.T) {
l := slog.NewWithHandlers(bw)
l.Info("buffered info message")

bts, err := ioutil.ReadFile(logfile)
assert.NoErr(t, err)
bts := fsutil.ReadFile(logfile)
assert.Empty(t, bts)

l.Warn("buffered warn message")
bts, err = ioutil.ReadFile(logfile)
assert.NoErr(t, err)

bts = fsutil.ReadFile(logfile)
str := string(bts)
assert.Contains(t, str, "[INFO]")

err = l.FlushAll()
assert.NoErr(t, err)

assert.NoErr(t, l.Close())

// test error
h.SetFormatter(newTestFormatter(true))
bw = handler.BufferWrapper(h, 128)
assert.Err(t, bw.Handle(newLogRecord("test error")))
}

func TestLineBufferedFile(t *testing.T) {
Expand Down
64 changes: 0 additions & 64 deletions handler/buffer_wrapper.go

This file was deleted.

52 changes: 33 additions & 19 deletions handler/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,45 @@ import (
********************************************************************************/

// ConsoleHandler definition
type ConsoleHandler struct {
IOWriterHandler
}
type ConsoleHandler = IOWriterHandler

// NewConsole create new ConsoleHandler
func NewConsole(levels []slog.Level) *ConsoleHandler {
return NewConsoleHandler(levels)
}
// NewConsoleWithLF create new ConsoleHandler and with custom slog.LevelFormattable
func NewConsoleWithLF(lf slog.LevelFormattable) *ConsoleHandler {
h := NewIOWriterWithLF(os.Stdout, lf)

// NewConsoleHandler create new ConsoleHandler
func NewConsoleHandler(levels []slog.Level) *ConsoleHandler {
h := &ConsoleHandler{
IOWriterHandler: *NewIOWriterHandler(os.Stdout, levels),
}

// create new formatter
// default use text formatter
f := slog.NewTextFormatter()
// enable color on console
f.EnableColor = color.SupportColor()
// default enable color on console
f.WithEnableColor(color.SupportColor())

h.SetFormatter(f)
return h
}

// TextFormatter get the formatter
func (h *ConsoleHandler) TextFormatter() *slog.TextFormatter {
return h.Formatter().(*slog.TextFormatter)
//
// ------------- Use max log level -------------
//

// ConsoleWithMaxLevel create new ConsoleHandler and with max log level
func ConsoleWithMaxLevel(level slog.Level) *ConsoleHandler {
return NewConsoleWithLF(slog.NewLvFormatter(level))
}

//
// ------------- Use multi log levels -------------
//

// NewConsole create new ConsoleHandler, alias of NewConsoleHandler
func NewConsole(levels []slog.Level) *ConsoleHandler {
return NewConsoleHandler(levels)
}

// ConsoleWithLevels create new ConsoleHandler and with limited log levels
func ConsoleWithLevels(levels []slog.Level) *ConsoleHandler {
return NewConsoleHandler(levels)
}

// NewConsoleHandler create new ConsoleHandler with limited log levels
func NewConsoleHandler(levels []slog.Level) *ConsoleHandler {
return NewConsoleWithLF(slog.NewLvsFormatter(levels))
}
19 changes: 19 additions & 0 deletions handler/console_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package handler_test

import (
"testing"

"github.com/gookit/goutil/testutil/assert"
"github.com/gookit/slog"
"github.com/gookit/slog/handler"
)

func TestConsoleWithMaxLevel(t *testing.T) {
l := slog.NewWithHandlers(handler.ConsoleWithMaxLevel(slog.InfoLevel))
l.DoNothingOnPanicFatal()

for _, level := range slog.AllLevels {
l.Log(level, "a test message")
}
assert.NoErr(t, l.LastErr())
}
55 changes: 20 additions & 35 deletions handler/file.go
Original file line number Diff line number Diff line change
@@ -1,76 +1,61 @@
package handler

import (
"github.com/gookit/goutil/basefn"
"github.com/gookit/slog"
)

// MustFileHandler create file handler
func MustFileHandler(logfile string, fns ...ConfigFn) *SyncCloseHandler {
h, err := NewFileHandler(logfile, fns...)
if err != nil {
panic(err)
}
return h
}

// JSONFileHandler create new FileHandler with JSON formatter
func JSONFileHandler(logfile string, fns ...ConfigFn) (*SyncCloseHandler, error) {
fns = append(fns, WithUseJSON(true))

return NewFileHandler(logfile, fns...)
return NewFileHandler(logfile, append(fns, WithUseJSON(true))...)
}

// NewBuffFileHandler create file handler with buff size
func NewBuffFileHandler(logfile string, buffSize int, fns ...ConfigFn) (*SyncCloseHandler, error) {
fns = append(fns, WithBuffSize(buffSize))
return NewFileHandler(logfile, append(fns, WithBuffSize(buffSize))...)
}

return NewFileHandler(logfile, fns...)
// MustFileHandler create file handler
func MustFileHandler(logfile string, fns ...ConfigFn) *SyncCloseHandler {
return basefn.Must(NewFileHandler(logfile, fns...))
}

// NewFileHandler create new FileHandler
func NewFileHandler(logfile string, fns ...ConfigFn) (h *SyncCloseHandler, err error) {
cfg := NewEmptyConfig(fns...).With(WithLogfile(logfile))

return cfg.CreateHandler()
return NewEmptyConfig(fns...).With(WithLogfile(logfile)).CreateHandler()
}

// MustSimpleFile new instance
func MustSimpleFile(filepath string) *SyncCloseHandler {
h, err := NewSimpleFileHandler(filepath)
if err != nil {
panic(err)
}
//
// ------------- simple file handler -------------
//

return h
// MustSimpleFile new instance
func MustSimpleFile(filepath string, maxLv ...slog.Level) *SyncCloseHandler {
return basefn.Must(NewSimpleFileHandler(filepath, maxLv...))
}

// NewSimpleFile new instance
func NewSimpleFile(filepath string) (*SyncCloseHandler, error) {
return NewSimpleFileHandler(filepath)
func NewSimpleFile(filepath string, maxLv ...slog.Level) (*SyncCloseHandler, error) {
return NewSimpleFileHandler(filepath, maxLv...)
}

// NewSimpleFileHandler instance
// NewSimpleFileHandler instance, default log level is InfoLevel
//
// Usage:
//
// h, err := NewSimpleFileHandler("/tmp/error.log")
//
// custom formatter
// Custom formatter:
//
// h.SetFormatter(slog.NewJSONFormatter())
// slog.PushHandler(h)
// slog.Info("log message")
func NewSimpleFileHandler(filePath string) (*SyncCloseHandler, error) {
func NewSimpleFileHandler(filePath string, maxLv ...slog.Level) (*SyncCloseHandler, error) {
file, err := QuickOpenFile(filePath)
if err != nil {
return nil, err
}

h := &SyncCloseHandler{
Output: file,
// init default log level
LevelFormattable: slog.NewLvFormatter(slog.InfoLevel),
}

h := SyncCloserWithMaxLevel(file, basefn.FirstOr(maxLv, slog.InfoLevel))
return h, nil
}
Loading

0 comments on commit 3a54534

Please sign in to comment.