diff options
author | Lukasz Wojciechowski <l.wojciechow@partner.samsung.com> | 2018-07-19 14:30:28 +0200 |
---|---|---|
committer | Lukasz Wojciechowski <l.wojciechow@partner.samsung.com> | 2018-09-20 20:12:40 +0200 |
commit | a79eef9b30b2b1f547d37b9f3458bf1a152aa308 (patch) | |
tree | 9ffa29741afdcd9ef3574ff1d892930186141685 | |
parent | 3f292640a204e4ddef6090a29205f6d3ff968ce3 (diff) | |
download | slav-a79eef9b30b2b1f547d37b9f3458bf1a152aa308.tar.gz slav-a79eef9b30b2b1f547d37b9f3458bf1a152aa308.tar.bz2 slav-a79eef9b30b2b1f547d37b9f3458bf1a152aa308.zip |
Define initial version of Logger
The new instance of a Logger can be created with NewLogger function.
It has one field: threshold defined, which is a general level for
the whole logger. Only more important log entries
(with lower Level value) will be processed by the Logger.
Patch defines SetThreshold and Threshold setter and getter
and a function PassThreshold for verification if entry level passes
Logger's threshold.
Change-Id: I3db0738dce2faef83f1e223c692465947f979535
Signed-off-by: Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
-rw-r--r-- | logger/error.go | 24 | ||||
-rw-r--r-- | logger/level.go | 5 | ||||
-rw-r--r-- | logger/level_test.go | 19 | ||||
-rw-r--r-- | logger/logger.go | 74 | ||||
-rw-r--r-- | logger/logger_test.go | 103 |
5 files changed, 225 insertions, 0 deletions
diff --git a/logger/error.go b/logger/error.go new file mode 100644 index 0000000..1cfec6a --- /dev/null +++ b/logger/error.go @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 "errors" + +var ( + // ErrInvalidLogLevel is returned in case of unknown log level usage. + ErrInvalidLogLevel = errors.New("invalid log level") +) diff --git a/logger/level.go b/logger/level.go index 0e8959c..2019f10 100644 --- a/logger/level.go +++ b/logger/level.go @@ -70,3 +70,8 @@ func (l Level) String() string { return "unknown" } } + +// IsValid verifies if level has a valid value. +func (l Level) IsValid() bool { + return (l <= DebugLevel) +} diff --git a/logger/level_test.go b/logger/level_test.go index 452ac98..2607a2c 100644 --- a/logger/level_test.go +++ b/logger/level_test.go @@ -37,4 +37,23 @@ var _ = Describe("Level", func() { T.Entry("DebugLevel", DebugLevel, "debug"), T.Entry("Unknown level", Level(0xBADC0DE), "unknown"), ) + Describe("IsValid", func() { + T.DescribeTable("should treat known log level as valid", + func(level Level) { + Expect(level.IsValid()).To(BeTrue()) + }, + T.Entry("EmergLevel", EmergLevel), + T.Entry("AlertLevel", AlertLevel), + T.Entry("CritLevel", CritLevel), + T.Entry("ErrLevel", ErrLevel), + T.Entry("WarningLevel", WarningLevel), + T.Entry("NoticeLevel", NoticeLevel), + T.Entry("InfoLevel", InfoLevel), + T.Entry("DebugLevel", DebugLevel), + ) + It("should treat unknown log level as invalid", func() { + badLevel := Level(0xBADC0DE) + Expect(badLevel.IsValid()).To(BeFalse()) + }) + }) }) diff --git a/logger/logger.go b/logger/logger.go new file mode 100644 index 0000000..45711a3 --- /dev/null +++ b/logger/logger.go @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 provides logging mechanism for SLAV projects. +package logger + +import ( + "sync" +) + +const ( + // DefaultThreshold is the default level of each newly created Logger. + DefaultThreshold = InfoLevel +) + +// Logger defines type for a single logger instance. +type Logger struct { + // threshold defines filter level for entries. + // Only entries with level equal or less than threshold will be logged. + // The default threshold is set to InfoLevel. + threshold Level + + // mutex protects Logger structure from concurrent access. + mutex *sync.Mutex +} + +// NewLogger creates a new Logger instance with default configuration. +// Default level threshold is set to InfoLevel. +func NewLogger() *Logger { + return &Logger{ + threshold: DefaultThreshold, + mutex: new(sync.Mutex), + } +} + +// SetThreshold defines Logger's filter level. +// Only entries with level equal or less than threshold will be logged. +func (l *Logger) SetThreshold(level Level) error { + if !level.IsValid() { + return ErrInvalidLogLevel + } + + l.mutex.Lock() + defer l.mutex.Unlock() + l.threshold = level + return nil +} + +// Threshold returns current Logger's filter level. +func (l *Logger) Threshold() Level { + l.mutex.Lock() + defer l.mutex.Unlock() + return l.threshold +} + +// PassThreshold verifies if message with given level passes threshold and should be logged. +func (l *Logger) PassThreshold(level Level) bool { + l.mutex.Lock() + defer l.mutex.Unlock() + return (level <= l.threshold) +} diff --git a/logger/logger_test.go b/logger/logger_test.go new file mode 100644 index 0000000..7d0e51f --- /dev/null +++ b/logger/logger_test.go @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 ( + . "github.com/onsi/ginkgo" + T "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/gomega" +) + +var _ = Describe("Logger", func() { + var L *Logger + + BeforeEach(func() { + L = NewLogger() + }) + + Describe("NewLogger", func() { + It("should create a new default logger object", func() { + Expect(L).NotTo(BeNil()) + Expect(L.mutex).NotTo(BeNil()) + L.mutex.Lock() + defer L.mutex.Unlock() + Expect(L.threshold).To(Equal(DefaultThreshold)) + }) + }) + Describe("Threshold", func() { + Describe("SetThreshold", func() { + T.DescribeTable("should set valid log level", + func(level Level) { + err := L.SetThreshold(level) + Expect(err).NotTo(HaveOccurred()) + L.mutex.Lock() + defer L.mutex.Unlock() + Expect(L.threshold).To(Equal(level)) + }, + T.Entry("EmergLevel", EmergLevel), + T.Entry("AlertLevel", AlertLevel), + T.Entry("CritLevel", CritLevel), + T.Entry("ErrLevel", ErrLevel), + T.Entry("WarningLevel", WarningLevel), + T.Entry("NoticeLevel", NoticeLevel), + T.Entry("InfoLevel", InfoLevel), + T.Entry("DebugLevel", DebugLevel), + ) + It("should fail to set invalid log level", func() { + badLevel := Level(0xBADC0DE) + err := L.SetThreshold(badLevel) + Expect(err).To(Equal(ErrInvalidLogLevel)) + Expect(L.threshold).To(Equal(DefaultThreshold)) + }) + }) + Describe("Threshold", func() { + T.DescribeTable("should return log level", + func(level Level) { + err := L.SetThreshold(level) + Expect(err).NotTo(HaveOccurred()) + + retLevel := L.Threshold() + Expect(retLevel).To(Equal(level)) + }, + T.Entry("EmergLevel", EmergLevel), + T.Entry("AlertLevel", AlertLevel), + T.Entry("CritLevel", CritLevel), + T.Entry("ErrLevel", ErrLevel), + T.Entry("WarningLevel", WarningLevel), + T.Entry("NoticeLevel", NoticeLevel), + T.Entry("InfoLevel", InfoLevel), + T.Entry("DebugLevel", DebugLevel), + ) + }) + Describe("PassThreshold", func() { + It("should pass threshold for high priority levels", func() { + levels := []Level{EmergLevel, AlertLevel, CritLevel, ErrLevel, WarningLevel, NoticeLevel, InfoLevel, DebugLevel, Level(0xBADC0DE)} + for ti, thr := range levels[:len(levels)-1] { + err := L.SetThreshold(thr) + Expect(err).NotTo(HaveOccurred(), "setting threshold to %s", thr) + + for _, lvl := range levels[:ti] { + Expect(L.PassThreshold(lvl)).To(BeTrue(), "threshold %s; level %s", thr, lvl) + } + for _, lvl := range levels[ti+1:] { + Expect(L.PassThreshold(lvl)).To(BeFalse(), "threshold %s; level %s", thr, lvl) + } + } + }) + }) + }) +}) |