|
@@ -1,278 +0,0 @@
|
|
|
-package main
|
|
|
-
|
|
|
-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
|
|
|
- }
|
|
|
-}
|