qoobing.com/gomod/log@v1.2.8/writer.go (about)

     1  package log
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"path/filepath"
     9  	"sync"
    10  )
    11  
    12  type baseWriter struct {
    13  	logw *os.File
    14  	stdw *os.File
    15  	errw *os.File
    16  
    17  	logFilename     string
    18  	logPreBackupTag string
    19  }
    20  
    21  type cacheWriter struct {
    22  	cache      bytes.Buffer
    23  	cacheing   bool
    24  	cacheLock  *sync.Mutex
    25  	baseWriter io.Writer
    26  }
    27  
    28  func NewBaseWriter(logw, stdw, errw *os.File) *baseWriter {
    29  	return &baseWriter{
    30  		logw: logw,
    31  		stdw: stdw,
    32  		errw: errw,
    33  	}
    34  }
    35  
    36  // OpenLogFile
    37  func (w *baseWriter) OpenLogFile(logDir, logName string, optLogDirs []string) {
    38  	// Step 1. try get available log dir
    39  	if _, err := os.Stat(logDir); err == nil {
    40  		logDir = logDir
    41  	} else if dir, err := tryOptLogDirs(optLogDirs); err == nil {
    42  		logDir = dir
    43  	} else if err := os.Mkdir(logDir, 0755); err == nil {
    44  		logDir = logDir
    45  	} else {
    46  		errstr := fmt.Sprintf("all path not exist:\n "+
    47  			"a.[%s]\n b.[%s]\n c.[%s]\n",
    48  			logDir, "./log/", "./logs/")
    49  		panic("failed initlog:" + errstr)
    50  	}
    51  
    52  	// Step 2. open base writer logfile
    53  	filename := filepath.Join(logDir, logName+".log")
    54  	w.logFilename = filename
    55  	w.logPreBackupTag = ""
    56  	w.ReopenLogFile()
    57  }
    58  
    59  // ReopenLogFile
    60  func (w *baseWriter) ReopenLogFile() {
    61  	var fil, err = os.OpenFile(w.logFilename,
    62  		os.O_APPEND|os.O_CREATE|os.O_WRONLY, os.ModePerm)
    63  	if err != nil {
    64  		panic("open log file failed:" + err.Error())
    65  	}
    66  	w.logw.Close()
    67  	w.logw = fil
    68  }
    69  
    70  // BackupLogFile
    71  func (w *baseWriter) TryBackupLogFile(tag string) bool {
    72  	if w.logPreBackupTag == "" {
    73  		w.logPreBackupTag = tag
    74  		return false
    75  	} else if w.logPreBackupTag == tag {
    76  		return false
    77  	}
    78  
    79  	w.logPreBackupTag = tag
    80  	newname := w.logFilename + "." + tag
    81  	if err := os.Rename(w.logFilename, newname); err != nil {
    82  		return false
    83  	}
    84  
    85  	w.ReopenLogFile()
    86  	return true
    87  }
    88  
    89  func NewCacheWriter(basewriter io.Writer) *cacheWriter {
    90  	return &cacheWriter{
    91  		cache:      bytes.Buffer{},
    92  		cacheing:   false,
    93  		cacheLock:  new(sync.Mutex),
    94  		baseWriter: basewriter,
    95  	}
    96  }
    97  
    98  func (w *baseWriter) Write(p []byte) (n int, err error) {
    99  	if w.errw != nil {
   100  		n, err = w.errw.Write(p)
   101  	}
   102  	if w.stdw != nil {
   103  		n, err = w.stdw.Write(p)
   104  	}
   105  	if w.logw != nil {
   106  		n, err = w.logw.Write(p)
   107  	}
   108  	return n, err
   109  }
   110  
   111  func (w *cacheWriter) Write(p []byte) (n int, err error) {
   112  	if w.cacheing {
   113  		w.cache.Write(p)
   114  	}
   115  	return w.baseWriter.Write(p)
   116  }
   117  
   118  func (w *cacheWriter) GetCacheLog() string {
   119  	if w.cacheing != true {
   120  		panic("GetCacheLog MUST call after StartCacheLog called")
   121  	}
   122  	return w.cache.String()
   123  }
   124  
   125  func (w *cacheWriter) StartCacheLog() {
   126  	w.cacheLock.Lock()
   127  	w.cacheing = true
   128  	w.cache.Reset()
   129  }
   130  
   131  func (w *cacheWriter) StopCacheLog() {
   132  	w.cacheLock.Unlock()
   133  	w.cacheing = true
   134  }