file.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. package log
  2. import (
  3. "fmt"
  4. "os"
  5. "strconv"
  6. "sync"
  7. "time"
  8. )
  9. type File struct {
  10. Filename string `json:"filename"`
  11. MaxSize int64 `json:"max_size"`
  12. MaxLogFiles int `json:"max_log_files"`
  13. Format string `json:"format"`
  14. Level int `json:"level"`
  15. locker sync.RWMutex
  16. buf []byte
  17. fp *os.File
  18. prefix string
  19. size int64
  20. }
  21. func itoa(buf *[]byte, i int, wid int) {
  22. // Assemble decimal in reverse order.
  23. var b [20]byte
  24. bp := len(b) - 1
  25. for i >= 10 || wid > 1 {
  26. wid--
  27. q := i / 10
  28. b[bp] = byte('0' + i - q*10)
  29. bp--
  30. i = q
  31. }
  32. // i < 10
  33. b[bp] = byte('0' + i)
  34. *buf = append(*buf, b[bp:]...)
  35. }
  36. func (log *File) SetLevel(lv int) {
  37. log.Level = lv
  38. }
  39. func (log *File) Prefix(s string) {
  40. log.prefix = s
  41. }
  42. func (log *File) Print(i ...interface{}) {
  43. log.write(TraceLevel, fmt.Sprint(i...))
  44. }
  45. func (log *File) Printf(format string, args ...interface{}) {
  46. log.write(TraceLevel, fmt.Sprintf(format, args...))
  47. }
  48. func (log *File) Debug(i ...interface{}) {
  49. log.write(DebugLevel, fmt.Sprint(i...))
  50. }
  51. func (log *File) Debugf(format string, args ...interface{}) {
  52. log.write(DebugLevel, fmt.Sprintf(format, args...))
  53. }
  54. func (log *File) Info(i ...interface{}) {
  55. log.write(InfoLevel, fmt.Sprint(i...))
  56. }
  57. func (log *File) Infof(format string, args ...interface{}) {
  58. log.write(InfoLevel, fmt.Sprintf(format, args...))
  59. }
  60. func (log *File) Warn(i ...interface{}) {
  61. log.write(WarnLevel, fmt.Sprint(i...))
  62. }
  63. func (log *File) Warnf(format string, args ...interface{}) {
  64. log.write(WarnLevel, fmt.Sprintf(format, args...))
  65. }
  66. func (log *File) Error(i ...interface{}) {
  67. log.write(ErrorLevel, fmt.Sprint(i...))
  68. }
  69. func (log *File) Errorf(format string, args ...interface{}) {
  70. log.write(ErrorLevel, fmt.Sprintf(format, args...))
  71. }
  72. func (log *File) Fatal(i ...interface{}) {
  73. log.write(FatalLevel, fmt.Sprint(i...))
  74. }
  75. func (log *File) Fatalf(format string, args ...interface{}) {
  76. log.write(FatalLevel, fmt.Sprintf(format, args...))
  77. }
  78. func (log *File) Panic(i ...interface{}) {
  79. log.write(PanicLevel, fmt.Sprint(i...))
  80. }
  81. func (log *File) Panicf(format string, args ...interface{}) {
  82. log.write(PanicLevel, fmt.Sprintf(format, args...))
  83. }
  84. func (log *File) format(buf *[]byte, level int, s string) (err error) {
  85. t := time.Now()
  86. year, month, day := t.Date()
  87. itoa(buf, year, 4)
  88. *buf = append(*buf, '-')
  89. itoa(buf, int(month), 2)
  90. *buf = append(*buf, '-')
  91. itoa(buf, day, 2)
  92. *buf = append(*buf, ' ')
  93. hour, min, sec := t.Clock()
  94. itoa(buf, hour, 2)
  95. *buf = append(*buf, ':')
  96. itoa(buf, min, 2)
  97. *buf = append(*buf, ':')
  98. itoa(buf, sec, 2)
  99. *buf = append(*buf, ' ')
  100. *buf = append(*buf, '[')
  101. *buf = append(*buf, getLevelText(level)...)
  102. *buf = append(*buf, ']')
  103. *buf = append(*buf, ' ')
  104. *buf = append(*buf, s...)
  105. return
  106. }
  107. func (log *File) write(level int, s string) {
  108. var (
  109. n int
  110. err error
  111. )
  112. if log.Level > level {
  113. return
  114. }
  115. log.locker.Lock()
  116. log.buf = log.buf[:0]
  117. if err = log.format(&log.buf, level, s); err != nil {
  118. log.locker.Unlock()
  119. return
  120. }
  121. log.buf = append(log.buf, '\n')
  122. if n, err = log.fp.Write(log.buf); err != nil {
  123. log.locker.Unlock()
  124. return
  125. }
  126. log.locker.Unlock()
  127. //write br
  128. log.size += int64(n)
  129. if log.MaxSize > 0 && log.size >= log.MaxSize {
  130. if err = log.rotate(); err != nil {
  131. return
  132. }
  133. log.size = 0
  134. }
  135. }
  136. func (log *File) isExists(filename string) bool {
  137. if _, err := os.Stat(filename); err == nil {
  138. return true
  139. } else {
  140. return false
  141. }
  142. }
  143. func (log *File) rotate() (err error) {
  144. log.locker.Lock()
  145. defer log.locker.Unlock()
  146. if err = log.close(); err != nil {
  147. return
  148. }
  149. for i := log.MaxLogFiles; i >= 0; i-- {
  150. filename := log.Filename
  151. if i > 0 {
  152. filename += "." + strconv.Itoa(i)
  153. }
  154. if i == log.MaxLogFiles {
  155. if log.isExists(filename) {
  156. if err = os.Remove(filename); err != nil {
  157. return
  158. }
  159. }
  160. } else {
  161. if log.isExists(filename) {
  162. if err = os.Rename(filename, log.Filename+"."+strconv.Itoa(i+1)); err != nil {
  163. return
  164. }
  165. }
  166. }
  167. }
  168. err = log.open()
  169. return
  170. }
  171. func (log *File) Reload() (err error) {
  172. log.locker.Lock()
  173. _ = log.close()
  174. err = log.open()
  175. log.locker.Unlock()
  176. return
  177. }
  178. func (log *File) open() (err error) {
  179. if log.fp, err = os.OpenFile(log.Filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600); err != nil {
  180. return
  181. }
  182. return
  183. }
  184. func (log *File) Open() (err error) {
  185. if err = log.open(); err != nil {
  186. return
  187. }
  188. if info, err := os.Stat(log.Filename); err == nil {
  189. log.size = info.Size()
  190. }
  191. return
  192. }
  193. func (log *File) close() (err error) {
  194. if log.fp != nil {
  195. err = log.fp.Close()
  196. }
  197. return
  198. }
  199. func (log *File) Close() (err error) {
  200. err = log.close()
  201. return
  202. }
  203. func NewFileLogger(filename string) *File {
  204. lg := &File{Filename: filename, buf: make([]byte, 1024)}
  205. return lg
  206. }