file.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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. mutex 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 (lg *File) SetLevel(lv int) {
  37. lg.Level = lv
  38. }
  39. func (lg *File) Prefix(s string) {
  40. lg.prefix = s
  41. }
  42. func (lg *File) Print(i ...interface{}) {
  43. lg.write(TraceLevel, fmt.Sprint(i...))
  44. }
  45. func (lg *File) Printf(format string, args ...interface{}) {
  46. lg.write(TraceLevel, fmt.Sprintf(format, args...))
  47. }
  48. func (lg *File) Debug(i ...interface{}) {
  49. lg.write(DebugLevel, fmt.Sprint(i...))
  50. }
  51. func (lg *File) Debugf(format string, args ...interface{}) {
  52. lg.write(DebugLevel, fmt.Sprintf(format, args...))
  53. }
  54. func (lg *File) Info(i ...interface{}) {
  55. lg.write(InfoLevel, fmt.Sprint(i...))
  56. }
  57. func (lg *File) Infof(format string, args ...interface{}) {
  58. lg.write(InfoLevel, fmt.Sprintf(format, args...))
  59. }
  60. func (lg *File) Warn(i ...interface{}) {
  61. lg.write(WarnLevel, fmt.Sprint(i...))
  62. }
  63. func (lg *File) Warnf(format string, args ...interface{}) {
  64. lg.write(WarnLevel, fmt.Sprintf(format, args...))
  65. }
  66. func (lg *File) Error(i ...interface{}) {
  67. lg.write(ErrorLevel, fmt.Sprint(i...))
  68. }
  69. func (lg *File) Errorf(format string, args ...interface{}) {
  70. lg.write(ErrorLevel, fmt.Sprintf(format, args...))
  71. }
  72. func (lg *File) Fatal(i ...interface{}) {
  73. lg.write(FatalLevel, fmt.Sprint(i...))
  74. }
  75. func (lg *File) Fatalf(format string, args ...interface{}) {
  76. lg.write(FatalLevel, fmt.Sprintf(format, args...))
  77. }
  78. func (lg *File) Panic(i ...interface{}) {
  79. lg.write(PanicLevel, fmt.Sprint(i...))
  80. }
  81. func (lg *File) Panicf(format string, args ...interface{}) {
  82. lg.write(PanicLevel, fmt.Sprintf(format, args...))
  83. }
  84. func (lg *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. //Write 实现标准的写入行数
  108. func (lg *File) Write(p []byte) (n int, err error) {
  109. lg.mutex.Lock()
  110. if n, err = lg.fp.Write(p); err == nil {
  111. lg.mutex.Unlock()
  112. lg.size += int64(n)
  113. if lg.MaxSize > 0 && lg.size >= lg.MaxSize {
  114. if err = lg.rotate(); err != nil {
  115. return
  116. }
  117. lg.size = 0
  118. }
  119. } else {
  120. lg.mutex.Unlock()
  121. }
  122. return
  123. }
  124. func (lg *File) write(level int, s string) {
  125. var (
  126. n int
  127. err error
  128. )
  129. if lg.Level > level {
  130. return
  131. }
  132. lg.mutex.Lock()
  133. lg.buf = lg.buf[:0]
  134. if err = lg.format(&lg.buf, level, s); err != nil {
  135. lg.mutex.Unlock()
  136. return
  137. }
  138. lg.buf = append(lg.buf, '\n')
  139. if n, err = lg.fp.Write(lg.buf); err != nil {
  140. lg.mutex.Unlock()
  141. return
  142. }
  143. lg.mutex.Unlock()
  144. //write br
  145. lg.size += int64(n)
  146. if lg.MaxSize > 0 && lg.size >= lg.MaxSize {
  147. if err = lg.rotate(); err != nil {
  148. return
  149. }
  150. lg.size = 0
  151. }
  152. }
  153. func (lg *File) isExists(filename string) bool {
  154. if _, err := os.Stat(filename); err == nil {
  155. return true
  156. } else {
  157. return false
  158. }
  159. }
  160. //rotate 实现日志滚动处理
  161. func (lg *File) rotate() (err error) {
  162. lg.mutex.Lock()
  163. defer lg.mutex.Unlock()
  164. if err = lg.close(); err != nil {
  165. return
  166. }
  167. for i := lg.MaxLogFiles; i >= 0; i-- {
  168. filename := lg.Filename
  169. if i > 0 {
  170. filename += "." + strconv.Itoa(i)
  171. }
  172. if i == lg.MaxLogFiles {
  173. if lg.isExists(filename) {
  174. if err = os.Remove(filename); err != nil {
  175. return
  176. }
  177. }
  178. } else {
  179. if lg.isExists(filename) {
  180. if err = os.Rename(filename, lg.Filename+"."+strconv.Itoa(i+1)); err != nil {
  181. return
  182. }
  183. }
  184. }
  185. }
  186. err = lg.open()
  187. return
  188. }
  189. func (lg *File) Reload() (err error) {
  190. lg.mutex.Lock()
  191. _ = lg.close()
  192. err = lg.open()
  193. lg.mutex.Unlock()
  194. return
  195. }
  196. func (lg *File) open() (err error) {
  197. if lg.fp, err = os.OpenFile(lg.Filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600); err != nil {
  198. return
  199. }
  200. return
  201. }
  202. func (lg *File) Open() (err error) {
  203. var (
  204. info os.FileInfo
  205. )
  206. if err = lg.open(); err != nil {
  207. return
  208. }
  209. if info, err = os.Stat(lg.Filename); err == nil {
  210. lg.size = info.Size()
  211. }
  212. return
  213. }
  214. func (lg *File) close() (err error) {
  215. if lg.fp != nil {
  216. err = lg.fp.Close()
  217. }
  218. return
  219. }
  220. func (lg *File) Close() (err error) {
  221. err = lg.close()
  222. return
  223. }
  224. func NewFileLogger(filename string) *File {
  225. lg := &File{Filename: filename, buf: make([]byte, 1024)}
  226. return lg
  227. }