feat(log): add global logger appliance, as process level default logger (#1761)

* add global logger appliance, as process level default logger

* replace DefaultLogger as global logger
pull/1762/head
realityone 3 years ago committed by GitHub
parent d082075676
commit 0ed2e0f379
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      app.go
  2. 2
      config/config.go
  3. 4
      config/config_test.go
  4. 4
      contrib/config/apollo/apollo.go
  5. 2
      contrib/config/apollo/watcher.go
  6. 126
      log/global.go
  7. 68
      log/global_test.go
  8. 2
      middleware/recovery/recovery.go
  9. 2
      middleware/recovery/recovery_test.go
  10. 2
      transport/grpc/resolver/discovery/builder.go
  11. 6
      transport/grpc/resolver/discovery/resolver_test.go
  12. 2
      transport/grpc/server.go
  13. 2
      transport/http/resolver.go
  14. 2
      transport/http/server.go

@ -39,7 +39,7 @@ type App struct {
func New(opts ...Option) *App {
o := options{
ctx: context.Background(),
logger: log.NewHelper(log.DefaultLogger),
logger: log.NewHelper(log.GetLogger()),
sigs: []os.Signal{syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT},
registrarTimeout: 10 * time.Second,
stopTimeout: 10 * time.Second,

@ -49,7 +49,7 @@ type config struct {
// New new a config with options.
func New(opts ...Option) Config {
o := options{
logger: log.DefaultLogger,
logger: log.GetLogger(),
decoder: defaultDecoder,
resolver: defaultResolver,
}

@ -123,7 +123,7 @@ func TestConfig(t *testing.T) {
WithSource(newTestJSONSource(_testJSON)),
WithDecoder(defaultDecoder),
WithResolver(defaultResolver),
WithLogger(log.DefaultLogger),
WithLogger(log.GetLogger()),
)
err = c.Close()
assert.Nil(t, err)
@ -133,7 +133,7 @@ func TestConfig(t *testing.T) {
sources: []Source{jSource},
decoder: defaultDecoder,
resolver: defaultResolver,
logger: log.DefaultLogger,
logger: log.GetLogger(),
}
cf := &config{}
cf.opts = opts

@ -99,7 +99,7 @@ func WithLogger(logger log.Logger) Option {
func NewSource(opts ...Option) config.Source {
op := options{
logger: log.DefaultLogger,
logger: log.GetLogger(),
}
for _, o := range opts {
o(&op)
@ -167,7 +167,7 @@ func resolve(key string, value interface{}, target map[string]interface{}) {
// current exists, then check existing value type, if it's not map
// that means duplicate keys, and at least one is not map instance.
if cursor, ok = v.(map[string]interface{}); !ok {
_ = log.DefaultLogger.Log(log.LevelWarn,
_ = log.GetLogger().Log(log.LevelWarn,
"msg",
fmt.Sprintf("duplicate key: %v\n", strings.Join(keys[:i+1], ".")),
)

@ -63,7 +63,7 @@ func (c *customChangeListener) OnNewestChange(changeEvent *storage.FullChangeEve
func newWatcher(a *apollo, logger log.Logger) (config.Watcher, error) {
if logger == nil {
logger = log.DefaultLogger
logger = log.GetLogger()
}
changeCh := make(chan []*config.KeyValue)

@ -0,0 +1,126 @@
package log
import (
"fmt"
"os"
"sync"
)
// globalLogger is designed as a global logger in current process.
var (
global = &loggerAppliance{}
)
type loggerAppliance struct {
lock sync.Mutex
logger Logger
helper *Helper
}
func init() {
global.SetLogger(DefaultLogger)
}
func (a *loggerAppliance) SetLogger(in Logger) {
a.lock.Lock()
defer a.lock.Unlock()
a.logger = in
a.helper = NewHelper(a.logger)
}
func (a *loggerAppliance) GetLogger() Logger {
return a.logger
}
// SetLogger should be called before any other log call.
// And it is NOT THREAD SAFE.
func SetLogger(logger Logger) {
global.SetLogger(logger)
}
func GetLogger() Logger {
return global.GetLogger()
}
// Log Print log by level and keyvals.
func Log(level Level, keyvals ...interface{}) {
_ = global.logger.Log(level, keyvals...)
}
// Debug logs a message at debug level.
func Debug(a ...interface{}) {
global.helper.Log(LevelDebug, global.helper.msgKey, fmt.Sprint(a...))
}
// Debugf logs a message at debug level.
func Debugf(format string, a ...interface{}) {
global.helper.Log(LevelDebug, global.helper.msgKey, fmt.Sprintf(format, a...))
}
// Debugw logs a message at debug level.
func Debugw(keyvals ...interface{}) {
global.helper.Log(LevelDebug, keyvals...)
}
// Info logs a message at info level.
func Info(a ...interface{}) {
global.helper.Log(LevelInfo, global.helper.msgKey, fmt.Sprint(a...))
}
// Infof logs a message at info level.
func Infof(format string, a ...interface{}) {
global.helper.Log(LevelInfo, global.helper.msgKey, fmt.Sprintf(format, a...))
}
// Infow logs a message at info level.
func Infow(keyvals ...interface{}) {
global.helper.Log(LevelInfo, keyvals...)
}
// Warn logs a message at warn level.
func Warn(a ...interface{}) {
global.helper.Log(LevelWarn, global.helper.msgKey, fmt.Sprint(a...))
}
// Warnf logs a message at warnf level.
func Warnf(format string, a ...interface{}) {
global.helper.Log(LevelWarn, global.helper.msgKey, fmt.Sprintf(format, a...))
}
// Warnw logs a message at warnf level.
func Warnw(keyvals ...interface{}) {
global.helper.Log(LevelWarn, keyvals...)
}
// Error logs a message at error level.
func Error(a ...interface{}) {
global.helper.Log(LevelError, global.helper.msgKey, fmt.Sprint(a...))
}
// Errorf logs a message at error level.
func Errorf(format string, a ...interface{}) {
global.helper.Log(LevelError, global.helper.msgKey, fmt.Sprintf(format, a...))
}
// Errorw logs a message at error level.
func Errorw(keyvals ...interface{}) {
global.helper.Log(LevelError, keyvals...)
}
// Fatal logs a message at fatal level.
func Fatal(a ...interface{}) {
global.helper.Log(LevelFatal, global.helper.msgKey, fmt.Sprint(a...))
os.Exit(1)
}
// Fatalf logs a message at fatal level.
func Fatalf(format string, a ...interface{}) {
global.helper.Log(LevelFatal, global.helper.msgKey, fmt.Sprintf(format, a...))
os.Exit(1)
}
// Fatalw logs a message at fatal level.
func Fatalw(keyvals ...interface{}) {
global.helper.Log(LevelFatal, keyvals...)
os.Exit(1)
}

@ -0,0 +1,68 @@
package log
import (
"bytes"
"fmt"
"strings"
"testing"
)
func TestGlobalLog(t *testing.T) {
buffer := &bytes.Buffer{}
SetLogger(NewStdLogger(buffer))
testCases := []struct {
level Level
content []interface{}
}{
{
LevelDebug,
[]interface{}{"test debug"},
},
{
LevelInfo,
[]interface{}{"test info"},
},
{
LevelInfo,
[]interface{}{"test %s", "info"},
},
{
LevelWarn,
[]interface{}{"test warn"},
},
{
LevelError,
[]interface{}{"test error"},
},
{
LevelError,
[]interface{}{"test %s", "error"},
},
}
expected := []string{}
for _, tc := range testCases {
msg := fmt.Sprintf(tc.content[0].(string), tc.content[1:]...)
switch tc.level {
case LevelDebug:
Debugf(tc.content[0].(string), tc.content[1:]...)
expected = append(expected, fmt.Sprintf("%s msg=%s", "DEBUG", msg))
case LevelInfo:
Infof(tc.content[0].(string), tc.content[1:]...)
expected = append(expected, fmt.Sprintf("%s msg=%s", "INFO", msg))
case LevelWarn:
Warnf(tc.content[0].(string), tc.content[1:]...)
expected = append(expected, fmt.Sprintf("%s msg=%s", "WARN", msg))
case LevelError:
Errorf(tc.content[0].(string), tc.content[1:]...)
expected = append(expected, fmt.Sprintf("%s msg=%s", "ERROR", msg))
}
}
expected = append(expected, "")
t.Logf("Content: %s", buffer.String())
if buffer.String() != strings.Join(expected, "\n") {
t.Errorf("Expected: %s, got: %s", strings.Join(expected, "\n"), buffer.String())
}
}

@ -40,7 +40,7 @@ func WithLogger(logger log.Logger) Option {
// Recovery is a server middleware that recovers from any panics.
func Recovery(opts ...Option) middleware.Middleware {
op := options{
logger: log.DefaultLogger,
logger: log.GetLogger(),
handler: func(ctx context.Context, req, err interface{}) error {
return ErrUnknownRequest
},

@ -19,7 +19,7 @@ func TestOnce(t *testing.T) {
next := func(ctx context.Context, req interface{}) (interface{}, error) {
panic("panic reason")
}
_, e := Recovery(WithLogger(log.DefaultLogger))(next)(context.Background(), "panic")
_, e := Recovery(WithLogger(log.GetLogger()))(next)(context.Background(), "panic")
t.Logf("succ and reason is %v", e)
}

@ -48,7 +48,7 @@ type builder struct {
func NewBuilder(d registry.Discovery, opts ...Option) resolver.Builder {
b := &builder{
discoverer: d,
logger: log.DefaultLogger,
logger: log.GetLogger(),
timeout: time.Second * 10,
insecure: false,
}

@ -56,7 +56,7 @@ func TestWatch(t *testing.T) {
r := &discoveryResolver{
w: &testWatch{},
cc: &testClientConn{te: t},
log: log.NewHelper(log.DefaultLogger),
log: log.NewHelper(log.GetLogger()),
ctx: ctx,
cancel: cancel,
insecure: false,
@ -75,7 +75,7 @@ func TestWatchError(t *testing.T) {
r := &discoveryResolver{
w: &testWatch{err: errors.New("bad")},
cc: &testClientConn{te: t},
log: log.NewHelper(log.DefaultLogger),
log: log.NewHelper(log.GetLogger()),
ctx: ctx,
cancel: cancel,
}
@ -93,7 +93,7 @@ func TestWatchContextCancel(t *testing.T) {
r := &discoveryResolver{
w: &testWatch{err: context.Canceled},
cc: &testClientConn{te: t},
log: log.NewHelper(log.DefaultLogger),
log: log.NewHelper(log.GetLogger()),
ctx: ctx,
cancel: cancel,
}

@ -122,7 +122,7 @@ func NewServer(opts ...ServerOption) *Server {
address: ":0",
timeout: 1 * time.Second,
health: health.NewServer(),
log: log.NewHelper(log.DefaultLogger),
log: log.NewHelper(log.GetLogger()),
}
for _, o := range opts {
o(srv)

@ -57,7 +57,7 @@ func newResolver(ctx context.Context, discovery registry.Discovery, target *Targ
r := &resolver{
target: target,
watcher: watcher,
logger: log.NewHelper(log.DefaultLogger),
logger: log.NewHelper(log.GetLogger()),
rebalancer: rebalancer,
insecure: insecure,
}

@ -143,7 +143,7 @@ func NewServer(opts ...ServerOption) *Server {
enc: DefaultResponseEncoder,
ene: DefaultErrorEncoder,
strictSlash: true,
log: log.NewHelper(log.DefaultLogger),
log: log.NewHelper(log.GetLogger()),
}
for _, o := range opts {
o(srv)

Loading…
Cancel
Save