Skip to content

Commit

Permalink
docs: comments and README.md for logging
Browse files Browse the repository at this point in the history
Signed-off-by: Jiangnan Jia <[email protected]>
  • Loading branch information
jnan806 committed Nov 10, 2022
1 parent 8110950 commit cd072c3
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 3 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,10 @@
OpenSergo control plane enables unified management for microservice governance rules with OpenSergo CRD (under Kubernetes).

![arch](https://user-images.githubusercontent.com/9434884/182856237-8ce85f41-1a1a-4a2a-8f58-db042bd4db42.png)



# Feature
## logger mechanism
Provider a common Logger interface which is highly extensible and multi implementable.
For detail please refer to [logging/README.md](./pkg/common/logging/README.md)
94 changes: 94 additions & 0 deletions pkg/common/logging/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# logging component

here provider a common Logger interface which is highly extensible and multi implementable

## Quick start
In this logging component, you can have only one global ConsoleLogger, and several FileLogger, By invoking function in [logger.go](./logger.go):
``` go
// AppendLoggerSlice add the Logger into loggerSlice
func AppendLoggerSlice(loggerAppend Logger) {
loggerSlice = append(loggerSlice, loggerAppend)
}

// SetConsoleLogger set the consoleLogger to print int stdout
func SetConsoleLogger(logger Logger) {
consoleLogger = logger
}
```

You can use the default implement of Logger directly, By new Logger instance implemented in [logger_default.go](./logger_default.go),
But first, you should new instances from [logger_default.go](./logger_default.go), like following:
``` go
// new instances
logging.NewDefaultConsoleLogger(logging.DebugLevel)
logging.NewDefaultFileLogger(logging.DebugLevel)
// invoke the function in Logger interface
logging.Error(errors.New("errors.New"), "this is error log in printErrorStack()")
logging.Info("this is info log in printErrorStack()")
logging.Debug("this is debug log in printErrorStack()")
```

You can format you log, by using [logger_assembler.go](./logger_assembler.go),
the assembler provides AssembleMsgJsonFormat and AssembleMsgSeparateFormat can be chosen.

``` go
// the unified entrance for AssembleMsg
func AssembleMsg(logFormat LogFormat, callerDepth int, logLevel, msg string, err error, errWithStack bool, keysAndValues ...interface{}) string

// AssembleMsgJsonFormat Assemble log-msg as json-format
//
// debug/info/warn:
// {"logLevel":"INFO","timestamp":"2006-01-02 15:04:05.000","caller":"opensergo_client.go:74","msg":"openSergoClient is starting..."}
//
// error:
// {"logLevel":"ERROR","timestamp":"2006-01-02 15:04:05.000","caller":"opensergo_client.go:83","msg":"can not connect.","error":"rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial tcp 33.1.33.1:10246: connect: connection refused\""}
// [ ERROR CAUSES WITH STACK ][ rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp 33.1.33.1:10246: connect: connection refused"
// github.com/opensergo/opensergo-go/pkg/client.handleReceive.func1
//
// .../opensergo-go-sdk/pkg/client/opensergo_client.go:82 ][ ERROR CAUSES WITH STACK END ]
func AssembleMsgJsonFormat(callerDepth int, logLevel, msg string, err error, errWithStack bool, keysAndValues ...interface{}) string

// AssembleMsgSeparateFormat Assemble log-msg as separate-format
//
// pattern:
// level | timestamp | callerFile:line | logContentJson | errorInfo
//
// debug/info/warn:
// INFO | 2006-01-02 15:04:05.000 | main.go:30 | {"msg":"connected.", kvs:{}}
//
// error:
// ERROR | 2006-01-02 15:04:05.000 | main.go:30 | {"msg":"connected.", kvs:{}} | rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp 33.1.33.1:10246: i/o timeout"
// [ ERROR CAUSES WITH STACK ][ rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp 33.1.33.1:10246: connect: connection refused"
// github.com/opensergo/opensergo-go/pkg/client.handleReceive.func1
//
// .../opensergo-go-sdk/pkg/client/opensergo_client.go:82 ][ ERROR CAUSES WITH STACK END ]
func AssembleMsgSeparateFormat(callerDepth int, logLevel, msg string, err error, errWithStack bool, keysAndValues ...interface{})
```

## Samples

### sample_simple_print
If you only want to use the Logger provided by default, you can new a ConsoleLogger, like following:
``` go
// default ConsoleLogger
// logging.NewDefaultConsoleLogger(logging.DebugLevel)
// custom ConsoleLogger
logging.NewConsoleLogger(logging.DebugLevel, logging.JsonFormat, true)
logging.Error(errors.New("errors.New"), "this is error log in printErrorStack()")
logging.Info("this is info log in printErrorStack()")
logging.Debug("this is debug log in printErrorStack()")
```
For detail, please refer to [sample_simple_print](./samples/sample_simple_print)

### sample_print_impl_logging
If you want to replace the logger implement where has integrated this logging component,
you can implement the [Logger](./logger.go) by your-self, append you Logger after invoke `ClearLoggerSlice()` in Logger,
or invoke `SetConsoleLogger(logger Logger)` to set the global ConsoleLogger.

For detail, please refer to [sample_print_impl_logging](./samples/sample_print_impl_logging)

### sample_print_use_logging
If you want to use this logging component to replace the other has already integrated,
you can re-implement the other Logger by invoking the function in Logger which was instanced.

For detail, please refer to [sample_print_use_logging](./samples/sample_print_use_logging)
58 changes: 58 additions & 0 deletions pkg/common/logging/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"reflect"
)

// Logger the common interface for logging.
type Logger interface {

// Print logs message no format as what the msg presents.
Expand Down Expand Up @@ -71,36 +72,79 @@ var (
consoleLogger Logger
)

// Print logs message no format as what the msg presents.
func Print(msg string) {
doLog("Print", nil, msg)
}

// Debug logs a non-error message with the given key/value pairs as context.
//
// The msg argument should be used to add some constant description to
// the log line. The key/value pairs can then be used to add additional
// variable information. The key/value pairs should alternate string
// keys and arbitrary values.
func Debug(msg string, keysAndValues ...interface{}) {
doLog("Debug", nil, msg, keysAndValues...)
}

// DebugWithCallerDepth logs a non-error message with the given key/value pairs as context.
//
// logCallerDepth: to calculate the caller:line
//
// The msg argument should be used to add some constant description to
// the log line. The key/value pairs can then be used to add additional
// variable information. The key/value pairs should alternate string
// keys and arbitrary values.
func DebugWithCallerDepth(logger Logger, logFormat LogFormat, logCallerDepth int, msg string, keysAndValues ...interface{}) {
if !logger.DebugEnabled() {
return
}
logger.Print(AssembleMsg(logFormat, logCallerDepth, "DEBUG", msg, nil, false, keysAndValues...))
}

// Info logs a non-error message with the given key/value pairs as context.
//
// The msg argument should be used to add some constant description to
// the log line. The key/value pairs can then be used to add additional
// variable information. The key/value pairs should alternate string
// keys and arbitrary values.
func Info(msg string, keysAndValues ...interface{}) {
doLog("Info", nil, msg, keysAndValues...)
}

// InfoWithCallerDepth logs a non-error message with the given key/value pairs as context.
//
// logCallerDepth: to calculate the caller:line
//
// The msg argument should be used to add some constant description to
// the log line. The key/value pairs can then be used to add additional
// variable information. The key/value pairs should alternate string
// keys and arbitrary values.
func InfoWithCallerDepth(logger Logger, logFormat LogFormat, logCallerDepth int, msg string, keysAndValues ...interface{}) {
if !logger.InfoEnabled() {
return
}
logger.Print(AssembleMsg(logFormat, logCallerDepth, "INFO", msg, nil, false, keysAndValues...))
}

// Warn logs a non-error message with the given key/value pairs as context.
//
// The msg argument should be used to add some constant description to
// the log line. The key/value pairs can then be used to add additional
// variable information. The key/value pairs should alternate string
// keys and arbitrary values.
func Warn(msg string, keysAndValues ...interface{}) {
doLog("Warn", nil, msg, keysAndValues...)
}

// WarnWithCallerDepth logs a non-error message with the given key/value pairs as context.
//
// logCallerDepth: to calculate the caller:line
//
// The msg argument should be used to add some constant description to
// the log line. The key/value pairs can then be used to add additional
// variable information. The key/value pairs should alternate string
// keys and arbitrary values.
func WarnWithCallerDepth(logger Logger, logFormat LogFormat, logCallerDepth int, msg string, keysAndValues ...interface{}) {
if !logger.WarnEnabled() {
return
Expand All @@ -109,10 +153,24 @@ func WarnWithCallerDepth(logger Logger, logFormat LogFormat, logCallerDepth int,
logger.Print(AssembleMsg(logFormat, logCallerDepth, "WARN", msg, nil, false, keysAndValues...))
}

// Error logs an error message with error and the given key/value pairs as context.
//
// The msg argument should be used to add some constant description to
// the log line. The key/value pairs can then be used to add additional
// variable information. The key/value pairs should alternate string
// keys and arbitrary values.
func Error(err error, msg string, keysAndValues ...interface{}) {
doLog("Error", err, msg, keysAndValues...)
}

// ErrorWithCallerDepth logs an error message with error and the given key/value pairs as context.
//
// logCallerDepth: to calculate the caller:line
//
// The msg argument should be used to add some constant description to
// the log line. The key/value pairs can then be used to add additional
// variable information. The key/value pairs should alternate string
// keys and arbitrary values.
func ErrorWithCallerDepth(logger Logger, logFormat LogFormat, logCallerDepth int, err error, errorWithStack bool, msg string, keysAndValues ...interface{}) {
if !logger.ErrorEnabled() {
return
Expand Down
9 changes: 6 additions & 3 deletions pkg/common/logging/logger_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ func (l *DefaultLogger) ErrorEnabled() bool {
}

// NewDefaultFileLogger
// filePath $HOME/logs/opensergo/opensergo-universal-transport-service.log
// loggerName FileLoggerName
// LoggerLevel DefaultLogLevel
func NewDefaultFileLogger(logLevel Level) (Logger, error) {
// log dir of 'OpenSergo universal transport service'
Expand All @@ -108,6 +106,7 @@ func NewDefaultFileLogger(logLevel Level) (Logger, error) {
return NewFileLogger(filePath, logLevel, JsonFormat, DefaultErrorWithStack)
}

// create a file to write log.
func mkdirLogFile(filePath string) {
dir := filepath.Dir(filePath)

Expand All @@ -124,7 +123,7 @@ func mkdirLogFile(filePath string) {

}

// NewFileLogger
// NewFileLogger new a Logger which write logs into file. And append the LoggerSlice.
// filepath is the full path(absolute path). eg: /root/logs/opensergo/opensergo-universal-transport-service.log
func NewFileLogger(filepath string, loggerLevel Level, logFormat LogFormat, errorWithStack bool) (Logger, error) {
mkdirLogFile(filepath)
Expand All @@ -142,12 +141,16 @@ func NewFileLogger(filepath string, loggerLevel Level, logFormat LogFormat, erro
return defaultLogger, err
}

// NewDefaultConsoleLogger new a default ConsoleLogger to print logs in console.
// And there is only one ConsoleLogger instance in the Global.
func NewDefaultConsoleLogger(logLevel Level) Logger {
defaultLogger := NewConsoleLogger(logLevel, ConsoleLogFormat, DefaultErrorWithStack)
SetConsoleLogger(defaultLogger)
return defaultLogger
}

// NewConsoleLogger new a ConsoleLogger to print logs in console.
// And there is only one ConsoleLogger instance in the Global.
func NewConsoleLogger(logLevel Level, logFormat LogFormat, errorWithStack bool) Logger {
defaultLogger := &DefaultLogger{
Logger: log.New(os.Stdout, "", 0),
Expand Down

0 comments on commit cd072c3

Please sign in to comment.