Skip to content

Commit

Permalink
log level exposed go-aah/aah#61, discard receiver added
Browse files Browse the repository at this point in the history
  • Loading branch information
jeevatkm committed Jun 9, 2017
1 parent f32cca0 commit 73fe517
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 40 deletions.
7 changes: 7 additions & 0 deletions console_receiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package log

import (
"os"
"testing"

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

exit = func(code int) {}
logger.Fatal("Yes, yes, yes - finally an error")
logger.Fatalf("Yes, yes, yes - %v", "finally an error")
logger.Fatalln("Yes, yes, yes - %v", "finally an error")
exit = os.Exit

assert.NotNil(t, logger.ToGoLogger())
}
41 changes: 37 additions & 4 deletions default.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"fmt"
"io"
slog "log"
"os"

"aahframework.org/config.v0"
)
Expand Down Expand Up @@ -92,19 +91,19 @@ func Println(format string, v ...interface{}) {
// Fatal logs message as `FATAL` and call to os.Exit(1).
func Fatal(v ...interface{}) {
std.output(levelFatal, 3, nil, v...)
os.Exit(1)
exit(1)
}

// Fatalf logs message as `FATAL` and call to os.Exit(1).
func Fatalf(format string, v ...interface{}) {
std.output(levelFatal, 3, &format, v...)
os.Exit(1)
exit(1)
}

// Fatalln logs message as `FATAL` and call to os.Exit(1).
func Fatalln(format string, v ...interface{}) {
std.output(levelFatal, 3, &format, v...)
os.Exit(1)
exit(1)
}

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

//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Logger level and assertion methods
//___________________________________

// Level method returns currently enabled logging level.
func Level() string {
return std.Level()
}

// IsLevelInfo method returns true if log level is INFO otherwise false.
func IsLevelInfo() bool {
return std.IsLevelInfo()
}

// IsLevelError method returns true if log level is ERROR otherwise false.
func IsLevelError() bool {
return std.IsLevelError()
}

// IsLevelWarn method returns true if log level is WARN otherwise false.
func IsLevelWarn() bool {
return std.IsLevelWarn()
}

// IsLevelDebug method returns true if log level is DEBUG otherwise false.
func IsLevelDebug() bool {
return std.IsLevelDebug()
}

// IsLevelTrace method returns true if log level is TRACE otherwise false.
func IsLevelTrace() bool {
return std.IsLevelTrace()
}

func init() {
cfg, _ := config.ParseString("log { }")
std, _ = New(cfg)
Expand Down
14 changes: 14 additions & 0 deletions default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package log

import (
"os"
"testing"

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

assert.Equal(t, "DEBUG", Level())
assert.True(t, IsLevelDebug())
assert.False(t, IsLevelError())
assert.False(t, IsLevelInfo())
assert.False(t, IsLevelWarn())
assert.False(t, IsLevelTrace())

exit = func(code int) {}
Fatal("fatal msg 1")
Fatalln("fatal msg %v", 2)
Fatalf("fatal msg %v", 3)
exit = os.Exit
}

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

assert.Equal(t, "DEBUG", newStd.Level())
assert.Nil(t, SetLevel("trace"))
assert.Nil(t, SetPattern("%level:-5 %message"))
}
Expand Down
2 changes: 1 addition & 1 deletion entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var (
// Entry represents a log entry and contains the timestamp when the entry
// was created, level, etc.
type Entry struct {
Level Level `json:"level,omitempty"`
Level level `json:"level,omitempty"`
Time time.Time `json:"timestamp,omitempty"`
Message string `json:"message,omitempty"`
File string `json:"file,omitempty"`
Expand Down
35 changes: 23 additions & 12 deletions file_receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"io"
"os"
"path/filepath"
"sync"
"time"

"aahframework.org/config.v0"
Expand All @@ -25,6 +26,7 @@ type FileReceiver struct {
flags *[]FlagPart
isCallerInfo bool
stats *receiverStats
mu *sync.Mutex
isClosed bool
rotatePolicy string
openDay int
Expand Down Expand Up @@ -53,7 +55,7 @@ func (f *FileReceiver) Init(cfg *config.Config) error {
f.rotatePolicy = cfg.StringDefault("log.rotate.policy", "daily")
switch f.rotatePolicy {
case "daily":
f.openDay = time.Now().Day()
f.openDay = f.getDay()
case "lines":
f.maxLines = int64(cfg.IntDefault("log.rotate.lines", 0))
case "size":
Expand All @@ -64,6 +66,8 @@ func (f *FileReceiver) Init(cfg *config.Config) error {
f.maxSize = maxSize
}

f.mu = &sync.Mutex{}

return nil
}

Expand All @@ -78,9 +82,7 @@ func (f *FileReceiver) SetPattern(pattern string) error {
f.isCallerInfo = isCallerInfo(f.flags)
}
f.isUTC = isFmtFlagExists(f.flags, FmtFlagUTCTime)
if f.isUTC {
f.openDay = time.Now().UTC().Day()
}
f.openDay = f.getDay()
return nil
}

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

// Log method logs the given entry values into file.
func (f *FileReceiver) Log(entry *Entry) {
f.mu.Lock()
if f.isRotate() {
_ = f.rotateFile()

// reset rotation values
f.openDay = f.getDay()
f.stats.lines = 0
f.stats.bytes = 0
}
f.mu.Unlock()

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

size, _ := f.out.Write(msg)
if size == 0 {
return
}

// calculate receiver stats
f.stats.bytes += int64(size)
Expand All @@ -123,16 +129,14 @@ func (f *FileReceiver) Writer() io.Writer {
func (f *FileReceiver) isRotate() bool {
switch f.rotatePolicy {
case "daily":
if f.isUTC {
return time.Now().UTC().Day() != f.openDay
}
return time.Now().Day() != f.openDay
return f.openDay != f.getDay()
case "lines":
return f.maxLines != 0 && f.stats.lines >= f.maxLines
case "size":
return f.maxSize != 0 && f.stats.bytes >= f.maxSize
default:
return false
}
return false
}

func (f *FileReceiver) rotateFile() error {
Expand Down Expand Up @@ -191,3 +195,10 @@ func (f *FileReceiver) backupFileName() string {
}
return filepath.Join(dir, fmt.Sprintf("%s-%s%s", baseName, t.Format(BackupTimeFormat), ext))
}

func (f *FileReceiver) getDay() int {
if f.isUTC {
return time.Now().UTC().Day()
}
return time.Now().Day()
}
2 changes: 1 addition & 1 deletion formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const (
// Format: "2006-01-02 15:04:05.000",
// }
type FlagPart struct {
Flag FmtFlag
Flag fmtFlag
Name string
Format string
}
Expand Down
60 changes: 47 additions & 13 deletions log.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,17 @@ import (
"aahframework.org/config.v0"
)

// Level type definition
type Level uint8
type (
// FmtFlag type definition
fmtFlag uint8

// FmtFlag type definition
type FmtFlag uint8
// Level type definition
level uint8
)

// Log Level definition
const (
levelFatal Level = iota
levelFatal level = iota
levelPanic
LevelError
LevelWarn
Expand All @@ -54,7 +56,7 @@ const (

// Format flags used to define log message format for each log entry
const (
FmtFlagLevel FmtFlag = iota
FmtFlagLevel fmtFlag = iota
FmtFlagTime
FmtFlagUTCTime
FmtFlagLongfile
Expand All @@ -67,7 +69,7 @@ const (

var (
// Version no. of aahframework.org/log library
Version = "0.4"
Version = "0.5"

// FmtFlags is the list of log format flags supported by aah/log library
// Usage of flag order is up to format composition.
Expand All @@ -79,7 +81,7 @@ var (
// line - outputs file line number: L23
// message - outputs given message along supplied arguments if they present
// custom - outputs string as-is into log entry
FmtFlags = map[string]FmtFlag{
FmtFlags = map[string]fmtFlag{
"level": FmtFlagLevel,
"time": FmtFlagTime,
"utctime": FmtFlagUTCTime,
Expand All @@ -106,6 +108,9 @@ var (
flagValueSeparator = ":"
defaultFormat = "%v"
filePermission = os.FileMode(0755)

// abstract it, can be unit tested
exit = os.Exit
)

type (
Expand All @@ -125,7 +130,7 @@ type (
Logger struct {
cfg *config.Config
m *sync.Mutex
level Level
level level
receiver Receiver
}
)
Expand Down Expand Up @@ -288,19 +293,19 @@ func (l *Logger) Println(format string, v ...interface{}) {
// Fatal logs message as `FATAL` and call to os.Exit(1).
func (l *Logger) Fatal(v ...interface{}) {
l.output(levelFatal, 3, nil, v...)
os.Exit(1)
exit(1)
}

// Fatalf logs message as `FATAL` and call to os.Exit(1).
func (l *Logger) Fatalf(format string, v ...interface{}) {
l.output(levelFatal, 3, &format, v...)
os.Exit(1)
exit(1)
}

// Fatalln logs message as `FATAL` and call to os.Exit(1).
func (l *Logger) Fatalln(format string, v ...interface{}) {
l.output(levelFatal, 3, &format, v...)
os.Exit(1)
exit(1)
}

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

//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Logger level methods
//___________________________________

// IsLevelInfo method returns true if log level is INFO otherwise false.
func (l *Logger) IsLevelInfo() bool {
return l.level == LevelInfo
}

// IsLevelError method returns true if log level is INFO otherwise false.
func (l *Logger) IsLevelError() bool {
return l.level == LevelError
}

// IsLevelWarn method returns true if log level is INFO otherwise false.
func (l *Logger) IsLevelWarn() bool {
return l.level == LevelWarn
}

// IsLevelDebug method returns true if log level is INFO otherwise false.
func (l *Logger) IsLevelDebug() bool {
return l.level == LevelDebug
}

// IsLevelTrace method returns true if log level is INFO otherwise false.
func (l *Logger) IsLevelTrace() bool {
return l.level == LevelTrace
}

//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Unexported methods
//___________________________________

// output method checks the level, formats the arguments and call to configured
// Log receivers.
func (l *Logger) output(level Level, calldepth int, format *string, v ...interface{}) {
func (l *Logger) output(level level, calldepth int, format *string, v ...interface{}) {
if level > l.level {
return
}
Expand Down
2 changes: 1 addition & 1 deletion log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func TestMisc(t *testing.T) {
assert.Equal(t, "log: config is nil", err.Error())

// Discard
discard := DiscardReceiver{}
discard := getReceiverByName("DISCARD")
_ = discard.Init(nil)
discard.Log(&Entry{})
_ = discard.SetPattern("nothing")
Expand Down
Loading

0 comments on commit 73fe517

Please sign in to comment.