Skip to content

Commit e927c36

Browse files
authored
Remove init register pattern (#11)
* Remove init register pattern * codecov: rename config file
1 parent f7f4c3a commit e927c36

15 files changed

+347
-344
lines changed

README.md

+25-24
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
)
2929

3030
func init() {
31-
err := log.New(log.ModeConsole)
31+
err := log.NewConsole()
3232
if err != nil {
3333
panic("unable to create new logger: " + err.Error())
3434
}
@@ -48,7 +48,7 @@ The code inside `init` function is equivalent to the following:
4848

4949
```go
5050
func init() {
51-
err := log.New(log.ModeConsole, 0, log.ConsoleConfig{
51+
err := log.NewConsole(0, log.ConsoleConfig{
5252
Level: log.LevelTrace,
5353
})
5454
if err != nil {
@@ -67,7 +67,7 @@ In production, you may want to make log less verbose and be asynchronous:
6767
func init() {
6868
// The buffer size mainly depends on number of logs could be produced at the same time,
6969
// 100 is a good default.
70-
err := log.New(log.ModeConsole, 100, log.ConsoleConfig{
70+
err := log.NewConsole(100, log.ConsoleConfig{
7171
Level: log.LevelInfo,
7272
})
7373
if err != nil {
@@ -79,19 +79,19 @@ func init() {
7979
- When you set level to be `LevelInfo`, calls to the `log.Trace` will be simply noop.
8080
- The console logger comes with color output, but for non-colorable destination, the color output will be disabled automatically.
8181

82-
Other builtin loggers are file (`log.ModeFile`), Slack (`log.ModeSlack`) and Discord (`log.ModeDiscord`), see later sections in the documentation for usage details.
82+
Other builtin loggers are file (`log.NewFile`), Slack (`log.NewSlack`) and Discord (`log.NewDiscord`), see later sections in the documentation for usage details.
8383

8484
### Multiple Loggers
8585

8686
You can have multiple loggers in different modes across levels.
8787

8888
```go
8989
func init() {
90-
err := log.New(log.ModeConsole)
90+
err := log.NewConsole()
9191
if err != nil {
9292
panic("unable to create new logger: " + err.Error())
9393
}
94-
err := log.New(log.ModeFile, log.FileConfig{
94+
err := log.NewFile(log.FileConfig{
9595
Level: log.LevelInfo,
9696
Filename: "clog.log",
9797
})
@@ -131,7 +131,7 @@ File logger is the single most powerful builtin logger, it has the ability to ro
131131

132132
```go
133133
func init() {
134-
err := log.New(log.ModeFile, 100, log.FileConfig{
134+
err := log.NewFile(100, log.FileConfig{
135135
Level: log.LevelInfo,
136136
Filename: "clog.log",
137137
FileRotationConfig: log.FileRotationConfig {
@@ -165,7 +165,7 @@ Slack logger is also supported in a simple way:
165165

166166
```go
167167
func init() {
168-
err := log.New(log.ModeSlack, 100, log.SlackConfig{
168+
err := log.NewSlack(100, log.SlackConfig{
169169
Level: log.LevelInfo,
170170
URL: "https://url-to-slack-webhook",
171171
})
@@ -183,7 +183,7 @@ Discord logger is supported in rich format via [Embed Object](https://discordapp
183183

184184
```go
185185
func init() {
186-
err := log.New(log.ModeDiscord, 100, log.DiscordConfig{
186+
err := log.NewDiscord(100, log.DiscordConfig{
187187
Level: log.LevelInfo,
188188
URL: "https://url-to-discord-webhook",
189189
})
@@ -204,44 +204,45 @@ Here is an example which sends all logs to a channel, we call it `chanLogger` he
204204
```go
205205
import log "unknwon.dev/clog/v2"
206206

207-
const modeChannel log.Mode = "channel"
208-
209207
type chanConfig struct {
210208
c chan string
211209
}
212210

213211
var _ log.Logger = (*chanLogger)(nil)
214212

215213
type chanLogger struct {
214+
name string
216215
level log.Level
217216
c chan string
218217
}
219218

220-
func (*chanLogger) Mode() log.Mode { return modeChannel }
219+
func (l *chanLogger) Name() string { return l.name }
221220
func (l *chanLogger) Level() log.Level { return l.level }
222221

223-
func (l *chanLogger) Write(m Messager) error {
222+
func (l *chanLogger) Write(m log.Messager) error {
224223
l.c <- m.String()
225224
return nil
226225
}
227226

228-
func init() {
229-
log.NewRegister(modeChannel, func(v interface{}) (log.Logger, error) {
230-
if v == nil {
231-
v = chanConfig{}
232-
}
233-
234-
cfg, ok := v.(chanConfig)
235-
if !ok {
236-
return nil, fmt.Errorf("invalid config object: want %T got %T", chanConfig{}, v)
227+
func main() {
228+
log.New("channel", func(name string, vs ...interface{}) (log.Logger, error) {
229+
var cfg *chanLogger
230+
for i := range vs {
231+
switch v := vs[i].(type) {
232+
case chanLogger:
233+
cfg = &v
234+
}
237235
}
238236

239-
if cfg.c == nil {
237+
if cfg == nil {
238+
return nil, fmt.Errorf("config object with the type '%T' not found", chanLogger{})
239+
} else if cfg.c == nil {
240240
return nil, errors.New("channel is nil")
241241
}
242242

243243
return &chanLogger{
244-
c: cfg.c,
244+
name: name,
245+
c: cfg.c,
245246
}, nil
246247
})
247248
}

clog.go

-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import (
66
"os"
77
)
88

9-
// Mode is the output source.
10-
type Mode string
11-
129
// Level is the logging level.
1310
type Level int
1411

clog_test.go

+40-43
Original file line numberDiff line numberDiff line change
@@ -37,37 +37,47 @@ func (l *chanLogger) Write(m Messager) error {
3737
}
3838

3939
func Test_chanLogger(t *testing.T) {
40-
mode1 := Mode("mode1")
41-
level1 := LevelTrace
42-
NewRegister(mode1, func(v interface{}) (Logger, error) {
43-
cfg, ok := v.(chanConfig)
44-
if !ok {
45-
return nil, fmt.Errorf("invalid config object: want %T got %T", chanConfig{}, v)
46-
}
47-
return &chanLogger{
48-
c: cfg.c,
49-
noopLogger: &noopLogger{
50-
mode: mode1,
51-
level: level1,
52-
},
53-
}, nil
54-
})
55-
56-
mode2 := Mode("mode2")
57-
level2 := LevelError
58-
NewRegister(mode2, func(v interface{}) (Logger, error) {
59-
cfg, ok := v.(chanConfig)
60-
if !ok {
61-
return nil, fmt.Errorf("invalid config object: want %T got %T", &chanConfig{}, v)
40+
initer := func(name string, level Level) Initer {
41+
return func(_ string, vs ...interface{}) (Logger, error) {
42+
var cfg *chanConfig
43+
for i := range vs {
44+
switch v := vs[i].(type) {
45+
case chanConfig:
46+
cfg = &v
47+
}
48+
}
49+
50+
if cfg == nil {
51+
return nil, fmt.Errorf("config object with the type '%T' not found", chanConfig{})
52+
}
53+
54+
return &chanLogger{
55+
c: cfg.c,
56+
noopLogger: &noopLogger{
57+
name: name,
58+
level: level,
59+
},
60+
}, nil
6261
}
63-
return &chanLogger{
64-
c: cfg.c,
65-
noopLogger: &noopLogger{
66-
mode: mode2,
67-
level: level2,
68-
},
69-
}, nil
70-
})
62+
}
63+
64+
test1 := "mode1"
65+
test1Initer := initer(test1, LevelTrace)
66+
67+
test2 := "mode2"
68+
test2Initer := initer(test2, LevelError)
69+
70+
c1 := make(chan string)
71+
c2 := make(chan string)
72+
73+
defer Remove(test1)
74+
defer Remove(test2)
75+
assert.Nil(t, New(test1, test1Initer, 1, chanConfig{
76+
c: c1,
77+
}))
78+
assert.Nil(t, New(test2, test2Initer, 1, chanConfig{
79+
c: c2,
80+
}))
7181

7282
tests := []struct {
7383
name string
@@ -106,19 +116,6 @@ func Test_chanLogger(t *testing.T) {
106116
containsStr2: "()] log message",
107117
},
108118
}
109-
110-
c1 := make(chan string)
111-
c2 := make(chan string)
112-
113-
defer Remove(mode1)
114-
defer Remove(mode2)
115-
assert.Nil(t, New(mode1, 1, chanConfig{
116-
c: c1,
117-
}))
118-
assert.Nil(t, New(mode2, 1, chanConfig{
119-
c: c2,
120-
}))
121-
122119
for _, tt := range tests {
123120
t.Run(tt.name, func(t *testing.T) {
124121
assert.Equal(t, 2, mgr.len())
File renamed without changes.

console.go

+32-22
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
package clog
22

33
import (
4-
"fmt"
54
"log"
65

76
"github.com/fatih/color"
87
)
98

10-
// ModeConsole is used to indicate console logger.
11-
const ModeConsole Mode = "console"
12-
13-
// Console color set for different levels.
9+
// consoleColors is the color set for different levels.
1410
var consoleColors = []func(a ...interface{}) string{
1511
color.New(color.FgBlue).SprintFunc(), // Trace
1612
color.New(color.FgGreen).SprintFunc(), // Info
@@ -28,37 +24,51 @@ type ConsoleConfig struct {
2824
var _ Logger = (*consoleLogger)(nil)
2925

3026
type consoleLogger struct {
31-
level Level
27+
*noopLogger
3228
*log.Logger
3329
}
3430

35-
func (*consoleLogger) Mode() Mode {
36-
return ModeConsole
31+
func (l *consoleLogger) Write(m Messager) error {
32+
l.Print(consoleColors[m.Level()](m.String()))
33+
return nil
3734
}
3835

39-
func (l *consoleLogger) Level() Level {
40-
return l.level
36+
// DefaultConsoleName is the default name for the console logger.
37+
const DefaultConsoleName = "console"
38+
39+
// NewConsole initializes and appends a new console logger with default name
40+
// to the managed list.
41+
func NewConsole(vs ...interface{}) error {
42+
return NewConsoleWithName(DefaultConsoleName, vs...)
4143
}
4244

43-
func (l *consoleLogger) Write(m Messager) error {
44-
l.Print(consoleColors[m.Level()](m.String()))
45-
return nil
45+
// NewConsoleWithName initializes and appends a new console logger with given
46+
// name to the managed list.
47+
func NewConsoleWithName(name string, vs ...interface{}) error {
48+
return New(name, ConsoleIniter(), vs...)
4649
}
4750

48-
func init() {
49-
NewRegister(ModeConsole, func(v interface{}) (Logger, error) {
50-
if v == nil {
51-
v = ConsoleConfig{}
51+
// ConsoleIniter returns the initer for the console logger.
52+
func ConsoleIniter() Initer {
53+
return func(name string, vs ...interface{}) (Logger, error) {
54+
var cfg *ConsoleConfig
55+
for i := range vs {
56+
switch v := vs[i].(type) {
57+
case ConsoleConfig:
58+
cfg = &v
59+
}
5260
}
5361

54-
cfg, ok := v.(ConsoleConfig)
55-
if !ok {
56-
return nil, fmt.Errorf("invalid config object: want %T got %T", ConsoleConfig{}, v)
62+
if cfg == nil {
63+
cfg = &ConsoleConfig{}
5764
}
5865

5966
return &consoleLogger{
60-
level: cfg.Level,
67+
noopLogger: &noopLogger{
68+
name: name,
69+
level: cfg.Level,
70+
},
6171
Logger: log.New(color.Output, "", log.Ldate|log.Ltime),
6272
}, nil
63-
})
73+
}
6474
}

console_test.go

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,51 @@
11
package clog
22

33
import (
4-
"errors"
54
"testing"
65

76
"github.com/stretchr/testify/assert"
87
)
98

10-
func Test_ModeConsole(t *testing.T) {
11-
defer Remove(ModeConsole)
9+
func Test_consoleLogger(t *testing.T) {
10+
testName := "Test_consoleLogger"
11+
defer Remove(DefaultConsoleName)
12+
defer Remove(testName)
1213

1314
tests := []struct {
1415
name string
16+
mode string
1517
config interface{}
1618
wantLevel Level
1719
wantErr error
1820
}{
1921
{
2022
name: "nil config",
23+
mode: DefaultConsoleName,
2124
wantErr: nil,
2225
},
2326
{
2427
name: "valid config",
28+
mode: DefaultConsoleName,
2529
config: ConsoleConfig{
2630
Level: LevelInfo,
2731
},
2832
wantErr: nil,
2933
},
3034
{
31-
name: "invalid config",
32-
config: "random things",
33-
wantErr: errors.New("initialize logger: invalid config object: want clog.ConsoleConfig got string"),
35+
name: "custom name",
36+
mode: testName,
37+
wantErr: nil,
3438
},
3539
}
3640
for _, tt := range tests {
3741
t.Run(tt.name, func(t *testing.T) {
38-
assert.Equal(t, tt.wantErr, New(ModeConsole, 10, tt.config))
42+
assert.Equal(t, tt.wantErr, NewConsoleWithName(tt.mode, 10, tt.config))
3943
})
4044
}
4145

42-
assert.Equal(t, 1, mgr.len())
43-
assert.Equal(t, ModeConsole, mgr.loggers[0].Mode())
46+
assert.Equal(t, 2, mgr.len())
47+
assert.Equal(t, DefaultConsoleName, mgr.loggers[0].Name())
4448
assert.Equal(t, LevelInfo, mgr.loggers[0].Level())
49+
assert.Equal(t, testName, mgr.loggers[1].Name())
50+
assert.Equal(t, LevelTrace, mgr.loggers[1].Level())
4551
}

0 commit comments

Comments
 (0)