20 Commits

Author SHA1 Message Date
a15a40a425 upgrade dependencies 2021-01-04 17:14:30 +08:00
08e6fdbd53 update at 2021-01-04 15:51:39 by ehlxr 2021-01-04 15:51:39 +08:00
7eee167d91 update at 2021-01-01 23:12:00 by ehlxr 2021-01-01 23:12:00 +08:00
c03451395f modify text encoder format bug 2020-12-31 17:26:35 +08:00
48e8f68955 format field content style 2020-12-31 17:16:11 +08:00
7b9983504f format field content style 2020-12-31 17:15:59 +08:00
6ac40ca1a2 format field content style 2020-12-31 17:15:40 +08:00
ac33bdc69f add field 2020-12-31 16:21:31 +08:00
63ba3dd7ab update at 2020-01-07 17:38:50 by ehlxr 2020-01-07 17:38:50 +08:00
aad0d71d1e update at 2019-12-02 10:37:02 by ehlxr 2019-12-02 10:37:02 +08:00
4c129271a5 update at 2019-11-11 10:30:05 by ehlxr 2019-11-11 10:30:05 +08:00
5820e0ded2 update at 2019-11-11 10:28:56 by ehlxr 2019-11-11 10:28:56 +08:00
119fee49af update at 2019-11-11 09:32:36 by ehlxr 2019-11-11 09:32:36 +08:00
a2a63aebee release v0.0.4 2019-11-08 18:18:03 +08:00
8dcedb0ce7 release v0.0.4 2019-11-08 17:45:09 +08:00
b3fbc466f1 add rotating log files daily feature; add file log config 2019-11-07 17:04:36 +08:00
911f959018 update at 2019-11-06 13:45:39 by ehlxr 2019-11-06 13:45:39 +08:00
ae2bfef999 release v0.0.2 2019-11-06 10:15:22 +08:00
98605355bb add log test 2019-11-06 10:12:49 +08:00
9712dbfd2c add log test 2019-11-06 10:11:12 +08:00
11 changed files with 240 additions and 114 deletions

4
.gitignore vendored
View File

@@ -1,2 +1,4 @@
.vscode .vscode
go.sum go.sum
/.idea/
logs

View File

@@ -1 +1,6 @@
# logger # logger
[![license](https://badgen.net/badge/license/MIT/blue)](./LICENSE)
[![](https://badgen.net/github/commits/ehlxr/log)](https://github.com/ehlxr/log/commits/)
[![](https://badgen.net/github/last-commit/ehlxr/log)]((https://github.com/ehlxr/log/commits/))
[![](https://badgen.net/github/releases/ehlxr/log)](https://github.com/ehlxr/log/releases)

View File

@@ -6,16 +6,14 @@ import (
"log" "log"
"os" "os"
"syscall" "syscall"
"github.com/pkg/errors"
) )
// CrashLog set crash log // NewCrashLog set crash log
func CrashLog(file string) { func NewCrashLog(file string) {
f, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) f, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil { if err != nil {
log.Fatalf("open crash log file error. %v", errors.WithStack(err)) log.Fatalf("open crash log file error. %v", err)
} else { } else {
syscall.Dup2(int(f.Fd()), 2) _ = syscall.Dup2(int(f.Fd()), 2)
} }
} }

View File

@@ -6,16 +6,14 @@ import (
"log" "log"
"os" "os"
"syscall" "syscall"
"github.com/pkg/errors"
) )
// CrashLog set crash log // NewCrashLog set crash log
func CrashLog(file string) { func NewCrashLog(file string) {
f, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) f, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil { if err != nil {
log.Fatalf("open crash log file error. %v", errors.WithStack(err)) log.Fatalf("open crash log file error. %v", err)
} else { } else {
syscall.Dup3(int(f.Fd()), 2, 0) _ = syscall.Dup3(int(f.Fd()), 2, 0)
} }
} }

View File

@@ -6,8 +6,6 @@ import (
"log" "log"
"os" "os"
"syscall" "syscall"
"github.com/pkg/errors"
) )
var ( var (
@@ -26,15 +24,15 @@ func setStdHandle(stdhandle int32, handle syscall.Handle) error {
return nil return nil
} }
// CrashLog set crash log // NewCrashLog set crash log
func CrashLog(file string) { func NewCrashLog(file string) {
f, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) f, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil { if err != nil {
log.Println(err.Error()) log.Println(err.Error())
} else { } else {
err = setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd())) err = setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd()))
if err != nil { if err != nil {
log.Fatalf("open crash log file error. %v", errors.WithStack(err)) log.Fatalf("open crash log file error. %v", err)
} }
} }
} }

View File

@@ -68,12 +68,13 @@ func (enc textEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*
if enc.TimeKey != "" && enc.EncodeTime != nil { if enc.TimeKey != "" && enc.EncodeTime != nil {
enc.EncodeTime(ent.Time, arr) enc.EncodeTime(ent.Time, arr)
} }
if enc.LevelKey != "" && enc.EncodeLevel != nil { if enc.LevelKey != "" && enc.EncodeLevel != nil {
enc.EncodeLevel(ent.Level, arr) enc.EncodeLevel(ent.Level, arr)
} }
if ent.LoggerName != "" && enc.NameKey != "" { if ent.LoggerName != "" && enc.NameKey != "" {
nameEncoder := enc.EncodeName nameEncoder := enc.EncodeName
if nameEncoder == nil { if nameEncoder == nil {
// Fall back to FullNameEncoder for backward compatibility. // Fall back to FullNameEncoder for backward compatibility.
nameEncoder = zapcore.FullNameEncoder nameEncoder = zapcore.FullNameEncoder
@@ -81,17 +82,23 @@ func (enc textEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*
nameEncoder(ent.LoggerName, arr) nameEncoder(ent.LoggerName, arr)
} }
if ent.Caller.Defined && enc.CallerKey != "" && enc.EncodeCaller != nil { if ent.Caller.Defined && enc.CallerKey != "" && enc.EncodeCaller != nil {
enc.EncodeCaller(ent.Caller, arr) enc.EncodeCaller(ent.Caller, arr)
} }
for i := range arr.elems { for i := range arr.elems {
// if i > 0 { // if i > 0 {
// line.AppendByte('\t') // line.AppendByte('\t')
// } // }
fmt.Fprint(line, arr.elems[i]) _, _ = fmt.Fprint(line, arr.elems[i])
} }
putSliceEncoder(arr) putSliceEncoder(arr)
// Add any structured context.
enc.writeContext(line, fields)
// Add the message itself. // Add the message itself.
if enc.MessageKey != "" { if enc.MessageKey != "" {
// c.addTabIfNecessary(line) // c.addTabIfNecessary(line)
@@ -99,9 +106,6 @@ func (enc textEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*
line.AppendString(ent.Message) line.AppendString(ent.Message)
} }
// Add any structured context.
enc.writeContext(line, fields)
// If there's no stacktrace key, honor that; this allows users to force // If there's no stacktrace key, honor that; this allows users to force
// single-line output. // single-line output.
if ent.Stack != "" && enc.StacktraceKey != "" { if ent.Stack != "" && enc.StacktraceKey != "" {
@@ -114,6 +118,7 @@ func (enc textEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*
} else { } else {
line.AppendString(zapcore.DefaultLineEnding) line.AppendString(zapcore.DefaultLineEnding)
} }
return line, nil return line, nil
} }
@@ -128,9 +133,10 @@ func (enc textEncoder) writeContext(line *buffer.Buffer, extra []zapcore.Field)
} }
// c.addTabIfNecessary(line) // c.addTabIfNecessary(line)
line.AppendByte('{') // line.AppendByte('{')
line.Write(context.buf.Bytes()) line.AppendByte(' ')
line.AppendByte('}') _, _ = line.Write(context.buf.Bytes())
// line.AppendByte('}')
} }
func (enc textEncoder) addTabIfNecessary(line *buffer.Buffer) { func (enc textEncoder) addTabIfNecessary(line *buffer.Buffer) {
@@ -185,6 +191,8 @@ func (enc *textEncoder) AddBool(key string, val bool) {
enc.addElementSeparator() enc.addElementSeparator()
enc.buf.AppendBool(val) enc.buf.AppendBool(val)
} }
//noinspection GoRedundantConversion
func (enc *textEncoder) AddComplex128(key string, val complex128) { func (enc *textEncoder) AddComplex128(key string, val complex128) {
enc.addKey(key) enc.addKey(key)
enc.addElementSeparator() enc.addElementSeparator()
@@ -214,11 +222,13 @@ func (enc *textEncoder) AddDuration(key string, val time.Duration) {
func (enc *textEncoder) AddFloat64(key string, val float64) { func (enc *textEncoder) AddFloat64(key string, val float64) {
enc.addKey(key) enc.addKey(key)
enc.appendFloat(val, 64) enc.appendFloat(val, 64)
enc.buf.AppendByte('}')
} }
func (enc *textEncoder) AddInt64(key string, val int64) { func (enc *textEncoder) AddInt64(key string, val int64) {
enc.addKey(key) enc.addKey(key)
enc.addElementSeparator() enc.addElementSeparator()
enc.buf.AppendInt(val) enc.buf.AppendInt(val)
enc.buf.AppendByte('}')
} }
func (enc *textEncoder) AddReflected(key string, obj interface{}) error { func (enc *textEncoder) AddReflected(key string, obj interface{}) error {
enc.resetReflectBuf() enc.resetReflectBuf()
@@ -239,9 +249,10 @@ func (enc *textEncoder) OpenNamespace(key string) {
func (enc *textEncoder) AddString(key, val string) { func (enc *textEncoder) AddString(key, val string) {
enc.addKey(key) enc.addKey(key)
enc.addElementSeparator() enc.addElementSeparator()
enc.buf.AppendByte('"') // enc.buf.AppendByte('"')
enc.safeAddString(val) enc.safeAddString(val)
enc.buf.AppendByte('"') // enc.buf.AppendByte('"')
enc.buf.AppendByte('}')
} }
func (enc *textEncoder) AddTime(key string, val time.Time) { func (enc *textEncoder) AddTime(key string, val time.Time) {
enc.addKey(key) enc.addKey(key)
@@ -259,7 +270,10 @@ func (enc *textEncoder) AddUint64(key string, val uint64) {
enc.addKey(key) enc.addKey(key)
enc.addElementSeparator() enc.addElementSeparator()
enc.buf.AppendUint(val) enc.buf.AppendUint(val)
enc.buf.AppendByte('}')
} }
//noinspection GoRedundantConversion
func (enc *textEncoder) AddComplex64(k string, v complex64) { enc.AddComplex128(k, complex128(v)) } func (enc *textEncoder) AddComplex64(k string, v complex64) { enc.AddComplex128(k, complex128(v)) }
func (enc *textEncoder) AddFloat32(k string, v float32) { enc.AddFloat64(k, float64(v)) } func (enc *textEncoder) AddFloat32(k string, v float32) { enc.AddFloat64(k, float64(v)) }
func (enc *textEncoder) AddInt(k string, v int) { enc.AddInt64(k, int64(v)) } func (enc *textEncoder) AddInt(k string, v int) { enc.AddInt64(k, int64(v)) }
@@ -274,7 +288,7 @@ func (enc *textEncoder) AddUintptr(k string, v uintptr) { enc.AddUint64(k, u
func (enc *textEncoder) Clone() zapcore.Encoder { func (enc *textEncoder) Clone() zapcore.Encoder {
clone := enc.clone() clone := enc.clone()
clone.buf.Write(enc.buf.Bytes()) _, _ = clone.buf.Write(enc.buf.Bytes())
return clone return clone
} }
@@ -289,15 +303,39 @@ func (enc *textEncoder) clone() *textEncoder {
func (enc *textEncoder) addKey(key string) { func (enc *textEncoder) addKey(key string) {
enc.addElementSeparator() enc.addElementSeparator()
enc.buf.AppendByte('"') // enc.buf.AppendByte('"')
if enc.replaceSeparator('}') {
enc.buf.AppendByte(',')
enc.buf.AppendByte(' ')
} else {
enc.buf.AppendByte('{')
}
enc.safeAddString(key) enc.safeAddString(key)
enc.buf.AppendByte('"') // enc.buf.AppendByte('"')
enc.buf.AppendByte(':') // enc.buf.AppendByte(':')
enc.buf.AppendByte('=')
if enc.spaced { if enc.spaced {
enc.buf.AppendByte(' ') enc.buf.AppendByte(' ')
} }
} }
func (enc *textEncoder) replaceSeparator(v byte) bool {
last := enc.buf.Len() - 1
if last < 0 {
return false
}
if enc.buf.Bytes()[last] == v {
t := enc.buf.Bytes()[:last]
enc.buf.Reset()
_, _ = enc.buf.Write(t)
return true
}
return false
}
func (enc *textEncoder) addElementSeparator() { func (enc *textEncoder) addElementSeparator() {
last := enc.buf.Len() - 1 last := enc.buf.Len() - 1
if last < 0 { if last < 0 {
@@ -307,7 +345,7 @@ func (enc *textEncoder) addElementSeparator() {
case '{', '[', ':', ',', ' ': case '{', '[', ':', ',', ' ':
return return
default: default:
enc.buf.AppendByte(',') // enc.buf.AppendByte(',')
if enc.spaced { if enc.spaced {
enc.buf.AppendByte(' ') enc.buf.AppendByte(' ')
} }
@@ -355,7 +393,7 @@ func (enc *textEncoder) safeAddByteString(s []byte) {
i++ i++
continue continue
} }
enc.buf.Write(s[i : i+size]) _, _ = enc.buf.Write(s[i : i+size])
i += size i += size
} }
} }

11
go.mod
View File

@@ -3,8 +3,11 @@ module github.com/ehlxr/log
go 1.13 go 1.13
require ( require (
github.com/ehlxr/logger v0.0.0-20191105075740-0235eee42e0f github.com/ehlxr/lumberjack v0.0.2-0.20200107093220-2a579f1b2e4d
github.com/pkg/errors v0.8.1 github.com/robfig/cron/v3 v3.0.1
go.uber.org/zap v1.12.0 go.uber.org/multierr v1.6.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 go.uber.org/zap v1.16.0
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect
golang.org/x/tools v0.0.0-20210104081019-d8d6ddbec6ee // indirect
honnef.co/go/tools v0.1.0 // indirect
) )

View File

@@ -35,15 +35,15 @@ const (
White White
) )
func (lc *logConfig) initColor() { func (config *logConfig) initColor() {
for level, color := range _levelToColor { for level, color := range _levelToColor {
lcs := level.String() lcs := level.String()
if lc.EnableCapitalLevel { if config.EnableCapitalLevel {
lcs = level.CapitalString() lcs = level.CapitalString()
} }
if lc.EnableLevelTruncation { if config.EnableLevelTruncation {
lcs = lcs[:4] lcs = lcs[:4]
} }
_levelToColorStrings[level] = color.Add(lcs) _levelToColorStrings[level] = color.Add(lcs)

172
log.go
View File

@@ -2,20 +2,19 @@ package log
import ( import (
"fmt" "fmt"
"github.com/ehlxr/lumberjack"
"log" "log"
"os" "os"
"path" "path"
"strings" "strings"
"time" "time"
"github.com/ehlxr/log/encoder"
"github.com/ehlxr/log/bufferpool" "github.com/ehlxr/log/bufferpool"
"github.com/ehlxr/log/crash" "github.com/ehlxr/log/crash"
"github.com/pkg/errors" "github.com/ehlxr/log/encoder"
"github.com/robfig/cron/v3"
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zapcore" "go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
) )
var logger *zap.SugaredLogger var logger *zap.SugaredLogger
@@ -32,11 +31,11 @@ const (
type logConfig struct { type logConfig struct {
Level zapcore.Level Level zapcore.Level
FilePath string
EnableColors bool EnableColors bool
CrashLogPath string CrashLogFilename string
ErrorLogPath string ErrorLogFilename string
EnableLineNumber bool EnableLineNumber bool
AddCallerSkip int
// enable the truncation of the level text to 4 characters. // enable the truncation of the level text to 4 characters.
EnableLevelTruncation bool EnableLevelTruncation bool
@@ -45,93 +44,100 @@ type logConfig struct {
EnableCapitalLevel bool EnableCapitalLevel bool
atomicLevel zap.AtomicLevel atomicLevel zap.AtomicLevel
Name string Name string
Fields []zap.Field
*lumberjack.Logger
} }
func init() { func init() {
lc := &logConfig{ config := &logConfig{
Level: InfoLevel, Logger: &lumberjack.Logger{
FilePath: "", LocalTime: true,
EnableColors: false, },
CrashLogPath: "",
ErrorLogPath: "",
EnableLineNumber: false,
EnableLevelTruncation: false,
EnableErrorStacktrace: false,
TimestampFormat: "",
EnableCapitalLevel: false,
Name: "",
} }
logger = lc.newLogger().Sugar() logger = config.newLogger().Sugar()
} }
func (lc *logConfig) Init() { func (config *logConfig) Init() {
logger = lc.newLogger().Sugar() logger = config.newLogger().Sugar()
}
func (config *logConfig) New() *zap.SugaredLogger {
return config.newLogger().Sugar()
} }
func NewLogConfig() *logConfig { func NewLogConfig() *logConfig {
return &logConfig{ return &logConfig{
Level: DebugLevel, Level: DebugLevel,
FilePath: "./log/",
EnableColors: true, EnableColors: true,
CrashLogPath: "./log/crash.log", CrashLogFilename: "./logs/crash.log",
ErrorLogPath: "./log/error_", ErrorLogFilename: "./logs/error.log",
EnableLineNumber: true, EnableLineNumber: true,
EnableLevelTruncation: true, EnableLevelTruncation: true,
EnableErrorStacktrace: true, EnableErrorStacktrace: true,
TimestampFormat: "2006-01-02 15:04:05.000", TimestampFormat: "2006-01-02 15:04:05.000",
EnableCapitalLevel: true, EnableCapitalLevel: true,
Logger: &lumberjack.Logger{
Filename: "./logs/log.log",
MaxSize: 200,
MaxAge: 0,
MaxBackups: 30,
LocalTime: true,
Compress: false,
BackupTimeFormat: "2006-01-02",
},
} }
} }
func (lc *logConfig) newLogger() *zap.Logger { func (config *logConfig) newLogger() *zap.Logger {
if lc.CrashLogPath != "" { if config.CrashLogFilename != "" {
writeCrashLog(lc.CrashLogPath) writeCrashLog(config.CrashLogFilename)
} }
lc.atomicLevel = zap.NewAtomicLevelAt(lc.Level) config.atomicLevel = zap.NewAtomicLevelAt(config.Level)
lc.initColor() config.initColor()
cores := []zapcore.Core{ cores := []zapcore.Core{
zapcore.NewCore( zapcore.NewCore(
encoder.NewTextEncoder(lc.encoderConfig()), encoder.NewTextEncoder(config.encoderConfig()),
zapcore.Lock(os.Stdout), zapcore.Lock(os.Stdout),
lc.atomicLevel, config.atomicLevel,
)} )}
if lc.FilePath != "" { if config.Filename != "" {
cores = append(cores, lc.fileCore()) cores = append(cores, config.fileCore())
} }
if lc.ErrorLogPath != "" { if config.ErrorLogFilename != "" {
cores = append(cores, lc.errorFileCore()) cores = append(cores, config.errorFileCore())
} }
core := zapcore.NewTee(cores...) core := zapcore.NewTee(cores...)
var options []zap.Option var options []zap.Option
if lc.EnableLineNumber { if config.EnableLineNumber {
options = append(options, zap.AddCaller(), zap.AddCallerSkip(1)) options = append(options, zap.AddCaller(), zap.AddCallerSkip(config.AddCallerSkip))
} }
if lc.EnableErrorStacktrace { if config.EnableErrorStacktrace {
options = append(options, zap.AddStacktrace(zapcore.ErrorLevel)) options = append(options, zap.AddStacktrace(zapcore.ErrorLevel))
} }
zapLog := zap.New(core, options...) zapLog := zap.New(core, options...)
if lc.Name != "" { if config.Name != "" {
zapLog = zapLog.Named(fmt.Sprintf("[%s]", lc.Name)) zapLog = zapLog.Named(fmt.Sprintf("[%s]", config.Name))
} }
return zapLog return zapLog.With(config.Fields...)
} }
func (lc *logConfig) encoderConfig() zapcore.EncoderConfig { func (config *logConfig) encoderConfig() zapcore.EncoderConfig {
el := lc.encodeLevel el := config.encodeLevel
if lc.EnableColors { if config.EnableColors {
el = lc.encodeColorLevel el = config.encodeColorLevel
} }
return zapcore.EncoderConfig{ return zapcore.EncoderConfig{
@@ -145,8 +151,8 @@ func (lc *logConfig) encoderConfig() zapcore.EncoderConfig {
EncodeLevel: el, EncodeLevel: el,
EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
tf := time.RFC3339 tf := time.RFC3339
if lc.TimestampFormat != "" { if config.TimestampFormat != "" {
tf = lc.TimestampFormat tf = config.TimestampFormat
} }
enc.AppendString(t.Format(fmt.Sprintf("[%s]", tf))) enc.AppendString(t.Format(fmt.Sprintf("[%s]", tf)))
}, },
@@ -157,40 +163,40 @@ func (lc *logConfig) encoderConfig() zapcore.EncoderConfig {
} }
} }
func (lc *logConfig) fileCore() zapcore.Core { func (config *logConfig) fileCore() zapcore.Core {
return zapcore.NewCore( return zapcore.NewCore(
encoder.NewTextEncoder(lc.encoderConfig()), encoder.NewTextEncoder(config.encoderConfig()),
// zapcore.NewMultiWriteSyncer( // zapcore.NewMultiWriteSyncer(
// zapcore.Lock(os.Stdout), // zapcore.Lock(os.Stdout),
// lc.fileWriteSyncer(), // config.fileWriteSyncer(),
// ), // ),
fileWriteSyncer(lc.FilePath), config.fileWriteSyncer(config.Filename),
lc.atomicLevel, config.atomicLevel,
) )
} }
func (lc *logConfig) errorFileCore() zapcore.Core { func (config *logConfig) errorFileCore() zapcore.Core {
return zapcore.NewCore( return zapcore.NewCore(
encoder.NewTextEncoder(lc.encoderConfig()), encoder.NewTextEncoder(config.encoderConfig()),
fileWriteSyncer(lc.ErrorLogPath), config.fileWriteSyncer(config.ErrorLogFilename),
zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl >= zapcore.ErrorLevel return lvl >= zapcore.ErrorLevel
}), }),
) )
} }
func (lc *logConfig) encodeLevel(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { func (config *logConfig) encodeLevel(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
levelString := l.CapitalString() levelString := l.CapitalString()
if lc.EnableLevelTruncation { if config.EnableLevelTruncation {
levelString = levelString[:4] levelString = levelString[:4]
} }
enc.AppendString(fmt.Sprintf("[%s]", levelString)) enc.AppendString(fmt.Sprintf("[%s]", levelString))
} }
func (lc *logConfig) encodeColorLevel(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { func (config *logConfig) encodeColorLevel(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
s, ok := _levelToColorStrings[l] s, ok := _levelToColorStrings[l]
if !ok { if !ok {
s = _unknownLevelColor.Add(l.CapitalString()) s = _unknownLevelColor.Add(l.CapitalString())
@@ -219,30 +225,52 @@ func trimCallerFilePath(ec zapcore.EntryCaller) string {
return fmt.Sprintf(" %s", caller) return fmt.Sprintf(" %s", caller)
} }
func fileWriteSyncer(name string) zapcore.WriteSyncer { func (config *logConfig) fileWriteSyncer(fileName string) zapcore.WriteSyncer {
fileName := fmt.Sprintf("%s%s.log", // go get github.com/lestrrat-go/file-rotatelogs
name, // writer, err := rotatelogs.New(
time.Now().Format("2006-01-02")) // name+".%Y%m%d",
// rotatelogs.WithLinkName(name), // 生成软链,指向最新日志文件
// rotatelogs.WithMaxAge(7*24*time.Hour), // 文件最大保存时间
// rotatelogs.WithRotationTime(24*time.Hour), // 日志切割时间间隔
// )
// if err != nil {
// log.Fatalf("config normal logger file error. %v", errors.WithStack(err))
// }
return zapcore.AddSync(&lumberjack.Logger{ writer := &lumberjack.Logger{
Filename: fileName, Filename: fileName,
MaxSize: 500, // 单个日志文件大小MB MaxSize: config.MaxSize, // 单个日志文件大小MB
MaxBackups: 10, MaxBackups: config.MaxBackups,
MaxAge: 30, // 保留多少天的日志 MaxAge: config.MaxAge, // 保留多少天的日志
LocalTime: true, LocalTime: config.LocalTime,
Compress: true, Compress: config.Compress,
BackupTimeFormat: config.BackupTimeFormat,
}
// Rotating log files daily
runner := cron.New(cron.WithSeconds(), cron.WithLocation(time.Local))
_, _ = runner.AddFunc("0 0 0 * * ?", func() {
_ = writer.Rotate(time.Now().AddDate(0, 0, -1))
}) })
go runner.Run()
return zapcore.AddSync(writer)
} }
func writeCrashLog(file string) { func writeCrashLog(file string) {
err := os.MkdirAll(path.Dir(file), os.ModePerm) err := os.MkdirAll(path.Dir(file), os.ModePerm)
if err != nil { if err != nil {
log.Fatalf("make crash log dir error. %v", errors.WithStack(err)) log.Fatalf("make crash log dir error. %v",
err)
} }
crash.CrashLog(file) crash.NewCrashLog(file)
} }
func Fields(args ...interface{}) { func Fields(args ...interface{}) {
logger = logger.With(args...) logger = logger.With(args...)
} }
func With(l *zap.SugaredLogger, args ...interface{}) *zap.SugaredLogger {
return l.With(args...)
}

56
log_test.go Normal file
View File

@@ -0,0 +1,56 @@
package log
import (
"testing"
"time"
"go.uber.org/zap"
)
func TestLog(t *testing.T) {
Debugf("this is %s message", "debug")
Infof("this is %s message", "info")
Errorf("this is %s message", "error")
// Panicf("this is %s message", "panic")
}
func TestLogWithConfig(t *testing.T) {
config := NewLogConfig()
_ = config.Level.Set("debug")
config.Name = "main"
// config.Fields = []zap.Field{zap.String("traceid", "12123123123")}
config.Init()
Fields("traceid", float64(21221212122))
Debugf("this is %s message", "debug")
config.Init()
Fields(zap.String("traceid", "12123123123"))
Infof("this is %s message", "info")
// Errorf("this is %s message", "error")
// Panicf("this is %s message", "panic")
}
func TestLogWithNew(t *testing.T) {
config := NewLogConfig()
_ = config.Level.Set("debug")
config.Name = "main"
logger := config.New()
log := With(logger, "traceid", float64(21221212122), "request", "[POST]/hello/v2")
log.Debugf("this is %s message", "debug")
log.Infof("this is %s message", "info")
}
func TestLogRote(t *testing.T) {
lc := NewLogConfig()
lc.MaxSize = 1
lc.Init()
for {
Infof("this is %s message", "info")
time.Sleep(time.Millisecond * 1)
}
}

View File

@@ -1 +1 @@
v0.0.1 v0.0.11