Browse Source

v1.3.5 Fix 修复goroutine并发调用初始化 nil pointer的问题

tags/v1.3.5
liangzy 4 years ago
parent
commit
e0682ed122
5 changed files with 83 additions and 63 deletions
  1. +61
    -54
      log.go
  2. +11
    -5
      log_test.go
  3. +5
    -3
      logs/alils/alils.go
  4. +1
    -1
      logs/alils/callback.go
  5. +5
    -0
      options.go

+ 61
- 54
log.go View File

@@ -11,12 +11,19 @@ var loggers = sync.Map{}


var envkey = "CENTER_RUNMODE" 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 { type Logger struct {
Lable string Lable string
*logs.BeeLogger *logs.BeeLogger
lock sync.RWMutex
} }


type Getter func() *Logger

func (self *Logger) SetAdapter(level Level, adapter Adapter) *Logger { func (self *Logger) SetAdapter(level Level, adapter Adapter) *Logger {
if call, ok := adatperSetMapper[adapter]; ok { if call, ok := adatperSetMapper[adapter]; ok {
if err := call(self, level); err != nil { if err := call(self, level); err != nil {
@@ -35,72 +42,61 @@ func (self *Logger) DropAdapter(adapter Adapter) *Logger {
return self 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)
return l
}())
var l *Logger
var once sync.Once
wapperGetter := Getter(func() *Logger {
once.Do(func() {


l = tmp.(*Logger)
return
}
var channelLensNum int64 = 100
if len(channelLens) > 0 && channelLens[0] > 0 {
channelLensNum = channelLens[0]
}


func New(label string, channelLens ...int64) (l *Logger, loaded bool) {
return newLogger(label, channelLens...)
}
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)
}
}
})


func Get(label string, channelLens ...int64) (l *Logger) {
var filelevel Level = LevelInfo
var loaded bool
if os.Getenv(envkey) == "dev" {
filelevel = LevelAll
}
return l
})


if l, loaded = New(label, channelLens...); !loaded {
l.SetAdapter(filelevel, AdapterFile).SetAdapter(LevelAll, AdapterConsole)
tmp, loaded := loggers.LoadOrStore(label, wapperGetter)
if loaded {
return tmp.(Getter)
} }
return
}


func GetEs(label string, channelLens ...int64) (l *Logger) {
var filelevel Level = LevelInfo
var loaded bool
if os.Getenv(envkey) == "dev" {
filelevel = LevelAll
}
return wapperGetter
}


if l, loaded = New(label, channelLens...); !loaded {
l.SetAdapter(filelevel, AdapterFile).SetAdapter(LevelAll, AdapterConsole).SetAdapter(filelevel, AdapterElasticSearch)
l.lock.Unlock()
}
return
func Get(label string, channelLens ...int64) *Logger {
getter := newLoggerFromMap(label, "", channelLens...)
return getter()
} }


func GetAli(label string, channelLens ...int64) (l *Logger) {
var filelevel Level = LevelInfo
var loaded bool
if os.Getenv(envkey) == "dev" {
filelevel = LevelAll
}
func GetEs(label string, channelLens ...int64) *Logger {
getter := newLoggerFromMap(label, "es", channelLens...)
return getter()
}


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) { func Close(lables ...string) {
@@ -136,3 +132,14 @@ func CloseAll() {
}) })
wg.Wait() 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}}
}

+ 11
- 5
log_test.go View File

@@ -4,6 +4,7 @@ import (
"errors" "errors"
_ "golib.gaore.com/GaoreGo/grlogs/logs/alils" _ "golib.gaore.com/GaoreGo/grlogs/logs/alils"
_ "golib.gaore.com/GaoreGo/grlogs/logs/es" _ "golib.gaore.com/GaoreGo/grlogs/logs/es"
"sync"
"testing" "testing"
"time" "time"
) )
@@ -61,14 +62,19 @@ func TestDropAdapter(t *testing.T) {
} }


func TestNew(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) { 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) }(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
- 3
logs/alils/alils.go View File

@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"github.com/aliyun/aliyun-log-go-sdk/producer" "github.com/aliyun/aliyun-log-go-sdk/producer"
"golib.gaore.com/GaoreGo/grlogs/logs" "golib.gaore.com/GaoreGo/grlogs/logs"
"os"
"runtime" "runtime"
"time" "time"
) )
@@ -28,6 +29,7 @@ type alilsLogger struct {
Source string `json:"source"` Source string `json:"source"`
Level int `json:"level"` Level int `json:"level"`
FlushWhen int `json:"flush_when"` FlushWhen int `json:"flush_when"`
Debug bool
} }


func (a *alilsLogger) Init(jsonconfig string) error { func (a *alilsLogger) Init(jsonconfig string) error {
@@ -43,12 +45,12 @@ func (a *alilsLogger) Init(jsonconfig string) error {
producerConfig.LingerMs = 100 producerConfig.LingerMs = 100
producerConfig.NoRetryStatusCodeList = []int{-1} producerConfig.NoRetryStatusCodeList = []int{-1}
producerConfig.Retries = 2 producerConfig.Retries = 2
producerConfig.AllowLogLevel = "err"
producerConfig.AllowLogLevel = "error"
producerConfig.MaxIoWorkerCount = int64(runtime.NumCPU()) producerConfig.MaxIoWorkerCount = int64(runtime.NumCPU())
a.producer = producer.InitProducer(producerConfig) a.producer = producer.InitProducer(producerConfig)
a.callback = &Callback{} a.callback = &Callback{}
a.producer.Start() a.producer.Start()
a.Debug = os.Getenv("GRLOG_ALILS_DEBUG") == "on"
return nil 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) log := producer.GenerateLog(uint32(when.Unix()), vals)


if env == "dev" || env == "test" {
if a.Debug {
for _, topic := range a.Topics { for _, topic := range a.Topics {
if err := a.producer.SendLogWithCallBack(a.Project, a.LogStore, topic, a.Source, log, a.callback); err != nil { if err := a.producer.SendLogWithCallBack(a.Project, a.LogStore, topic, a.Source, log, a.callback); err != nil {
return err return err


+ 1
- 1
logs/alils/callback.go View File

@@ -11,7 +11,7 @@ type Callback struct {
func (callback *Callback) Success(result *producer.Result) { func (callback *Callback) Success(result *producer.Result) {
attemptList := result.GetReservedAttempts() attemptList := result.GetReservedAttempts()
for _, attempt := range attemptList { for _, attempt := range attemptList {
fmt.Printf("%+v \n", attempt)
fmt.Printf("alilog %+v \n", attempt)
} }
} }




+ 5
- 0
options.go View File

@@ -4,6 +4,11 @@ type Level int


type Adapter string type Adapter string


type AdapterTupple struct {
Level Level
Adapter Adapter
}

const ( const (
_ Level = iota _ Level = iota
LevelNone Level = iota LevelNone Level = iota


Loading…
Cancel
Save