func (l *LogManager) Fatalx(logID, format string, a ...interface{}) (err error) {
	l.lock.RLock()
	defer l.lock.RUnlock()
	for _, v := range l.loggers {
		if v.logger == nil || !v.enable {
			continue
		}
		v.logger.Fatalx(logID, format, a...)
	}
	return
}
Fatalx implements XLogger
package xlog
import (
	"errors"
	"fmt"
	"sync"
)
type LogInstance struct {
	logger  XLogger
	enable  bool
	initial bool
	source  string
}
type LogManager struct {
	loggers map[string]*LogInstance
	lock    sync.RWMutex
}
func CreateLogManager(name string, config map[string]string, source ...string) (*LogManager, error) {
	mgr := &LogManager{
		loggers: make(map[string]*LogInstance),
	}
	if err := mgr.Init(name, config, source...); err != nil {
		return nil, err
	}
	return mgr, nil
}
func (l *LogManager) Init(name string, config map[string]string, source ...string) (err error) {
	if err := l.RegisterLogger("console", NewXConsoleLog()); err != nil {
		return err
	}
	if err := l.RegisterLogger("file", NewXFileLog()); err != nil {
		return err
	}
	err = l.initLogger(name, config)
	for _, v := range l.loggers {
		if v.logger == nil || !v.enable {
			continue
		}
		if v.source == "auto" {
			v.enable = false
		}
	}
	return
}
func (l *LogManager) initLogger(name string, config map[string]string, source ...string) (err error) {
	l.lock.Lock()
	defer l.lock.Unlock()
	instance, ok := l.loggers[name]
	if !ok {
		err = fmt.Errorf("not found logger[%s]", name)
		return
	}
	err = instance.logger.Init(config)
	if err != nil {
		return
	}
	if len(source) > 0 {
		instance.source = source[0]
	} else {
		instance.source = ""
	}
	instance.enable = true
	instance.initial = true
	return
}
func (l *LogManager) RegisterLogger(name string, logger XLogger) (err error) {
	l.lock.Lock()
	defer l.lock.Unlock()
	_, ok := l.loggers[name]
	if ok {
		err = fmt.Errorf("duplicate logger[%s]", name)
		return
	}
	l.loggers[name] = &LogInstance{
		logger:  logger,
		enable:  false,
		initial: false,
	}
	return
}
func (l *LogManager) UnregisterLogger(name string) (err error) {
	l.lock.Lock()
	defer l.lock.Unlock()
	v, ok := l.loggers[name]
	if !ok {
		err = fmt.Errorf("not found logger[%s]", name)
		return
	}
	if v != nil {
		v.logger.Close()
	}
	delete(l.loggers, name)
	return
}
func (l *LogManager) EnableLogger(name string, enable bool) (err error) {
	l.lock.Lock()
	defer l.lock.Unlock()
	instance, ok := l.loggers[name]
	if !ok {
		err = fmt.Errorf("not found logger[%s]", name)
		return
	}
	if !instance.initial {
		instance.enable = false
		return
	}
	instance.enable = enable
	return
}
func (l *LogManager) GetLogger(name string) (logger XLogger, err error) {
	l.lock.RLock()
	defer l.lock.RUnlock()
	instance, ok := l.loggers[name]
	if !ok {
		err = fmt.Errorf("not found logger[%s]", name)
		return
	}
	logger = instance.logger
	return
}
func (l *LogManager) ReOpen() (err error) {
	l.lock.RLock()
	defer l.lock.RUnlock()
	var errorMsg string
	for k, v := range l.loggers {
		if v.logger == nil || !v.enable {
			continue
		}
		errRet := v.logger.ReOpen()
		if errRet != nil {
			errorMsg += fmt.Sprintf("logger[%s] reload failed, err[%v]\n", k, errRet)
			continue
		}
	}
	err = errors.New(errorMsg)
	return
}
func (l *LogManager) SetLevelAll(level string) {
	l.lock.RLock()
	defer l.lock.RUnlock()
	for _, v := range l.loggers {
		if !v.enable || v.logger == nil {
			continue
		}
		v.logger.SetLevel(level)
	}
}
func (l *LogManager) SetLevel(name, level string) (err error) {
	l.lock.Lock()
	defer l.lock.Unlock()
	v, ok := l.loggers[name]
	if !ok || v.logger == nil {
		err = fmt.Errorf("not found logger[%s]", name)
		return
	}
	v.logger.SetLevel(level)
	return
}
func (l *LogManager) Warn(format string, a ...interface{}) (err error) {
	l.lock.RLock()
	defer l.lock.RUnlock()
	for _, v := range l.loggers {
		if v.logger == nil || !v.enable {
			continue
		}
		v.logger.Warn(format, a...)
	}
	return
}
func (l *LogManager) Fatal(format string, a ...interface{}) (err error) {
	l.lock.RLock()
	defer l.lock.RUnlock()
	for _, v := range l.loggers {
		if v.logger == nil || !v.enable {
			continue
		}
		v.logger.Fatal(format, a...)
	}
	return
}
func (l *LogManager) Notice(format string, a ...interface{}) (err error) {
	l.lock.RLock()
	defer l.lock.RUnlock()
	for _, v := range l.loggers {
		if v.logger == nil || !v.enable {
			continue
		}
		v.logger.Notice(format, a...)
	}
	return
}
func (l *LogManager) Trace(format string, a ...interface{}) (err error) {
	l.lock.RLock()
	defer l.lock.RUnlock()
	for _, v := range l.loggers {
		if v.logger == nil || !v.enable {
			continue
		}
		v.logger.Trace(format, a...)
	}
	return
}
func (l *LogManager) Debug(format string, a ...interface{}) (err error) {
	l.lock.RLock()
	defer l.lock.RUnlock()
	for _, v := range l.loggers {
		if v.logger == nil || !v.enable {
			continue
		}
		v.logger.Debug(format, a...)
	}
	return
}
func (l *LogManager) Warnx(logID, format string, a ...interface{}) (err error) {
	l.lock.RLock()
	defer l.lock.RUnlock()
	for _, v := range l.loggers {
		if v.logger == nil || !v.enable {
			continue
		}
		v.logger.Warnx(logID, format, a...)
	}
	return
}