123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- package log
- import (
- "fmt"
- "os"
- "strconv"
- "sync"
- "time"
- )
- type File struct {
- Filename string `json:"filename"`
- MaxSize int64 `json:"max_size"`
- MaxLogFiles int `json:"max_log_files"`
- Format string `json:"format"`
- Level int `json:"level"`
- mutex sync.RWMutex
- buf []byte
- fp *os.File
- prefix string
- size int64
- }
- func itoa(buf *[]byte, i int, wid int) {
- // Assemble decimal in reverse order.
- var b [20]byte
- bp := len(b) - 1
- for i >= 10 || wid > 1 {
- wid--
- q := i / 10
- b[bp] = byte('0' + i - q*10)
- bp--
- i = q
- }
- // i < 10
- b[bp] = byte('0' + i)
- *buf = append(*buf, b[bp:]...)
- }
- func (lg *File) SetLevel(lv int) {
- lg.Level = lv
- }
- func (lg *File) Prefix(s string) {
- lg.prefix = s
- }
- func (lg *File) Print(i ...interface{}) {
- lg.write(TraceLevel, fmt.Sprint(i...))
- }
- func (lg *File) Printf(format string, args ...interface{}) {
- lg.write(TraceLevel, fmt.Sprintf(format, args...))
- }
- func (lg *File) Debug(i ...interface{}) {
- lg.write(DebugLevel, fmt.Sprint(i...))
- }
- func (lg *File) Debugf(format string, args ...interface{}) {
- lg.write(DebugLevel, fmt.Sprintf(format, args...))
- }
- func (lg *File) Info(i ...interface{}) {
- lg.write(InfoLevel, fmt.Sprint(i...))
- }
- func (lg *File) Infof(format string, args ...interface{}) {
- lg.write(InfoLevel, fmt.Sprintf(format, args...))
- }
- func (lg *File) Warn(i ...interface{}) {
- lg.write(WarnLevel, fmt.Sprint(i...))
- }
- func (lg *File) Warnf(format string, args ...interface{}) {
- lg.write(WarnLevel, fmt.Sprintf(format, args...))
- }
- func (lg *File) Error(i ...interface{}) {
- lg.write(ErrorLevel, fmt.Sprint(i...))
- }
- func (lg *File) Errorf(format string, args ...interface{}) {
- lg.write(ErrorLevel, fmt.Sprintf(format, args...))
- }
- func (lg *File) Fatal(i ...interface{}) {
- lg.write(FatalLevel, fmt.Sprint(i...))
- }
- func (lg *File) Fatalf(format string, args ...interface{}) {
- lg.write(FatalLevel, fmt.Sprintf(format, args...))
- }
- func (lg *File) Panic(i ...interface{}) {
- lg.write(PanicLevel, fmt.Sprint(i...))
- }
- func (lg *File) Panicf(format string, args ...interface{}) {
- lg.write(PanicLevel, fmt.Sprintf(format, args...))
- }
- func (lg *File) format(buf *[]byte, level int, s string) (err error) {
- t := time.Now()
- year, month, day := t.Date()
- itoa(buf, year, 4)
- *buf = append(*buf, '-')
- itoa(buf, int(month), 2)
- *buf = append(*buf, '-')
- itoa(buf, day, 2)
- *buf = append(*buf, ' ')
- hour, min, sec := t.Clock()
- itoa(buf, hour, 2)
- *buf = append(*buf, ':')
- itoa(buf, min, 2)
- *buf = append(*buf, ':')
- itoa(buf, sec, 2)
- *buf = append(*buf, ' ')
- *buf = append(*buf, '[')
- *buf = append(*buf, getLevelText(level)...)
- *buf = append(*buf, ']')
- *buf = append(*buf, ' ')
- *buf = append(*buf, s...)
- return
- }
- // Write 实现标准的写入行数
- func (lg *File) Write(p []byte) (n int, err error) {
- lg.mutex.Lock()
- defer lg.mutex.Unlock()
- if n, err = lg.fp.Write(p); err != nil {
- return
- }
- lg.size += int64(n)
- if lg.MaxSize > 0 && lg.size >= lg.MaxSize {
- if err = lg.rotate(); err != nil {
- return
- }
- lg.size = 0
- }
- return
- }
- func (lg *File) write(level int, s string) {
- var (
- n int
- err error
- )
- if lg.Level > level {
- return
- }
- lg.mutex.Lock()
- defer lg.mutex.Unlock()
- lg.buf = lg.buf[:0]
- if err = lg.format(&lg.buf, level, s); err != nil {
- return
- }
- lg.buf = append(lg.buf, '\n')
- if n, err = lg.fp.Write(lg.buf); err != nil {
- return
- }
- lg.size += int64(n)
- if lg.MaxSize > 0 && lg.size >= lg.MaxSize {
- if err = lg.rotate(); err != nil {
- return
- }
- lg.size = 0
- }
- }
- func (lg *File) isExists(filename string) bool {
- if _, err := os.Stat(filename); err == nil {
- return true
- } else {
- return false
- }
- }
- // rotate 实现日志滚动处理
- func (lg *File) rotate() (err error) {
- if err = lg.close(); err != nil {
- return
- }
- for i := lg.MaxLogFiles; i >= 0; i-- {
- filename := lg.Filename
- if i > 0 {
- filename += "." + strconv.Itoa(i)
- }
- if i == lg.MaxLogFiles {
- if lg.isExists(filename) {
- if err = os.Remove(filename); err != nil {
- return
- }
- }
- } else {
- if lg.isExists(filename) {
- if err = os.Rename(filename, lg.Filename+"."+strconv.Itoa(i+1)); err != nil {
- return
- }
- }
- }
- }
- err = lg.open()
- return
- }
- func (lg *File) Reload() (err error) {
- lg.mutex.Lock()
- defer lg.mutex.Unlock()
- _ = lg.close()
- err = lg.open()
- return
- }
- func (lg *File) open() (err error) {
- if lg.fp, err = os.OpenFile(lg.Filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600); err != nil {
- return
- }
- return
- }
- func (lg *File) Open() (err error) {
- var (
- info os.FileInfo
- )
- if err = lg.open(); err != nil {
- return
- }
- if info, err = os.Stat(lg.Filename); err == nil {
- lg.size = info.Size()
- }
- return
- }
- func (lg *File) close() (err error) {
- if lg.fp != nil {
- err = lg.fp.Close()
- }
- return
- }
- func (lg *File) Close() (err error) {
- err = lg.close()
- return
- }
- func NewFileLogger(filename string) *File {
- lg := &File{Filename: filename, buf: make([]byte, 1024)}
- return lg
- }
|