| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 | 
							- package log
 
- import (
 
- 	"bufio"
 
- 	"bytes"
 
- 	"fmt"
 
- 	"io"
 
- 	"log"
 
- 	"os"
 
- 	"path/filepath"
 
- 	"strings"
 
- 	"sync"
 
- 	"time"
 
- )
 
- func NewFileWriter(tag, path string) io.WriteCloser {
 
- 	return &file{
 
- 		Tag:  tag,
 
- 		Path: path,
 
- 	}
 
- }
 
- func NewLogger(dept int, w ...io.Writer) *Log {
 
- 	return New("", dept, w...)
 
- }
 
- func New(prefix string, dept int, w ...io.Writer) *Log {
 
- 	if len(w) == 0 {
 
- 		return Discard()
 
- 	}
 
- 	if prefix != "" {
 
- 		prefix = buildPrefix(prefix) + " "
 
- 	}
 
- 	return NewLog(w, prefix, dept, 0)
 
- }
 
- func Console() *Log {
 
- 	return NewLog([]io.Writer{os.Stdout}, "", 2, 0)
 
- }
 
- func Discard() *Log {
 
- 	return NewLog([]io.Writer{io.Discard}, "", 0, 0)
 
- }
 
- func Fork(l Logger, subPath, tag string) Logger {
 
- 	old, ok := l.(*Log)
 
- 	if !ok {
 
- 		return Console()
 
- 	}
 
- 	pool := make([]io.Writer, 0, len(old.wPool))
 
- 	for _, w := range old.wPool {
 
- 		if f, o := w.(*file); o {
 
- 			pool = append(pool, NewFileWriter(tag, filepath.Join(f.Path, subPath)), f)
 
- 		} else {
 
- 			pool = append(pool, w)
 
- 		}
 
- 	}
 
- 	return NewLog(pool, old.prefix, old.depth, old.buf)
 
- }
 
- func Part(l Logger, subPath, tag string) Logger {
 
- 	old, ok := l.(*Log)
 
- 	if !ok {
 
- 		return l
 
- 	}
 
- 	pool := make([]io.Writer, 0, len(old.wPool))
 
- 	for _, w := range old.wPool {
 
- 		if f, o := w.(*file); o {
 
- 			pool = append(pool, NewFileWriter(tag, filepath.Join(f.Path, subPath)))
 
- 		} else {
 
- 			pool = append(pool, w)
 
- 		}
 
- 	}
 
- 	return NewLog(pool, old.prefix, old.depth, old.buf)
 
- }
 
- const (
 
- 	LevelError uint8 = iota
 
- 	LevelWarn
 
- 	LevelInfo
 
- 	LevelDebug
 
- )
 
- const (
 
- 	LevelsError = "[E]"
 
- 	LevelsWarn  = "[W]"
 
- 	LevelsInfo  = "[I]"
 
- 	LevelsDebug = "[D]"
 
- )
 
- const (
 
- 	PrintFlags = log.LstdFlags | log.Llongfile
 
- )
 
- const (
 
- 	dateLayout = "2006_01_02"
 
- )
 
- func buildPrefix(s string) string {
 
- 	return "[" + strings.ToUpper(s) + "]"
 
- }
 
- func spitPrefix(s string) string {
 
- 	idx := strings.Index(s, " ")
 
- 	if idx == -1 {
 
- 		return s
 
- 	}
 
- 	s = strings.ToLower(s[:idx])
 
- 	s = strings.TrimPrefix(s, "[")
 
- 	s = strings.TrimSuffix(s, "]")
 
- 	return s
 
- }
 
- type file struct {
 
- 	Tag  string    // svc
 
- 	Path string    // /var/log
 
- 	date time.Time // 2006_01_02
 
- 	fi   *os.File
 
- }
 
- func (f *file) Write(b []byte) (n int, err error) {
 
- 	if err = f.check(); err != nil {
 
- 		return 0, err
 
- 	}
 
- 	return f.fi.Write(b)
 
- }
 
- func (f *file) Close() error {
 
- 	return f.fi.Close()
 
- }
 
- func (f *file) createDir() error {
 
- 	if _, err := os.Stat(f.Path); err != nil {
 
- 		if os.IsNotExist(err) {
 
- 			// 这里文件夹权限即使设置为 ModePerm, Linux 系统权限也是 755
 
- 			if err = os.MkdirAll(f.Path, os.ModePerm); err != nil {
 
- 				return err
 
- 			}
 
- 		}
 
- 		return err
 
- 	}
 
- 	return nil
 
- }
 
- func (f *file) openFile(date string) (*os.File, error) {
 
- 	return os.OpenFile(f.name(date), os.O_WRONLY|os.O_CREATE|os.O_APPEND, os.ModePerm) // 创建文件
 
- }
 
- func (f *file) name(date string) string {
 
- 	path := fmt.Sprintf("%s_%s%s", f.Tag, date, ".log")
 
- 	if f.Tag == "" {
 
- 		path = date + ".log"
 
- 	}
 
- 	// /var/log/svc_2006_01_02.log
 
- 	return filepath.Join(f.Path, path)
 
- }
 
- func (f *file) checkDate(cur time.Time) bool {
 
- 	curY, curM, curD := cur.Date()
 
- 	oldY, oldM, oldD := f.date.Date()
 
- 	if curY == oldY && curM == oldM && curD == oldD {
 
- 		return true
 
- 	}
 
- 	return false
 
- }
 
- func (f *file) check() error {
 
- 	if f.fi == nil {
 
- 		if err := f.createDir(); err != nil {
 
- 			return err
 
- 		}
 
- 	}
 
- 	cur := time.Now()
 
- 	if f.checkDate(cur) {
 
- 		return nil
 
- 	}
 
- 	if f.fi != nil {
 
- 		_ = f.fi.Close()
 
- 	}
 
- 	fi, err := f.openFile(cur.Format(dateLayout))
 
- 	if err != nil {
 
- 		return err
 
- 	}
 
- 	f.fi = fi
 
- 	f.date = cur
 
- 	return nil
 
- }
 
- type Log struct {
 
- 	depth  int // 2
 
- 	prefix string
 
- 	buf    int
 
- 	wPool  []io.Writer
 
- 	logs   []*log.Logger
 
- 	mu sync.Mutex
 
- }
 
- func NewLog(writers []io.Writer, prefix string, depth int, buf int) *Log {
 
- 	if len(writers) == 0 {
 
- 		writers = []io.Writer{io.Discard}
 
- 	}
 
- 	l := new(Log)
 
- 	l.prefix = prefix
 
- 	l.depth = depth
 
- 	l.wPool = writers
 
- 	l.buf = buf
 
- 	l.logs = make([]*log.Logger, len(l.wPool))
 
- 	for i := 0; i < len(l.wPool); i++ {
 
- 		w := l.wPool[i]
 
- 		if buf > 0 {
 
- 			w = bufio.NewWriterSize(w, buf)
 
- 		}
 
- 		l.logs[i] = log.New(w, prefix, func() int {
 
- 			if depth <= 0 {
 
- 				return log.LstdFlags
 
- 			}
 
- 			return PrintFlags
 
- 		}())
 
- 	}
 
- 	return l
 
- }
 
- func (l *Log) CallDepthPlus() {
 
- 	l.depth++
 
- }
 
- func (l *Log) CallDepthMinus() {
 
- 	l.depth--
 
- }
 
- func (l *Log) Write(b []byte) (int, error) {
 
- 	l.mu.Lock()
 
- 	n, err := bytes.NewReader(b).WriteTo(io.MultiWriter(l.wPool...))
 
- 	l.mu.Unlock()
 
- 	return int(n), err
 
- }
 
- func (l *Log) Prefix(prefix string, f string, v ...any) {
 
- 	l.mu.Lock()
 
- 	for _, lg := range l.logs {
 
- 		l.setPrefixFmt(lg, prefix)
 
- 		_ = lg.Output(l.depth, fmt.Sprintf(f, v...))
 
- 	}
 
- 	l.mu.Unlock()
 
- }
 
- func (l *Log) Println(f string, v ...any) {
 
- 	l.mu.Lock()
 
- 	for _, lg := range l.logs {
 
- 		l.setPrefixFmt(lg, "")
 
- 		_ = lg.Output(l.depth, fmt.Sprintf(f, v...))
 
- 	}
 
- 	l.mu.Unlock()
 
- }
 
- // Logger start
 
- func (l *Log) Error(f string, v ...any) {
 
- 	l.mu.Lock()
 
- 	for _, lg := range l.logs {
 
- 		l.setPrefixFmt(lg, LevelsError)
 
- 		_ = lg.Output(l.depth, fmt.Sprintf(f, v...))
 
- 	}
 
- 	l.mu.Unlock()
 
- }
 
- func (l *Log) Warn(f string, v ...any) {
 
- 	l.mu.Lock()
 
- 	for _, lg := range l.logs {
 
- 		l.setPrefixFmt(lg, LevelsWarn)
 
- 		_ = lg.Output(l.depth, fmt.Sprintf(f, v...))
 
- 	}
 
- 	l.mu.Unlock()
 
- }
 
- func (l *Log) Info(f string, v ...any) {
 
- 	l.mu.Lock()
 
- 	for _, lg := range l.logs {
 
- 		l.setPrefixFmt(lg, LevelsInfo)
 
- 		_ = lg.Output(l.depth, fmt.Sprintf(f, v...))
 
- 	}
 
- 	l.mu.Unlock()
 
- }
 
- func (l *Log) Debug(f string, v ...any) {
 
- 	l.mu.Lock()
 
- 	for _, lg := range l.logs {
 
- 		l.setPrefixFmt(lg, LevelsDebug)
 
- 		_ = lg.Output(l.depth, fmt.Sprintf(f, v...))
 
- 	}
 
- 	l.mu.Unlock()
 
- }
 
- // Logger end
 
- func (l *Log) setPrefixFmt(logger *log.Logger, s string) {
 
- 	prefix := s + " "
 
- 	if logger.Prefix() == prefix {
 
- 		return
 
- 	}
 
- 	logger.SetPrefix(prefix)
 
- }
 
 
  |