github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zlog/file.go (about)

     1  package zlog
     2  
     3  import (
     4  	"io"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"github.com/sohaha/zlsgo/zfile"
    11  	"github.com/sohaha/zlsgo/ztime"
    12  )
    13  
    14  var LogMaxDurationDate = 15
    15  
    16  func openFile(filepa string, archive bool) (file *zfile.MemoryFile, fileName, fileDir string, err error) {
    17  	fullPath := zfile.RealPath(filepa)
    18  	fileDir, fileName = filepath.Split(fullPath)
    19  	opt := []zfile.MemoryFileOption{zfile.MemoryFileAutoFlush(1)}
    20  	if archive {
    21  		ext := filepath.Ext(fileName)
    22  		base := strings.TrimSuffix(fileName, ext)
    23  		fileDir = zfile.RealPathMkdir(fileDir+base, true)
    24  		fullPath = fileDir + fileName
    25  		lastArchiveName := ""
    26  		opt = append(opt, zfile.MemoryFileFlushBefore(func(f *zfile.MemoryFile) error {
    27  			archiveName := ztime.Now("Y-m-d")
    28  			if lastArchiveName != archiveName {
    29  				if lastArchiveName != "" {
    30  					// Delete the log file that is too old
    31  					go func() {
    32  						now := ztime.UnixMicro(ztime.Clock())
    33  						_ = filepath.Walk(fileDir, func(path string, info os.FileInfo, err error) error {
    34  							if err != nil {
    35  								return err
    36  							}
    37  							if info.IsDir() {
    38  								return nil
    39  							}
    40  
    41  							// The log may have been modified, so the modification time of the file is no longer used here.
    42  							// if info.ModTime().AddDate(0, 0, LogMaxDurationDate).Before(now) {
    43  							// 	_ = os.Remove(path)
    44  							// }
    45  
    46  							date, err := ztime.Parse(strings.TrimSuffix(filepath.Base(path), ext), "Y-m-d")
    47  							if err == nil && date.AddDate(0, 0, LogMaxDurationDate).Before(now) {
    48  								_ = os.Remove(path)
    49  							}
    50  							return nil
    51  
    52  						})
    53  					}()
    54  				}
    55  				lastArchiveName = archiveName
    56  			}
    57  			fileName = archiveName + ext
    58  			f.SetName(fileDir + fileName)
    59  			return nil
    60  		}))
    61  	}
    62  	f := zfile.NewMemoryFile(fullPath, opt...)
    63  	return f, fileName, fileDir, nil
    64  }
    65  
    66  // SetFile Setting log file output
    67  func (log *Logger) SetFile(filepath string, archive ...bool) {
    68  	log.DisableConsoleColor()
    69  	logArchive := len(archive) > 0 && archive[0]
    70  	log.setLogfile(filepath, logArchive)
    71  }
    72  
    73  func (log *Logger) setLogfile(filepath string, archive bool) {
    74  	fileObj, fileName, fileDir, _ := openFile(filepath, archive)
    75  	log.mu.Lock()
    76  	log.CloseFile()
    77  	log.file = fileObj
    78  	log.fileDir = fileDir
    79  	log.fileName = fileName
    80  	if log.fileAndStdout {
    81  		log.out = io.MultiWriter(log.file, log.out)
    82  	} else {
    83  		log.out = fileObj
    84  	}
    85  	log.mu.Unlock()
    86  }
    87  
    88  func (log *Logger) Discard() {
    89  	log.mu.Lock()
    90  	log.out = ioutil.Discard
    91  	if log.file != nil {
    92  		_ = log.file.Close()
    93  	}
    94  	log.level = LogNot
    95  	log.mu.Unlock()
    96  }
    97  
    98  func (log *Logger) SetSaveFile(filepath string, archive ...bool) {
    99  	log.SetFile(filepath, archive...)
   100  	log.mu.Lock()
   101  	log.fileAndStdout = true
   102  	log.out = io.MultiWriter(log.file, os.Stdout)
   103  	log.mu.Unlock()
   104  }
   105  
   106  func (log *Logger) CloseFile() {
   107  	if log.file != nil {
   108  		_ = log.file.Close()
   109  		log.file = nil
   110  		log.out = os.Stderr
   111  	}
   112  }