This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git


The following commit(s) were added to refs/heads/main by this push:
     new 4390d4f  Introduce logging system
4390d4f is described below

commit 4390d4f3410771666fc3b248ff281e12b13e7136
Author: Gao Hongtao <[email protected]>
AuthorDate: Fri Apr 9 09:15:51 2021 +0800

    Introduce logging system
    
    Signed-off-by: Gao Hongtao <[email protected]>
---
 banyand/config/default/standalone.yaml |  3 +-
 banyand/executor/executor.go           |  6 +--
 banyand/index/index.go                 |  6 +--
 banyand/internal/cmd/standalone.go     | 17 ++++---
 banyand/series/series.go               |  6 +--
 banyand/shard/shard.go                 |  6 +--
 go.mod                                 |  1 +
 pkg/config/logging.go                  |  1 +
 pkg/logger/logger.go                   | 67 ++++++++++++++++++++++---
 pkg/logger/setting.go                  | 77 ++++++++++++++++++++++++++++
 pkg/logger/setting_test.go             | 91 ++++++++++++++++++++++++++++++++++
 11 files changed, 255 insertions(+), 26 deletions(-)

diff --git a/banyand/config/default/standalone.yaml 
b/banyand/config/default/standalone.yaml
index 01d1873..33d0cc6 100644
--- a/banyand/config/default/standalone.yaml
+++ b/banyand/config/default/standalone.yaml
@@ -16,4 +16,5 @@
 # specific language governing permissions and limitations
 # under the License.
 logging:
-  level: info
\ No newline at end of file
+  env: dev
+  level: info
diff --git a/banyand/executor/executor.go b/banyand/executor/executor.go
index fb7993e..ac25e9e 100644
--- a/banyand/executor/executor.go
+++ b/banyand/executor/executor.go
@@ -35,17 +35,17 @@ type Executor struct {
 func NewExecutor(bus *bus.Bus) *Executor {
        return &Executor{
                bus: bus,
-               log: logger.Log.Scope("executor"),
+               log: logger.GetLogger("executor"),
        }
 }
 
 func (s Executor) Rev(message bus.Message) {
-       s.log.Sugar().Infow("rev", "msg", message.Data())
+       s.log.Info("rev", logger.Any("msg", message.Data()))
        _ = s.bus.Publish(storage.TraceIndex, 
bus.NewMessage(bus.MessageID(time.Now().UnixNano()), "index message"))
        _ = s.bus.Publish(storage.TraceData, 
bus.NewMessage(bus.MessageID(time.Now().UnixNano()), "data message"))
 }
 
 func (s Executor) Close() error {
-       s.log.Sugar().Infow("closed")
+       s.log.Info("closed")
        return nil
 }
diff --git a/banyand/index/index.go b/banyand/index/index.go
index 5f228d5..d29eb89 100644
--- a/banyand/index/index.go
+++ b/banyand/index/index.go
@@ -30,15 +30,15 @@ type Index struct {
 
 func NewIndex() *Index {
        return &Index{
-               log: logger.Log.Scope("Index"),
+               log: logger.GetLogger("Index"),
        }
 }
 
 func (s Index) Rev(message bus.Message) {
-       s.log.Sugar().Infow("rev", "msg", message.Data())
+       s.log.Info("rev", logger.Any("msg", message.Data()))
 }
 
 func (s Index) Close() error {
-       s.log.Sugar().Infow("closed")
+       s.log.Info("closed")
        return nil
 }
diff --git a/banyand/internal/cmd/standalone.go 
b/banyand/internal/cmd/standalone.go
index 3526eaf..27ca159 100644
--- a/banyand/internal/cmd/standalone.go
+++ b/banyand/internal/cmd/standalone.go
@@ -19,7 +19,6 @@ package cmd
 
 import (
        "context"
-       "fmt"
        "os"
        "os/signal"
        "syscall"
@@ -38,18 +37,24 @@ import (
        "github.com/apache/skywalking-banyandb/pkg/version"
 )
 
+var standAloneConfig config.Standalone
+
 func newStandaloneCmd() *cobra.Command {
        standaloneCmd := &cobra.Command{
                Use:     "standalone",
                Version: version.Build(),
                Short:   "Run as the standalone mode",
-               RunE: func(cmd *cobra.Command, args []string) (err error) {
-                       logger.Log.Info("starting as a standalone server")
-                       var sc config.Standalone
-                       if sc, err = config.Load(); err != nil {
+               PersistentPreRunE: func(cmd *cobra.Command, args []string) (err 
error) {
+                       if standAloneConfig, err = config.Load(); err != nil {
+                               return err
+                       }
+                       if err = logger.InitLogger(standAloneConfig.Logging); 
err != nil {
                                return err
                        }
-                       fmt.Println(sc)
+                       return nil
+               },
+               RunE: func(cmd *cobra.Command, args []string) (err error) {
+                       logger.GetLogger().Info("starting as a standalone 
server")
                        dataBus := bus.NewBus()
                        err = multierr.Append(err, 
dataBus.Subscribe(storage.TraceRaw, shard.NewShard(dataBus)))
                        err = multierr.Append(err, 
dataBus.Subscribe(storage.TraceSharded, executor.NewExecutor(dataBus)))
diff --git a/banyand/series/series.go b/banyand/series/series.go
index 6790575..a51a2a1 100644
--- a/banyand/series/series.go
+++ b/banyand/series/series.go
@@ -30,15 +30,15 @@ type Series struct {
 
 func NewSeries() *Series {
        return &Series{
-               log: logger.Log.Scope("series"),
+               log: logger.GetLogger("series"),
        }
 }
 
 func (s Series) Rev(message bus.Message) {
-       s.log.Sugar().Infow("rev", "msg", message.Data())
+       s.log.Info("rev", logger.Any("msg", message.Data()))
 }
 
 func (s Series) Close() error {
-       s.log.Sugar().Infow("closed")
+       s.log.Info("closed")
        return nil
 }
diff --git a/banyand/shard/shard.go b/banyand/shard/shard.go
index 75c2100..a25baff 100644
--- a/banyand/shard/shard.go
+++ b/banyand/shard/shard.go
@@ -35,16 +35,16 @@ type Shard struct {
 func NewShard(bus *bus.Bus) *Shard {
        return &Shard{
                bus: bus,
-               log: logger.Log.Scope("shard"),
+               log: logger.GetLogger("shard"),
        }
 }
 
 func (s Shard) Rev(message bus.Message) {
-       s.log.Sugar().Infow("rev", "msg", message.Data())
+       s.log.Info("rev", logger.Any("msg", message.Data()))
        _ = s.bus.Publish(storage.TraceSharded, 
bus.NewMessage(bus.MessageID(time.Now().UnixNano()), "sharded message"))
 }
 
 func (s Shard) Close() error {
-       s.log.Sugar().Infow("closed")
+       s.log.Info("closed")
        return nil
 }
diff --git a/go.mod b/go.mod
index a628b50..fd684ee 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.16
 require (
        github.com/spf13/cobra v1.1.3
        github.com/spf13/viper v1.7.1
+       github.com/stretchr/testify v1.4.0
        go.uber.org/atomic v1.7.0
        go.uber.org/multierr v1.6.0
        go.uber.org/zap v1.16.0
diff --git a/pkg/config/logging.go b/pkg/config/logging.go
index 85ecd8e..0ddb698 100644
--- a/pkg/config/logging.go
+++ b/pkg/config/logging.go
@@ -18,5 +18,6 @@
 package config
 
 type Logging struct {
+       Env   string
        Level string
 }
diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go
index 7f78176..1429a5a 100644
--- a/pkg/logger/logger.go
+++ b/pkg/logger/logger.go
@@ -19,19 +19,72 @@ package logger
 
 import (
        "go.uber.org/zap"
+       "go.uber.org/zap/zapcore"
 )
 
+// Logger is wrapper for zap logger with module, it is singleton.
 type Logger struct {
-       *zap.Logger
+       module string
+       logger *zap.Logger
 }
 
-func (l Logger) Scope(scope string) *Logger {
-       return &Logger{l.Logger.Named(scope)}
+// Debug logs a message at DebugLevel. The message includes any fields passed
+// at the log site, as well as any fields accumulated on the logger.
+func (l *Logger) Debug(msg string, fields ...zap.Field) {
+       l.logger.Debug(msg, fields...)
 }
 
-var Log *Logger
+// Info logs a message at InfoLevel. The message includes any fields passed
+// at the log site, as well as any fields accumulated on the logger.
+func (l *Logger) Info(msg string, fields ...zap.Field) {
+       l.logger.Info(msg, fields...)
+}
+
+// Warn logs a message at WarnLevel. The message includes any fields passed
+// at the log site, as well as any fields accumulated on the logger.
+func (l *Logger) Warn(msg string, fields ...zap.Field) {
+       l.logger.Warn(msg, fields...)
+}
+
+// Error logs a message at ErrorLevel. The message includes any fields passed
+// at the log site, as well as any fields accumulated on the logger.
+func (l *Logger) Error(msg string, fields ...zap.Field) {
+       l.logger.Error(msg, fields...)
+}
+
+// String constructs a field with the given key and value.
+func String(key string, val string) zap.Field {
+       return zap.Field{Key: key, Type: zapcore.StringType, String: val}
+}
+
+// Error is shorthand for the common idiom NamedError("error", err).
+func Error(err error) zap.Field {
+       return zap.NamedError("error", err)
+}
+
+// Uint16 constructs a field with the given key and value.
+func Uint16(key string, val uint16) zap.Field {
+       return zap.Field{Key: key, Type: zapcore.Uint16Type, Integer: 
int64(val)}
+}
+
+// Uint32 constructs a field with the given key and value.
+func Uint32(key string, val uint32) zap.Field {
+       return zap.Field{Key: key, Type: zapcore.Uint32Type, Integer: 
int64(val)}
+}
+
+// Int32 constructs a field with the given key and value.
+func Int32(key string, val int32) zap.Field {
+       return zap.Field{Key: key, Type: zapcore.Int32Type, Integer: int64(val)}
+}
+
+// Int64 constructs a field with the given key and value.
+func Int64(key string, val int64) zap.Field {
+       return zap.Field{Key: key, Type: zapcore.Int64Type, Integer: val}
+}
 
-func init() {
-       l, _ := zap.NewDevelopment()
-       Log = &Logger{l}
+// Any takes a key and an arbitrary value and chooses the best way to represent
+// them as a field, falling back to a reflection-based approach only if
+// necessary.
+func Any(key string, value interface{}) zap.Field {
+       return zap.Any(key, value)
 }
diff --git a/pkg/logger/setting.go b/pkg/logger/setting.go
new file mode 100644
index 0000000..5fb7dbd
--- /dev/null
+++ b/pkg/logger/setting.go
@@ -0,0 +1,77 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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 (
+       "strings"
+       "sync"
+
+       "go.uber.org/zap"
+       "go.uber.org/zap/zapcore"
+
+       "github.com/apache/skywalking-banyandb/pkg/config"
+)
+
+var (
+       root *Logger
+       once sync.Once
+)
+
+// GetLogger return logger with a scope
+func GetLogger(scope ...string) *Logger {
+       if len(scope) < 1 {
+               return root
+       }
+       module := strings.Join(scope, ".")
+       return &Logger{module: module, logger: root.logger.Named(module)}
+}
+
+// InitLogger initializes a zap logger from user config
+func InitLogger(cfg config.Logging) (err error) {
+       once.Do(func() {
+               root, err = getLogger(cfg)
+       })
+       if err != nil {
+               return err
+       }
+       return nil
+}
+
+// getLogger initializes a root logger
+func getLogger(cfg config.Logging) (*Logger, error) {
+       // parse logging level
+       level := zap.NewAtomicLevelAt(zapcore.InfoLevel)
+       if err := level.UnmarshalText([]byte(cfg.Level)); err != nil {
+               return nil, err
+       }
+       var encoderConfig zap.Config
+       switch cfg.Env {
+       case "dev":
+               encoderConfig = zap.NewDevelopmentConfig()
+               encoderConfig.EncoderConfig.EncodeLevel = 
zapcore.CapitalColorLevelEncoder
+               break
+       default:
+               encoderConfig = zap.NewProductionConfig()
+       }
+       encoderConfig.Level = level
+       l, err := encoderConfig.Build()
+       if err != nil {
+               return nil, err
+       }
+       return &Logger{module: "root", logger: l}, nil
+}
diff --git a/pkg/logger/setting_test.go b/pkg/logger/setting_test.go
new file mode 100644
index 0000000..d065af2
--- /dev/null
+++ b/pkg/logger/setting_test.go
@@ -0,0 +1,91 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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 (
+       "reflect"
+       "testing"
+
+       "github.com/stretchr/testify/assert"
+       "go.uber.org/zap/zapcore"
+
+       "github.com/apache/skywalking-banyandb/pkg/config"
+)
+
+func TestInitLogger(t *testing.T) {
+       type args struct {
+               cfg config.Logging
+       }
+       type want struct {
+               isDev bool
+               level zapcore.Level
+       }
+       tests := []struct {
+               name    string
+               args    args
+               want    want
+               wantErr bool
+       }{
+               {
+                       name: "golden path",
+                       args: args{config.Logging{Env: "prod", Level: "info"}},
+                       want: want{level: zapcore.InfoLevel},
+               },
+               {
+                       name: "empty config",
+                       args: args{config.Logging{}},
+                       want: want{level: zapcore.InfoLevel},
+               },
+               {
+                       name: "development mode",
+                       args: args{config.Logging{Env: "dev"}},
+                       want: want{isDev: true, level: zapcore.InfoLevel},
+               },
+               {
+                       name: "debug level",
+                       args: args{config.Logging{Level: "debug"}},
+                       want: want{level: zapcore.DebugLevel},
+               },
+               {
+                       name: "invalid env",
+                       args: args{config.Logging{Env: "invalid"}},
+                       want: want{level: zapcore.InfoLevel},
+               },
+               {
+                       name:    "invalid level",
+                       args:    args{config.Logging{Level: "invalid"}},
+                       wantErr: true,
+               },
+       }
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       var err error
+                       var logger *Logger
+                       if logger, err = getLogger(tt.args.cfg); (err != nil) 
!= tt.wantErr {
+                               t.Errorf("InitLogger() error = %v, wantErr %v", 
err, tt.wantErr)
+                       }
+                       if err == nil {
+                               assert.NotNil(t, logger)
+                               assert.NotNil(t, logger.logger)
+                               assert.NotEmpty(t, logger.module)
+                               assert.Equal(t, tt.want.isDev, 
reflect.ValueOf(*logger.logger).FieldByName("development").Bool())
+                               assert.NotNil(t, 
logger.logger.Check(tt.want.level, "foo"))
+                       }
+               })
+       }
+}

Reply via email to