feature: add context log (#21)

* feature: add context log

Signed-off-by: 1046102779 <seachen@tencent.com>

* feature: add context log

Signed-off-by: 1046102779 <seachen@tencent.com>

* feature: add context log

Signed-off-by: 1046102779 <seachen@tencent.com>

* feature: add context log

Signed-off-by: 1046102779 <seachen@tencent.com>

* feature: add context log

Signed-off-by: 1046102779 <seachen@tencent.com>

Signed-off-by: 1046102779 <seachen@tencent.com>
This commit is contained in:
yellow chicks 2022-12-12 01:36:11 +08:00 committed by GitHub
parent b2486486ce
commit bcf6ee0931
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 123 additions and 0 deletions

75
logger/default.go Normal file
View File

@ -0,0 +1,75 @@
/*
Copyright 2022 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package logger
import "io"
type nopLogger struct{}
// EnableJSONOutput enables JSON formatted output log.
func (n *nopLogger) EnableJSONOutput(dnabled bool) {}
// SetAppID sets dapr_id field in the log. nopLogger value is empty string.
func (n *nopLogger) SetAppID(id string) {}
// SetOutputLevel sets log output level.
func (n *nopLogger) SetOutputLevel(outputLevel LogLevel) {}
// SetOutput sets the destination for the logs
func (n *nopLogger) SetOutput(dst io.Writer) {}
// IsOutputLevelEnabled returns true if the logger will output this LogLevel.
func (n *nopLogger) IsOutputLevelEnabled(level LogLevel) bool { return true }
// WithLogType specify the log_type field in log. nopLogger value is LogTypeLog.
func (n *nopLogger) WithLogType(logType string) Logger {
return n
}
// WithFields returns a logger with the added structured fields.
func (n *nopLogger) WithFields(fields map[string]any) Logger {
return n
}
// Info logs a message at level Info.
func (n *nopLogger) Info(args ...interface{}) {}
// Infof logs a message at level Info.
func (n *nopLogger) Infof(format string, args ...interface{}) {}
// Debug logs a message at level Debug.
func (n *nopLogger) Debug(args ...interface{}) {}
// Debugf logs a message at level Debug.
func (n *nopLogger) Debugf(format string, args ...interface{}) {}
// Warn logs a message at level Warn.
func (n *nopLogger) Warn(args ...interface{}) {}
// Warnf logs a message at level Warn.
func (n *nopLogger) Warnf(format string, args ...interface{}) {}
// Error logs a message at level Error.
func (n *nopLogger) Error(args ...interface{}) {}
// Errorf logs a message at level Error.
func (n *nopLogger) Errorf(format string, args ...interface{}) {}
// Fatal logs a message at level Fatal then the process will exit with status set to 1.
func (n *nopLogger) Fatal(args ...interface{}) {}
// Fatalf logs a message at level Fatal then the process will exit with status set to 1.
func (n *nopLogger) Fatalf(format string, args ...interface{}) {}

View File

@ -14,6 +14,7 @@ limitations under the License.
package logger
import (
"context"
"io"
"strings"
"sync"
@ -36,6 +37,11 @@ const (
logFieldAppID = "app_id"
)
type logContextKeyType struct{}
// logContextKey is how we find Loggers in a context.Context
var logContextKey = logContextKeyType{}
// LogLevel is Dapr Logger Level type.
type LogLevel string
@ -60,6 +66,7 @@ const (
var (
globalLoggers = map[string]Logger{}
globalLoggersLock = sync.RWMutex{}
defaultOpLogger = &nopLogger{}
)
// Logger includes the logging api sets.
@ -150,3 +157,19 @@ func getLoggers() map[string]Logger {
return l
}
// NewContext returns a new Context, derived from ctx, which carries the
// provided Logger.
func NewContext(ctx context.Context, logger Logger) context.Context {
return context.WithValue(ctx, logContextKey, logger)
}
// FromContextOrDiscard returns a Logger from ctx. If no Logger is found, this
// returns a Logger that discards all log messages.
func FromContextOrDefault(ctx context.Context) Logger {
if v, ok := ctx.Value(logContextKey).(Logger); ok {
return v
}
return defaultOpLogger
}

View File

@ -14,6 +14,7 @@ limitations under the License.
package logger
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
@ -74,3 +75,27 @@ func TestToLogLevel(t *testing.T) {
assert.Equal(t, UndefinedLevel, toLogLevel("undefined"))
})
}
func TestNewContext(t *testing.T) {
t.Run("input nil logger", func(t *testing.T) {
ctx := NewContext(context.Background(), nil)
assert.NotNil(t, ctx, "ctx is not nil")
logger := FromContextOrDefault(ctx)
assert.NotNil(t, logger, "logger is not nil")
assert.Equal(t, logger, defaultOpLogger)
})
t.Run("input non-nil logger", func(t *testing.T) {
testLoggerName := "dapr.test"
logger := NewLogger(testLoggerName)
assert.NotNil(t, logger)
ctx := NewContext(context.Background(), logger)
assert.NotNil(t, ctx, "ctx is not nil")
logger2 := FromContextOrDefault(ctx)
assert.NotNil(t, logger2)
assert.Equal(t, logger2, logger)
assert.NotEqual(t, logger2, defaultOpLogger)
})
}