mirror of
https://github.com/nabbar/golib.git
synced 2025-09-26 20:01:15 +08:00
Package Logger:
- Add option to define the buffer size for logger file - Rework Hashicorp wrapper to not use a standalone pointer of logger and prefer a function to retrieve the logger - reword some panic recovery message
This commit is contained in:
@@ -27,7 +27,11 @@
|
||||
|
||||
package config
|
||||
|
||||
import "os"
|
||||
import (
|
||||
"os"
|
||||
|
||||
libsiz "github.com/nabbar/golib/size"
|
||||
)
|
||||
|
||||
type OptionsFile struct {
|
||||
// LogLevel define the allowed level of log for this file.
|
||||
@@ -59,6 +63,9 @@ type OptionsFile struct {
|
||||
|
||||
// EnableAccessLog allow to add all message from api router for access log and error log.
|
||||
EnableAccessLog bool `json:"enableAccessLog,omitempty" yaml:"enableAccessLog,omitempty" toml:"enableAccessLog,omitempty" mapstructure:"enableAccessLog,omitempty"`
|
||||
|
||||
// FileBufferSize define the size for buffer size (by default the buffer size is set to 32KB).
|
||||
FileBufferSize libsiz.Size `json:"file-buffer-size,omitempty" yaml:"file-buffer-size,omitempty" toml:"file-buffer-size,omitempty" mapstructure:"file-buffer-size,omitempty"`
|
||||
}
|
||||
|
||||
type OptionsFiles []OptionsFile
|
||||
|
@@ -32,12 +32,12 @@ import (
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
)
|
||||
|
||||
func New(logger liblog.Logger) hclog.Logger {
|
||||
func New(logger liblog.FuncLog) hclog.Logger {
|
||||
return &_hclog{
|
||||
l: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefault(log liblog.Logger) {
|
||||
func SetDefault(log liblog.FuncLog) {
|
||||
hclog.SetDefault(New(log))
|
||||
}
|
||||
|
@@ -30,10 +30,10 @@ package hashicorp
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
logcfg "github.com/nabbar/golib/logger/config"
|
||||
loglvl "github.com/nabbar/golib/logger/level"
|
||||
)
|
||||
|
||||
@@ -43,74 +43,167 @@ const (
|
||||
)
|
||||
|
||||
type _hclog struct {
|
||||
l liblog.Logger
|
||||
l liblog.FuncLog
|
||||
}
|
||||
|
||||
func (o *_hclog) Log(level hclog.Level, msg string, args ...interface{}) {
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch level {
|
||||
case hclog.NoLevel, hclog.Off:
|
||||
return
|
||||
case hclog.Trace:
|
||||
o.l.Debug(msg, nil, args...)
|
||||
lg.Entry(loglvl.DebugLevel, msg, args...).Log()
|
||||
case hclog.Debug:
|
||||
o.l.Debug(msg, nil, args...)
|
||||
lg.Entry(loglvl.DebugLevel, msg, args...).Log()
|
||||
case hclog.Info:
|
||||
o.l.Info(msg, nil, args...)
|
||||
lg.Entry(loglvl.InfoLevel, msg, args...).Log()
|
||||
case hclog.Warn:
|
||||
o.l.Warning(msg, nil, args...)
|
||||
lg.Entry(loglvl.WarnLevel, msg, args...).Log()
|
||||
case hclog.Error:
|
||||
o.l.Error(msg, nil, args...)
|
||||
lg.Entry(loglvl.ErrorLevel, msg, args...).Log()
|
||||
}
|
||||
}
|
||||
|
||||
func (o *_hclog) logger() liblog.Logger {
|
||||
if o.l == nil {
|
||||
return nil
|
||||
} else if lg := o.l(); lg == nil {
|
||||
return nil
|
||||
} else {
|
||||
return lg
|
||||
}
|
||||
}
|
||||
|
||||
func (o *_hclog) Trace(msg string, args ...interface{}) {
|
||||
o.l.Debug(msg, nil, args...)
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
lg.Entry(loglvl.DebugLevel, msg, args...).Log()
|
||||
}
|
||||
|
||||
func (o *_hclog) Debug(msg string, args ...interface{}) {
|
||||
o.l.Debug(msg, nil, args...)
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
lg.Entry(loglvl.DebugLevel, msg, args...).Log()
|
||||
}
|
||||
|
||||
func (o *_hclog) Info(msg string, args ...interface{}) {
|
||||
o.l.Info(msg, nil, args...)
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
lg.Entry(loglvl.InfoLevel, msg, args...).Log()
|
||||
}
|
||||
|
||||
func (o *_hclog) Warn(msg string, args ...interface{}) {
|
||||
o.l.Warning(msg, nil, args...)
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
lg.Entry(loglvl.WarnLevel, msg, args...).Log()
|
||||
}
|
||||
|
||||
func (o *_hclog) Error(msg string, args ...interface{}) {
|
||||
o.l.Error(msg, nil, args...)
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
lg.Entry(loglvl.ErrorLevel, msg, args...).Log()
|
||||
}
|
||||
|
||||
func (o *_hclog) IsTrace() bool {
|
||||
if opt := o.l.GetOptions(); opt == nil {
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return false
|
||||
} else if opt.Stdout == nil {
|
||||
return false
|
||||
} else {
|
||||
return opt.Stdout.EnableTrace
|
||||
}
|
||||
|
||||
if opt := lg.GetOptions(); opt == nil {
|
||||
return false
|
||||
} else if opt.Stdout != nil && opt.Stdout.EnableTrace {
|
||||
return true
|
||||
} else {
|
||||
for _, f := range opt.LogFile {
|
||||
if f.EnableTrace {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, f := range opt.LogSyslog {
|
||||
if f.EnableTrace {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (o *_hclog) IsDebug() bool {
|
||||
return o.l.GetLevel() >= loglvl.DebugLevel
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return lg.GetLevel() >= loglvl.DebugLevel
|
||||
}
|
||||
|
||||
func (o *_hclog) IsInfo() bool {
|
||||
return o.l.GetLevel() >= loglvl.InfoLevel
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return lg.GetLevel() >= loglvl.InfoLevel
|
||||
}
|
||||
|
||||
func (o *_hclog) IsWarn() bool {
|
||||
return o.l.GetLevel() >= loglvl.WarnLevel
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return lg.GetLevel() >= loglvl.WarnLevel
|
||||
}
|
||||
|
||||
func (o *_hclog) IsError() bool {
|
||||
return o.l.GetLevel() >= loglvl.ErrorLevel
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return lg.GetLevel() >= loglvl.ErrorLevel
|
||||
}
|
||||
|
||||
func (o *_hclog) ImpliedArgs() []interface{} {
|
||||
fields := o.l.GetFields()
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return make([]interface{}, 0)
|
||||
}
|
||||
|
||||
fields := lg.GetFields()
|
||||
|
||||
if i, l := fields.Load(HCLogArgs); !l {
|
||||
return make([]interface{}, 0)
|
||||
@@ -122,12 +215,24 @@ func (o *_hclog) ImpliedArgs() []interface{} {
|
||||
}
|
||||
|
||||
func (o *_hclog) With(args ...interface{}) hclog.Logger {
|
||||
o.l.SetFields(o.l.GetFields().Add(HCLogArgs, args))
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return o
|
||||
}
|
||||
|
||||
lg.SetFields(lg.GetFields().Add(HCLogArgs, args))
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *_hclog) Name() string {
|
||||
fields := o.l.GetFields()
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
fields := lg.GetFields()
|
||||
|
||||
if i, l := fields.Load(HCLogName); !l {
|
||||
return ""
|
||||
@@ -139,40 +244,77 @@ func (o *_hclog) Name() string {
|
||||
}
|
||||
|
||||
func (o *_hclog) Named(name string) hclog.Logger {
|
||||
o.l.SetFields(o.l.GetFields().Add(HCLogName, name))
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return o
|
||||
}
|
||||
|
||||
lg.SetFields(lg.GetFields().Add(HCLogName, name))
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *_hclog) ResetNamed(name string) hclog.Logger {
|
||||
o.l.SetFields(o.l.GetFields().Add(HCLogName, name))
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return o
|
||||
}
|
||||
|
||||
lg.SetFields(lg.GetFields().Add(HCLogName, name))
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *_hclog) SetLevel(level hclog.Level) {
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch level {
|
||||
case hclog.NoLevel, hclog.Off:
|
||||
o.l.SetLevel(loglvl.NilLevel)
|
||||
lg.SetLevel(loglvl.NilLevel)
|
||||
case hclog.Trace:
|
||||
opt := o.l.GetOptions()
|
||||
if opt.Stdout == nil {
|
||||
opt.Stdout = &logcfg.OptionsStd{}
|
||||
opt := lg.GetOptions()
|
||||
|
||||
if opt.Stdout != nil {
|
||||
opt.Stdout.EnableTrace = true
|
||||
}
|
||||
opt.Stdout.EnableTrace = true
|
||||
_ = o.l.SetOptions(opt)
|
||||
o.l.SetLevel(loglvl.DebugLevel)
|
||||
|
||||
if len(opt.LogFile) > 0 {
|
||||
for i := range opt.LogFile {
|
||||
opt.LogFile[i].EnableTrace = true
|
||||
}
|
||||
}
|
||||
|
||||
if len(opt.LogSyslog) > 0 {
|
||||
for i := range opt.LogSyslog {
|
||||
opt.LogSyslog[i].EnableTrace = true
|
||||
}
|
||||
}
|
||||
|
||||
_ = lg.SetOptions(opt)
|
||||
lg.SetLevel(loglvl.DebugLevel)
|
||||
case hclog.Debug:
|
||||
o.l.SetLevel(loglvl.DebugLevel)
|
||||
lg.SetLevel(loglvl.DebugLevel)
|
||||
case hclog.Info:
|
||||
o.l.SetLevel(loglvl.InfoLevel)
|
||||
lg.SetLevel(loglvl.InfoLevel)
|
||||
case hclog.Warn:
|
||||
o.l.SetLevel(loglvl.WarnLevel)
|
||||
lg.SetLevel(loglvl.WarnLevel)
|
||||
case hclog.Error:
|
||||
o.l.SetLevel(loglvl.ErrorLevel)
|
||||
lg.SetLevel(loglvl.ErrorLevel)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *_hclog) GetLevel() hclog.Level {
|
||||
switch o.l.GetLevel() {
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return hclog.NoLevel
|
||||
}
|
||||
|
||||
switch lg.GetLevel() {
|
||||
case loglvl.NilLevel:
|
||||
return hclog.NoLevel
|
||||
case loglvl.DebugLevel:
|
||||
@@ -193,6 +335,12 @@ func (o *_hclog) GetLevel() hclog.Level {
|
||||
}
|
||||
|
||||
func (o *_hclog) StandardLogger(opts *hclog.StandardLoggerOptions) *log.Logger {
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return log.Default()
|
||||
}
|
||||
|
||||
var lvl loglvl.Level
|
||||
switch opts.ForceLevel {
|
||||
case hclog.NoLevel, hclog.Off:
|
||||
@@ -209,9 +357,15 @@ func (o *_hclog) StandardLogger(opts *hclog.StandardLoggerOptions) *log.Logger {
|
||||
lvl = loglvl.ErrorLevel
|
||||
}
|
||||
|
||||
return o.l.GetStdLogger(lvl, 0)
|
||||
return lg.GetStdLogger(lvl, 0)
|
||||
}
|
||||
|
||||
func (o *_hclog) StandardWriter(opts *hclog.StandardLoggerOptions) io.Writer {
|
||||
return o.l
|
||||
var lg = o.logger()
|
||||
|
||||
if lg == nil {
|
||||
return os.Stdout
|
||||
}
|
||||
|
||||
return lg
|
||||
}
|
||||
|
@@ -36,6 +36,7 @@ import (
|
||||
logcfg "github.com/nabbar/golib/logger/config"
|
||||
loglvl "github.com/nabbar/golib/logger/level"
|
||||
logtps "github.com/nabbar/golib/logger/types"
|
||||
libsiz "github.com/nabbar/golib/size"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@@ -78,6 +79,7 @@ func New(opt logcfg.OptionsFile, format logrus.Formatter) (HookFile, error) {
|
||||
n := &hkf{
|
||||
s: new(atomic.Value),
|
||||
d: new(atomic.Value),
|
||||
b: new(atomic.Int64),
|
||||
o: ohkf{
|
||||
format: format,
|
||||
flags: flags,
|
||||
@@ -93,6 +95,12 @@ func New(opt logcfg.OptionsFile, format logrus.Formatter) (HookFile, error) {
|
||||
},
|
||||
}
|
||||
|
||||
if opt.FileBufferSize <= libsiz.SizeKilo {
|
||||
n.b.Store(opt.FileBufferSize.Int64())
|
||||
} else {
|
||||
n.b.Store(sizeBuffer)
|
||||
}
|
||||
|
||||
if opt.CreatePath {
|
||||
if e := libiot.PathCheckCreate(true, opt.Filepath, opt.FileMode, opt.PathMode); e != nil {
|
||||
return nil, e
|
||||
|
@@ -54,6 +54,7 @@ type hkf struct {
|
||||
s *atomic.Value // channel stop struct{}
|
||||
d *atomic.Value // channel data []byte
|
||||
o ohkf // config data
|
||||
b *atomic.Int64 // buffer size
|
||||
}
|
||||
|
||||
func (o *hkf) Levels() []logrus.Level {
|
||||
|
@@ -32,6 +32,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
@@ -40,12 +41,26 @@ import (
|
||||
|
||||
const sizeBuffer = 32 * 1024
|
||||
|
||||
func (o *hkf) getBufferSize() int {
|
||||
b := o.b.Load()
|
||||
|
||||
if b < sizeBuffer {
|
||||
b = sizeBuffer
|
||||
}
|
||||
|
||||
if b > math.MaxInt {
|
||||
return math.MaxInt
|
||||
} else {
|
||||
return int(b)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *hkf) newBuffer(size int) *bytes.Buffer {
|
||||
if size > 0 {
|
||||
return bytes.NewBuffer(make([]byte, 0, size))
|
||||
}
|
||||
|
||||
return bytes.NewBuffer(make([]byte, 0, sizeBuffer))
|
||||
return bytes.NewBuffer(make([]byte, 0, o.getBufferSize()))
|
||||
}
|
||||
|
||||
func (o *hkf) writeBuffer(buf *bytes.Buffer) error {
|
||||
@@ -67,7 +82,7 @@ func (o *hkf) writeBuffer(buf *bytes.Buffer) error {
|
||||
|
||||
defer func() {
|
||||
if rec := recover(); rec != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "recovering panic thread on golib/logger/hookfile/system.\nfor log file '%s'\n%v\n", p, rec)
|
||||
_, _ = fmt.Fprintf(os.Stderr, "recovering panic thread on writeBuffer function in golib/logger/hookfile/system.\nfor log file '%s'\n%v\n", p, rec)
|
||||
}
|
||||
if h != nil {
|
||||
_ = h.Close()
|
||||
@@ -95,18 +110,17 @@ func (o *hkf) writeBuffer(buf *bytes.Buffer) error {
|
||||
func (o *hkf) freeBuffer(buf *bytes.Buffer, size int) *bytes.Buffer {
|
||||
defer func() {
|
||||
if rec := recover(); rec != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "recovering panic thread on golib/logger/hookfile/system.\nfor log file '%s'\n%v\n", o.getFilepath(), rec)
|
||||
_, _ = fmt.Fprintf(os.Stderr, "recovering panic thread on freeBuffer function in golib/logger/hookfile/system.\nfor log file '%s'\n%v\n", o.getFilepath(), rec)
|
||||
}
|
||||
}()
|
||||
|
||||
if size > buf.Cap() {
|
||||
size = buf.Cap()
|
||||
} else {
|
||||
size = buf.Cap() - size
|
||||
var a = o.newBuffer(o.getBufferSize())
|
||||
|
||||
if size < a.Cap() {
|
||||
size = a.Cap() - size
|
||||
a.WriteString(buf.String()[0:size])
|
||||
}
|
||||
|
||||
var a = o.newBuffer(buf.Cap())
|
||||
a.WriteString(buf.String()[0:size])
|
||||
return a
|
||||
}
|
||||
|
||||
@@ -120,7 +134,7 @@ func (o *hkf) Run(ctx context.Context) {
|
||||
|
||||
defer func() {
|
||||
if rec := recover(); rec != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "recovering panic thread on golib/logger/hookfile/system.\nfor log file '%s'\n%v\n", o.getFilepath(), rec)
|
||||
_, _ = fmt.Fprintf(os.Stderr, "recovering panic thread on run function in golib/logger/hookfile/system.\nfor log file '%s'\n%v\n", o.getFilepath(), rec)
|
||||
}
|
||||
//flush buffer before exit function
|
||||
if b.Len() > 0 {
|
||||
|
@@ -44,7 +44,7 @@ func (o *hks) Run(ctx context.Context) {
|
||||
|
||||
defer func() {
|
||||
if rec := recover(); rec != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "recovering panic thread on golib/logger/hooksyslog/system\n%v\n", rec)
|
||||
_, _ = fmt.Fprintf(os.Stderr, "recovering panic thread on run function in golib/logger/hooksyslog/system\n%v\n", rec)
|
||||
}
|
||||
if s != nil {
|
||||
w.Wait()
|
||||
@@ -84,7 +84,7 @@ func (o *hks) writeWrapper(w Wrapper, d data, done func()) {
|
||||
|
||||
defer func() {
|
||||
if rec := recover(); rec != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "recovering panic thread on golib/logger/hooksyslog/system\n%v\n", rec)
|
||||
_, _ = fmt.Fprintf(os.Stderr, "recovering panic thread on writeWrapper function in golib/logger/hooksyslog/system\n%v\n", rec)
|
||||
}
|
||||
done()
|
||||
}()
|
||||
|
Reference in New Issue
Block a user