github.com/sereiner/library@v0.0.0-20200518095232-1fa3e640cc5f/log/manager.go (about) 1 package log 2 3 import ( 4 "errors" 5 "sync" 6 "time" 7 8 "github.com/sereiner/library/concurrent/cmap" 9 ) 10 11 var isOpen bool 12 13 type ILoggerAppenderFactory interface { 14 MakeAppender(*Appender, *LogEvent) (IAppender, error) 15 MakeUniq(*Appender, *LogEvent) string 16 } 17 18 type loggerManager struct { 19 appenders cmap.ConcurrentMap 20 factory ILoggerAppenderFactory 21 configs []*Appender 22 ticker *time.Ticker 23 lock sync.RWMutex 24 isClose bool 25 } 26 type appenderEntity struct { 27 appender IAppender 28 last time.Time 29 } 30 31 func newLoggerManager() (m *loggerManager, err error) { 32 m = &loggerManager{isClose: false} 33 m.factory = &loggerAppenderFactory{} 34 m.appenders = cmap.New(2) 35 m.configs = ReadConfig() 36 isOpen = len(m.configs) > 0 37 if isOpen { 38 m.ticker = time.NewTicker(time.Second * 300) 39 go m.clearUp() 40 return m, nil 41 } 42 return nil, errors.New("未启动日志") 43 } 44 func (a *loggerManager) append(app *Appender) { 45 a.lock.Lock() 46 defer a.lock.Unlock() 47 for _, v := range a.configs { 48 if v.Type == app.Type { 49 return 50 } 51 } 52 a.configs = append(a.configs, app) 53 } 54 func (a *loggerManager) remote(t string) { 55 a.lock.Lock() 56 defer a.lock.Unlock() 57 for i, v := range a.configs { 58 if v.Type == t { 59 a.configs = append(a.configs[:i], a.configs[i+1]) 60 } 61 } 62 } 63 64 // Log 将日志内容写入appender, 如果appender不存在则创建 65 // callBack回调函数,如果不需要传nil 66 func (a *loggerManager) Log(event *LogEvent) { 67 if a.isClose { 68 return 69 } 70 a.lock.RLock() 71 defer a.lock.RUnlock() 72 for _, config := range a.configs { 73 uniq := a.factory.MakeUniq(config, event) 74 _, currentAppender, err := a.appenders.SetIfAbsentCb(uniq, func(p ...interface{}) (entity interface{}, err error) { 75 l := p[0].(*Appender) 76 app, err := a.factory.MakeAppender(l, event) 77 if err != nil { 78 return 79 } 80 entity = &appenderEntity{appender: app, last: time.Now()} 81 return 82 }, config) 83 if err == nil { 84 capp := currentAppender.(*appenderEntity) 85 a.write(capp, config.Layout, event) 86 } else { 87 sysLoggerError(err) 88 } 89 } 90 } 91 func (a *loggerManager) write(capp *appenderEntity, format string, event *LogEvent) { 92 defer func() { 93 if r := recover(); r != nil { 94 sysLoggerError(r) 95 } 96 }() 97 capp.last = time.Now() 98 event.Output = transform(format, event) 99 capp.appender.Write(event) 100 } 101 func (a *loggerManager) clearUp() { 102 START: 103 for { 104 select { 105 case _, ok := <-a.ticker.C: 106 if ok { 107 count := a.appenders.RemoveIterCb(func(key string, v interface{}) bool { 108 apd := v.(*appenderEntity) 109 if time.Now().Sub(apd.last).Seconds() > 10 { 110 apd.appender.Close() 111 return true 112 } 113 return false 114 }) 115 if count > 0 { 116 //sysLoggerInfo("已移除:", count) 117 } 118 } else { 119 break START 120 } 121 } 122 } 123 } 124 125 func (a *loggerManager) Close() { 126 a.isClose = true 127 if a.ticker != nil { 128 a.ticker.Stop() 129 } 130 131 a.appenders.RemoveIterCb(func(key string, v interface{}) bool { 132 apd := v.(*appenderEntity) 133 apd.appender.Close() 134 return true 135 }) 136 }