filewriter.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package log
  2. import (
  3. "io"
  4. "os"
  5. "path/filepath"
  6. "sync"
  7. "time"
  8. )
  9. var _ io.Writer = &Files{}
  10. type ByType int
  11. const (
  12. ByDay ByType = iota
  13. ByHour
  14. ByMonth
  15. )
  16. var (
  17. formats = map[ByType]string{
  18. ByDay: "2006-01-02",
  19. ByHour: "2006-01-02-15",
  20. ByMonth: "2006-01",
  21. }
  22. )
  23. func SetFileFormat(t ByType, format string) {
  24. formats[t] = format
  25. }
  26. func (b ByType) Format() string {
  27. return formats[b]
  28. }
  29. type Files struct {
  30. FileOptions
  31. f *os.File
  32. lastFormat string
  33. lock sync.Mutex
  34. }
  35. type FileOptions struct {
  36. Dir string
  37. ByType ByType
  38. Loc *time.Location
  39. }
  40. func prepareFileOption(opts []FileOptions) FileOptions {
  41. var opt FileOptions
  42. if len(opts) > 0 {
  43. opt = opts[0]
  44. }
  45. if opt.Dir == "" {
  46. opt.Dir = "./"
  47. }
  48. err := os.MkdirAll(opt.Dir, os.ModePerm)
  49. if err != nil {
  50. panic(err.Error())
  51. }
  52. if opt.Loc == nil {
  53. opt.Loc = time.Local
  54. }
  55. return opt
  56. }
  57. func NewFileWriter(opts ...FileOptions) *Files {
  58. opt := prepareFileOption(opts)
  59. return &Files{
  60. FileOptions: opt,
  61. }
  62. }
  63. func (f *Files) getFile() (*os.File, error) {
  64. var err error
  65. t := time.Now().In(f.Loc)
  66. if f.f == nil {
  67. f.lastFormat = t.Format(f.ByType.Format())
  68. f.f, err = os.OpenFile(filepath.Join(f.Dir, f.lastFormat+".log"),
  69. os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
  70. return f.f, err
  71. }
  72. if f.lastFormat != t.Format(f.ByType.Format()) {
  73. f.f.Close()
  74. f.lastFormat = t.Format(f.ByType.Format())
  75. f.f, err = os.OpenFile(filepath.Join(f.Dir, f.lastFormat+".log"),
  76. os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
  77. return f.f, err
  78. }
  79. return f.f, nil
  80. }
  81. func (f *Files) Write(bs []byte) (int, error) {
  82. f.lock.Lock()
  83. defer f.lock.Unlock()
  84. w, err := f.getFile()
  85. if err != nil {
  86. return 0, err
  87. }
  88. return w.Write(bs)
  89. }
  90. func (f *Files) Close() {
  91. if f.f != nil {
  92. f.f.Close()
  93. f.f = nil
  94. }
  95. f.lastFormat = ""
  96. }