Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
8dcedb0ce7 | |||
b3fbc466f1 | |||
911f959018 |
@@ -6,15 +6,13 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCrashLog set crash log
|
// NewCrashLog set crash log
|
||||||
func NewCrashLog(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)
|
||||||
}
|
}
|
||||||
|
@@ -6,15 +6,13 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCrashLog set crash log
|
// NewCrashLog set crash log
|
||||||
func NewCrashLog(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)
|
||||||
}
|
}
|
||||||
|
@@ -6,8 +6,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -34,7 +32,7 @@ func NewCrashLog(file string) {
|
|||||||
} 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -88,7 +88,7 @@ func (enc textEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*
|
|||||||
// 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)
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ 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.Write(context.buf.Bytes())
|
||||||
line.AppendByte('}')
|
line.AppendByte('}')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +185,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()
|
||||||
@@ -260,6 +262,8 @@ func (enc *textEncoder) AddUint64(key string, val uint64) {
|
|||||||
enc.addElementSeparator()
|
enc.addElementSeparator()
|
||||||
enc.buf.AppendUint(val)
|
enc.buf.AppendUint(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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 +278,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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +359,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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
go.mod
5
go.mod
@@ -3,7 +3,8 @@ module github.com/ehlxr/log
|
|||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/pkg/errors v0.8.1
|
github.com/ehlxr/lumberjack v2.0.0+incompatible
|
||||||
|
github.com/robfig/cron/v3 v3.0.0
|
||||||
go.uber.org/zap v1.12.0
|
go.uber.org/zap v1.12.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||||
)
|
)
|
||||||
|
78
log.go
78
log.go
@@ -2,18 +2,17 @@ package log
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"gopkg.in/natefinch/lumberjack.v2"
|
"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"
|
||||||
)
|
)
|
||||||
@@ -32,10 +31,9 @@ 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
|
||||||
|
|
||||||
// enable the truncation of the level text to 4 characters.
|
// enable the truncation of the level text to 4 characters.
|
||||||
@@ -45,21 +43,15 @@ type logConfig struct {
|
|||||||
EnableCapitalLevel bool
|
EnableCapitalLevel bool
|
||||||
atomicLevel zap.AtomicLevel
|
atomicLevel zap.AtomicLevel
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
|
*lumberjack.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
lc := &logConfig{
|
lc := &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 = lc.newLogger().Sugar()
|
||||||
@@ -72,21 +64,29 @@ func (lc *logConfig) Init() {
|
|||||||
func NewLogConfig() *logConfig {
|
func NewLogConfig() *logConfig {
|
||||||
return &logConfig{
|
return &logConfig{
|
||||||
Level: DebugLevel,
|
Level: DebugLevel,
|
||||||
FilePath: "./logs/",
|
|
||||||
EnableColors: true,
|
EnableColors: true,
|
||||||
CrashLogPath: "./logs/crash.log",
|
CrashLogFilename: "./logs/crash.log",
|
||||||
ErrorLogPath: "./logs/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 (lc *logConfig) newLogger() *zap.Logger {
|
||||||
if lc.CrashLogPath != "" {
|
if lc.CrashLogFilename != "" {
|
||||||
writeCrashLog(lc.CrashLogPath)
|
writeCrashLog(lc.CrashLogFilename)
|
||||||
}
|
}
|
||||||
|
|
||||||
lc.atomicLevel = zap.NewAtomicLevelAt(lc.Level)
|
lc.atomicLevel = zap.NewAtomicLevelAt(lc.Level)
|
||||||
@@ -99,11 +99,11 @@ func (lc *logConfig) newLogger() *zap.Logger {
|
|||||||
lc.atomicLevel,
|
lc.atomicLevel,
|
||||||
)}
|
)}
|
||||||
|
|
||||||
if lc.FilePath != "" {
|
if lc.Filename != "" {
|
||||||
cores = append(cores, lc.fileCore())
|
cores = append(cores, lc.fileCore())
|
||||||
}
|
}
|
||||||
|
|
||||||
if lc.ErrorLogPath != "" {
|
if lc.ErrorLogFilename != "" {
|
||||||
cores = append(cores, lc.errorFileCore())
|
cores = append(cores, lc.errorFileCore())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ func (lc *logConfig) fileCore() zapcore.Core {
|
|||||||
// zapcore.Lock(os.Stdout),
|
// zapcore.Lock(os.Stdout),
|
||||||
// lc.fileWriteSyncer(),
|
// lc.fileWriteSyncer(),
|
||||||
// ),
|
// ),
|
||||||
fileWriteSyncer(lc.FilePath),
|
lc.fileWriteSyncer(lc.Filename),
|
||||||
lc.atomicLevel,
|
lc.atomicLevel,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -173,7 +173,7 @@ func (lc *logConfig) errorFileCore() zapcore.Core {
|
|||||||
return zapcore.NewCore(
|
return zapcore.NewCore(
|
||||||
encoder.NewTextEncoder(lc.encoderConfig()),
|
encoder.NewTextEncoder(lc.encoderConfig()),
|
||||||
|
|
||||||
fileWriteSyncer(lc.ErrorLogPath),
|
lc.fileWriteSyncer(lc.ErrorLogFilename),
|
||||||
zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
|
zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
|
||||||
return lvl >= zapcore.ErrorLevel
|
return lvl >= zapcore.ErrorLevel
|
||||||
}),
|
}),
|
||||||
@@ -219,7 +219,7 @@ func trimCallerFilePath(ec zapcore.EntryCaller) string {
|
|||||||
return fmt.Sprintf(" %s", caller)
|
return fmt.Sprintf(" %s", caller)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fileWriteSyncer(name string) zapcore.WriteSyncer {
|
func (lc *logConfig) fileWriteSyncer(fileName string) zapcore.WriteSyncer {
|
||||||
// go get github.com/lestrrat-go/file-rotatelogs
|
// go get github.com/lestrrat-go/file-rotatelogs
|
||||||
// writer, err := rotatelogs.New(
|
// writer, err := rotatelogs.New(
|
||||||
// name+".%Y%m%d",
|
// name+".%Y%m%d",
|
||||||
@@ -232,14 +232,22 @@ func fileWriteSyncer(name string) zapcore.WriteSyncer {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
writer := &lumberjack.Logger{
|
writer := &lumberjack.Logger{
|
||||||
Filename: fmt.Sprintf("%s%s.log", name, time.Now().Format("2006-01-02")),
|
Filename: fileName,
|
||||||
MaxSize: 500, // 单个日志文件大小(MB)
|
MaxSize: lc.MaxSize, // 单个日志文件大小(MB)
|
||||||
MaxBackups: 10,
|
MaxBackups: lc.MaxBackups,
|
||||||
MaxAge: 30, // 保留多少天的日志
|
MaxAge: lc.MaxAge, // 保留多少天的日志
|
||||||
LocalTime: true,
|
LocalTime: lc.LocalTime,
|
||||||
Compress: true,
|
Compress: lc.Compress,
|
||||||
|
BackupTimeFormat: lc.BackupTimeFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rotating log files daily
|
||||||
|
runner := cron.New(cron.WithSeconds(), cron.WithLocation(time.UTC))
|
||||||
|
_, _ = runner.AddFunc("0 0 0 * * ?", func() {
|
||||||
|
_ = writer.Rotate(time.Now().AddDate(0, 0, -1))
|
||||||
|
})
|
||||||
|
go runner.Run()
|
||||||
|
|
||||||
return zapcore.AddSync(writer)
|
return zapcore.AddSync(writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +255,7 @@ 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",
|
log.Fatalf("make crash log dir error. %v",
|
||||||
errors.WithStack(err))
|
err)
|
||||||
}
|
}
|
||||||
|
|
||||||
crash.NewCrashLog(file)
|
crash.NewCrashLog(file)
|
||||||
|
16
log_test.go
16
log_test.go
@@ -2,6 +2,7 @@ package log
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLog(t *testing.T) {
|
func TestLog(t *testing.T) {
|
||||||
@@ -11,11 +12,10 @@ func TestLog(t *testing.T) {
|
|||||||
// Panicf("this is %s message", "panic")
|
// Panicf("this is %s message", "panic")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestLogWithConfig(t *testing.T) {
|
func TestLogWithConfig(t *testing.T) {
|
||||||
lc := NewLogConfig()
|
lc := NewLogConfig()
|
||||||
_ = lc.Level.Set("info")
|
_ = lc.Level.Set("info")
|
||||||
lc.Name="main"
|
lc.Name = "main"
|
||||||
lc.Init()
|
lc.Init()
|
||||||
|
|
||||||
Debugf("this is %s message", "debug")
|
Debugf("this is %s message", "debug")
|
||||||
@@ -23,3 +23,15 @@ func TestLogWithConfig(t *testing.T) {
|
|||||||
Errorf("this is %s message", "error")
|
Errorf("this is %s message", "error")
|
||||||
// Panicf("this is %s message", "panic")
|
// Panicf("this is %s message", "panic")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLogRote(t *testing.T) {
|
||||||
|
lc := NewLogConfig()
|
||||||
|
lc.MaxSize = 1
|
||||||
|
|
||||||
|
lc.Init()
|
||||||
|
|
||||||
|
for {
|
||||||
|
Infof("this is %s message", "info")
|
||||||
|
time.Sleep(time.Millisecond * 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user