Ver Fonte

first commit

liuchangshun há 2 anos atrás
commit
3835395d56
3 ficheiros alterados com 310 adições e 0 exclusões
  1. 29 0
      .gitignore
  2. 3 0
      go.mod
  3. 278 0
      myLog.go

+ 29 - 0
.gitignore

@@ -0,0 +1,29 @@
+# ---> Go
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+.idea
+log
+myLog
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
+cs.go
+

+ 3 - 0
go.mod

@@ -0,0 +1,3 @@
+module mylog
+
+go 1.19

+ 278 - 0
myLog.go

@@ -0,0 +1,278 @@
+package tools
+
+import (
+	"fmt"
+	"os"
+	"runtime"
+	"strconv"
+	"time"
+)
+
+// 异步写日志
+
+var MyLog *FileLog
+
+const (
+	LogSplitTypeHour = iota
+	LogSplitTypeSize
+	logPath  = "myLog"
+	logName  = "myLog"
+	chanSize = 5000
+)
+
+type FileLog struct {
+	logPath       string
+	logName       string
+	file          *os.File //普通日志
+	warnFile      *os.File //错误日志 级别低
+	logDataChan   chan *LogData
+	logSplitType  int   //分割类型
+	logSplitSize  int64 //分割体积
+	lastSplitHour int   //分割时间
+}
+
+type LogData struct {
+	Message  string
+	TimeStr  string
+	LevelStr string
+	IsWarn   bool
+	File     string
+}
+
+func InitLog() (log *FileLog) {
+	config := make(map[string]string, 8)
+	config["log_path"] = "."
+	config["log_name"] = "server"
+	config["log_chan_size"] = "50000" //chan size 可以不用
+	config["log_split_type"] = "size"
+	config["log_split_size"] = strconv.Itoa(100 * 1024 * 1024) // 100MB
+	log, err := NewFileLog(config)
+	if err != nil {
+		panic("init log err")
+	}
+	MyLog = log
+	return log
+}
+
+func NewFileLog(config map[string]string) (logFile *FileLog, err error) {
+
+	var logSplitType = LogSplitTypeSize
+	var logSplitSize int64
+
+	splitType, ok := config["log_split_type"]
+	if !ok {
+		splitType = "hour"
+	} else {
+		if splitType == "size" {
+			splitSize, ok := config["log_split_size"]
+			if !ok {
+				splitSize = "104857600" //100M 以文字来讲很多了
+			}
+
+			logSplitSize, err = strconv.ParseInt(splitSize, 10, 64)
+			if err != nil {
+				logSplitSize = 104857600
+			}
+
+			logSplitType = LogSplitTypeSize
+		} else {
+			logSplitType = LogSplitTypeHour
+		}
+	}
+	//打开日志文件
+	exist, err := PathIsExists(logPath)
+	if err != nil {
+		fmt.Printf("get dir error![%v]\n", err)
+		return
+	}
+	if !exist {
+		err = os.Mkdir(logPath, os.ModePerm)
+		if err != nil {
+			fmt.Printf("mkdir failed![%v]\n", err)
+			return
+		} else {
+			fmt.Printf("mkdir success!\n")
+		}
+	}
+	//正常日志
+	fileName := fmt.Sprintf("%s/%s.log", logPath, logName)
+	file, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755)
+	//错误日志
+	fileNameWarn := fmt.Sprintf("%s/%s.log.err", logPath, logName)
+	fileWarn, err := os.OpenFile(fileNameWarn, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755)
+	if err != nil {
+		return
+	}
+	logFile = &FileLog{
+		logPath:       logPath,
+		logName:       logName,
+		logDataChan:   make(chan *LogData, chanSize),
+		file:          file,
+		warnFile:      fileWarn,
+		logSplitType:  logSplitType,
+		logSplitSize:  logSplitSize,
+		lastSplitHour: time.Now().Hour(),
+	}
+	go logFile.writeLogBackGround()
+	return
+}
+
+// 判断文件夹是否存在
+func PathIsExists(path string) (bool, error) {
+	_, err := os.Stat(path)
+	if err == nil {
+		return true, nil
+	}
+	if os.IsNotExist(err) {
+		return false, nil
+	}
+	return false, err
+}
+
+func (f *FileLog) Info(message string) {
+	_, file, line, _ := runtime.Caller(1)
+	fi := file + ":" + strconv.Itoa(line)
+	f.print(message, "info", fi)
+}
+func (f *FileLog) Debug(message string) {
+	_, file, line, _ := runtime.Caller(1)
+	fi := file + ":" + strconv.Itoa(line)
+	f.print(message, "debug", fi)
+}
+func (f *FileLog) Warn(message string) {
+	_, file, line, _ := runtime.Caller(1)
+	fi := file + ":" + strconv.Itoa(line)
+	f.print(message, "warn", fi)
+}
+func (f *FileLog) Error(message string) {
+	_, file, line, _ := runtime.Caller(1)
+	fi := file + ":" + strconv.Itoa(line)
+	f.print(message, "error", fi)
+}
+
+func (f *FileLog) print(message, Type string, file string) {
+	isWarn := false
+	if Type == "error" {
+		isWarn = true
+	}
+	msg := &LogData{
+		Message:  message,
+		TimeStr:  time.Now().Format("2006-01-02 15:04:05"),
+		LevelStr: Type,
+		IsWarn:   isWarn,
+		File:     file,
+	}
+	// 怕chan满了插不进去
+	select {
+	case f.logDataChan <- msg:
+	default:
+
+	}
+}
+
+func (f *FileLog) writeLogBackGround() {
+	for logData := range f.logDataChan {
+		var file = f.file
+		if logData.IsWarn {
+			file = f.warnFile
+		}
+
+		f.checkSplitFile(logData.IsWarn) // 检查文件分割类型
+		fmt.Fprintf(file, "%s %s %s %s\n", logData.TimeStr, logData.LevelStr, logData.Message, logData.File)
+	}
+}
+
+func (f *FileLog) checkSplitFile(isWarn bool) {
+	if f.logSplitType == LogSplitTypeHour {
+		f.splitHour(isWarn)
+		return
+	}
+	f.splitSize(isWarn)
+}
+
+// 根据时间切割
+func (f *FileLog) splitHour(isWarn bool) {
+
+	now := time.Now()
+	hour := now.Hour()
+
+	if hour == f.lastSplitHour {
+		return
+	}
+
+	f.lastSplitHour = hour
+
+	var backupFileName string
+	var fileName string
+
+	if isWarn {
+		backupFileName = fmt.Sprintf("%s/%s.log.err_%s", f.logPath, f.logName, now.Format("20060102150405"))
+		fileName = fmt.Sprintf("%s/%s.log.err", f.logPath, f.logName)
+	} else {
+		backupFileName = fmt.Sprintf("%s/%s.log_%s", f.logPath, f.logName, now.Format("20060102150405"))
+		fileName = fmt.Sprintf("%s/%s.log", f.logPath, f.logName)
+	}
+
+	file := f.file
+	if isWarn {
+		file = f.warnFile
+	}
+	file.Close()
+	os.Rename(fileName, backupFileName)
+
+	file, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755)
+	if err != nil {
+		return
+	}
+
+	if isWarn {
+		f.warnFile = file
+	} else {
+		f.file = file
+	}
+
+}
+
+// 根据文件大小来分割
+func (f *FileLog) splitSize(isWarn bool) {
+	file := f.file
+	if isWarn {
+		file = f.warnFile
+	}
+	fileInfo, err := file.Stat() // 可以得到文件的参数
+	if err != nil {
+		return
+	}
+
+	fileSize := fileInfo.Size()
+	if fileSize <= f.logSplitSize {
+		return
+	}
+
+	var backupFileName string
+	var fileName string
+
+	now := time.Now()
+
+	if isWarn {
+		backupFileName = fmt.Sprintf("%s/%s.log_%s", f.logPath, f.logName, now.Format("20060102150405"))
+		fileName = fmt.Sprintf("%s/%s.log", f.logPath, f.logName)
+	} else {
+		backupFileName = fmt.Sprintf("%s/%s.log.err_%s", f.logPath, f.logName, now.Format("20060102150405"))
+		fileName = fmt.Sprintf("%s/%s.log.err", f.logPath, f.logName)
+	}
+
+	file.Close()
+	os.Rename(fileName, backupFileName)
+
+	file, err = os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755)
+	if err != nil {
+		return
+	}
+
+	if isWarn {
+		f.warnFile = file
+	} else {
+		f.file = file
+	}
+}