123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- package lxlog
- 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
- }
- // _ = tools.InitLog()
- 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(1024 * 1024 * 1024) // 1g
- 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.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.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
- }
- }
|