Skip to content

Commit f80d281

Browse files
committed
log level exposed go-aah/aah#61, discard receiver added
1 parent f32cca0 commit f80d281

File tree

9 files changed

+143
-40
lines changed

9 files changed

+143
-40
lines changed

console_receiver_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package log
66

77
import (
8+
"os"
89
"testing"
910

1011
"aahframework.org/config.v0"
@@ -121,5 +122,11 @@ func testConsoleLogger(t *testing.T, cfgStr string) {
121122
logger.Error("Yes, yes, yes - finally an error")
122123
logger.Errorf("Yes, yes, yes - %v", "finally an error")
123124

125+
exit = func(code int) {}
126+
logger.Fatal("Yes, yes, yes - finally an error")
127+
logger.Fatalf("Yes, yes, yes - %v", "finally an error")
128+
logger.Fatalln("Yes, yes, yes - %v", "finally an error")
129+
exit = os.Exit
130+
124131
assert.NotNil(t, logger.ToGoLogger())
125132
}

default.go

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"fmt"
99
"io"
1010
slog "log"
11-
"os"
1211

1312
"aahframework.org/config.v0"
1413
)
@@ -92,19 +91,19 @@ func Println(format string, v ...interface{}) {
9291
// Fatal logs message as `FATAL` and call to os.Exit(1).
9392
func Fatal(v ...interface{}) {
9493
std.output(levelFatal, 3, nil, v...)
95-
os.Exit(1)
94+
exit(1)
9695
}
9796

9897
// Fatalf logs message as `FATAL` and call to os.Exit(1).
9998
func Fatalf(format string, v ...interface{}) {
10099
std.output(levelFatal, 3, &format, v...)
101-
os.Exit(1)
100+
exit(1)
102101
}
103102

104103
// Fatalln logs message as `FATAL` and call to os.Exit(1).
105104
func Fatalln(format string, v ...interface{}) {
106105
std.output(levelFatal, 3, &format, v...)
107-
os.Exit(1)
106+
exit(1)
108107
}
109108

110109
// Panic logs message as `PANIC` and call to panic().
@@ -150,6 +149,40 @@ func SetPattern(pattern string) error {
150149
return std.SetPattern(pattern)
151150
}
152151

152+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
153+
// Logger level and assertion methods
154+
//___________________________________
155+
156+
// Level method returns currently enabled logging level.
157+
func Level() string {
158+
return std.Level()
159+
}
160+
161+
// IsLevelInfo method returns true if log level is INFO otherwise false.
162+
func IsLevelInfo() bool {
163+
return std.IsLevelInfo()
164+
}
165+
166+
// IsLevelError method returns true if log level is ERROR otherwise false.
167+
func IsLevelError() bool {
168+
return std.IsLevelError()
169+
}
170+
171+
// IsLevelWarn method returns true if log level is WARN otherwise false.
172+
func IsLevelWarn() bool {
173+
return std.IsLevelWarn()
174+
}
175+
176+
// IsLevelDebug method returns true if log level is DEBUG otherwise false.
177+
func IsLevelDebug() bool {
178+
return std.IsLevelDebug()
179+
}
180+
181+
// IsLevelTrace method returns true if log level is TRACE otherwise false.
182+
func IsLevelTrace() bool {
183+
return std.IsLevelTrace()
184+
}
185+
153186
func init() {
154187
cfg, _ := config.ParseString("log { }")
155188
std, _ = New(cfg)

default_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package log
66

77
import (
8+
"os"
89
"testing"
910

1011
"aahframework.org/config.v0"
@@ -42,6 +43,18 @@ func TestDefaultLogger(t *testing.T) {
4243
testStdPanic("panicf", "this is panicf")
4344
testStdPanic("panicln", "this is panicln")
4445

46+
assert.Equal(t, "DEBUG", Level())
47+
assert.True(t, IsLevelDebug())
48+
assert.False(t, IsLevelError())
49+
assert.False(t, IsLevelInfo())
50+
assert.False(t, IsLevelWarn())
51+
assert.False(t, IsLevelTrace())
52+
53+
exit = func(code int) {}
54+
Fatal("fatal msg 1")
55+
Fatalln("fatal msg %v", 2)
56+
Fatalf("fatal msg %v", 3)
57+
exit = os.Exit
4558
}
4659

4760
func TestDefaultLoggerMisc(t *testing.T) {
@@ -52,6 +65,7 @@ func TestDefaultLoggerMisc(t *testing.T) {
5265
Printf("welcome 2 printf")
5366
Println("welcome 2 println")
5467

68+
assert.Equal(t, "DEBUG", newStd.Level())
5569
assert.Nil(t, SetLevel("trace"))
5670
assert.Nil(t, SetPattern("%level:-5 %message"))
5771
}

entry.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ var (
1919
// Entry represents a log entry and contains the timestamp when the entry
2020
// was created, level, etc.
2121
type Entry struct {
22-
Level Level `json:"level,omitempty"`
22+
Level level `json:"level,omitempty"`
2323
Time time.Time `json:"timestamp,omitempty"`
2424
Message string `json:"message,omitempty"`
2525
File string `json:"file,omitempty"`

file_receiver.go

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"io"
1010
"os"
1111
"path/filepath"
12+
"sync"
1213
"time"
1314

1415
"aahframework.org/config.v0"
@@ -25,6 +26,7 @@ type FileReceiver struct {
2526
flags *[]FlagPart
2627
isCallerInfo bool
2728
stats *receiverStats
29+
mu *sync.Mutex
2830
isClosed bool
2931
rotatePolicy string
3032
openDay int
@@ -53,7 +55,7 @@ func (f *FileReceiver) Init(cfg *config.Config) error {
5355
f.rotatePolicy = cfg.StringDefault("log.rotate.policy", "daily")
5456
switch f.rotatePolicy {
5557
case "daily":
56-
f.openDay = time.Now().Day()
58+
f.openDay = f.getDay()
5759
case "lines":
5860
f.maxLines = int64(cfg.IntDefault("log.rotate.lines", 0))
5961
case "size":
@@ -64,6 +66,8 @@ func (f *FileReceiver) Init(cfg *config.Config) error {
6466
f.maxSize = maxSize
6567
}
6668

69+
f.mu = &sync.Mutex{}
70+
6771
return nil
6872
}
6973

@@ -78,9 +82,7 @@ func (f *FileReceiver) SetPattern(pattern string) error {
7882
f.isCallerInfo = isCallerInfo(f.flags)
7983
}
8084
f.isUTC = isFmtFlagExists(f.flags, FmtFlagUTCTime)
81-
if f.isUTC {
82-
f.openDay = time.Now().UTC().Day()
83-
}
85+
f.openDay = f.getDay()
8486
return nil
8587
}
8688

@@ -92,19 +94,23 @@ func (f *FileReceiver) IsCallerInfo() bool {
9294

9395
// Log method logs the given entry values into file.
9496
func (f *FileReceiver) Log(entry *Entry) {
97+
f.mu.Lock()
9598
if f.isRotate() {
9699
_ = f.rotateFile()
100+
101+
// reset rotation values
102+
f.openDay = f.getDay()
103+
f.stats.lines = 0
104+
f.stats.bytes = 0
97105
}
106+
f.mu.Unlock()
98107

99108
msg := applyFormatter(f.formatter, f.flags, entry)
100109
if len(msg) == 0 || msg[len(msg)-1] != '\n' {
101110
msg = append(msg, '\n')
102111
}
103112

104113
size, _ := f.out.Write(msg)
105-
if size == 0 {
106-
return
107-
}
108114

109115
// calculate receiver stats
110116
f.stats.bytes += int64(size)
@@ -123,16 +129,14 @@ func (f *FileReceiver) Writer() io.Writer {
123129
func (f *FileReceiver) isRotate() bool {
124130
switch f.rotatePolicy {
125131
case "daily":
126-
if f.isUTC {
127-
return time.Now().UTC().Day() != f.openDay
128-
}
129-
return time.Now().Day() != f.openDay
132+
return f.openDay != f.getDay()
130133
case "lines":
131134
return f.maxLines != 0 && f.stats.lines >= f.maxLines
132135
case "size":
133136
return f.maxSize != 0 && f.stats.bytes >= f.maxSize
137+
default:
138+
return false
134139
}
135-
return false
136140
}
137141

138142
func (f *FileReceiver) rotateFile() error {
@@ -191,3 +195,10 @@ func (f *FileReceiver) backupFileName() string {
191195
}
192196
return filepath.Join(dir, fmt.Sprintf("%s-%s%s", baseName, t.Format(BackupTimeFormat), ext))
193197
}
198+
199+
func (f *FileReceiver) getDay() int {
200+
if f.isUTC {
201+
return time.Now().UTC().Day()
202+
}
203+
return time.Now().Day()
204+
}

formatter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const (
2424
// Format: "2006-01-02 15:04:05.000",
2525
// }
2626
type FlagPart struct {
27-
Flag FmtFlag
27+
Flag fmtFlag
2828
Name string
2929
Format string
3030
}

log.go

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,17 @@ import (
3434
"aahframework.org/config.v0"
3535
)
3636

37-
// Level type definition
38-
type Level uint8
37+
type (
38+
// FmtFlag type definition
39+
fmtFlag uint8
3940

40-
// FmtFlag type definition
41-
type FmtFlag uint8
41+
// Level type definition
42+
level uint8
43+
)
4244

4345
// Log Level definition
4446
const (
45-
levelFatal Level = iota
47+
levelFatal level = iota
4648
levelPanic
4749
LevelError
4850
LevelWarn
@@ -54,7 +56,7 @@ const (
5456

5557
// Format flags used to define log message format for each log entry
5658
const (
57-
FmtFlagLevel FmtFlag = iota
59+
FmtFlagLevel fmtFlag = iota
5860
FmtFlagTime
5961
FmtFlagUTCTime
6062
FmtFlagLongfile
@@ -67,7 +69,7 @@ const (
6769

6870
var (
6971
// Version no. of aahframework.org/log library
70-
Version = "0.4"
72+
Version = "0.5"
7173

7274
// FmtFlags is the list of log format flags supported by aah/log library
7375
// Usage of flag order is up to format composition.
@@ -79,7 +81,7 @@ var (
7981
// line - outputs file line number: L23
8082
// message - outputs given message along supplied arguments if they present
8183
// custom - outputs string as-is into log entry
82-
FmtFlags = map[string]FmtFlag{
84+
FmtFlags = map[string]fmtFlag{
8385
"level": FmtFlagLevel,
8486
"time": FmtFlagTime,
8587
"utctime": FmtFlagUTCTime,
@@ -106,6 +108,9 @@ var (
106108
flagValueSeparator = ":"
107109
defaultFormat = "%v"
108110
filePermission = os.FileMode(0755)
111+
112+
// abstract it, can be unit tested
113+
exit = os.Exit
109114
)
110115

111116
type (
@@ -125,7 +130,7 @@ type (
125130
Logger struct {
126131
cfg *config.Config
127132
m *sync.Mutex
128-
level Level
133+
level level
129134
receiver Receiver
130135
}
131136
)
@@ -288,19 +293,19 @@ func (l *Logger) Println(format string, v ...interface{}) {
288293
// Fatal logs message as `FATAL` and call to os.Exit(1).
289294
func (l *Logger) Fatal(v ...interface{}) {
290295
l.output(levelFatal, 3, nil, v...)
291-
os.Exit(1)
296+
exit(1)
292297
}
293298

294299
// Fatalf logs message as `FATAL` and call to os.Exit(1).
295300
func (l *Logger) Fatalf(format string, v ...interface{}) {
296301
l.output(levelFatal, 3, &format, v...)
297-
os.Exit(1)
302+
exit(1)
298303
}
299304

300305
// Fatalln logs message as `FATAL` and call to os.Exit(1).
301306
func (l *Logger) Fatalln(format string, v ...interface{}) {
302307
l.output(levelFatal, 3, &format, v...)
303-
os.Exit(1)
308+
exit(1)
304309
}
305310

306311
// Panic logs message as `PANIC` and call to panic().
@@ -321,13 +326,42 @@ func (l *Logger) Panicln(format string, v ...interface{}) {
321326
panic(fmt.Sprintf(format, v...))
322327
}
323328

329+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
330+
// Logger level methods
331+
//___________________________________
332+
333+
// IsLevelInfo method returns true if log level is INFO otherwise false.
334+
func (l *Logger) IsLevelInfo() bool {
335+
return l.level == LevelInfo
336+
}
337+
338+
// IsLevelError method returns true if log level is ERROR otherwise false.
339+
func (l *Logger) IsLevelError() bool {
340+
return l.level == LevelError
341+
}
342+
343+
// IsLevelWarn method returns true if log level is WARN otherwise false.
344+
func (l *Logger) IsLevelWarn() bool {
345+
return l.level == LevelWarn
346+
}
347+
348+
// IsLevelDebug method returns true if log level is DEBUG otherwise false.
349+
func (l *Logger) IsLevelDebug() bool {
350+
return l.level == LevelDebug
351+
}
352+
353+
// IsLevelTrace method returns true if log level is TRACE otherwise false.
354+
func (l *Logger) IsLevelTrace() bool {
355+
return l.level == LevelTrace
356+
}
357+
324358
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
325359
// Unexported methods
326360
//___________________________________
327361

328362
// output method checks the level, formats the arguments and call to configured
329363
// Log receivers.
330-
func (l *Logger) output(level Level, calldepth int, format *string, v ...interface{}) {
364+
func (l *Logger) output(level level, calldepth int, format *string, v ...interface{}) {
331365
if level > l.level {
332366
return
333367
}

log_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func TestMisc(t *testing.T) {
6767
assert.Equal(t, "log: config is nil", err.Error())
6868

6969
// Discard
70-
discard := DiscardReceiver{}
70+
discard := getReceiverByName("DISCARD")
7171
_ = discard.Init(nil)
7272
discard.Log(&Entry{})
7373
_ = discard.SetPattern("nothing")

0 commit comments

Comments
 (0)