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  }