v1.3.5 Fix 修复goroutine并发调用初始化 nil pointer的问题
This commit is contained in:
		
							parent
							
								
									cd85fd66ff
								
							
						
					
					
						commit
						e0682ed122
					
				
							
								
								
									
										119
									
								
								log.go
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								log.go
									
									
									
									
									
								
							@ -11,12 +11,19 @@ var loggers = sync.Map{}
 | 
			
		||||
 | 
			
		||||
var envkey = "CENTER_RUNMODE"
 | 
			
		||||
 | 
			
		||||
var defaultModeMapping = map[string][]AdapterTupple{
 | 
			
		||||
	"es":  []AdapterTupple{{LevelAll, AdapterConsole}, {LevelAll, AdapterElasticSearch}},
 | 
			
		||||
	"ali": []AdapterTupple{{LevelAll, AdapterConsole}, {LevelAll, AdapterAliLs}},
 | 
			
		||||
	"":    []AdapterTupple{{LevelAll, AdapterConsole}, {LevelAll, AdapterFile}},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Logger struct {
 | 
			
		||||
	Lable string
 | 
			
		||||
	*logs.BeeLogger
 | 
			
		||||
	lock sync.RWMutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Getter func() *Logger
 | 
			
		||||
 | 
			
		||||
func (self *Logger) SetAdapter(level Level, adapter Adapter) *Logger {
 | 
			
		||||
	if call, ok := adatperSetMapper[adapter]; ok {
 | 
			
		||||
		if err := call(self, level); err != nil {
 | 
			
		||||
@ -35,72 +42,61 @@ func (self *Logger) DropAdapter(adapter Adapter) *Logger {
 | 
			
		||||
	return self
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newLogger(label string, channelLens ...int64) (l *Logger, loaded bool) {
 | 
			
		||||
	var channellens int64
 | 
			
		||||
	var tmp interface{}
 | 
			
		||||
func newLoggerFromMap(label string, defaultmode string, channelLens ...int64) Getter {
 | 
			
		||||
 | 
			
		||||
	if len(channelLens) > 0 {
 | 
			
		||||
		channellens = channelLens[0]
 | 
			
		||||
	if tmp, ok := loggers.Load(label); ok {
 | 
			
		||||
		return tmp.(Getter)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tmp, loaded = loggers.LoadOrStore(label, func() *Logger {
 | 
			
		||||
		l := &Logger{BeeLogger: logs.NewLogger(channellens)}
 | 
			
		||||
		l.Lable = label
 | 
			
		||||
		l.BeeLogger = logs.NewLogger(channellens)
 | 
			
		||||
		l.BeeLogger.Lable = label
 | 
			
		||||
		l.Env = os.Getenv(envkey)
 | 
			
		||||
		l.SetPrefix(fmt.Sprintf("[env:%s logger:%s]", os.Getenv(envkey), label))
 | 
			
		||||
		l.EnableFuncCallDepth(true)
 | 
			
		||||
		l.SetLogFuncCallDepth(2)
 | 
			
		||||
	var l *Logger
 | 
			
		||||
	var once sync.Once
 | 
			
		||||
	wapperGetter := Getter(func() *Logger {
 | 
			
		||||
		once.Do(func() {
 | 
			
		||||
 | 
			
		||||
			var channelLensNum int64 = 100
 | 
			
		||||
			if len(channelLens) > 0 && channelLens[0] > 0 {
 | 
			
		||||
				channelLensNum = channelLens[0]
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			l = &Logger{BeeLogger: logs.NewLogger(channelLensNum)}
 | 
			
		||||
			l.Lable = label
 | 
			
		||||
			l.BeeLogger = logs.NewLogger(channelLensNum)
 | 
			
		||||
			l.BeeLogger.Lable = label
 | 
			
		||||
			l.Env = os.Getenv(envkey)
 | 
			
		||||
			l.SetPrefix(fmt.Sprintf("[env:%s logger:%s]", os.Getenv(envkey), label))
 | 
			
		||||
			l.EnableFuncCallDepth(true)
 | 
			
		||||
			l.SetLogFuncCallDepth(2)
 | 
			
		||||
			if mode, ok := defaultModeMapping[defaultmode]; ok {
 | 
			
		||||
				for _, v := range mode {
 | 
			
		||||
					l.SetAdapter(v.Level, v.Adapter)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		return l
 | 
			
		||||
	}())
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	l = tmp.(*Logger)
 | 
			
		||||
	return
 | 
			
		||||
	tmp, loaded := loggers.LoadOrStore(label, wapperGetter)
 | 
			
		||||
	if loaded {
 | 
			
		||||
		return tmp.(Getter)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return wapperGetter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New(label string, channelLens ...int64) (l *Logger, loaded bool) {
 | 
			
		||||
	return newLogger(label, channelLens...)
 | 
			
		||||
func Get(label string, channelLens ...int64) *Logger {
 | 
			
		||||
	getter := newLoggerFromMap(label, "", channelLens...)
 | 
			
		||||
	return getter()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Get(label string, channelLens ...int64) (l *Logger) {
 | 
			
		||||
	var filelevel Level = LevelInfo
 | 
			
		||||
	var loaded bool
 | 
			
		||||
	if os.Getenv(envkey) == "dev" {
 | 
			
		||||
		filelevel = LevelAll
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if l, loaded = New(label, channelLens...); !loaded {
 | 
			
		||||
		l.SetAdapter(filelevel, AdapterFile).SetAdapter(LevelAll, AdapterConsole)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
func GetEs(label string, channelLens ...int64) *Logger {
 | 
			
		||||
	getter := newLoggerFromMap(label, "es", channelLens...)
 | 
			
		||||
	return getter()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetEs(label string, channelLens ...int64) (l *Logger) {
 | 
			
		||||
	var filelevel Level = LevelInfo
 | 
			
		||||
	var loaded bool
 | 
			
		||||
	if os.Getenv(envkey) == "dev" {
 | 
			
		||||
		filelevel = LevelAll
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if l, loaded = New(label, channelLens...); !loaded {
 | 
			
		||||
		l.SetAdapter(filelevel, AdapterFile).SetAdapter(LevelAll, AdapterConsole).SetAdapter(filelevel, AdapterElasticSearch)
 | 
			
		||||
		l.lock.Unlock()
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetAli(label string, channelLens ...int64) (l *Logger) {
 | 
			
		||||
	var filelevel Level = LevelInfo
 | 
			
		||||
	var loaded bool
 | 
			
		||||
	if os.Getenv(envkey) == "dev" {
 | 
			
		||||
		filelevel = LevelAll
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if l, loaded = New(label, channelLens...); !loaded {
 | 
			
		||||
		l.SetAdapter(LevelAll, AdapterConsole).SetAdapter(filelevel, AdapterFile).SetAdapter(filelevel, AdapterAliLs)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
func GetAli(label string, channelLens ...int64) *Logger {
 | 
			
		||||
	getter := newLoggerFromMap(label, "ali", channelLens...)
 | 
			
		||||
	return getter()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Close(lables ...string) {
 | 
			
		||||
@ -136,3 +132,14 @@ func CloseAll() {
 | 
			
		||||
	})
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	var level Level = LevelInfo
 | 
			
		||||
	if os.Getenv(envkey) == "dev" {
 | 
			
		||||
		level = LevelAll
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defaultModeMapping["es"] = []AdapterTupple{{level, AdapterConsole}, {level, AdapterElasticSearch}}
 | 
			
		||||
	defaultModeMapping["ali"] = []AdapterTupple{{level, AdapterConsole}, {level, AdapterAliLs}}
 | 
			
		||||
	defaultModeMapping[""] = []AdapterTupple{{level, AdapterConsole}, {level, AdapterFile}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								log_test.go
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								log_test.go
									
									
									
									
									
								
							@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	_ "golib.gaore.com/GaoreGo/grlogs/logs/alils"
 | 
			
		||||
	_ "golib.gaore.com/GaoreGo/grlogs/logs/es"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
@ -61,14 +62,19 @@ func TestDropAdapter(t *testing.T) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNew(t *testing.T) {
 | 
			
		||||
	for i := 1; i < 10; i++ {
 | 
			
		||||
	wg := sync.WaitGroup{}
 | 
			
		||||
	for i := 0; i < 10; i++ {
 | 
			
		||||
		wg.Add(1)
 | 
			
		||||
		go func(i int) {
 | 
			
		||||
			GetEs("ok").Debug("%d", i)
 | 
			
		||||
			time.Sleep(1 * time.Second)
 | 
			
		||||
			GetAli("ok").Debug("%d", i)
 | 
			
		||||
			time.Sleep(time.Second * 10)
 | 
			
		||||
			wg.Done()
 | 
			
		||||
		}(i)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i := 1; i < 10; i++ {
 | 
			
		||||
		GetEs("ok").Debug("aaaaaa%d", i)
 | 
			
		||||
	for i := 0; i < 10; i++ {
 | 
			
		||||
		GetAli("ok").Debug("aaaaaa%d", i)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/aliyun/aliyun-log-go-sdk/producer"
 | 
			
		||||
	"golib.gaore.com/GaoreGo/grlogs/logs"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
@ -28,6 +29,7 @@ type alilsLogger struct {
 | 
			
		||||
	Source    string   `json:"source"`
 | 
			
		||||
	Level     int      `json:"level"`
 | 
			
		||||
	FlushWhen int      `json:"flush_when"`
 | 
			
		||||
	Debug     bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *alilsLogger) Init(jsonconfig string) error {
 | 
			
		||||
@ -43,12 +45,12 @@ func (a *alilsLogger) Init(jsonconfig string) error {
 | 
			
		||||
	producerConfig.LingerMs = 100
 | 
			
		||||
	producerConfig.NoRetryStatusCodeList = []int{-1}
 | 
			
		||||
	producerConfig.Retries = 2
 | 
			
		||||
	producerConfig.AllowLogLevel = "err"
 | 
			
		||||
	producerConfig.AllowLogLevel = "error"
 | 
			
		||||
	producerConfig.MaxIoWorkerCount = int64(runtime.NumCPU())
 | 
			
		||||
	a.producer = producer.InitProducer(producerConfig)
 | 
			
		||||
	a.callback = &Callback{}
 | 
			
		||||
	a.producer.Start()
 | 
			
		||||
 | 
			
		||||
	a.Debug = os.Getenv("GRLOG_ALILS_DEBUG") == "on"
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -66,7 +68,7 @@ func (a *alilsLogger) WriteMsg(when time.Time, msg string, level int, lable stri
 | 
			
		||||
 | 
			
		||||
	log := producer.GenerateLog(uint32(when.Unix()), vals)
 | 
			
		||||
 | 
			
		||||
	if env == "dev" || env == "test" {
 | 
			
		||||
	if a.Debug {
 | 
			
		||||
		for _, topic := range a.Topics {
 | 
			
		||||
			if err := a.producer.SendLogWithCallBack(a.Project, a.LogStore, topic, a.Source, log, a.callback); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,7 @@ type Callback struct {
 | 
			
		||||
func (callback *Callback) Success(result *producer.Result) {
 | 
			
		||||
	attemptList := result.GetReservedAttempts()
 | 
			
		||||
	for _, attempt := range attemptList {
 | 
			
		||||
		fmt.Printf("%+v \n", attempt)
 | 
			
		||||
		fmt.Printf("alilog %+v \n", attempt)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,11 @@ type Level int
 | 
			
		||||
 | 
			
		||||
type Adapter string
 | 
			
		||||
 | 
			
		||||
type AdapterTupple struct {
 | 
			
		||||
	Level   Level
 | 
			
		||||
	Adapter Adapter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	_             Level = iota
 | 
			
		||||
	LevelNone     Level = iota
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user