mirror of
https://github.com/duanhf2012/origin.git
synced 2026-02-15 08:14:46 +08:00
重构并优化日志库
This commit is contained in:
91
log/buffer.go
Normal file
91
log/buffer.go
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
package log // import "go.uber.org/zap/buffer"
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
const _size = 9216
|
||||||
|
|
||||||
|
type Buffer struct {
|
||||||
|
bs []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (buff *Buffer) Init(){
|
||||||
|
buff.bs = make([]byte,_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendByte writes a single byte to the Buffer.
|
||||||
|
func (b *Buffer) AppendByte(v byte) {
|
||||||
|
b.bs = append(b.bs, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Buffer) AppendBytes(v []byte) {
|
||||||
|
b.bs = append(b.bs, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendString writes a string to the Buffer.
|
||||||
|
func (b *Buffer) AppendString(s string) {
|
||||||
|
b.bs = append(b.bs, s...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInt appends an integer to the underlying buffer (assuming base 10).
|
||||||
|
func (b *Buffer) AppendInt(i int64) {
|
||||||
|
b.bs = strconv.AppendInt(b.bs, i, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUint appends an unsigned integer to the underlying buffer (assuming
|
||||||
|
// base 10).
|
||||||
|
func (b *Buffer) AppendUint(i uint64) {
|
||||||
|
b.bs = strconv.AppendUint(b.bs, i, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendBool appends a bool to the underlying buffer.
|
||||||
|
func (b *Buffer) AppendBool(v bool) {
|
||||||
|
b.bs = strconv.AppendBool(b.bs, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendFloat appends a float to the underlying buffer. It doesn't quote NaN
|
||||||
|
// or +/- Inf.
|
||||||
|
func (b *Buffer) AppendFloat(f float64, bitSize int) {
|
||||||
|
b.bs = strconv.AppendFloat(b.bs, f, 'f', -1, bitSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the length of the underlying byte slice.
|
||||||
|
func (b *Buffer) Len() int {
|
||||||
|
return len(b.bs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cap returns the capacity of the underlying byte slice.
|
||||||
|
func (b *Buffer) Cap() int {
|
||||||
|
return cap(b.bs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes returns a mutable reference to the underlying byte slice.
|
||||||
|
func (b *Buffer) Bytes() []byte {
|
||||||
|
return b.bs
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a string copy of the underlying byte slice.
|
||||||
|
func (b *Buffer) String() string {
|
||||||
|
return string(b.bs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset resets the underlying byte slice. Subsequent writes re-use the slice's
|
||||||
|
// backing array.
|
||||||
|
func (b *Buffer) Reset() {
|
||||||
|
b.bs = b.bs[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write implements io.Writer.
|
||||||
|
func (b *Buffer) Write(bs []byte) (int, error) {
|
||||||
|
b.bs = append(b.bs, bs...)
|
||||||
|
return len(bs), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrimNewline trims any final "\n" byte from the end of the buffer.
|
||||||
|
func (b *Buffer) TrimNewline() {
|
||||||
|
if i := len(b.bs) - 1; i >= 0 {
|
||||||
|
if b.bs[i] == '\n' {
|
||||||
|
b.bs = b.bs[:i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
385
log/log.go
385
log/log.go
@@ -9,9 +9,15 @@ import (
|
|||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"sync"
|
||||||
|
"io"
|
||||||
|
"runtime"
|
||||||
|
syslog "log"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
)
|
)
|
||||||
|
|
||||||
var OpenConsole bool = true
|
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||||
|
var OpenConsole bool
|
||||||
|
|
||||||
// levels
|
// levels
|
||||||
const (
|
const (
|
||||||
@@ -35,15 +41,50 @@ const (
|
|||||||
type Logger struct {
|
type Logger struct {
|
||||||
filePath string
|
filePath string
|
||||||
filepre string
|
filepre string
|
||||||
logTime time.Time
|
|
||||||
|
//logTime time.Time
|
||||||
|
fileDay int
|
||||||
level int
|
level int
|
||||||
stdLogger *log.Logger
|
|
||||||
baseLogger *log.Logger
|
|
||||||
baseFile *os.File
|
|
||||||
flag int
|
flag int
|
||||||
|
buf Buffer
|
||||||
|
|
||||||
|
outFile io.Writer // destination for output
|
||||||
|
outConsole io.Writer //os.Stdout
|
||||||
|
|
||||||
|
mu sync.Mutex // ensures atomic writes; protects the following fields
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(strLevel string, pathname string, filepre string, flag int) (*Logger, error) {
|
func (logger *Logger) GenDayFile(now *time.Time) error {
|
||||||
|
if logger.fileDay == now.Day() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := fmt.Sprintf("%d%02d%02d_%02d_%02d_%02d.log",
|
||||||
|
now.Year(),
|
||||||
|
now.Month(),
|
||||||
|
now.Day(),
|
||||||
|
now.Hour(),
|
||||||
|
now.Minute(),
|
||||||
|
now.Second())
|
||||||
|
|
||||||
|
if logger.filePath != "" {
|
||||||
|
var err error
|
||||||
|
logger.outFile,err = os.Create(path.Join(logger.filePath, logger.filepre+filename))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logger.fileDay = now.Day()
|
||||||
|
if OpenConsole == true {
|
||||||
|
logger.outConsole = os.Stdout
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
logger.outConsole = os.Stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(strLevel string, pathName string, filePre string, flag int) (*Logger, error) {
|
||||||
// level
|
// level
|
||||||
var level int
|
var level int
|
||||||
switch strings.ToLower(strLevel) {
|
switch strings.ToLower(strLevel) {
|
||||||
@@ -63,88 +104,213 @@ func New(strLevel string, pathname string, filepre string, flag int) (*Logger, e
|
|||||||
return nil, errors.New("unknown level: " + strLevel)
|
return nil, errors.New("unknown level: " + strLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// logger
|
|
||||||
var baseLogger *log.Logger
|
|
||||||
var baseFile *os.File
|
|
||||||
now := time.Now()
|
|
||||||
if pathname != "" {
|
|
||||||
filename := fmt.Sprintf("%d%02d%02d_%02d_%02d_%02d.log",
|
|
||||||
now.Year(),
|
|
||||||
now.Month(),
|
|
||||||
now.Day(),
|
|
||||||
now.Hour(),
|
|
||||||
now.Minute(),
|
|
||||||
now.Second())
|
|
||||||
|
|
||||||
file, err := os.Create(path.Join(pathname, filepre+filename))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
baseLogger = log.New(file, "", flag)
|
|
||||||
baseFile = file
|
|
||||||
} else {
|
|
||||||
baseLogger = log.New(os.Stdout, "", flag)
|
|
||||||
OpenConsole = false
|
|
||||||
}
|
|
||||||
// new
|
// new
|
||||||
logger := new(Logger)
|
logger := new(Logger)
|
||||||
logger.level = level
|
logger.level = level
|
||||||
logger.stdLogger = log.New(os.Stdout, "", flag)
|
logger.filePath = pathName
|
||||||
logger.baseLogger = baseLogger
|
logger.filepre = filePre
|
||||||
logger.baseFile = baseFile
|
|
||||||
logger.logTime = now
|
|
||||||
logger.filePath = pathname
|
|
||||||
logger.flag = flag
|
logger.flag = flag
|
||||||
logger.filepre = filepre
|
logger.buf.Init()
|
||||||
|
now := time.Now()
|
||||||
|
err := logger.GenDayFile(&now)
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
|
||||||
return logger, nil
|
return logger, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's dangerous to call the method on logging
|
// It's dangerous to call the method on logging
|
||||||
func (logger *Logger) Close() {
|
func (logger *Logger) Close() {
|
||||||
if logger.baseFile != nil {
|
if logger.outFile != nil {
|
||||||
logger.baseFile.Close()
|
logger.outFile.(io.Closer).Close()
|
||||||
|
logger.outFile = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.baseLogger = nil
|
|
||||||
logger.baseFile = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) doPrintf(level int, printLevel string, format string, a ...interface{}) {
|
func (logger *Logger) doPrintf(level int, printLevel string, format string, a ...interface{}) {
|
||||||
if level < logger.level {
|
if level < logger.level {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if logger.baseLogger == nil {
|
now := time.Now()
|
||||||
panic("logger closed")
|
|
||||||
|
logger.mu.Lock()
|
||||||
|
logger.GenDayFile(&now)
|
||||||
|
|
||||||
|
logger.buf.Reset()
|
||||||
|
logger.formatHeader(3,&now)
|
||||||
|
logger.buf.AppendString(printLevel)
|
||||||
|
logger.buf.AppendString(fmt.Sprintf(format, a...))
|
||||||
|
logger.buf.AppendByte('\n')
|
||||||
|
if logger.outFile!= nil {
|
||||||
|
logger.outFile.Write(logger.buf.Bytes())
|
||||||
}
|
}
|
||||||
|
if logger.outConsole!= nil {
|
||||||
|
logger.outConsole.Write(logger.buf.Bytes())
|
||||||
|
}
|
||||||
|
logger.mu.Unlock()
|
||||||
|
if level == fatalLevel {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if logger.baseFile != nil {
|
|
||||||
now := time.Now()
|
|
||||||
if now.Day() != logger.logTime.Day() {
|
|
||||||
filename := fmt.Sprintf("%d%02d%02d_%02d_%02d_%02d.log",
|
|
||||||
now.Year(),
|
|
||||||
now.Month(),
|
|
||||||
now.Day(),
|
|
||||||
now.Hour(),
|
|
||||||
now.Minute(),
|
|
||||||
now.Second())
|
|
||||||
|
|
||||||
file, err := os.Create(path.Join(logger.filePath, logger.filepre+filename))
|
func (logger *Logger) doSPrintf(level int, printLevel string, a []interface{}) {
|
||||||
if err == nil {
|
if level < logger.level {
|
||||||
logger.baseFile.Close()
|
return
|
||||||
logger.baseLogger = log.New(file, "", logger.flag)
|
}
|
||||||
logger.baseFile = file
|
now := time.Now()
|
||||||
logger.logTime = now
|
logger.mu.Lock()
|
||||||
|
logger.GenDayFile(&now)
|
||||||
|
logger.buf.Reset()
|
||||||
|
logger.formatHeader(3,&now)
|
||||||
|
logger.buf.AppendString(printLevel)
|
||||||
|
for _,s := range a {
|
||||||
|
switch s.(type) {
|
||||||
|
case int:
|
||||||
|
logger.buf.AppendInt(int64(s.(int)))
|
||||||
|
case int8:
|
||||||
|
logger.buf.AppendInt(int64(s.(int8)))
|
||||||
|
case int16:
|
||||||
|
logger.buf.AppendInt(int64(s.(int16)))
|
||||||
|
case int32:
|
||||||
|
logger.buf.AppendInt(int64(s.(int32)))
|
||||||
|
case int64:
|
||||||
|
logger.buf.AppendInt(s.(int64))
|
||||||
|
case uint:
|
||||||
|
logger.buf.AppendUint(uint64(s.(uint)))
|
||||||
|
case uint8:
|
||||||
|
logger.buf.AppendUint(uint64(s.(uint8)))
|
||||||
|
case uint16:
|
||||||
|
logger.buf.AppendUint(uint64(s.(uint16)))
|
||||||
|
case uint32:
|
||||||
|
logger.buf.AppendUint(uint64(s.(uint32)))
|
||||||
|
case uint64:
|
||||||
|
logger.buf.AppendUint(s.(uint64))
|
||||||
|
case float32:
|
||||||
|
logger.buf.AppendFloat(float64(s.(float32)),32)
|
||||||
|
case float64:
|
||||||
|
logger.buf.AppendFloat(s.(float64),64)
|
||||||
|
case bool:
|
||||||
|
logger.buf.AppendBool(s.(bool))
|
||||||
|
case string:
|
||||||
|
logger.buf.AppendString(s.(string))
|
||||||
|
case *int:
|
||||||
|
val := s.(*int)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendInt(int64(*val))
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*int>")
|
||||||
}
|
}
|
||||||
|
case *int8:
|
||||||
|
val := s.(*int8)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendInt(int64(*val))
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*int8>")
|
||||||
|
}
|
||||||
|
case *int16:
|
||||||
|
val := s.(*int16)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendInt(int64(*val))
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*int16>")
|
||||||
|
}
|
||||||
|
case *int32:
|
||||||
|
val := s.(*int32)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendInt(int64(*val))
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*int32>")
|
||||||
|
}
|
||||||
|
case *int64:
|
||||||
|
val := s.(*int64)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendInt(int64(*val))
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*int64>")
|
||||||
|
}
|
||||||
|
case *uint:
|
||||||
|
val := s.(*uint)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendUint(uint64(*val))
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*uint>")
|
||||||
|
}
|
||||||
|
case *uint8:
|
||||||
|
val := s.(*uint8)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendUint(uint64(*val))
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*uint8>")
|
||||||
|
}
|
||||||
|
case *uint16:
|
||||||
|
val := s.(*uint16)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendUint(uint64(*val))
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*uint16>")
|
||||||
|
}
|
||||||
|
case *uint32:
|
||||||
|
val := s.(*uint32)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendUint(uint64(*val))
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*uint32>")
|
||||||
|
}
|
||||||
|
case *uint64:
|
||||||
|
val := s.(*uint64)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendUint(uint64(*val))
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*uint64>")
|
||||||
|
}
|
||||||
|
case *float32:
|
||||||
|
val := s.(*float32)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendFloat(float64(*val),32)
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*float32>")
|
||||||
|
}
|
||||||
|
case *float64:
|
||||||
|
val := s.(*float32)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendFloat(float64(*val),64)
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*float64>")
|
||||||
|
}
|
||||||
|
case *bool:
|
||||||
|
val := s.(*bool)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendBool(*val)
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*bool>")
|
||||||
|
}
|
||||||
|
case *string:
|
||||||
|
val := s.(*string)
|
||||||
|
if val != nil {
|
||||||
|
logger.buf.AppendString(*val)
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendString("nil<*string>")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
b,err := json.Marshal(s)
|
||||||
|
if err != nil {
|
||||||
|
logger.buf.AppendString("<unknown type>")
|
||||||
|
}else{
|
||||||
|
logger.buf.AppendBytes(b)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logger.buf.AppendByte('\n')
|
||||||
format = printLevel + format
|
if logger.outFile!= nil {
|
||||||
logger.baseLogger.Output(3, fmt.Sprintf(format, a...))
|
logger.outFile.Write(logger.buf.Bytes())
|
||||||
if OpenConsole == true {
|
|
||||||
logger.stdLogger.Output(3, fmt.Sprintf(format, a...))
|
|
||||||
}
|
}
|
||||||
|
if logger.outConsole!= nil {
|
||||||
|
logger.outConsole.Write(logger.buf.Bytes())
|
||||||
|
}
|
||||||
|
logger.mu.Unlock()
|
||||||
if level == fatalLevel {
|
if level == fatalLevel {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@@ -211,3 +377,94 @@ func Fatal(format string, a ...interface{}) {
|
|||||||
func Close() {
|
func Close() {
|
||||||
gLogger.Close()
|
gLogger.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SDebug(a ...interface{}) {
|
||||||
|
gLogger.doSPrintf(debugLevel, printDebugLevel, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SRelease(a ...interface{}) {
|
||||||
|
gLogger.doSPrintf(releaseLevel, printReleaseLevel, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SWarning(a ...interface{}) {
|
||||||
|
gLogger.doSPrintf(warningLevel, printWarningLevel, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SError(a ...interface{}) {
|
||||||
|
gLogger.doSPrintf(errorLevel, printErrorLevel, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SStack(a ...interface{}) {
|
||||||
|
gLogger.doSPrintf(stackLevel, printStackLevel, a)
|
||||||
|
gLogger.doSPrintf(stackLevel, printStackLevel, []interface{}{string(debug.Stack())})
|
||||||
|
}
|
||||||
|
|
||||||
|
func SFatal(a ...interface{}) {
|
||||||
|
gLogger.doSPrintf(fatalLevel, printFatalLevel, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeFlag = syslog.Ldate|syslog.Ltime|syslog.Lmicroseconds
|
||||||
|
func (l *Logger) formatHeader(calldepth int,t *time.Time) {
|
||||||
|
var file string
|
||||||
|
var line int
|
||||||
|
if l.flag&(syslog.Lshortfile|syslog.Llongfile) != 0 {
|
||||||
|
// Release lock while getting caller info - it's expensive.
|
||||||
|
var ok bool
|
||||||
|
_, file, line, ok = runtime.Caller(calldepth)
|
||||||
|
if !ok {
|
||||||
|
file = "???"
|
||||||
|
line = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if l.flag&syslog.Lmsgprefix != 0 {
|
||||||
|
l.buf.AppendString(l.filepre)
|
||||||
|
}
|
||||||
|
if l.flag&timeFlag != 0 {
|
||||||
|
if l.flag&syslog.Ldate != 0 {
|
||||||
|
year, month, day := t.Date()
|
||||||
|
l.buf.AppendInt(int64(year))
|
||||||
|
l.buf.AppendByte('/')
|
||||||
|
l.buf.AppendInt(int64(month))
|
||||||
|
l.buf.AppendByte('/')
|
||||||
|
l.buf.AppendInt(int64(day))
|
||||||
|
l.buf.AppendByte(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
if l.flag&(syslog.Ltime|syslog.Lmicroseconds) != 0 {
|
||||||
|
hour, min, sec := t.Clock()
|
||||||
|
l.buf.AppendInt(int64(hour))
|
||||||
|
l.buf.AppendByte(':')
|
||||||
|
l.buf.AppendInt(int64(min))
|
||||||
|
l.buf.AppendByte(':')
|
||||||
|
|
||||||
|
l.buf.AppendInt(int64(sec))
|
||||||
|
|
||||||
|
if l.flag&syslog.Lmicroseconds != 0 {
|
||||||
|
l.buf.AppendByte('.')
|
||||||
|
l.buf.AppendInt(int64(t.Nanosecond()/1e3))
|
||||||
|
}
|
||||||
|
l.buf.AppendByte(' ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.flag&(syslog.Lshortfile|syslog.Llongfile) != 0 {
|
||||||
|
if l.flag&syslog.Lshortfile != 0 {
|
||||||
|
short := file
|
||||||
|
for i := len(file) - 1; i > 0; i-- {
|
||||||
|
if file[i] == '/' {
|
||||||
|
short = file[i+1:]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file = short
|
||||||
|
}
|
||||||
|
l.buf.AppendString(file)
|
||||||
|
l.buf.AppendByte(':')
|
||||||
|
l.buf.AppendInt(int64(line))
|
||||||
|
l.buf.AppendString(": ")
|
||||||
|
}
|
||||||
|
|
||||||
|
if l.flag&syslog.Lmsgprefix != 0 {
|
||||||
|
l.buf.AppendString(l.filepre)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user