关于日志

1 使用go自带的log函数存储日志

参考资料:https://golang.org/pkg/log/

package main

import (
	"io"
	"log"
	"os"
)

func setLogFile(filename string) error {
	f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return err
	}
	log.SetOutput(io.MultiWriter(os.Stdout, f))
	return nil
}

func main() {
	err := setLogFile("./a.log")
	if err != nil {
		panic(err)
	}
	log.Println(1234)
	log.Println(map[string]string{
		"a": "asdf",
	})
}

2.使用第三方的插件库存储日志

地址:https://github.com/donnie4w/go-logger

func setLog(err error) error{
	logger.SetRollingDaily(`./logs`, "dataerror.log")	//备份日志以日期切割
	logger.SetLevel(logger.INFO)										//日志级别
	//存放日志
	var lg = logger.GetLogger()
	lg.SetLevelFile(logger.ERROR, `./logs/`, "error.log")
	lg.Error(err)
	return nil
}

3.自定义的日志  

package nlog

import (
	"bufio"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"
)

const BUFFIO_SIZE = 4096
const AUTO_RESET_TIME = 2 * time.Second

var CST = time.FixedZone("CST", 28800)

type ErrorCB func(err error)

type LogFile struct {
	mu             sync.Mutex
	f              *os.File
	bw             *bufio.Writer
	isClosed       bool
	filename       string
	filenameFormat string
	errorCB        ErrorCB
}

/*
	const filenameFormat = "./logs/error/2006-01-02_15_04.error.log"
	log, err := nlog.NewLogFile(filenameFormat, func(err error) {
		// 处理在后台自动写数据和生成新文件时的错误
		fmt.Println("err:", err)
	})
	panicif(err)
	log.Println('a', true, time.Now())
*/
func NewLogFile(filenameFormat string, errorCB ErrorCB) (*LogFile, error) {
	var o = &LogFile{
		filenameFormat: filenameFormat,
		errorCB:        errorCB,
	}
	var err = o.reset()
	if err != nil {
		return nil, err
	}
	o.autoReset()
	return o, nil
}

func (ths *LogFile) autoReset() {
	go func() {
		var ticker = time.NewTicker(AUTO_RESET_TIME)
		defer ticker.Stop()
		for {
			<-ticker.C
			if !ths.isClosed {
				var err = ths.reset()
				if ths.errorCB != nil && err != nil {
					ths.errorCB(err)
				}
			}
		}
	}()
}

func (ths *LogFile) reset() error {
	ths.mu.Lock()
	defer ths.mu.Unlock()

	var t = time.Now().In(CST)
	var filename = t.Format(ths.filenameFormat)
	_, err := os.Stat(filename)
	if os.IsNotExist(err) {
		// 如果文件被删除,重新生成文件
		ths.filename = ""
	}

	// 判断是否需要重新生成文件
	if ths.f == nil || ths.filename != filename {
		if ths.f != nil {
			if err := ths.close(); err != nil {
				return err
			}
		}
		var err = os.MkdirAll(filepath.Dir(filename), 0777)
		if err != nil {
			return err
		}
		f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
		if err != nil {
			return err
		}
		ths.isClosed = false
		ths.filename = filename
		ths.f = f
		ths.bw = bufio.NewWriterSize(f, BUFFIO_SIZE)
	} else {
		if err := ths.bw.Flush(); err != nil {
			return err
		}
	}
	return nil
}

func (ths *LogFile) Printfln(format string, v ...interface{}) (n int, err error) {
	ths.mu.Lock()
	defer ths.mu.Unlock()
	return ths.write(fmt.Sprintf(format, v...))
}

func (ths *LogFile) Println(v ...interface{}) (n int, err error) {
	ths.mu.Lock()
	defer ths.mu.Unlock()
	return ths.write(fmt.Sprint(v...))
}

func (ths *LogFile) write(s string) (n int, err error) {
	if ths.isClosed {
		return 0, errors.New("LogFile is closed: " + ths.filename)
	}
	s = strings.Replace(s, "\r", "#", -1)
	s = strings.Replace(s, "\n", "#", -1)
	return ths.bw.WriteString(s + "\r\n")
}

func (ths *LogFile) Close() error {
	ths.mu.Lock()
	defer ths.mu.Unlock()
	return ths.close()
}

func (ths *LogFile) close() error {
	if ths.isClosed {
		return nil
	}
	ths.isClosed = true
	if err := ths.bw.Flush(); err != nil {
		ths.f.Close()
		return err
	}
	return ths.f.Close()
}

猜你喜欢

转载自www.cnblogs.com/8013-cmf/p/10025669.html