123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- 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"`
- locker 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 (log *File) SetLevel(lv int) {
- log.Level = lv
- }
- func (log *File) Prefix(s string) {
- log.prefix = s
- }
- func (log *File) Print(i ...interface{}) {
- log.write(TraceLevel, fmt.Sprint(i...))
- }
- func (log *File) Printf(format string, args ...interface{}) {
- log.write(TraceLevel, fmt.Sprintf(format, args...))
- }
- func (log *File) Debug(i ...interface{}) {
- log.write(DebugLevel, fmt.Sprint(i...))
- }
- func (log *File) Debugf(format string, args ...interface{}) {
- log.write(DebugLevel, fmt.Sprintf(format, args...))
- }
- func (log *File) Info(i ...interface{}) {
- log.write(InfoLevel, fmt.Sprint(i...))
- }
- func (log *File) Infof(format string, args ...interface{}) {
- log.write(InfoLevel, fmt.Sprintf(format, args...))
- }
- func (log *File) Warn(i ...interface{}) {
- log.write(WarnLevel, fmt.Sprint(i...))
- }
- func (log *File) Warnf(format string, args ...interface{}) {
- log.write(WarnLevel, fmt.Sprintf(format, args...))
- }
- func (log *File) Error(i ...interface{}) {
- log.write(ErrorLevel, fmt.Sprint(i...))
- }
- func (log *File) Errorf(format string, args ...interface{}) {
- log.write(ErrorLevel, fmt.Sprintf(format, args...))
- }
- func (log *File) Fatal(i ...interface{}) {
- log.write(FatalLevel, fmt.Sprint(i...))
- }
- func (log *File) Fatalf(format string, args ...interface{}) {
- log.write(FatalLevel, fmt.Sprintf(format, args...))
- }
- func (log *File) Panic(i ...interface{}) {
- log.write(PanicLevel, fmt.Sprint(i...))
- }
- func (log *File) Panicf(format string, args ...interface{}) {
- log.write(PanicLevel, fmt.Sprintf(format, args...))
- }
- func (log *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
- }
- func (log *File) write(level int, s string) {
- var (
- n int
- err error
- )
- if log.Level > level {
- return
- }
- log.locker.Lock()
- log.buf = log.buf[:0]
- if err = log.format(&log.buf, level, s); err != nil {
- log.locker.Unlock()
- return
- }
- log.buf = append(log.buf, '\n')
- if n, err = log.fp.Write(log.buf); err != nil {
- log.locker.Unlock()
- return
- }
- log.locker.Unlock()
- //write br
- log.size += int64(n)
- if log.MaxSize > 0 && log.size >= log.MaxSize {
- if err = log.rotate(); err != nil {
- return
- }
- log.size = 0
- }
- }
- func (log *File) isExists(filename string) bool {
- if _, err := os.Stat(filename); err == nil {
- return true
- } else {
- return false
- }
- }
- func (log *File) rotate() (err error) {
- log.locker.Lock()
- defer log.locker.Unlock()
- if err = log.close(); err != nil {
- return
- }
- for i := log.MaxLogFiles; i >= 0; i-- {
- filename := log.Filename
- if i > 0 {
- filename += "." + strconv.Itoa(i)
- }
- if i == log.MaxLogFiles {
- if log.isExists(filename) {
- if err = os.Remove(filename); err != nil {
- return
- }
- }
- } else {
- if log.isExists(filename) {
- if err = os.Rename(filename, log.Filename+"."+strconv.Itoa(i+1)); err != nil {
- return
- }
- }
- }
- }
- err = log.open()
- return
- }
- func (log *File) Reload() (err error) {
- log.locker.Lock()
- _ = log.close()
- err = log.open()
- log.locker.Unlock()
- return
- }
- func (log *File) open() (err error) {
- if log.fp, err = os.OpenFile(log.Filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600); err != nil {
- return
- }
- return
- }
- func (log *File) Open() (err error) {
- if err = log.open(); err != nil {
- return
- }
- if info, err := os.Stat(log.Filename); err == nil {
- log.size = info.Size()
- }
- return
- }
- func (log *File) close() (err error) {
- if log.fp != nil {
- err = log.fp.Close()
- }
- return
- }
- func (log *File) Close() (err error) {
- err = log.close()
- return
- }
- func NewFileLogger(filename string) *File {
- lg := &File{Filename: filename, buf: make([]byte, 1024)}
- return lg
- }
|