Skip to content

Commit

Permalink
[FAB-6272] SDK Go logging interface and provider
Browse files Browse the repository at this point in the history
-added fabric api interface
-provided implementation in fabric pkg by using
standard go lang logging
-added AddCustomLogging() where a custom logger
can be plugged in
-test coverage : 92.2%


Change-Id: If7a1c2ed510806511d0da23b98c9617857ae4e2f
Signed-off-by: Sudesh Shetty <[email protected]>
  • Loading branch information
sudeshrshetty committed Sep 28, 2017
1 parent f1c390e commit 17ad794
Show file tree
Hide file tree
Showing 5 changed files with 898 additions and 0 deletions.
52 changes: 52 additions & 0 deletions api/apilogging/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package apilogging

//Logger - Standard logger interface
type Logger interface {
Fatal(v ...interface{})

Fatalf(format string, v ...interface{})

Fatalln(v ...interface{})

Panic(v ...interface{})

Panicf(format string, v ...interface{})

Panicln(v ...interface{})

Print(v ...interface{})

Printf(format string, v ...interface{})

Println(v ...interface{})

Debug(args ...interface{})

Debugf(format string, args ...interface{})

Debugln(args ...interface{})

Info(args ...interface{})

Infof(format string, args ...interface{})

Infoln(args ...interface{})

Warn(args ...interface{})

Warnf(format string, args ...interface{})

Warnln(args ...interface{})

Error(args ...interface{})

Errorf(format string, args ...interface{})

Errorln(args ...interface{})
}
94 changes: 94 additions & 0 deletions pkg/logging/level.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package logging

import (
"errors"
"strings"
"sync"
)

// ErrInvalidLogLevel is used when an invalid log level has been used.
var ErrInvalidLogLevel = errors.New("logger: invalid log level")

// Level defines all available log levels for log messages.
type Level int

// Log levels.
const (
CRITICAL Level = iota
ERROR
WARNING
INFO
DEBUG
)

var levelNames = []string{
"CRITICAL",
"ERROR",
"WARNING",
"INFO",
"DEBUG",
}

// String returns the string representation of a logging level.
func (p Level) String() string {
return levelNames[p]
}

// LogLevel returns the log level from a string representation.
func LogLevel(level string) (Level, error) {
for i, name := range levelNames {
if strings.EqualFold(name, level) {
return Level(i), nil
}
}
return ERROR, ErrInvalidLogLevel
}

// Leveled interface is the interface required to be able to add leveled
// logging.
type Leveled interface {
GetLevel(string) Level
SetLevel(Level, string)
IsEnabledFor(Level, string) bool
}

type moduleLeveled struct {
sync.RWMutex
levels map[string]Level
}

// GetLevel returns the log level for the given module.
func (l *moduleLeveled) GetLevel(module string) Level {
l.RLock()
defer l.RUnlock()
level, exists := l.levels[module]
if exists == false {
level, exists = l.levels[""]
// no configuration exists, default to info
if exists == false {
level = INFO
}
}
return level
}

// SetLevel sets the log level for the given module.
func (l *moduleLeveled) SetLevel(level Level, module string) {
l.Lock()
defer l.Unlock()
if l.levels == nil {
l.levels = make(map[string]Level)
}
l.levels[module] = level
}

// IsEnabledFor will return true if logging is enabled for the given module.
func (l *moduleLeveled) IsEnabledFor(level Level, module string) bool {
return level <= l.GetLevel(module)
}
95 changes: 95 additions & 0 deletions pkg/logging/level_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package logging

import (
"testing"
)

func TestLogLevels(t *testing.T) {

mlevel := moduleLeveled{}

mlevel.SetLevel(INFO, "module-xyz-info")
mlevel.SetLevel(DEBUG, "module-xyz-debug")
mlevel.SetLevel(ERROR, "module-xyz-error")
mlevel.SetLevel(WARNING, "module-xyz-warning")

//Run info level checks
verifyTrue(t, mlevel.IsEnabledFor(INFO, "module-xyz-info"))
verifyFalse(t, mlevel.IsEnabledFor(DEBUG, "module-xyz-info"))
verifyTrue(t, mlevel.IsEnabledFor(ERROR, "module-xyz-info"))
verifyTrue(t, mlevel.IsEnabledFor(WARNING, "module-xyz-info"))

//Run debug level checks
verifyTrue(t, mlevel.IsEnabledFor(INFO, "module-xyz-debug"))
verifyTrue(t, mlevel.IsEnabledFor(DEBUG, "module-xyz-debug"))
verifyTrue(t, mlevel.IsEnabledFor(ERROR, "module-xyz-debug"))
verifyTrue(t, mlevel.IsEnabledFor(WARNING, "module-xyz-debug"))

//Run info level checks
verifyFalse(t, mlevel.IsEnabledFor(INFO, "module-xyz-error"))
verifyFalse(t, mlevel.IsEnabledFor(DEBUG, "module-xyz-error"))
verifyTrue(t, mlevel.IsEnabledFor(ERROR, "module-xyz-error"))
verifyFalse(t, mlevel.IsEnabledFor(WARNING, "module-xyz-error"))

//Run info level checks
verifyFalse(t, mlevel.IsEnabledFor(INFO, "module-xyz-warning"))
verifyFalse(t, mlevel.IsEnabledFor(DEBUG, "module-xyz-warning"))
verifyTrue(t, mlevel.IsEnabledFor(ERROR, "module-xyz-warning"))
verifyTrue(t, mlevel.IsEnabledFor(WARNING, "module-xyz-warning"))

//Run default log level check --> which is info currently
verifyTrue(t, mlevel.IsEnabledFor(INFO, "module-xyz-random-module"))
verifyFalse(t, mlevel.IsEnabledFor(DEBUG, "module-xyz-random-module"))
verifyTrue(t, mlevel.IsEnabledFor(ERROR, "module-xyz-random-module"))
verifyTrue(t, mlevel.IsEnabledFor(WARNING, "module-xyz-random-module"))

}

func TestGetLogLevels(t *testing.T) {

level, err := LogLevel("info")
verifyLogLevel(t, INFO, level, err, true)

level, err = LogLevel("iNfO")
verifyLogLevel(t, INFO, level, err, true)

level, err = LogLevel("debug")
verifyLogLevel(t, DEBUG, level, err, true)

level, err = LogLevel("DeBuG")
verifyLogLevel(t, DEBUG, level, err, true)

level, err = LogLevel("warning")
verifyLogLevel(t, WARNING, level, err, true)

level, err = LogLevel("WarNIng")
verifyLogLevel(t, WARNING, level, err, true)

level, err = LogLevel("error")
verifyLogLevel(t, ERROR, level, err, true)

level, err = LogLevel("eRRoR")
verifyLogLevel(t, ERROR, level, err, true)

level, err = LogLevel("outofthebox")
verifyLogLevel(t, -1, level, err, false)

level, err = LogLevel("")
verifyLogLevel(t, -1, level, err, false)
}

func verifyLogLevel(t *testing.T, expectedLevel Level, currentlevel Level, err error, success bool) {
if success {
verifyEmpty(t, err, "not supposed to get error for this scenario")
} else {
verifyNotEmpty(t, err, "supposed to get error for this scenario, but got error : %v", err)
return
}

verifyTrue(t, currentlevel == expectedLevel, "unexpected log level : expected '%s', but got '%s'", expectedLevel, currentlevel)
}
Loading

0 comments on commit 17ad794

Please sign in to comment.