github.com/TeaOSLab/EdgeNode@v1.3.8/internal/apps/log_writer.go (about)

     1  package apps
     2  
     3  import (
     4  	"github.com/TeaOSLab/EdgeNode/internal/goman"
     5  	"github.com/TeaOSLab/EdgeNode/internal/utils"
     6  	"github.com/iwind/TeaGo/Tea"
     7  	"github.com/iwind/TeaGo/files"
     8  	timeutil "github.com/iwind/TeaGo/utils/time"
     9  	"log"
    10  	"os"
    11  	"runtime"
    12  	"strconv"
    13  	"strings"
    14  )
    15  
    16  type LogWriter struct {
    17  	fp *os.File
    18  	c  chan string
    19  }
    20  
    21  func (this *LogWriter) Init() {
    22  	// 创建目录
    23  	var dir = files.NewFile(Tea.LogDir())
    24  	if !dir.Exists() {
    25  		err := dir.Mkdir()
    26  		if err != nil {
    27  			log.Println("[LOG]create log dir failed: " + err.Error())
    28  		}
    29  	}
    30  
    31  	// 打开要写入的日志文件
    32  	var logPath = Tea.LogFile("run.log")
    33  	fp, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    34  	if err != nil {
    35  		log.Println("[LOG]open log file failed: " + err.Error())
    36  	} else {
    37  		this.fp = fp
    38  	}
    39  
    40  	this.c = make(chan string, 1024)
    41  
    42  	// 异步写入文件
    43  	var maxFileSize int64 = 128 << 20 // 文件最大尺寸,超出此尺寸则清空
    44  	if fp != nil {
    45  		goman.New(func() {
    46  			var totalSize int64 = 0
    47  			stat, err := fp.Stat()
    48  			if err == nil {
    49  				totalSize = stat.Size()
    50  			}
    51  
    52  			for message := range this.c {
    53  				totalSize += int64(len(message))
    54  				_, err := fp.WriteString(timeutil.Format("Y/m/d H:i:s ") + message + "\n")
    55  				if err != nil {
    56  					log.Println("[LOG]write log failed: " + err.Error())
    57  				} else {
    58  					// 如果太大则Truncate
    59  					if totalSize > maxFileSize {
    60  						_ = fp.Truncate(0)
    61  						totalSize = 0
    62  					}
    63  				}
    64  			}
    65  		})
    66  	}
    67  }
    68  
    69  func (this *LogWriter) Write(message string) {
    70  	backgroundEnv, _ := os.LookupEnv("EdgeBackground")
    71  	if backgroundEnv != "on" {
    72  		// 文件和行号
    73  		var file string
    74  		var line int
    75  		if Tea.IsTesting() {
    76  			var callDepth = 3
    77  			var ok bool
    78  			_, file, line, ok = runtime.Caller(callDepth)
    79  			if ok {
    80  				file = utils.RemoveWorkspace(this.packagePath(file))
    81  			}
    82  		}
    83  
    84  		if len(file) > 0 {
    85  			log.Println(message + " (" + file + ":" + strconv.Itoa(line) + ")")
    86  		} else {
    87  			log.Println(message)
    88  		}
    89  	}
    90  
    91  	select {
    92  	case this.c <- message:
    93  	default:
    94  	}
    95  }
    96  
    97  func (this *LogWriter) Close() {
    98  	if this.fp != nil {
    99  		_ = this.fp.Close()
   100  	}
   101  
   102  	close(this.c)
   103  }
   104  
   105  func (this *LogWriter) packagePath(path string) string {
   106  	var pieces = strings.Split(path, "/")
   107  	if len(pieces) >= 2 {
   108  		return strings.Join(pieces[len(pieces)-2:], "/")
   109  	}
   110  	return path
   111  }