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 }