summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Wojciechowski <l.wojciechow@partner.samsung.com>2018-07-19 14:30:28 +0200
committerLukasz Wojciechowski <l.wojciechow@partner.samsung.com>2018-09-20 20:12:40 +0200
commita79eef9b30b2b1f547d37b9f3458bf1a152aa308 (patch)
tree9ffa29741afdcd9ef3574ff1d892930186141685
parent3f292640a204e4ddef6090a29205f6d3ff968ce3 (diff)
downloadslav-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.go24
-rw-r--r--logger/level.go5
-rw-r--r--logger/level_test.go19
-rw-r--r--logger/logger.go74
-rw-r--r--logger/logger_test.go103
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)
+ }
+ }
+ })
+ })
+ })
+})