├── .gitignore
├── CODEOWNERS
├── in-repo.yaml
├── images
├── go-logger.png
└── go-logger.svg
├── .travis.yml
├── shims
├── _fake
│ ├── fake_test.go
│ ├── fake_suite_test.go
│ └── fake_logger.go
├── kitlog
│ ├── kitlog_suite_test.go
│ ├── kitlog.go
│ └── kitlog_test.go
├── zerolog
│ ├── zerolog_suite_test.go
│ ├── zerolog.go
│ └── zerolog_test.go
├── logrus
│ ├── logrus_suite_test.go
│ ├── logrus.go
│ └── logrus_test.go
└── testlog
│ ├── testlog_suite_test.go
│ ├── safe.go
│ ├── testlog.go
│ └── testlog_test.go
├── log_suite_test.go
├── LICENSE
├── _example
└── example.go
├── Makefile
├── log_test.go
├── log.go
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | .idea
3 |
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @InVisionApp/architecture
--------------------------------------------------------------------------------
/in-repo.yaml:
--------------------------------------------------------------------------------
1 | owner:
2 | active:
3 | team: core
4 | since: 2018-02-04
5 |
--------------------------------------------------------------------------------
/images/go-logger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/InVisionApp/go-logger/HEAD/images/go-logger.png
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | before_install:
4 | - go get -t -v ./...
5 |
6 | script:
7 | - make test/codecov
8 |
9 | after_success:
10 | - bash <(curl -s https://codecov.io/bash)
11 |
--------------------------------------------------------------------------------
/shims/_fake/fake_test.go:
--------------------------------------------------------------------------------
1 | package fake
2 |
3 | import (
4 | "github.com/InVisionApp/go-logger"
5 | . "github.com/onsi/ginkgo"
6 | )
7 |
8 | var _ = Describe("meets the interface", func() {
9 | var _ log.Logger = &FakeLogger{}
10 | })
11 |
--------------------------------------------------------------------------------
/shims/kitlog/kitlog_suite_test.go:
--------------------------------------------------------------------------------
1 | package kitlog_test
2 |
3 | import (
4 | . "github.com/onsi/ginkgo"
5 | . "github.com/onsi/gomega"
6 |
7 | "testing"
8 | )
9 |
10 | func TestKitlog(t *testing.T) {
11 | RegisterFailHandler(Fail)
12 | RunSpecs(t, "Kitlog Suite")
13 | }
14 |
--------------------------------------------------------------------------------
/shims/zerolog/zerolog_suite_test.go:
--------------------------------------------------------------------------------
1 | package zerolog_test
2 |
3 | import (
4 | . "github.com/onsi/ginkgo"
5 | . "github.com/onsi/gomega"
6 |
7 | "testing"
8 | )
9 |
10 | func TestZerolog(t *testing.T) {
11 | RegisterFailHandler(Fail)
12 | RunSpecs(t, "Zerolog Suite")
13 | }
14 |
--------------------------------------------------------------------------------
/log_suite_test.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/sirupsen/logrus"
7 |
8 | . "github.com/onsi/ginkgo"
9 | . "github.com/onsi/gomega"
10 | )
11 |
12 | func TestLoggersSuite(t *testing.T) {
13 | // reduce the noise when testing
14 | logrus.SetLevel(logrus.FatalLevel)
15 |
16 | RegisterFailHandler(Fail)
17 | RunSpecs(t, "Loggers Suite")
18 | }
19 |
--------------------------------------------------------------------------------
/shims/logrus/logrus_suite_test.go:
--------------------------------------------------------------------------------
1 | package logrus
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/sirupsen/logrus"
7 |
8 | . "github.com/onsi/ginkgo"
9 | . "github.com/onsi/gomega"
10 | )
11 |
12 | func TestLogrusSuite(t *testing.T) {
13 | // reduce the noise when testing
14 | logrus.SetLevel(logrus.FatalLevel)
15 |
16 | RegisterFailHandler(Fail)
17 | RunSpecs(t, "Logrus Suite")
18 | }
19 |
--------------------------------------------------------------------------------
/shims/_fake/fake_suite_test.go:
--------------------------------------------------------------------------------
1 | package fake
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/sirupsen/logrus"
7 |
8 | . "github.com/onsi/ginkgo"
9 | . "github.com/onsi/gomega"
10 | )
11 |
12 | func TestFakeLoggerSuite(t *testing.T) {
13 | // reduce the noise when testing
14 | logrus.SetLevel(logrus.FatalLevel)
15 |
16 | RegisterFailHandler(Fail)
17 | RunSpecs(t, "FakeLogger Suite")
18 | }
19 |
--------------------------------------------------------------------------------
/shims/testlog/testlog_suite_test.go:
--------------------------------------------------------------------------------
1 | package testlog
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/sirupsen/logrus"
7 |
8 | . "github.com/onsi/ginkgo"
9 | . "github.com/onsi/gomega"
10 | )
11 |
12 | func TestSuiteNameSuite(t *testing.T) {
13 | // reduce the noise when testing
14 | logrus.SetLevel(logrus.FatalLevel)
15 |
16 | RegisterFailHandler(Fail)
17 | RunSpecs(t, "SuiteName Suite")
18 | }
19 |
--------------------------------------------------------------------------------
/shims/testlog/safe.go:
--------------------------------------------------------------------------------
1 | package testlog
2 |
3 | import "sync"
4 |
5 | /*************
6 | Safe Counter
7 | *************/
8 |
9 | type counter struct {
10 | num int
11 | mu *sync.Mutex
12 | }
13 |
14 | //New counter stating at 0
15 | func newCounter() *counter {
16 | return &counter{num: 0, mu: &sync.Mutex{}}
17 | }
18 |
19 | func (c *counter) inc() {
20 | c.mu.Lock()
21 | defer c.mu.Unlock()
22 | c.num++
23 | }
24 |
25 | func (c *counter) reset() {
26 | c.mu.Lock()
27 | defer c.mu.Unlock()
28 | c.num = 0
29 | }
30 |
31 | func (c *counter) val() int {
32 | c.mu.Lock()
33 | defer c.mu.Unlock()
34 | return c.num
35 | }
36 |
--------------------------------------------------------------------------------
/shims/logrus/logrus.go:
--------------------------------------------------------------------------------
1 | package logrus
2 |
3 | import (
4 | "github.com/InVisionApp/go-logger"
5 | "github.com/sirupsen/logrus"
6 | )
7 |
8 | type shim struct {
9 | *logrus.Entry
10 | }
11 |
12 | // NewLogrus can be used to override the default logger.
13 | // Optionally pass in an existing logrus logger or pass in
14 | // `nil` to use the default logger.
15 | func New(logger *logrus.Logger) log.Logger {
16 | if logger == nil {
17 | logger = logrus.StandardLogger()
18 | }
19 |
20 | return &shim{logrus.NewEntry(logger)}
21 | }
22 |
23 | // WithFields will return a new logger based on the original logger with
24 | // the additional supplied fields. Wrapper for logrus Entry.WithFields()
25 | func (s *shim) WithFields(fields log.Fields) log.Logger {
26 | cp := &shim{
27 | s.Entry.WithFields(logrus.Fields(fields)),
28 | }
29 | return cp
30 | }
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 InVision
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/_example/example.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 |
7 | "github.com/InVisionApp/go-logger"
8 | "github.com/InVisionApp/go-logger/shims/_fake"
9 | "github.com/InVisionApp/go-logger/shims/logrus"
10 | "github.com/InVisionApp/go-logger/shims/testlog"
11 | )
12 |
13 | func main() {
14 | /**********************
15 | Simple, no-op, logrus
16 | **********************/
17 |
18 | loggers := map[string]log.Logger{
19 | "Simple": log.NewSimple(),
20 | "No-op": log.NewNoop(),
21 | "Logrus": logrus.New(nil),
22 | }
23 |
24 | // sleeps for print order
25 | for name, lg := range loggers {
26 | time.Sleep(time.Millisecond * 10)
27 | fmt.Printf("__%s Logger__________\n", name)
28 | time.Sleep(time.Millisecond * 10)
29 |
30 | lg.Info(name, "logger")
31 | lg.WithFields(log.Fields{"foo": "bar"}).Errorf("%s logger", name)
32 |
33 | time.Sleep(time.Millisecond * 10)
34 | fmt.Println()
35 | }
36 |
37 | time.Sleep(time.Millisecond * 10)
38 |
39 | /************
40 | Test Logger
41 | ************/
42 |
43 | fmt.Println("__Test Logger__________")
44 | tl := testlog.New()
45 | tl.Infof("this is a test %s", "log")
46 | fmt.Print(string(tl.Bytes()))
47 | fmt.Println("call count:", tl.CallCount())
48 | fmt.Println()
49 |
50 | /************
51 | Fake Logger
52 | ************/
53 |
54 | fmt.Println("__Fake Logger__________")
55 | fakeLog := &fake.FakeLogger{}
56 |
57 | fakeLog.Debug("this is a ", "fakelog")
58 | fmt.Println("call count:", fakeLog.DebugCallCount())
59 | }
60 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | OUTPUT_DIR = build
2 | TMP_DIR := .tmp
3 | RELEASE_VER := $(shell git rev-parse --short HEAD)
4 | NAME = default
5 | COVERMODE = atomic
6 |
7 | TEST_PACKAGES := $(shell go list ./... | grep -v vendor | grep -v fakes)
8 |
9 | .PHONY: help
10 | .DEFAULT_GOAL := help
11 |
12 | test: getdeps test/integration ## Perform both unit and integration tests
13 |
14 | testv: getdeps testv/integration ## Perform both unit and integration tests (with verbose flags)
15 |
16 | test/unit: ## Perform unit tests
17 | go test -cover $(TEST_PACKAGES)
18 |
19 | testv/unit: ## Perform unit tests (with verbose flag)
20 | go test -v -cover $(TEST_PACKAGES)
21 |
22 | test/integration: ## Perform integration tests
23 | go test -cover -tags integration $(TEST_PACKAGES)
24 |
25 | testv/integration: ## Perform integration tests
26 | go test -v -cover -tags integration $(TEST_PACKAGES)
27 |
28 | test/race: ## Perform unit tests and enable the race detector
29 | go test -race -cover $(TEST_PACKAGES)
30 |
31 | test/cover: ## Run all tests + open coverage report for all packages
32 | echo 'mode: $(COVERMODE)' > .coverage
33 | for PKG in $(TEST_PACKAGES); do \
34 | go test -coverprofile=.coverage.tmp -tags "integration" $$PKG; \
35 | grep -v -E '^mode:' .coverage.tmp >> .coverage; \
36 | done
37 | go tool cover -html=.coverage
38 | $(RM) .coverage .coverage.tmp
39 |
40 | test/codecov: ## Run all tests + open coverage report for all packages
41 | ECODE=0; \
42 | for PKG in $(TEST_PACKAGES); do \
43 | go test -covermode=$(COVERMODE) -coverprofile=profile.out $$PKG; \
44 | ECODE=$$((ECODE+$$?));\
45 | if [ -f profile.out ]; then\
46 | cat profile.out >> coverage.txt;\
47 | rm profile.out;\
48 | fi;\
49 | done;\
50 | $(RM) profile.out ;\
51 | exit $$ECODE;\
52 |
53 | getdeps: ## Install needed dependencies for various middlewares
54 | go get -t -v ./...
55 |
56 | generate: ## Run generate for non-vendor packages only
57 | go list ./... | grep -v vendor | xargs go generate
58 |
59 | help: ## Display this help message
60 | @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_\/-]+:.*?## / {printf "\033[34m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | \
61 | sort | \
62 | grep -v '#'
63 |
--------------------------------------------------------------------------------
/shims/kitlog/kitlog.go:
--------------------------------------------------------------------------------
1 | package kitlog
2 |
3 | import (
4 | "fmt"
5 | "os"
6 |
7 | "github.com/InVisionApp/go-logger"
8 | kitlog "github.com/go-kit/kit/log"
9 | "github.com/go-kit/kit/log/level"
10 | )
11 |
12 | type shim struct {
13 | logger kitlog.Logger
14 | }
15 |
16 | // New can be used to override the default logger.
17 | // Optionally pass in an existing kitlog logger or
18 | // pass in `nil` to use the default logger.
19 | func New(logger kitlog.Logger) log.Logger {
20 | if logger == nil {
21 | logger = kitlog.NewLogfmtLogger(kitlog.NewSyncWriter(os.Stdout))
22 | }
23 |
24 | return &shim{logger: logger}
25 | }
26 |
27 | // this will add a space between all elements in the slice
28 | // this func is needed because fmt.Sprint will not separate
29 | // inputs by a space in all cases, which makes the resulting
30 | // output very hard to read
31 | func spaceSep(a []interface{}) []interface{} {
32 | aLen := len(a)
33 | if aLen <= 1 {
34 | return a
35 | }
36 |
37 | // we only allocate enough room to add a single space between
38 | // all elements, so len(a) - 1
39 | spaceSlice := make([]interface{}, aLen-1)
40 | // add the empty space to the end of the original slice
41 | a = append(a, spaceSlice...)
42 |
43 | // stagger the values. this will leave an empty slot between all
44 | // values to be filled with a space
45 | for i := aLen - 1; i > 0; i-- {
46 | a[i+i] = a[i]
47 | a[i+i-1] = " "
48 | }
49 |
50 | return a
51 | }
52 |
53 | func (s *shim) Debug(msg ...interface{}) {
54 | level.Debug(s.logger).Log("msg", fmt.Sprint(spaceSep(msg)...))
55 | }
56 |
57 | func (s *shim) Info(msg ...interface{}) {
58 | level.Info(s.logger).Log("msg", fmt.Sprint(spaceSep(msg)...))
59 | }
60 |
61 | func (s *shim) Warn(msg ...interface{}) {
62 | level.Warn(s.logger).Log("msg", fmt.Sprint(spaceSep(msg)...))
63 | }
64 |
65 | func (s *shim) Error(msg ...interface{}) {
66 | level.Error(s.logger).Log("msg", fmt.Sprint(spaceSep(msg)...))
67 | }
68 |
69 | func (s *shim) Debugln(msg ...interface{}) {
70 | level.Debug(s.logger).Log("msg", fmt.Sprint(spaceSep(msg)...))
71 | }
72 |
73 | func (s *shim) Infoln(msg ...interface{}) {
74 | level.Info(s.logger).Log("msg", fmt.Sprint(spaceSep(msg)...))
75 | }
76 |
77 | func (s *shim) Warnln(msg ...interface{}) {
78 | level.Warn(s.logger).Log("msg", fmt.Sprint(spaceSep(msg)...))
79 | }
80 |
81 | func (s *shim) Errorln(msg ...interface{}) {
82 | level.Error(s.logger).Log("msg", fmt.Sprint(spaceSep(msg)...))
83 | }
84 |
85 | func (s *shim) Debugf(format string, args ...interface{}) {
86 | level.Debug(s.logger).Log("msg", fmt.Sprintf(format, args...))
87 | }
88 |
89 | func (s *shim) Infof(format string, args ...interface{}) {
90 | level.Info(s.logger).Log("msg", fmt.Sprintf(format, args...))
91 | }
92 |
93 | func (s *shim) Warnf(format string, args ...interface{}) {
94 | level.Warn(s.logger).Log("msg", fmt.Sprintf(format, args...))
95 | }
96 |
97 | func (s *shim) Errorf(format string, args ...interface{}) {
98 | level.Error(s.logger).Log("msg", fmt.Sprintf(format, args...))
99 | }
100 |
101 | // WithFields will return a new logger derived from the original
102 | // kitlog logger, with the provided fields added to the log string,
103 | // as a key-value pair
104 | func (s *shim) WithFields(fields log.Fields) log.Logger {
105 | var keyvals []interface{}
106 |
107 | for key, value := range fields {
108 | keyvals = append(keyvals, key, value)
109 | }
110 |
111 | return &shim{
112 | logger: kitlog.With(s.logger, keyvals...),
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/shims/zerolog/zerolog.go:
--------------------------------------------------------------------------------
1 | package zerolog
2 |
3 | import (
4 | "fmt"
5 | "os"
6 |
7 | "github.com/InVisionApp/go-logger"
8 | "github.com/rs/zerolog"
9 | )
10 |
11 | type shim struct {
12 | logger *zerolog.Logger
13 | }
14 |
15 | // New can be used to override the default logger.
16 | // Optionally pass in an existing zerolog logger or
17 | // pass in `nil` to use the default logger
18 | func New(logger *zerolog.Logger) log.Logger {
19 | if logger == nil {
20 | lg := zerolog.New(os.Stdout).With().Timestamp().Logger()
21 | logger = &lg
22 | }
23 |
24 | return &shim{logger: logger}
25 | }
26 |
27 | // this will add a space between all elements in the slice
28 | // this func is needed because fmt.Sprint will not separate
29 | // inputs by a space in all cases, which makes the resulting
30 | // output very hard to read
31 | func spaceSep(a []interface{}) []interface{} {
32 | aLen := len(a)
33 | if aLen <= 1 {
34 | return a
35 | }
36 |
37 | // we only allocate enough room to add a single space between
38 | // all elements, so len(a) - 1
39 | spaceSlice := make([]interface{}, aLen-1)
40 | // add the empty space to the end of the original slice
41 | a = append(a, spaceSlice...)
42 |
43 | // stagger the values. this will leave an empty slot between all
44 | // values to be filled with a space
45 | for i := aLen - 1; i > 0; i-- {
46 | a[i+i] = a[i]
47 | a[i+i-1] = " "
48 | }
49 |
50 | return a
51 | }
52 |
53 | func (s *shim) Debug(msg ...interface{}) {
54 | s.logger.Debug().Msg(fmt.Sprint(spaceSep(msg)...))
55 | }
56 |
57 | func (s *shim) Info(msg ...interface{}) {
58 | s.logger.Info().Msg(fmt.Sprint(spaceSep(msg)...))
59 | }
60 |
61 | func (s *shim) Warn(msg ...interface{}) {
62 | s.logger.Warn().Msg(fmt.Sprint(spaceSep(msg)...))
63 | }
64 |
65 | func (s *shim) Error(msg ...interface{}) {
66 | s.logger.Error().Msg(fmt.Sprint(spaceSep(msg)...))
67 | }
68 |
69 | /*******************************************************************
70 | *ln funcs
71 | zerolog is a json-only structured logger.
72 | To implement human-readable console logging,
73 | you must initialize the logger using zerolog.ConsoleWriter
74 | as your io.Writer. Calling a *ln func when zerolog
75 | is in structured logging mode is a no-op
76 | *******************************************************************/
77 |
78 | func (s *shim) Debugln(msg ...interface{}) {
79 | msg = append(msg, "\n")
80 | s.logger.Debug().Msg(fmt.Sprint(spaceSep(msg)...))
81 | }
82 |
83 | func (s *shim) Infoln(msg ...interface{}) {
84 | msg = append(msg, "\n")
85 | s.logger.Info().Msg(fmt.Sprint(spaceSep(msg)...))
86 | }
87 |
88 | func (s *shim) Warnln(msg ...interface{}) {
89 | msg = append(msg, "\n")
90 | s.logger.Warn().Msg(fmt.Sprint(spaceSep(msg)...))
91 | }
92 |
93 | func (s *shim) Errorln(msg ...interface{}) {
94 | msg = append(msg, "\n")
95 | s.logger.Error().Msg(fmt.Sprint(spaceSep(msg)...))
96 | }
97 |
98 | func (s *shim) Debugf(format string, args ...interface{}) {
99 | s.logger.Debug().Msgf(format, args...)
100 | }
101 |
102 | func (s *shim) Infof(format string, args ...interface{}) {
103 | s.logger.Info().Msgf(format, args...)
104 | }
105 |
106 | func (s *shim) Warnf(format string, args ...interface{}) {
107 | s.logger.Warn().Msgf(format, args...)
108 | }
109 |
110 | func (s *shim) Errorf(format string, args ...interface{}) {
111 | s.logger.Error().Msgf(format, args...)
112 | }
113 |
114 | // WithFields will return a new logger derived from the original
115 | // zerolog logger, with the provided fields added to the log string,
116 | // as a key-value pair
117 | func (s *shim) WithFields(fields log.Fields) log.Logger {
118 | lg := s.logger.With().Fields(fields).Logger()
119 | s.logger = &lg
120 |
121 | return s
122 | }
123 |
--------------------------------------------------------------------------------
/shims/testlog/testlog.go:
--------------------------------------------------------------------------------
1 | package testlog
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 |
7 | "github.com/InVisionApp/go-logger"
8 | )
9 |
10 | // TestLogger is used to capture logs during the execution of a test.
11 | // It writes the logs to a byte buffer which can be dumped and
12 | // inspected. It also tracks a call count of the total number of
13 | // times the logger has been called. Note that this logger is not
14 | // meant to be used in production. It is meant only for tests.
15 | type TestLogger struct {
16 | buf *bytes.Buffer
17 | count *counter
18 | fields map[string]interface{}
19 | }
20 |
21 | // NewTestLog generates a new TestLogger
22 | func New() *TestLogger {
23 | b := &bytes.Buffer{}
24 |
25 | return &TestLogger{
26 | buf: b,
27 | count: newCounter(),
28 | }
29 | }
30 |
31 | // Bytes returns all bytes of the log buffer
32 | func (t *TestLogger) Bytes() []byte {
33 | return t.buf.Bytes()
34 | }
35 |
36 | // CallCount returns the number of times this logger was called
37 | func (t *TestLogger) CallCount() int {
38 | return t.count.val()
39 | }
40 |
41 | // Reset the log buffer and call count
42 | func (t *TestLogger) Reset() {
43 | t.buf.Reset()
44 | t.count.reset()
45 | }
46 |
47 | func (t *TestLogger) write(level, msg string) {
48 | t.buf.WriteString(fmt.Sprintf("[%s] %s %s", level, msg, pretty(t.fields)+"\n"))
49 | t.count.inc()
50 | }
51 |
52 | //Debugln log line message
53 | func (t *TestLogger) Debugln(msg ...interface{}) {
54 | a := fmt.Sprintln(msg...)
55 | t.write("DEBUG", a[:len(a)-1])
56 | }
57 |
58 | //Infoln log line message
59 | func (t *TestLogger) Infoln(msg ...interface{}) {
60 | a := fmt.Sprintln(msg...)
61 | t.write("INFO", a[:len(a)-1])
62 | }
63 |
64 | //Warnln log line message
65 | func (t *TestLogger) Warnln(msg ...interface{}) {
66 | a := fmt.Sprintln(msg...)
67 | t.write("WARN", a[:len(a)-1])
68 | }
69 |
70 | //Errorln log line message
71 | func (t *TestLogger) Errorln(msg ...interface{}) {
72 | a := fmt.Sprintln(msg...)
73 | t.write("ERROR", a[:len(a)-1])
74 | }
75 |
76 | // Debug log message
77 | func (t *TestLogger) Debug(msg ...interface{}) {
78 | t.write("DEBUG", fmt.Sprint(msg...))
79 | }
80 |
81 | // Info log message
82 | func (t *TestLogger) Info(msg ...interface{}) {
83 | t.write("INFO", fmt.Sprint(msg...))
84 | }
85 |
86 | // Warn log message
87 | func (t *TestLogger) Warn(msg ...interface{}) {
88 | t.write("WARN", fmt.Sprint(msg...))
89 | }
90 |
91 | // Error log message
92 | func (t *TestLogger) Error(msg ...interface{}) {
93 | t.write("ERROR", fmt.Sprint(msg...))
94 | }
95 |
96 | // Debugf log message with formatting
97 | func (t *TestLogger) Debugf(format string, args ...interface{}) {
98 | t.write("DEBUG", fmt.Sprintf(format, args...))
99 | }
100 |
101 | // Infof log message with formatting
102 | func (t *TestLogger) Infof(format string, args ...interface{}) {
103 | t.write("INFO", fmt.Sprintf(format, args...))
104 | }
105 |
106 | // Warnf log message with formatting
107 | func (t *TestLogger) Warnf(format string, args ...interface{}) {
108 | t.write("WARN", fmt.Sprintf(format, args...))
109 | }
110 |
111 | // Errorf log message with formatting
112 | func (t *TestLogger) Errorf(format string, args ...interface{}) {
113 | t.write("ERROR", fmt.Sprintf(format, args...))
114 | }
115 |
116 | // WithFields will return a new logger based on the original logger
117 | // with the additional supplied fields
118 | func (t *TestLogger) WithFields(fields log.Fields) log.Logger {
119 | cp := &TestLogger{
120 | buf: t.buf,
121 | count: t.count,
122 | }
123 |
124 | if t.fields == nil {
125 | cp.fields = fields
126 | return cp
127 | }
128 |
129 | cp.fields = make(map[string]interface{}, len(t.fields)+len(fields))
130 | for k, v := range t.fields {
131 | cp.fields[k] = v
132 | }
133 |
134 | for k, v := range fields {
135 | cp.fields[k] = v
136 | }
137 |
138 | return cp
139 | }
140 |
141 | // helper for pretty printing of fields
142 | func pretty(m map[string]interface{}) string {
143 | if len(m) < 1 {
144 | return ""
145 | }
146 |
147 | s := ""
148 | for k, v := range m {
149 | s += fmt.Sprintf("%s=%v ", k, v)
150 | }
151 |
152 | return s[:len(s)-1]
153 | }
154 |
--------------------------------------------------------------------------------
/shims/logrus/logrus_test.go:
--------------------------------------------------------------------------------
1 | package logrus
2 |
3 | import (
4 | "bytes"
5 |
6 | "github.com/InVisionApp/go-logger"
7 | . "github.com/onsi/ginkgo"
8 | . "github.com/onsi/gomega"
9 | "github.com/sirupsen/logrus"
10 | )
11 |
12 | var _ = Describe("meets the interface", func() {
13 | var _ log.Logger = &shim{}
14 | })
15 |
16 | var _ = Describe("logrus logger", func() {
17 | var (
18 | newOut *bytes.Buffer
19 | l log.Logger
20 | )
21 |
22 | BeforeEach(func() {
23 | newOut = &bytes.Buffer{}
24 | logrus.SetOutput(newOut)
25 | logrus.SetLevel(logrus.DebugLevel)
26 | l = New(nil)
27 | })
28 |
29 | Context("happy path", func() {
30 | It("prints all log levels", func() {
31 | logFuncs := map[string]func(...interface{}){
32 | "debug": l.Debug,
33 | "info": l.Info,
34 | "warn": l.Warn,
35 | "error": l.Error,
36 | }
37 |
38 | for level, logFunc := range logFuncs {
39 | logFunc("hi there")
40 |
41 | b := newOut.Bytes()
42 | newOut.Reset()
43 | Expect(string(b)).To(SatisfyAll(
44 | ContainSubstring("hi there"),
45 | ContainSubstring("level="+level),
46 | ))
47 | }
48 | })
49 |
50 | It("prints all log levels", func() {
51 | logFuncs := map[string]func(...interface{}){
52 | "debug": l.Debugln,
53 | "info": l.Infoln,
54 | "warn": l.Warnln,
55 | "error": l.Errorln,
56 | }
57 |
58 | for level, logFunc := range logFuncs {
59 | logFunc("hi", "there")
60 |
61 | b := newOut.Bytes()
62 | newOut.Reset()
63 | Expect(string(b)).To(SatisfyAll(
64 | ContainSubstring("hi there"),
65 | ContainSubstring("level="+level),
66 | ))
67 | }
68 | })
69 |
70 | It("prints all log levels on formatted", func() {
71 | logFuncs := map[string]func(string, ...interface{}){
72 | "debug": l.Debugf,
73 | "info": l.Infof,
74 | "warn": l.Warnf,
75 | "error": l.Errorf,
76 | }
77 |
78 | for level, logFunc := range logFuncs {
79 | logFunc("hi %s", "there")
80 |
81 | b := newOut.Bytes()
82 | newOut.Reset()
83 | Expect(string(b)).To(SatisfyAll(
84 | ContainSubstring("hi there"),
85 | ContainSubstring("level="+level),
86 | ))
87 | }
88 | })
89 |
90 | It("join multiple strings", func() {
91 | l.Debug("hi there ", "you")
92 |
93 | b := newOut.Bytes()
94 | Expect(string(b)).To(SatisfyAll(
95 | ContainSubstring("hi there you"),
96 | ContainSubstring("level=debug"),
97 | ))
98 | })
99 |
100 | It("formatting", func() {
101 | l.Debugf("hi there %s", "you")
102 |
103 | b := newOut.Bytes()
104 | Expect(string(b)).To(SatisfyAll(
105 | ContainSubstring("hi there you"),
106 | ContainSubstring("level=debug"),
107 | ))
108 | })
109 |
110 | Context("with fields", func() {
111 | It("appends to preexisting fields", func() {
112 | withFields := l.WithFields(map[string]interface{}{
113 | "foo": "oldval",
114 | "baz": "origval",
115 | })
116 |
117 | withFields.WithFields(map[string]interface{}{
118 | "foo": "newval",
119 | "biz": "buzz",
120 | }).Debug("hi there")
121 |
122 | b := newOut.Bytes()
123 | Expect(string(b)).To(SatisfyAll(
124 | ContainSubstring("hi there"),
125 | ContainSubstring("foo=newval"),
126 | ContainSubstring("baz=origval"),
127 | ContainSubstring("biz=buzz"),
128 | ))
129 |
130 | })
131 |
132 | It("creates a copy", func() {
133 | l.WithFields(map[string]interface{}{
134 | "foo": "bar",
135 | "baz": 2,
136 | }).Debug("hi there ", "you")
137 |
138 | b := newOut.Bytes()
139 | Expect(string(b)).To(SatisfyAll(
140 | ContainSubstring("hi there you"),
141 | ContainSubstring("foo=bar"),
142 | ContainSubstring("baz=2"),
143 | ))
144 |
145 | newOut.Reset()
146 |
147 | // should not see any of the other fields
148 |
149 | l.WithFields(map[string]interface{}{
150 | "biz": "bar",
151 | "buz": 2,
152 | }).Debugf("hi there %s", "you")
153 |
154 | bb := newOut.Bytes()
155 | Expect(string(bb)).To(SatisfyAll(
156 | ContainSubstring("hi there you"),
157 | ContainSubstring("biz=bar"),
158 | ContainSubstring("buz=2"),
159 | ))
160 | Expect(string(bb)).ToNot(SatisfyAll(
161 | ContainSubstring("foo=bar"),
162 | ContainSubstring("baz=2"),
163 | ))
164 | })
165 | })
166 | })
167 | })
168 |
--------------------------------------------------------------------------------
/shims/kitlog/kitlog_test.go:
--------------------------------------------------------------------------------
1 | package kitlog
2 |
3 | import (
4 | "bytes"
5 | "errors"
6 | "fmt"
7 | "math/rand"
8 |
9 | "github.com/InVisionApp/go-logger"
10 | kitlog "github.com/go-kit/kit/log"
11 |
12 | . "github.com/onsi/ginkgo"
13 | . "github.com/onsi/gomega"
14 | "io"
15 | "os"
16 | )
17 |
18 | var _ = Describe("satisfies interface", func() {
19 | var _ log.Logger = &shim{}
20 | })
21 |
22 | var _ = Describe("kitlog logger", func() {
23 | var (
24 | newOut *bytes.Buffer
25 | l log.Logger
26 | )
27 | BeforeEach(func() {
28 | newOut = &bytes.Buffer{}
29 | l = New(kitlog.NewLogfmtLogger(kitlog.NewSyncWriter(newOut)))
30 | })
31 | Context("spaceSep", func() {
32 | It("works on even length slices", func() {
33 | s := []interface{}{
34 | 1, "cat", errors.New("foo"), struct{ Name string }{"bar"},
35 | }
36 | s = spaceSep(s)
37 | Expect(len(s)).To(Equal(7))
38 |
39 | sstr := fmt.Sprint(s...)
40 | Expect(sstr).To(Equal("1 cat foo {bar}"))
41 | })
42 | It("works on odd length slices", func() {
43 | s := []interface{}{
44 | 1, "cat", errors.New("foo"), struct{ Name string }{"bar"}, []string{},
45 | }
46 | s = spaceSep(s)
47 | Expect(len(s)).To(Equal(9))
48 |
49 | sstr := fmt.Sprint(s...)
50 | Expect(sstr).To(Equal("1 cat foo {bar} []"))
51 | })
52 | It("works on big slices", func() {
53 | s := make([]interface{}, 10000)
54 | for i := 0; i < 10000; i++ {
55 | s[i] = rand.Intn(10)
56 | }
57 | s = spaceSep(s)
58 | Expect(len(s)).To(Equal(19999))
59 |
60 | sstr := fmt.Sprint(s...)
61 | Expect(len(sstr)).To(Equal(19999))
62 | })
63 | It("works on little slices", func() {
64 | s := []interface{}{1, 2}
65 |
66 | s = spaceSep(s)
67 | Expect(len(s)).To(Equal(3))
68 |
69 | sstr := fmt.Sprint(s...)
70 | Expect(sstr).To(Equal("1 2"))
71 | })
72 | It("works on really little slices", func() {
73 | s := []interface{}{1}
74 |
75 | s = spaceSep(s)
76 | Expect(len(s)).To(Equal(1))
77 |
78 | sstr := fmt.Sprint(s...)
79 | Expect(sstr).To(Equal("1"))
80 | })
81 | })
82 | Context("log funcs", func() {
83 | It("prints all the log levels", func() {
84 | logFuncs := map[string]func(...interface{}){
85 | "debug": l.Debug,
86 | "info": l.Info,
87 | "warn": l.Warn,
88 | "error": l.Error,
89 | }
90 |
91 | for level, logFunc := range logFuncs {
92 | logFunc("hi there")
93 |
94 | b := newOut.Bytes()
95 | newOut.Reset()
96 | Expect(string(b)).To(SatisfyAll(
97 | ContainSubstring("hi there"),
98 | ContainSubstring("level="+level),
99 | ))
100 | }
101 | })
102 | It("prints all the log levels: *ln", func() {
103 | logFuncs := map[string]func(...interface{}){
104 | "debug?": l.Debugln,
105 | "info": l.Infoln,
106 | "warn": l.Warnln,
107 | "error?": l.Errorln,
108 | }
109 | for level, logFunc := range logFuncs {
110 | logFunc("hi", "there")
111 |
112 | b := newOut.Bytes()
113 | newOut.Reset()
114 | Expect(string(b)).To(SatisfyAll(
115 | ContainSubstring("hi there"),
116 | MatchRegexp(level),
117 | ))
118 | }
119 | })
120 | It("prints all the log levels: *f", func() {
121 | logFuncs := map[string]func(string, ...interface{}){
122 | "debug": l.Debugf,
123 | "info": l.Infof,
124 | "warn": l.Warnf,
125 | "error": l.Errorf,
126 | }
127 | for level, logFunc := range logFuncs {
128 | logFunc("hi %s", "there")
129 |
130 | b := newOut.Bytes()
131 | newOut.Reset()
132 | Expect(string(b)).To(SatisfyAll(
133 | ContainSubstring("hi there"),
134 | ContainSubstring("level="+level),
135 | ))
136 | }
137 | })
138 | It("nil logger", func() {
139 | // need to intercept stdout
140 | // https://stackoverflow.com/a/10476304
141 | old := os.Stdout
142 |
143 | r, w, _ := os.Pipe()
144 | os.Stdout = w
145 |
146 | l = New(nil)
147 | l.Debug("i am default")
148 |
149 | outC := make(chan string)
150 | go func() {
151 | var buf bytes.Buffer
152 | io.Copy(&buf, r)
153 | outC <- buf.String()
154 | }()
155 | w.Close()
156 | os.Stdout = old
157 |
158 | out := <-outC
159 | Expect(out).To(MatchRegexp(`level=debug msg="i am default"`))
160 | })
161 | })
162 | Context("fields", func() {
163 | It("", func() {
164 | l = l.WithFields(log.Fields{
165 | "foo": "bar",
166 | "tf": true,
167 | "pet": "cat",
168 | "age": 1,
169 | })
170 |
171 | l.Debug("hi there")
172 | b := newOut.Bytes()
173 |
174 | Expect(string(b)).To(SatisfyAll(
175 | ContainSubstring("hi there"),
176 | ContainSubstring("level=debug"),
177 | ContainSubstring("foo=bar"),
178 | ContainSubstring("tf=true"),
179 | ContainSubstring("pet=cat"),
180 | ContainSubstring("age=1"),
181 | ))
182 | })
183 | })
184 | })
185 |
--------------------------------------------------------------------------------
/shims/testlog/testlog_test.go:
--------------------------------------------------------------------------------
1 | package testlog
2 |
3 | import (
4 | "github.com/InVisionApp/go-logger"
5 | . "github.com/onsi/ginkgo"
6 | . "github.com/onsi/gomega"
7 | )
8 |
9 | var _ = Describe("meets the interface", func() {
10 | var _ log.Logger = &TestLogger{}
11 | })
12 |
13 | var _ = Describe("test logger", func() {
14 | var (
15 | testOut *TestLogger
16 | l log.Logger
17 | )
18 |
19 | BeforeEach(func() {
20 | testOut = New()
21 | l = testOut
22 | })
23 |
24 | Context("happy path", func() {
25 | It("prints all log levels", func() {
26 | logFuncs := map[string]func(...interface{}){
27 | "DEBUG": l.Debug,
28 | "INFO": l.Info,
29 | "WARN": l.Warn,
30 | "ERROR": l.Error,
31 | }
32 |
33 | for level, logFunc := range logFuncs {
34 | logFunc("hi there")
35 |
36 | b := testOut.Bytes()
37 | testOut.Reset()
38 | Expect(string(b)).To(SatisfyAll(
39 | ContainSubstring("hi there"),
40 | ContainSubstring(level),
41 | ))
42 | }
43 | })
44 |
45 | It("prints all log line levels", func() {
46 | logFuncs := map[string]func(...interface{}){
47 | "DEBUG": l.Debugln,
48 | "INFO": l.Infoln,
49 | "WARN": l.Warnln,
50 | "ERROR": l.Errorln,
51 | }
52 |
53 | for level, logFunc := range logFuncs {
54 | logFunc("hi", "there")
55 |
56 | b := testOut.Bytes()
57 | testOut.Reset()
58 | Expect(string(b)).To(SatisfyAll(
59 | ContainSubstring("hi there"),
60 | ContainSubstring(level),
61 | ))
62 | }
63 | })
64 |
65 | It("prints all log levels on formatted", func() {
66 | logFuncs := map[string]func(string, ...interface{}){
67 | "DEBUG": l.Debugf,
68 | "INFO": l.Infof,
69 | "WARN": l.Warnf,
70 | "ERROR": l.Errorf,
71 | }
72 |
73 | for level, logFunc := range logFuncs {
74 | logFunc("hi %s", "there")
75 |
76 | b := testOut.Bytes()
77 | testOut.Reset()
78 | Expect(string(b)).To(SatisfyAll(
79 | ContainSubstring("hi there"),
80 | ContainSubstring(level),
81 | ))
82 | }
83 | })
84 |
85 | It("join multiple strings", func() {
86 | l.Debug("hi there ", "you")
87 |
88 | b := testOut.Bytes()
89 | Expect(string(b)).To(SatisfyAll(
90 | ContainSubstring("hi there you"),
91 | ContainSubstring("DEBUG"),
92 | ))
93 | })
94 |
95 | It("formatting", func() {
96 | l.Debugf("hi there %s", "you")
97 |
98 | b := testOut.Bytes()
99 | Expect(string(b)).To(SatisfyAll(
100 | ContainSubstring("hi there you"),
101 | ContainSubstring("DEBUG"),
102 | ))
103 | })
104 |
105 | Context("Bytes", func() {
106 | It("returns the bytes in the buffer", func() {
107 | testOut.buf.WriteString("foo")
108 |
109 | b := testOut.Bytes()
110 |
111 | Expect(string(b)).To(Equal("foo"))
112 | })
113 | })
114 |
115 | Context("CallCount", func() {
116 | It("returns the call count", func() {
117 | l.Info("foo")
118 | l.Info("foo")
119 | l.Info("foo")
120 |
121 | Expect(testOut.CallCount()).To(Equal(3))
122 | })
123 | })
124 |
125 | Context("reset", func() {
126 | It("resets the buffer and the call count", func() {
127 | l.Info("foo")
128 |
129 | testOut.Reset()
130 |
131 | Expect(testOut.Bytes()).To(BeEmpty())
132 | Expect(testOut.CallCount()).To(Equal(0))
133 | })
134 | })
135 |
136 | Context("with fields", func() {
137 | It("appends to preexisting fields", func() {
138 | withFields := l.WithFields(map[string]interface{}{
139 | "foo": "oldval",
140 | "baz": "origval",
141 | })
142 |
143 | withFields.WithFields(map[string]interface{}{
144 | "foo": "newval",
145 | "biz": "buzz",
146 | }).Debug("hi there")
147 |
148 | b := testOut.Bytes()
149 | Expect(string(b)).To(SatisfyAll(
150 | ContainSubstring("hi there"),
151 | ContainSubstring("foo=newval"),
152 | ContainSubstring("baz=origval"),
153 | ContainSubstring("biz=buzz"),
154 | ))
155 |
156 | })
157 |
158 | It("creates a copy", func() {
159 | l.WithFields(map[string]interface{}{
160 | "foo": "bar",
161 | "baz": 2,
162 | }).Debug("hi there ", "you")
163 |
164 | b := testOut.Bytes()
165 | Expect(string(b)).To(SatisfyAll(
166 | ContainSubstring("hi there you"),
167 | ContainSubstring("foo=bar"),
168 | ContainSubstring("baz=2"),
169 | ))
170 |
171 | testOut.Reset()
172 |
173 | // should not see any of the other fields
174 |
175 | l.WithFields(map[string]interface{}{
176 | "biz": "bar",
177 | "buz": 2,
178 | }).Debugf("hi there %s", "you")
179 |
180 | bb := testOut.Bytes()
181 | Expect(string(bb)).To(SatisfyAll(
182 | ContainSubstring("hi there you"),
183 | ContainSubstring("biz=bar"),
184 | ContainSubstring("buz=2"),
185 | ))
186 | Expect(string(bb)).ToNot(SatisfyAll(
187 | ContainSubstring("foo=bar"),
188 | ContainSubstring("baz=2"),
189 | ))
190 | })
191 | })
192 | })
193 | })
194 |
--------------------------------------------------------------------------------
/shims/zerolog/zerolog_test.go:
--------------------------------------------------------------------------------
1 | package zerolog
2 |
3 | import (
4 | "bytes"
5 | "errors"
6 | "fmt"
7 | "math/rand"
8 |
9 | "github.com/InVisionApp/go-logger"
10 | "github.com/rs/zerolog"
11 |
12 | . "github.com/onsi/ginkgo"
13 | . "github.com/onsi/gomega"
14 | "io"
15 | "os"
16 | )
17 |
18 | var _ = Describe("satisfies interface", func() {
19 | var _ log.Logger = &shim{}
20 | })
21 |
22 | var _ = Describe("zerolog logger", func() {
23 | var (
24 | newOut *bytes.Buffer
25 | l log.Logger
26 | )
27 | BeforeEach(func() {
28 | newOut = &bytes.Buffer{}
29 | zerolog.SetGlobalLevel(zerolog.DebugLevel)
30 | zl := zerolog.New(newOut).With().Timestamp().Logger()
31 | l = New(&zl)
32 | })
33 | Context("spaceSep", func() {
34 | It("works on even length slices", func() {
35 | s := []interface{}{
36 | 1, "cat", errors.New("foo"), struct{ Name string }{"bar"},
37 | }
38 | s = spaceSep(s)
39 | Expect(len(s)).To(Equal(7))
40 |
41 | sstr := fmt.Sprint(s...)
42 | Expect(sstr).To(Equal("1 cat foo {bar}"))
43 | })
44 | It("works on odd length slices", func() {
45 | s := []interface{}{
46 | 1, "cat", errors.New("foo"), struct{ Name string }{"bar"}, []string{},
47 | }
48 | s = spaceSep(s)
49 | Expect(len(s)).To(Equal(9))
50 |
51 | sstr := fmt.Sprint(s...)
52 | Expect(sstr).To(Equal("1 cat foo {bar} []"))
53 | })
54 | It("works on big slices", func() {
55 | s := make([]interface{}, 10000)
56 | for i := 0; i < 10000; i++ {
57 | s[i] = rand.Intn(10)
58 | }
59 | s = spaceSep(s)
60 | Expect(len(s)).To(Equal(19999))
61 |
62 | sstr := fmt.Sprint(s...)
63 | Expect(len(sstr)).To(Equal(19999))
64 | })
65 | It("works on little slices", func() {
66 | s := []interface{}{1, 2}
67 |
68 | s = spaceSep(s)
69 | Expect(len(s)).To(Equal(3))
70 |
71 | sstr := fmt.Sprint(s...)
72 | Expect(sstr).To(Equal("1 2"))
73 | })
74 | It("works on really little slices", func() {
75 | s := []interface{}{1}
76 |
77 | s = spaceSep(s)
78 | Expect(len(s)).To(Equal(1))
79 |
80 | sstr := fmt.Sprint(s...)
81 | Expect(sstr).To(Equal("1"))
82 | })
83 | })
84 | Context("log funcs", func() {
85 | It("prints all the log levels", func() {
86 | logFuncs := map[string]func(...interface{}){
87 | "debug": l.Debug,
88 | "info": l.Info,
89 | "warn": l.Warn,
90 | "error": l.Error,
91 | }
92 |
93 | for level, logFunc := range logFuncs {
94 | logFunc("hi there")
95 |
96 | b := newOut.Bytes()
97 | newOut.Reset()
98 | Expect(string(b)).To(SatisfyAll(
99 | ContainSubstring("hi there"),
100 | ContainSubstring(`"level":"`+level+`"`),
101 | ))
102 | }
103 | })
104 | It("prints all the log levels: *ln", func() {
105 | zl := zerolog.New(zerolog.ConsoleWriter{
106 | Out: newOut,
107 | NoColor: true,
108 | })
109 | l = New(&zl)
110 | logFuncs := map[string]func(...interface{}){
111 | "DEBUG?": l.Debugln,
112 | "INFO": l.Infoln,
113 | "WARN": l.Warnln,
114 | "ERROR?": l.Errorln,
115 | }
116 | for level, logFunc := range logFuncs {
117 | logFunc("hi", "there")
118 |
119 | b := newOut.Bytes()
120 | newOut.Reset()
121 | Expect(string(b)).To(SatisfyAll(
122 | ContainSubstring("hi there"),
123 | MatchRegexp(level),
124 | ))
125 | }
126 | })
127 | It("prints all the log levels: *f", func() {
128 | logFuncs := map[string]func(string, ...interface{}){
129 | "debug": l.Debugf,
130 | "info": l.Infof,
131 | "warn": l.Warnf,
132 | "error": l.Errorf,
133 | }
134 | for level, logFunc := range logFuncs {
135 | logFunc("hi %s", "there")
136 |
137 | b := newOut.Bytes()
138 | newOut.Reset()
139 | Expect(string(b)).To(SatisfyAll(
140 | ContainSubstring("hi there"),
141 | ContainSubstring(`"level":"`+level+`"`),
142 | ))
143 | }
144 | })
145 | It("nil logger", func() {
146 | // need to intercept stdout
147 | // https://stackoverflow.com/a/10476304
148 | old := os.Stdout
149 |
150 | r, w, _ := os.Pipe()
151 | os.Stdout = w
152 |
153 | l = New(nil)
154 | l.Debug("i am default")
155 |
156 | outC := make(chan string)
157 | go func() {
158 | var buf bytes.Buffer
159 | io.Copy(&buf, r)
160 | outC <- buf.String()
161 | }()
162 | w.Close()
163 | os.Stdout = old
164 |
165 | out := <-outC
166 | Expect(out).To(MatchRegexp(`{"level":"debug","time":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z?(-\d{2}:\d{2})?","message":"i am default"}`))
167 | })
168 | })
169 | Context("fields", func() {
170 | It("", func() {
171 | l = l.WithFields(log.Fields{
172 | "foo": "bar",
173 | "tf": true,
174 | "pet": "cat",
175 | "age": 1,
176 | })
177 |
178 | l.Debug("hi there")
179 | b := newOut.Bytes()
180 |
181 | Expect(string(b)).To(SatisfyAll(
182 | ContainSubstring("hi there"),
183 | ContainSubstring(`"level":"debug"`),
184 | ContainSubstring(`"foo":"bar"`),
185 | ContainSubstring(`"tf":true`),
186 | ContainSubstring(`"pet":"cat"`),
187 | ContainSubstring(`"age":1`),
188 | ))
189 | })
190 | })
191 | })
192 |
--------------------------------------------------------------------------------
/log_test.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | import (
4 | "bytes"
5 | stdlog "log"
6 |
7 | . "github.com/onsi/ginkgo"
8 | . "github.com/onsi/gomega"
9 | )
10 |
11 | var _ = Describe("simple logger", func() {
12 | Describe("meets the interface", func() {
13 | var _ Logger = &simple{}
14 | })
15 |
16 | var (
17 | newOut *bytes.Buffer
18 | l Logger
19 | )
20 |
21 | BeforeEach(func() {
22 | newOut = &bytes.Buffer{}
23 | stdlog.SetOutput(newOut)
24 | l = NewSimple()
25 | })
26 |
27 | Context("happy path", func() {
28 | It("prints all log levels", func() {
29 | logFuncs := map[string]func(...interface{}){
30 | "DEBUG": l.Debug,
31 | "INFO": l.Info,
32 | "WARN": l.Warn,
33 | "ERROR": l.Error,
34 | }
35 |
36 | for level, logFunc := range logFuncs {
37 | logFunc("hi there")
38 |
39 | b := newOut.Bytes()
40 | newOut.Reset()
41 | Expect(string(b)).To(SatisfyAll(
42 | ContainSubstring("hi there"),
43 | ContainSubstring(level),
44 | ))
45 | }
46 | })
47 |
48 | It("prints all log line levels", func() {
49 | logFuncs := map[string]func(...interface{}){
50 | "DEBUG": l.Debugln,
51 | "INFO": l.Infoln,
52 | "WARN": l.Warnln,
53 | "ERROR": l.Errorln,
54 | }
55 |
56 | for level, logFunc := range logFuncs {
57 | logFunc("hi", "there")
58 |
59 | b := newOut.Bytes()
60 | newOut.Reset()
61 | Expect(string(b)).To(SatisfyAll(
62 | ContainSubstring("hi there"),
63 | ContainSubstring(level),
64 | ))
65 | }
66 | })
67 |
68 | It("prints all log levels on formatted", func() {
69 | logFuncs := map[string]func(string, ...interface{}){
70 | "DEBUG": l.Debugf,
71 | "INFO": l.Infof,
72 | "WARN": l.Warnf,
73 | "ERROR": l.Errorf,
74 | }
75 |
76 | for level, logFunc := range logFuncs {
77 | logFunc("hi %s", "there")
78 |
79 | b := newOut.Bytes()
80 | newOut.Reset()
81 | Expect(string(b)).To(SatisfyAll(
82 | ContainSubstring("hi there"),
83 | ContainSubstring(level),
84 | ))
85 | }
86 | })
87 |
88 | It("join multiple strings", func() {
89 | l.Debug("hi there ", "you")
90 |
91 | b := newOut.Bytes()
92 | Expect(string(b)).To(ContainSubstring("[DEBUG] hi there you"))
93 | })
94 |
95 | It("formatting", func() {
96 | l.Debugf("hi there %s", "you")
97 |
98 | b := newOut.Bytes()
99 | Expect(string(b)).To(ContainSubstring("[DEBUG] hi there you"))
100 | })
101 |
102 | Context("with fields", func() {
103 | It("appends to preexisting fields", func() {
104 | withFields := l.WithFields(map[string]interface{}{
105 | "foo": "oldval",
106 | "baz": "origval",
107 | })
108 |
109 | withFields.WithFields(map[string]interface{}{
110 | "foo": "newval",
111 | "biz": "buzz",
112 | }).Debug("hi there")
113 |
114 | b := newOut.Bytes()
115 | Expect(string(b)).To(SatisfyAll(
116 | ContainSubstring("[DEBUG] hi there"),
117 | ContainSubstring("foo=newval"),
118 | ContainSubstring("baz=origval"),
119 | ContainSubstring("biz=buzz"),
120 | ))
121 |
122 | })
123 |
124 | It("creates a copy", func() {
125 | l.WithFields(map[string]interface{}{
126 | "foo": "bar",
127 | "baz": 2,
128 | }).Debug("hi there ", "you")
129 |
130 | b := newOut.Bytes()
131 | Expect(string(b)).To(SatisfyAll(
132 | ContainSubstring("[DEBUG] hi there you"),
133 | ContainSubstring("foo=bar"),
134 | ContainSubstring("baz=2"),
135 | ))
136 |
137 | newOut.Reset()
138 |
139 | // should not see any of the other fields
140 |
141 | l.WithFields(map[string]interface{}{
142 | "biz": "bar",
143 | "buz": 2,
144 | }).Debugf("hi there %s", "you")
145 |
146 | bb := newOut.Bytes()
147 | Expect(string(bb)).To(SatisfyAll(
148 | ContainSubstring("[DEBUG] hi there you"),
149 | ContainSubstring("biz=bar"),
150 | ContainSubstring("buz=2"),
151 | ))
152 | Expect(string(bb)).ToNot(SatisfyAll(
153 | ContainSubstring("foo=bar"),
154 | ContainSubstring("baz=2"),
155 | ))
156 | })
157 | })
158 | })
159 | })
160 |
161 | var _ = Describe("noop logger", func() {
162 | Describe("meets the interface", func() {
163 | var _ Logger = &noop{}
164 | })
165 |
166 | var (
167 | l Logger
168 | )
169 |
170 | BeforeEach(func() {
171 | l = NewNoop()
172 | })
173 |
174 | Context("happy path", func() {
175 | It("does nothing", func() {
176 | logFuncs := map[string]func(...interface{}){
177 | "DEBUG": l.Debugln,
178 | "INFO": l.Infoln,
179 | "WARN": l.Warnln,
180 | "ERROR": l.Errorln,
181 | }
182 |
183 | for _, logFunc := range logFuncs {
184 | logFunc("hi there")
185 | }
186 | })
187 |
188 | It("does nothing", func() {
189 | logFuncs := map[string]func(...interface{}){
190 | "DEBUG": l.Debug,
191 | "INFO": l.Info,
192 | "WARN": l.Warn,
193 | "ERROR": l.Error,
194 | }
195 |
196 | for _, logFunc := range logFuncs {
197 | logFunc("hi there")
198 | }
199 | })
200 |
201 | It("does nothing on formatted", func() {
202 | logFuncs := map[string]func(string, ...interface{}){
203 | "DEBUG": l.Debugf,
204 | "INFO": l.Infof,
205 | "WARN": l.Warnf,
206 | "ERROR": l.Errorf,
207 | }
208 |
209 | for _, logFunc := range logFuncs {
210 | logFunc("hi %s", "there")
211 | }
212 | })
213 |
214 | It("join multiple strings", func() {
215 | l.Debug("hi there ", "you")
216 | })
217 |
218 | It("formatting", func() {
219 | l.Debugf("hi there %s", "you")
220 | })
221 |
222 | Context("with fields", func() {
223 | It("appends to preexisting fields", func() {
224 | withFields := l.WithFields(map[string]interface{}{
225 | "foo": "oldval",
226 | "baz": "origval",
227 | })
228 |
229 | withFields.WithFields(map[string]interface{}{
230 | "foo": "newval",
231 | "biz": "buzz",
232 | }).Debug("hi there")
233 | })
234 | })
235 | })
236 | })
237 |
--------------------------------------------------------------------------------
/log.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | import (
4 | "fmt"
5 | stdlog "log"
6 | )
7 |
8 | //go:generate counterfeiter -o shims/fake/fake_logger.go . Logger
9 |
10 | // Logger interface allows you to maintain a unified interface while using a
11 | // custom logger. This allows you to write log statements without dictating
12 | // the specific underlying library used for logging. You can avoid vendoring
13 | // of logging libraries, which is especially useful when writing shared code
14 | // such as a library. This package contains a simple logger and a no-op logger
15 | // which both implement this interface. It is also supplemented with some
16 | // additional helpers/shims for other common logging libraries such as logrus
17 | type Logger interface {
18 | Debug(msg ...interface{})
19 | Info(msg ...interface{})
20 | Warn(msg ...interface{})
21 | Error(msg ...interface{})
22 |
23 | Debugln(msg ...interface{})
24 | Infoln(msg ...interface{})
25 | Warnln(msg ...interface{})
26 | Errorln(msg ...interface{})
27 |
28 | Debugf(format string, args ...interface{})
29 | Infof(format string, args ...interface{})
30 | Warnf(format string, args ...interface{})
31 | Errorf(format string, args ...interface{})
32 |
33 | WithFields(Fields) Logger
34 | }
35 |
36 | // Fields is used to define structured fields which are appended to log messages
37 | type Fields map[string]interface{}
38 |
39 | /**************
40 | Simple Logger
41 | **************/
42 |
43 | type simple struct {
44 | fields map[string]interface{}
45 | }
46 |
47 | // NewSimple creates a basic logger that wraps the core log library.
48 | func NewSimple() Logger {
49 | return &simple{}
50 | }
51 |
52 | // WithFields will return a new logger based on the original logger
53 | // with the additional supplied fields
54 | func (b *simple) WithFields(fields Fields) Logger {
55 | cp := &simple{}
56 |
57 | if b.fields == nil {
58 | cp.fields = fields
59 | return cp
60 | }
61 |
62 | cp.fields = make(map[string]interface{}, len(b.fields)+len(fields))
63 | for k, v := range b.fields {
64 | cp.fields[k] = v
65 | }
66 |
67 | for k, v := range fields {
68 | cp.fields[k] = v
69 | }
70 |
71 | return cp
72 | }
73 |
74 | // Debug log message
75 | func (b *simple) Debug(msg ...interface{}) {
76 | stdlog.Printf("[DEBUG] %s %s", fmt.Sprint(msg...), pretty(b.fields))
77 | }
78 |
79 | // Info log message
80 | func (b *simple) Info(msg ...interface{}) {
81 | stdlog.Printf("[INFO] %s %s", fmt.Sprint(msg...), pretty(b.fields))
82 | }
83 |
84 | // Warn log message
85 | func (b *simple) Warn(msg ...interface{}) {
86 | stdlog.Printf("[WARN] %s %s", fmt.Sprint(msg...), pretty(b.fields))
87 | }
88 |
89 | // Error log message
90 | func (b *simple) Error(msg ...interface{}) {
91 | stdlog.Printf("[ERROR] %s %s", fmt.Sprint(msg...), pretty(b.fields))
92 | }
93 |
94 | // Debugln log line message
95 | func (b *simple) Debugln(msg ...interface{}) {
96 | a := fmt.Sprintln(msg...)
97 | stdlog.Println("[DEBUG]", a[:len(a)-1], pretty(b.fields))
98 | }
99 |
100 | // Infoln log line message
101 | func (b *simple) Infoln(msg ...interface{}) {
102 | a := fmt.Sprintln(msg...)
103 | stdlog.Println("[INFO]", a[:len(a)-1], pretty(b.fields))
104 | }
105 |
106 | // Warnln log line message
107 | func (b *simple) Warnln(msg ...interface{}) {
108 | a := fmt.Sprintln(msg...)
109 | stdlog.Println("[WARN]", a[:len(a)-1], pretty(b.fields))
110 | }
111 |
112 | // Errorln log line message
113 | func (b *simple) Errorln(msg ...interface{}) {
114 | a := fmt.Sprintln(msg...)
115 | stdlog.Println("[ERROR]", a[:len(a)-1], pretty(b.fields))
116 | }
117 |
118 | // Debugf log message with formatting
119 | func (b *simple) Debugf(format string, args ...interface{}) {
120 | stdlog.Print(fmt.Sprintf("[DEBUG] "+format, args...), " ", pretty(b.fields))
121 | }
122 |
123 | // Infof log message with formatting
124 | func (b *simple) Infof(format string, args ...interface{}) {
125 | stdlog.Print(fmt.Sprintf("[INFO] "+format, args...), " ", pretty(b.fields))
126 | }
127 |
128 | // Warnf log message with formatting
129 | func (b *simple) Warnf(format string, args ...interface{}) {
130 | stdlog.Print(fmt.Sprintf("[WARN] "+format, args...), " ", pretty(b.fields))
131 | }
132 |
133 | // Errorf log message with formatting
134 | func (b *simple) Errorf(format string, args ...interface{}) {
135 | stdlog.Print(fmt.Sprintf("[ERROR] "+format, args...), " ", pretty(b.fields))
136 | }
137 |
138 | // helper for pretty printing of fields
139 | func pretty(m map[string]interface{}) string {
140 | if len(m) < 1 {
141 | return ""
142 | }
143 |
144 | s := ""
145 | for k, v := range m {
146 | s += fmt.Sprintf("%s=%v ", k, v)
147 | }
148 |
149 | return s[:len(s)-1]
150 | }
151 |
152 | /*************
153 | No-Op Logger
154 | *************/
155 |
156 | type noop struct{}
157 |
158 | // NewNoop creates a no-op logger that can be used to silence
159 | // all logging from this library. Also useful in tests.
160 | func NewNoop() Logger {
161 | return &noop{}
162 | }
163 |
164 | // Debug log message no-op
165 | func (n *noop) Debug(msg ...interface{}) {}
166 |
167 | // Info log message no-op
168 | func (n *noop) Info(msg ...interface{}) {}
169 |
170 | // Warn log message no-op
171 | func (n *noop) Warn(msg ...interface{}) {}
172 |
173 | // Error log message no-op
174 | func (n *noop) Error(msg ...interface{}) {}
175 |
176 | // Debugln line log message no-op
177 | func (n *noop) Debugln(msg ...interface{}) {}
178 |
179 | // Infoln line log message no-op
180 | func (n *noop) Infoln(msg ...interface{}) {}
181 |
182 | // Warnln line log message no-op
183 | func (n *noop) Warnln(msg ...interface{}) {}
184 |
185 | // Errorln line log message no-op
186 | func (n *noop) Errorln(msg ...interface{}) {}
187 |
188 | // Debugf log message with formatting no-op
189 | func (n *noop) Debugf(format string, args ...interface{}) {}
190 |
191 | // Infof log message with formatting no-op
192 | func (n *noop) Infof(format string, args ...interface{}) {}
193 |
194 | // Warnf log message with formatting no-op
195 | func (n *noop) Warnf(format string, args ...interface{}) {}
196 |
197 | // Errorf log message with formatting no-op
198 | func (n *noop) Errorf(format string, args ...interface{}) {}
199 |
200 | // WithFields no-op
201 | func (n *noop) WithFields(fields Fields) Logger { return n }
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | | :warning: This project is no longer actively supported.
2 | | ---
3 |
4 | [](LICENSE)
5 | [](https://travis-ci.com/InVisionApp/go-logger)
6 | [](https://codecov.io/gh/InVisionApp/go-logger)
7 | [](https://goreportcard.com/report/github.com/InVisionApp/go-logger)
8 | [](https://godoc.org/github.com/InVisionApp/go-logger)
9 |
10 |
11 |
12 |
13 |
14 | # go-logger
15 | This package provides a standard interface for logging in any go application.
16 | Logger interface allows you to maintain a unified interface while using a custom logger. This allows you to write log statements without dictating the specific underlying library used for logging. You can avoid vendoring of logging libraries, which is especially useful when writing shared code such as a library.
17 | This package also contains a simple logger and a no-op logger which both implement the interface. The simple logger is a wrapper for the standard logging library which meets this logger interface. The no-op logger can be used to easily silence all logging.
18 | This library is also supplemented with some additional helpers/shims for other common logging libraries such as logrus to allow them to meet the logger interface.
19 |
20 | ## Usage
21 | The logger interface defines 4 levels of logging: `Debug`, `Info`, `Warn`, and `Error`. These will accept a variadic list of strings as in `fmt.Println`. All the string parameters will be concatenated into a single message.
22 | Additionally, each of the log levels offers a formatted string as well: `Debugf`, `Infof`, `Warnf`, and `Errorf`. These functions, like `fmt.Printf` and offer the ability to define a format string and parameters to populate it.
23 | Finally, there is a `WithFields(Fields)` method that will allow you to define a set of fields that will always be logged with evey message. This method returns copy of the logger and appends all fields to any preexisting fields.
24 |
25 | ## Implementations
26 |
27 | ### Simple Logger
28 | The simple logger is a wrapper for the standard logging library which meets this logger interface. It provides very basic logging functionality with log levels in messages.
29 |
30 | ```go
31 | import "github.com/InVisionApp/go-logger"
32 |
33 | logger := log.NewSimple()
34 | logger.Debug("this is a debug message")
35 | ```
36 | output:
37 | ```
38 | 2018/03/04 12:55:08 [DEBUG] Simplelogger
39 | ```
40 |
41 | ### No-op Logger
42 | If you do not wish to perform any sort of logging whatsoever, you can point to a noop logger. This is useful for silencing logs in tests, or allowing users to turn of logging in your library.
43 |
44 | ```go
45 | import "github.com/InVisionApp/go-logger"
46 |
47 | logger := log.NewNoop()
48 | logger.Debug("this is a debug message")
49 | ```
50 | _no output_
51 |
52 | ### Logrus Logger
53 | This shim allows you to use logrus as your logger implementation. If you wish to use the standard logrus logger, pass `nil` to the constructor. Otherwise, pass in your own `logrus.Logger`.
54 |
55 | ```go
56 | import "github.com/InVisionApp/go-logger/shims/logrus"
57 |
58 | // Default logrus logger
59 | logger := logrus.New(nil)
60 | logger.Debug("this is a debug message")
61 | ```
62 |
63 | Or alternatively, you can provide your own logrus logger:
64 | ```go
65 | import (
66 | lgrs "github.com/sirupsen/logrus"
67 | "github.com/InVisionApp/go-logger/shims/logrus"
68 | )
69 |
70 | myLogrus := lgrs.New()
71 | myLogrus.Out = &bytes.Buffer{}
72 | logger := logrus.New(myLogrus)
73 | logger.Debug("this is a debug message")
74 | ```
75 |
76 | output:
77 | ```
78 | time="2018-03-04T13:12:35-08:00" level=debug msg="this is a debug message"
79 | ```
80 |
81 | ### Zerolog Logger
82 | This shim allows you to use [zerolog](https://github.com/rs/zerolog) as your logging implementation. If you pass `nil` into `New(...)`,
83 | you will get a default `zerolog.Logger` writing to `stdout` with a timestamp attached.
84 |
85 | Alternatively, you can pass your own instance of `zerolog.Logger` to `New(...)`.
86 |
87 | Using the `zerolog` default logger:
88 | ```go
89 | import "github.com/InVisionApp/go-logger/shims/zerolog"
90 |
91 | func main() {
92 | logger := zerolog.New(nil)
93 | logger.Debug("this is a debug message!")
94 | }
95 |
96 | ```
97 |
98 | Using your own logger:
99 | ```go
100 | import (
101 | "os"
102 |
103 | zl "github.com/rs/zerolog"
104 | "github.com/InVisionApp/go-logger/shims/zerolog"
105 | )
106 |
107 | func main() {
108 | // zerolog is a structured logger by default
109 | structuredLogger := zl.New(os.Stdout).Logger()
110 | sLogger := zerolog.New(structuredLogger)
111 | sLogger.Debug("debug message")
112 | // {"level":"debug", "message":"debug message"}
113 |
114 | // If you want to use zerolog for human-readable console logging,
115 | // you create a ConsoleWriter and use it as your io.Writer implementation
116 | consoleLogger := zl.New(zl.ConsoleWriter{
117 | Out: os.Stdout,
118 | })
119 | cLogger := zerolog.New(consoleLogger)
120 | cLogger.Debug("debug message")
121 | // |DEBUG| debug message
122 | }
123 | ```
124 |
125 | ### Test Logger
126 | The test logger is for capturing logs during the execution of a test. It writes the logs to a byte buffer which can be dumped and inspected. It also tracks a call count of the total number of times the logger has been called.
127 | **_Note:_** this logger is not meant to be used in production. It is purely designed for use in tests.
128 |
129 | ### Fake Logger
130 | A generated fake that meets the logger interface. This is useful if you want to stub out your own functionality for the logger in tests. This logger is meant for use in tests and not in production. If you simply want to silence logs, use the no-op logger.
131 |
132 | ---
133 |
134 | #### \[Credit\]
135 | The go-logger gopher image by [talpert](https://github.com/talpert)
136 | Original artwork designed by Renée French
137 |
--------------------------------------------------------------------------------
/shims/_fake/fake_logger.go:
--------------------------------------------------------------------------------
1 | // Code generated by counterfeiter. DO NOT EDIT.
2 | package fake
3 |
4 | import (
5 | "sync"
6 |
7 | log "github.com/InVisionApp/go-logger"
8 | )
9 |
10 | type FakeLogger struct {
11 | DebugStub func(msg ...interface{})
12 | debugMutex sync.RWMutex
13 | debugArgsForCall []struct {
14 | msg []interface{}
15 | }
16 | InfoStub func(msg ...interface{})
17 | infoMutex sync.RWMutex
18 | infoArgsForCall []struct {
19 | msg []interface{}
20 | }
21 | WarnStub func(msg ...interface{})
22 | warnMutex sync.RWMutex
23 | warnArgsForCall []struct {
24 | msg []interface{}
25 | }
26 | ErrorStub func(msg ...interface{})
27 | errorMutex sync.RWMutex
28 | errorArgsForCall []struct {
29 | msg []interface{}
30 | }
31 | DebugfStub func(format string, args ...interface{})
32 | debugfMutex sync.RWMutex
33 | debugfArgsForCall []struct {
34 | format string
35 | args []interface{}
36 | }
37 | InfofStub func(format string, args ...interface{})
38 | infofMutex sync.RWMutex
39 | infofArgsForCall []struct {
40 | format string
41 | args []interface{}
42 | }
43 | WarnfStub func(format string, args ...interface{})
44 | warnfMutex sync.RWMutex
45 | warnfArgsForCall []struct {
46 | format string
47 | args []interface{}
48 | }
49 | ErrorfStub func(format string, args ...interface{})
50 | errorfMutex sync.RWMutex
51 | errorfArgsForCall []struct {
52 | format string
53 | args []interface{}
54 | }
55 | WithFieldsStub func(log.Fields) log.Logger
56 | withFieldsMutex sync.RWMutex
57 | withFieldsArgsForCall []struct {
58 | arg1 log.Fields
59 | }
60 | withFieldsReturns struct {
61 | result1 log.Logger
62 | }
63 | withFieldsReturnsOnCall map[int]struct {
64 | result1 log.Logger
65 | }
66 | invocations map[string][][]interface{}
67 | invocationsMutex sync.RWMutex
68 | }
69 |
70 | func (fake *FakeLogger) Debug(msg ...interface{}) {
71 | fake.debugMutex.Lock()
72 | fake.debugArgsForCall = append(fake.debugArgsForCall, struct {
73 | msg []interface{}
74 | }{msg})
75 | fake.recordInvocation("Debug", []interface{}{msg})
76 | fake.debugMutex.Unlock()
77 | if fake.DebugStub != nil {
78 | fake.DebugStub(msg...)
79 | }
80 | }
81 |
82 | func (fake *FakeLogger) DebugCallCount() int {
83 | fake.debugMutex.RLock()
84 | defer fake.debugMutex.RUnlock()
85 | return len(fake.debugArgsForCall)
86 | }
87 |
88 | func (fake *FakeLogger) DebugArgsForCall(i int) []interface{} {
89 | fake.debugMutex.RLock()
90 | defer fake.debugMutex.RUnlock()
91 | return fake.debugArgsForCall[i].msg
92 | }
93 |
94 | func (fake *FakeLogger) Info(msg ...interface{}) {
95 | fake.infoMutex.Lock()
96 | fake.infoArgsForCall = append(fake.infoArgsForCall, struct {
97 | msg []interface{}
98 | }{msg})
99 | fake.recordInvocation("Info", []interface{}{msg})
100 | fake.infoMutex.Unlock()
101 | if fake.InfoStub != nil {
102 | fake.InfoStub(msg...)
103 | }
104 | }
105 |
106 | func (fake *FakeLogger) InfoCallCount() int {
107 | fake.infoMutex.RLock()
108 | defer fake.infoMutex.RUnlock()
109 | return len(fake.infoArgsForCall)
110 | }
111 |
112 | func (fake *FakeLogger) InfoArgsForCall(i int) []interface{} {
113 | fake.infoMutex.RLock()
114 | defer fake.infoMutex.RUnlock()
115 | return fake.infoArgsForCall[i].msg
116 | }
117 |
118 | func (fake *FakeLogger) Warn(msg ...interface{}) {
119 | fake.warnMutex.Lock()
120 | fake.warnArgsForCall = append(fake.warnArgsForCall, struct {
121 | msg []interface{}
122 | }{msg})
123 | fake.recordInvocation("Warn", []interface{}{msg})
124 | fake.warnMutex.Unlock()
125 | if fake.WarnStub != nil {
126 | fake.WarnStub(msg...)
127 | }
128 | }
129 |
130 | func (fake *FakeLogger) WarnCallCount() int {
131 | fake.warnMutex.RLock()
132 | defer fake.warnMutex.RUnlock()
133 | return len(fake.warnArgsForCall)
134 | }
135 |
136 | func (fake *FakeLogger) WarnArgsForCall(i int) []interface{} {
137 | fake.warnMutex.RLock()
138 | defer fake.warnMutex.RUnlock()
139 | return fake.warnArgsForCall[i].msg
140 | }
141 |
142 | func (fake *FakeLogger) Error(msg ...interface{}) {
143 | fake.errorMutex.Lock()
144 | fake.errorArgsForCall = append(fake.errorArgsForCall, struct {
145 | msg []interface{}
146 | }{msg})
147 | fake.recordInvocation("Error", []interface{}{msg})
148 | fake.errorMutex.Unlock()
149 | if fake.ErrorStub != nil {
150 | fake.ErrorStub(msg...)
151 | }
152 | }
153 |
154 | func (fake *FakeLogger) ErrorCallCount() int {
155 | fake.errorMutex.RLock()
156 | defer fake.errorMutex.RUnlock()
157 | return len(fake.errorArgsForCall)
158 | }
159 |
160 | func (fake *FakeLogger) ErrorArgsForCall(i int) []interface{} {
161 | fake.errorMutex.RLock()
162 | defer fake.errorMutex.RUnlock()
163 | return fake.errorArgsForCall[i].msg
164 | }
165 |
166 | func (fake *FakeLogger) Debugf(format string, args ...interface{}) {
167 | fake.debugfMutex.Lock()
168 | fake.debugfArgsForCall = append(fake.debugfArgsForCall, struct {
169 | format string
170 | args []interface{}
171 | }{format, args})
172 | fake.recordInvocation("Debugf", []interface{}{format, args})
173 | fake.debugfMutex.Unlock()
174 | if fake.DebugfStub != nil {
175 | fake.DebugfStub(format, args...)
176 | }
177 | }
178 |
179 | func (fake *FakeLogger) DebugfCallCount() int {
180 | fake.debugfMutex.RLock()
181 | defer fake.debugfMutex.RUnlock()
182 | return len(fake.debugfArgsForCall)
183 | }
184 |
185 | func (fake *FakeLogger) DebugfArgsForCall(i int) (string, []interface{}) {
186 | fake.debugfMutex.RLock()
187 | defer fake.debugfMutex.RUnlock()
188 | return fake.debugfArgsForCall[i].format, fake.debugfArgsForCall[i].args
189 | }
190 |
191 | func (fake *FakeLogger) Infof(format string, args ...interface{}) {
192 | fake.infofMutex.Lock()
193 | fake.infofArgsForCall = append(fake.infofArgsForCall, struct {
194 | format string
195 | args []interface{}
196 | }{format, args})
197 | fake.recordInvocation("Infof", []interface{}{format, args})
198 | fake.infofMutex.Unlock()
199 | if fake.InfofStub != nil {
200 | fake.InfofStub(format, args...)
201 | }
202 | }
203 |
204 | func (fake *FakeLogger) InfofCallCount() int {
205 | fake.infofMutex.RLock()
206 | defer fake.infofMutex.RUnlock()
207 | return len(fake.infofArgsForCall)
208 | }
209 |
210 | func (fake *FakeLogger) InfofArgsForCall(i int) (string, []interface{}) {
211 | fake.infofMutex.RLock()
212 | defer fake.infofMutex.RUnlock()
213 | return fake.infofArgsForCall[i].format, fake.infofArgsForCall[i].args
214 | }
215 |
216 | func (fake *FakeLogger) Warnf(format string, args ...interface{}) {
217 | fake.warnfMutex.Lock()
218 | fake.warnfArgsForCall = append(fake.warnfArgsForCall, struct {
219 | format string
220 | args []interface{}
221 | }{format, args})
222 | fake.recordInvocation("Warnf", []interface{}{format, args})
223 | fake.warnfMutex.Unlock()
224 | if fake.WarnfStub != nil {
225 | fake.WarnfStub(format, args...)
226 | }
227 | }
228 |
229 | func (fake *FakeLogger) WarnfCallCount() int {
230 | fake.warnfMutex.RLock()
231 | defer fake.warnfMutex.RUnlock()
232 | return len(fake.warnfArgsForCall)
233 | }
234 |
235 | func (fake *FakeLogger) WarnfArgsForCall(i int) (string, []interface{}) {
236 | fake.warnfMutex.RLock()
237 | defer fake.warnfMutex.RUnlock()
238 | return fake.warnfArgsForCall[i].format, fake.warnfArgsForCall[i].args
239 | }
240 |
241 | func (fake *FakeLogger) Errorf(format string, args ...interface{}) {
242 | fake.errorfMutex.Lock()
243 | fake.errorfArgsForCall = append(fake.errorfArgsForCall, struct {
244 | format string
245 | args []interface{}
246 | }{format, args})
247 | fake.recordInvocation("Errorf", []interface{}{format, args})
248 | fake.errorfMutex.Unlock()
249 | if fake.ErrorfStub != nil {
250 | fake.ErrorfStub(format, args...)
251 | }
252 | }
253 |
254 | func (fake *FakeLogger) ErrorfCallCount() int {
255 | fake.errorfMutex.RLock()
256 | defer fake.errorfMutex.RUnlock()
257 | return len(fake.errorfArgsForCall)
258 | }
259 |
260 | func (fake *FakeLogger) ErrorfArgsForCall(i int) (string, []interface{}) {
261 | fake.errorfMutex.RLock()
262 | defer fake.errorfMutex.RUnlock()
263 | return fake.errorfArgsForCall[i].format, fake.errorfArgsForCall[i].args
264 | }
265 |
266 | func (fake *FakeLogger) WithFields(arg1 log.Fields) log.Logger {
267 | fake.withFieldsMutex.Lock()
268 | ret, specificReturn := fake.withFieldsReturnsOnCall[len(fake.withFieldsArgsForCall)]
269 | fake.withFieldsArgsForCall = append(fake.withFieldsArgsForCall, struct {
270 | arg1 log.Fields
271 | }{arg1})
272 | fake.recordInvocation("WithFields", []interface{}{arg1})
273 | fake.withFieldsMutex.Unlock()
274 | if fake.WithFieldsStub != nil {
275 | return fake.WithFieldsStub(arg1)
276 | }
277 | if specificReturn {
278 | return ret.result1
279 | }
280 | return fake.withFieldsReturns.result1
281 | }
282 |
283 | func (fake *FakeLogger) WithFieldsCallCount() int {
284 | fake.withFieldsMutex.RLock()
285 | defer fake.withFieldsMutex.RUnlock()
286 | return len(fake.withFieldsArgsForCall)
287 | }
288 |
289 | func (fake *FakeLogger) WithFieldsArgsForCall(i int) log.Fields {
290 | fake.withFieldsMutex.RLock()
291 | defer fake.withFieldsMutex.RUnlock()
292 | return fake.withFieldsArgsForCall[i].arg1
293 | }
294 |
295 | func (fake *FakeLogger) WithFieldsReturns(result1 log.Logger) {
296 | fake.WithFieldsStub = nil
297 | fake.withFieldsReturns = struct {
298 | result1 log.Logger
299 | }{result1}
300 | }
301 |
302 | func (fake *FakeLogger) WithFieldsReturnsOnCall(i int, result1 log.Logger) {
303 | fake.WithFieldsStub = nil
304 | if fake.withFieldsReturnsOnCall == nil {
305 | fake.withFieldsReturnsOnCall = make(map[int]struct {
306 | result1 log.Logger
307 | })
308 | }
309 | fake.withFieldsReturnsOnCall[i] = struct {
310 | result1 log.Logger
311 | }{result1}
312 | }
313 |
314 | func (fake *FakeLogger) Invocations() map[string][][]interface{} {
315 | fake.invocationsMutex.RLock()
316 | defer fake.invocationsMutex.RUnlock()
317 | fake.debugMutex.RLock()
318 | defer fake.debugMutex.RUnlock()
319 | fake.infoMutex.RLock()
320 | defer fake.infoMutex.RUnlock()
321 | fake.warnMutex.RLock()
322 | defer fake.warnMutex.RUnlock()
323 | fake.errorMutex.RLock()
324 | defer fake.errorMutex.RUnlock()
325 | fake.debugfMutex.RLock()
326 | defer fake.debugfMutex.RUnlock()
327 | fake.infofMutex.RLock()
328 | defer fake.infofMutex.RUnlock()
329 | fake.warnfMutex.RLock()
330 | defer fake.warnfMutex.RUnlock()
331 | fake.errorfMutex.RLock()
332 | defer fake.errorfMutex.RUnlock()
333 | fake.withFieldsMutex.RLock()
334 | defer fake.withFieldsMutex.RUnlock()
335 | copiedInvocations := map[string][][]interface{}{}
336 | for key, value := range fake.invocations {
337 | copiedInvocations[key] = value
338 | }
339 | return copiedInvocations
340 | }
341 |
342 | func (fake *FakeLogger) recordInvocation(key string, args []interface{}) {
343 | fake.invocationsMutex.Lock()
344 | defer fake.invocationsMutex.Unlock()
345 | if fake.invocations == nil {
346 | fake.invocations = map[string][][]interface{}{}
347 | }
348 | if fake.invocations[key] == nil {
349 | fake.invocations[key] = [][]interface{}{}
350 | }
351 | fake.invocations[key] = append(fake.invocations[key], args)
352 | }
353 |
354 | var _ log.Logger = new(FakeLogger)
355 |
--------------------------------------------------------------------------------
/images/go-logger.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------