diff --git a/.gitignore b/.gitignore
index f6207cd..1d3d262 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
*.sw[op]
.DS_Store
+.idea/
\ No newline at end of file
diff --git a/config.go b/config.go
index 4e90f8f..5eec44f 100644
--- a/config.go
+++ b/config.go
@@ -127,7 +127,7 @@ func (log Logger) LoadConfiguration(filename string) {
continue
}
- log[xmlfilt.Tag] = &Filter{lvl, filt}
+ log[xmlfilt.Tag] = &Filter{lvl, filt, xmlfilt.Tag}
}
}
@@ -180,6 +180,7 @@ func xmlToFileLogWriter(filename string, props []xmlProperty, enabled bool) (*Fi
format := "[%D %T] [%L] (%S) %M"
maxlines := 0
maxsize := 0
+ hourly := false
daily := false
rotate := false
@@ -194,6 +195,8 @@ func xmlToFileLogWriter(filename string, props []xmlProperty, enabled bool) (*Fi
maxlines = strToNumSuffix(strings.Trim(prop.Value, " \r\n"), 1000)
case "maxsize":
maxsize = strToNumSuffix(strings.Trim(prop.Value, " \r\n"), 1024)
+ case "hourly":
+ hourly = strings.Trim(prop.Value, " \r\n") != "false"
case "daily":
daily = strings.Trim(prop.Value, " \r\n") != "false"
case "rotate":
@@ -218,6 +221,7 @@ func xmlToFileLogWriter(filename string, props []xmlProperty, enabled bool) (*Fi
flw.SetFormat(format)
flw.SetRotateLines(maxlines)
flw.SetRotateSize(maxsize)
+ flw.SetRotateHourly(hourly)
flw.SetRotateDaily(daily)
return flw, true
}
diff --git a/filelog.go b/filelog.go
index adbc1f7..cceae04 100644
--- a/filelog.go
+++ b/filelog.go
@@ -6,6 +6,7 @@ import (
"fmt"
"os"
"time"
+ "strings"
)
// This log writer sends output to a file
@@ -35,6 +36,10 @@ type FileLogWriter struct {
daily bool
daily_opendate int
+ // Rotate hourly
+ hourly bool
+ hourly_opendate int
+
// Keep old logfiles (.001, .002, etc)
rotate bool
maxbackup int
@@ -97,7 +102,8 @@ func NewFileLogWriter(fname string, rotate bool) *FileLogWriter {
now := time.Now()
if (w.maxlines > 0 && w.maxlines_curlines >= w.maxlines) ||
(w.maxsize > 0 && w.maxsize_cursize >= w.maxsize) ||
- (w.daily && now.Day() != w.daily_opendate) {
+ (w.hourly && now.Hour() != w.hourly_opendate) ||
+ (w.daily && now.Day() != w.daily_opendate) {
if err := w.intRotate(); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
return
@@ -135,17 +141,19 @@ func (w *FileLogWriter) intRotate() error {
}
// If we are keeping log files, move it to the next available number
+ fileName := getActualPathReplacePattern(w.filename)
if w.rotate {
- _, err := os.Lstat(w.filename)
+ _, err := os.Lstat(fileName)
if err == nil { // file exists
// Find the next available number
num := 1
fname := ""
+ //cutting by daily
if w.daily && time.Now().Day() != w.daily_opendate {
yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
for ; err == nil && num <= w.maxbackup; num++ {
- fname = w.filename + fmt.Sprintf(".%s.%03d", yesterday, num)
+ fname = fileName + fmt.Sprintf(".%s.%03d", yesterday, num)
_, err = os.Lstat(fname)
}
// return error if the last file checked still existed
@@ -155,8 +163,8 @@ func (w *FileLogWriter) intRotate() error {
} else {
num = w.maxbackup - 1
for ; num >= 1; num-- {
- fname = w.filename + fmt.Sprintf(".%d", num)
- nfname := w.filename + fmt.Sprintf(".%d", num+1)
+ fname = fileName + fmt.Sprintf(".%d", num)
+ nfname := fileName + fmt.Sprintf(".%d", num+1)
_, err = os.Lstat(fname)
if err == nil {
os.Rename(fname, nfname)
@@ -166,7 +174,7 @@ func (w *FileLogWriter) intRotate() error {
w.file.Close()
// Rename the file to its newfound home
- err = os.Rename(w.filename, fname)
+ err = os.Rename(fileName, fname)
if err != nil {
return fmt.Errorf("Rotate: %s\n", err)
}
@@ -174,7 +182,7 @@ func (w *FileLogWriter) intRotate() error {
}
// Open the log file
- fd, err := os.OpenFile(w.filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660)
+ fd, err := os.OpenFile(fileName, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660)
if err != nil {
return err
}
@@ -185,6 +193,7 @@ func (w *FileLogWriter) intRotate() error {
// Set the daily open date to the current date
w.daily_opendate = now.Day()
+ w.hourly_opendate = now.Hour()
// initialize rotation values
w.maxlines_curlines = 0
@@ -227,6 +236,13 @@ func (w *FileLogWriter) SetRotateSize(maxsize int) *FileLogWriter {
return w
}
+// Set rotate hourly (chainable). Must be called before the first log message is
+// written.
+func (w *FileLogWriter) SetRotateHourly(hourly bool) *FileLogWriter {
+ w.hourly = hourly
+ return w
+}
+
// Set rotate daily (chainable). Must be called before the first log message is
// written.
func (w *FileLogWriter) SetRotateDaily(daily bool) *FileLogWriter {
@@ -262,3 +278,20 @@ func NewXMLLogWriter(fname string, rotate bool) *FileLogWriter {
%M
`).SetHeadFoot("", "")
}
+
+
+func getActualPathReplacePattern(pattern string) string {
+ now := time.Now()
+ Y := fmt.Sprintf("%d",now.Year())
+ M := fmt.Sprintf("%02d",now.Month())
+ D := fmt.Sprintf("%02d",now.Day())
+ H := fmt.Sprintf("%02d",now.Hour())
+ m := fmt.Sprintf("%02d",now.Minute())
+
+ pattern = strings.Replace(pattern, "%Y", Y, -1)
+ pattern = strings.Replace(pattern, "%M", M, -1)
+ pattern = strings.Replace(pattern, "%D", D, -1)
+ pattern = strings.Replace(pattern, "%H", H, -1)
+ pattern = strings.Replace(pattern, "%m", m, -1)
+ return pattern
+}
\ No newline at end of file
diff --git a/log4go.go b/log4go.go
index 822e890..d7d04d1 100644
--- a/log4go.go
+++ b/log4go.go
@@ -46,20 +46,20 @@
package log4go
import (
- "errors"
- "fmt"
- "os"
- "runtime"
- "strings"
- "time"
+ "errors"
+ "fmt"
+ "os"
+ "runtime"
+ "strings"
+ "time"
)
// Version information
const (
- L4G_VERSION = "log4go-v3.0.1"
- L4G_MAJOR = 3
- L4G_MINOR = 0
- L4G_BUILD = 1
+ L4G_VERSION = "log4go-v3.0.1"
+ L4G_MAJOR = 3
+ L4G_MINOR = 0
+ L4G_BUILD = 1
)
/****** Constants ******/
@@ -68,55 +68,55 @@ const (
type Level int
const (
- FINEST Level = iota
- FINE
- DEBUG
- TRACE
- INFO
- WARNING
- ERROR
- CRITICAL
+ FINEST Level = iota
+ FINE
+ DEBUG
+ TRACE
+ INFO
+ WARNING
+ ERROR
+ CRITICAL
)
// Logging level strings
var (
- levelStrings = [...]string{"FNST", "FINE", "DEBG", "TRAC", "INFO", "WARN", "EROR", "CRIT"}
+ levelStrings = [...]string{"FNST", "FINE", "DEBG", "TRAC", "INFO", "WARN", "EROR", "CRIT"}
)
func (l Level) String() string {
- if l < 0 || int(l) > len(levelStrings) {
- return "UNKNOWN"
- }
- return levelStrings[int(l)]
+ if l < 0 || int(l) > len(levelStrings) {
+ return "UNKNOWN"
+ }
+ return levelStrings[int(l)]
}
/****** Variables ******/
var (
- // LogBufferLength specifies how many log messages a particular log4go
- // logger can buffer at a time before writing them.
- LogBufferLength = 32
+ // LogBufferLength specifies how many log messages a particular log4go
+ // logger can buffer at a time before writing them.
+ LogBufferLength = 32
)
/****** LogRecord ******/
// A LogRecord contains all of the pertinent information for each message
type LogRecord struct {
- Level Level // The log level
- Created time.Time // The time at which the log message was created (nanoseconds)
- Source string // The message source
- Message string // The log message
+ Level Level // The log level
+ Created time.Time // The time at which the log message was created (nanoseconds)
+ Source string // The message source
+ Message string // The log message
}
/****** LogWriter ******/
// This is an interface for anything that should be able to write logs
type LogWriter interface {
- // This will be called to log a LogRecord message.
- LogWrite(rec *LogRecord)
+ // This will be called to log a LogRecord message.
+ LogWrite(rec *LogRecord)
- // This should clean up anything lingering about the LogWriter, as it is called before
- // the LogWriter is removed. LogWrite should not be called after Close.
- Close()
+ // This should clean up anything lingering about the LogWriter, as it is called before
+ // the LogWriter is removed. LogWrite should not be called after Close.
+ Close()
}
/****** Logger ******/
@@ -124,8 +124,9 @@ type LogWriter interface {
// A Filter represents the log level below which no log records are written to
// the associated LogWriter.
type Filter struct {
- Level Level
- LogWriter
+ Level Level
+ LogWriter LogWriter
+ Tag string
}
// A Logger represents a collection of Filters through which log messages are
@@ -136,8 +137,8 @@ type Logger map[string]*Filter
//
// DEPRECATED: Use make(Logger) instead.
func NewLogger() Logger {
- os.Stderr.WriteString("warning: use of deprecated NewLogger\n")
- return make(Logger)
+ os.Stderr.WriteString("warning: use of deprecated NewLogger\n")
+ return make(Logger)
}
// Create a new logger with a "stdout" filter configured to send log messages at
@@ -145,18 +146,18 @@ func NewLogger() Logger {
//
// DEPRECATED: use NewDefaultLogger instead.
func NewConsoleLogger(lvl Level) Logger {
- os.Stderr.WriteString("warning: use of deprecated NewConsoleLogger\n")
- return Logger{
- "stdout": &Filter{lvl, NewConsoleLogWriter()},
- }
+ os.Stderr.WriteString("warning: use of deprecated NewConsoleLogger\n")
+ return Logger{
+ "stdout": &Filter{Level: lvl, LogWriter: NewConsoleLogWriter()},
+ }
}
// Create a new logger with a "stdout" filter configured to send log messages at
// or above lvl to standard output.
func NewDefaultLogger(lvl Level) Logger {
- return Logger{
- "stdout": &Filter{lvl, NewConsoleLogWriter()},
- }
+ return Logger{
+ "stdout": &Filter{Level: lvl, LogWriter: NewConsoleLogWriter()},
+ }
}
// Closes all log writers in preparation for exiting the program or a
@@ -164,185 +165,197 @@ func NewDefaultLogger(lvl Level) Logger {
// you want to guarantee that all log messages are written. Close removes
// all filters (and thus all LogWriters) from the logger.
func (log Logger) Close() {
- // Close all open loggers
- for name, filt := range log {
- filt.Close()
- delete(log, name)
- }
+ // Close all open loggers
+ for name, filt := range log {
+ filt.LogWriter.Close()
+ delete(log, name)
+ }
}
// Add a new LogWriter to the Logger which will only log messages at lvl or
// higher. This function should not be called from multiple goroutines.
// Returns the logger for chaining.
func (log Logger) AddFilter(name string, lvl Level, writer LogWriter) Logger {
- log[name] = &Filter{lvl, writer}
- return log
+ log[name] = &Filter{Level: lvl, LogWriter: NewConsoleLogWriter()}
+ return log
}
/******* Logging *******/
// Send a formatted log message internally
func (log Logger) intLogf(lvl Level, format string, args ...interface{}) {
- skip := true
-
- // Determine if any logging will be done
- for _, filt := range log {
- if lvl >= filt.Level {
- skip = false
- break
- }
- }
- if skip {
- return
- }
-
- // Determine caller func
- pc, _, lineno, ok := runtime.Caller(2)
- src := ""
- if ok {
- src = fmt.Sprintf("%s:%d", runtime.FuncForPC(pc).Name(), lineno)
- }
-
- msg := format
- if len(args) > 0 {
- msg = fmt.Sprintf(format, args...)
- }
-
- // Make the log record
- rec := &LogRecord{
- Level: lvl,
- Created: time.Now(),
- Source: src,
- Message: msg,
- }
-
- // Dispatch the logs
- for _, filt := range log {
- if lvl < filt.Level {
- continue
- }
- filt.LogWrite(rec)
- }
+ skip := true
+
+ // Determine if any logging will be done
+ for _, filt := range log {
+ if lvl >= filt.Level {
+ skip = false
+ break
+ }
+ }
+ if skip {
+ return
+ }
+
+ // Determine caller func
+ pc, _, lineno, ok := runtime.Caller(2)
+ src := ""
+ if ok {
+ src = fmt.Sprintf("%s:%d", runtime.FuncForPC(pc).Name(), lineno)
+ }
+
+ msg := format
+ if len(args) > 0 {
+ msg = fmt.Sprintf(format, args...)
+ }
+
+ // Make the log record
+ rec := &LogRecord{
+ Level: lvl,
+ Created: time.Now(),
+ Source: src,
+ Message: msg,
+ }
+ pac := strings.Split(src, ":")[0]
+
+ // Dispatch the logs
+ for _, filt := range log {
+ if lvl < filt.Level {
+ continue
+ }
+ skip1 := false
+ tags := strings.Split(filt.Tag, ",")
+ for _, tag := range tags {
+ if strings.Contains(pac, tag) {
+ skip1 = true
+ break
+ }
+ }
+ if skip1 {
+ filt.LogWriter.LogWrite(rec)
+ }
+
+ }
}
// Send a closure log message internally
func (log Logger) intLogc(lvl Level, closure func() string) {
- skip := true
-
- // Determine if any logging will be done
- for _, filt := range log {
- if lvl >= filt.Level {
- skip = false
- break
- }
- }
- if skip {
- return
- }
-
- // Determine caller func
- pc, _, lineno, ok := runtime.Caller(2)
- src := ""
- if ok {
- src = fmt.Sprintf("%s:%d", runtime.FuncForPC(pc).Name(), lineno)
- }
-
- // Make the log record
- rec := &LogRecord{
- Level: lvl,
- Created: time.Now(),
- Source: src,
- Message: closure(),
- }
-
- // Dispatch the logs
- for _, filt := range log {
- if lvl < filt.Level {
- continue
- }
- filt.LogWrite(rec)
- }
+ skip := true
+
+ // Determine if any logging will be done
+ for _, filt := range log {
+ if lvl >= filt.Level {
+ skip = false
+ break
+ }
+ }
+ if skip {
+ return
+ }
+
+ // Determine caller func
+ pc, _, lineno, ok := runtime.Caller(2)
+ src := ""
+ if ok {
+ src = fmt.Sprintf("%s:%d", runtime.FuncForPC(pc).Name(), lineno)
+ }
+
+ // Make the log record
+ rec := &LogRecord{
+ Level: lvl,
+ Created: time.Now(),
+ Source: src,
+ Message: closure(),
+ }
+
+ // Dispatch the logs
+ for _, filt := range log {
+ if lvl < filt.Level {
+ continue
+ }
+ filt.LogWriter.LogWrite(rec)
+ }
}
// Send a log message with manual level, source, and message.
func (log Logger) Log(lvl Level, source, message string) {
- skip := true
-
- // Determine if any logging will be done
- for _, filt := range log {
- if lvl >= filt.Level {
- skip = false
- break
- }
- }
- if skip {
- return
- }
-
- // Make the log record
- rec := &LogRecord{
- Level: lvl,
- Created: time.Now(),
- Source: source,
- Message: message,
- }
-
- // Dispatch the logs
- for _, filt := range log {
- if lvl < filt.Level {
- continue
- }
- filt.LogWrite(rec)
- }
+ skip := true
+
+ // Determine if any logging will be done
+ for _, filt := range log {
+ if lvl >= filt.Level {
+ skip = false
+ break
+ }
+ }
+ if skip {
+ return
+ }
+
+ // Make the log record
+ rec := &LogRecord{
+ Level: lvl,
+ Created: time.Now(),
+ Source: source,
+ Message: message,
+ }
+
+ // Dispatch the logs
+ for _, filt := range log {
+ if lvl < filt.Level {
+ continue
+ }
+ filt.LogWriter.LogWrite(rec)
+ }
}
// Logf logs a formatted log message at the given log level, using the caller as
// its source.
func (log Logger) Logf(lvl Level, format string, args ...interface{}) {
- log.intLogf(lvl, format, args...)
+ log.intLogf(lvl, format, args...)
}
// Logc logs a string returned by the closure at the given log level, using the caller as
// its source. If no log message would be written, the closure is never called.
func (log Logger) Logc(lvl Level, closure func() string) {
- log.intLogc(lvl, closure)
+ log.intLogc(lvl, closure)
}
// Finest logs a message at the finest log level.
// See Debug for an explanation of the arguments.
func (log Logger) Finest(arg0 interface{}, args ...interface{}) {
- const (
- lvl = FINEST
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- log.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- log.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
+ const (
+ lvl = FINEST
+ )
+ switch first := arg0.(type) {
+ case string:
+ // Use the string as a format string
+ log.intLogf(lvl, first, args...)
+ case func() string:
+ // Log the closure (no other arguments used)
+ log.intLogc(lvl, first)
+ default:
+ // Build a format string so that it will be similar to Sprint
+ log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
+ }
}
// Fine logs a message at the fine log level.
// See Debug for an explanation of the arguments.
func (log Logger) Fine(arg0 interface{}, args ...interface{}) {
- const (
- lvl = FINE
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- log.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- log.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
+ const (
+ lvl = FINE
+ )
+ switch first := arg0.(type) {
+ case string:
+ // Use the string as a format string
+ log.intLogf(lvl, first, args...)
+ case func() string:
+ // Log the closure (no other arguments used)
+ log.intLogc(lvl, first)
+ default:
+ // Build a format string so that it will be similar to Sprint
+ log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
+ }
}
// Debug is a utility method for debug log messages.
@@ -358,58 +371,58 @@ func (log Logger) Fine(arg0 interface{}, args ...interface{}) {
// When given anything else, the log message will be each of the arguments
// formatted with %v and separated by spaces (ala Sprint).
func (log Logger) Debug(arg0 interface{}, args ...interface{}) {
- const (
- lvl = DEBUG
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- log.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- log.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
+ const (
+ lvl = DEBUG
+ )
+ switch first := arg0.(type) {
+ case string:
+ // Use the string as a format string
+ log.intLogf(lvl, first, args...)
+ case func() string:
+ // Log the closure (no other arguments used)
+ log.intLogc(lvl, first)
+ default:
+ // Build a format string so that it will be similar to Sprint
+ log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
+ }
}
// Trace logs a message at the trace log level.
// See Debug for an explanation of the arguments.
func (log Logger) Trace(arg0 interface{}, args ...interface{}) {
- const (
- lvl = TRACE
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- log.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- log.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
+ const (
+ lvl = TRACE
+ )
+ switch first := arg0.(type) {
+ case string:
+ // Use the string as a format string
+ log.intLogf(lvl, first, args...)
+ case func() string:
+ // Log the closure (no other arguments used)
+ log.intLogc(lvl, first)
+ default:
+ // Build a format string so that it will be similar to Sprint
+ log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
+ }
}
// Info logs a message at the info log level.
// See Debug for an explanation of the arguments.
func (log Logger) Info(arg0 interface{}, args ...interface{}) {
- const (
- lvl = INFO
- )
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- log.intLogf(lvl, first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- log.intLogc(lvl, first)
- default:
- // Build a format string so that it will be similar to Sprint
- log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
- }
+ const (
+ lvl = INFO
+ )
+ switch first := arg0.(type) {
+ case string:
+ // Use the string as a format string
+ log.intLogf(lvl, first, args...)
+ case func() string:
+ // Log the closure (no other arguments used)
+ log.intLogc(lvl, first)
+ default:
+ // Build a format string so that it will be similar to Sprint
+ log.intLogf(lvl, fmt.Sprint(arg0)+strings.Repeat(" %v", len(args)), args...)
+ }
}
// Warn logs a message at the warning log level and returns the formatted error.
@@ -418,67 +431,67 @@ func (log Logger) Info(arg0 interface{}, args ...interface{}) {
// closures are executed to format the error message.
// See Debug for further explanation of the arguments.
func (log Logger) Warn(arg0 interface{}, args ...interface{}) error {
- const (
- lvl = WARNING
- )
- var msg string
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- msg = fmt.Sprintf(first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- msg = first()
- default:
- // Build a format string so that it will be similar to Sprint
- msg = fmt.Sprintf(fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...)
- }
- log.intLogf(lvl, msg)
- return errors.New(msg)
+ const (
+ lvl = WARNING
+ )
+ var msg string
+ switch first := arg0.(type) {
+ case string:
+ // Use the string as a format string
+ msg = fmt.Sprintf(first, args...)
+ case func() string:
+ // Log the closure (no other arguments used)
+ msg = first()
+ default:
+ // Build a format string so that it will be similar to Sprint
+ msg = fmt.Sprintf(fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...)
+ }
+ log.intLogf(lvl, msg)
+ return errors.New(msg)
}
// Error logs a message at the error log level and returns the formatted error,
// See Warn for an explanation of the performance and Debug for an explanation
// of the parameters.
func (log Logger) Error(arg0 interface{}, args ...interface{}) error {
- const (
- lvl = ERROR
- )
- var msg string
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- msg = fmt.Sprintf(first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- msg = first()
- default:
- // Build a format string so that it will be similar to Sprint
- msg = fmt.Sprintf(fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...)
- }
- log.intLogf(lvl, msg)
- return errors.New(msg)
+ const (
+ lvl = ERROR
+ )
+ var msg string
+ switch first := arg0.(type) {
+ case string:
+ // Use the string as a format string
+ msg = fmt.Sprintf(first, args...)
+ case func() string:
+ // Log the closure (no other arguments used)
+ msg = first()
+ default:
+ // Build a format string so that it will be similar to Sprint
+ msg = fmt.Sprintf(fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...)
+ }
+ log.intLogf(lvl, msg)
+ return errors.New(msg)
}
// Critical logs a message at the critical log level and returns the formatted error,
// See Warn for an explanation of the performance and Debug for an explanation
// of the parameters.
func (log Logger) Critical(arg0 interface{}, args ...interface{}) error {
- const (
- lvl = CRITICAL
- )
- var msg string
- switch first := arg0.(type) {
- case string:
- // Use the string as a format string
- msg = fmt.Sprintf(first, args...)
- case func() string:
- // Log the closure (no other arguments used)
- msg = first()
- default:
- // Build a format string so that it will be similar to Sprint
- msg = fmt.Sprintf(fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...)
- }
- log.intLogf(lvl, msg)
- return errors.New(msg)
+ const (
+ lvl = CRITICAL
+ )
+ var msg string
+ switch first := arg0.(type) {
+ case string:
+ // Use the string as a format string
+ msg = fmt.Sprintf(first, args...)
+ case func() string:
+ // Log the closure (no other arguments used)
+ msg = first()
+ default:
+ // Build a format string so that it will be similar to Sprint
+ msg = fmt.Sprintf(fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...)
+ }
+ log.intLogf(lvl, msg)
+ return errors.New(msg)
}
diff --git a/log4go_test.go b/log4go_test.go
index c4b92f6..9a9f346 100644
--- a/log4go_test.go
+++ b/log4go_test.go
@@ -94,7 +94,7 @@ var logRecordWriteTests = []struct {
}
func TestConsoleLogWriter(t *testing.T) {
- console := make(ConsoleLogWriter)
+ console := &ConsoleLogWriter{}
r, w := io.Pipe()
go console.run(w)
@@ -301,6 +301,17 @@ func TestCountMallocs(t *testing.T) {
fmt.Printf("mallocs per unlogged sl.Logf(WARNING, \"%%s is a log message with level %%d\", \"This\", WARNING): %d\n", mallocs/N)
}
+func TestGetActualPathReplacePattern(t *testing.T) {
+ fileName := "bid.%Y%M%D%H.log"
+ pattern := getActualPathReplacePattern(fileName)
+ fmt.Println(pattern)
+
+
+ fileName = "p.%Y-%M-%D.log"
+ pattern = getActualPathReplacePattern(fileName)
+ fmt.Println(pattern)
+}
+
func TestXMLConfig(t *testing.T) {
const (
configfile = "example.xml"
@@ -383,7 +394,7 @@ func TestXMLConfig(t *testing.T) {
}
// Make sure they're the right type
- if _, ok := log["stdout"].LogWriter.(ConsoleLogWriter); !ok {
+ if _, ok := log["stdout"].LogWriter.(*ConsoleLogWriter); !ok {
t.Fatalf("XMLConfig: Expected stdout to be ConsoleLogWriter, found %T", log["stdout"].LogWriter)
}
if _, ok := log["file"].LogWriter.(*FileLogWriter); !ok {
diff --git a/wrapper.go b/wrapper.go
index 2ae222b..4407f82 100644
--- a/wrapper.go
+++ b/wrapper.go
@@ -27,7 +27,7 @@ func AddFilter(name string, lvl Level, writer LogWriter) {
Global.AddFilter(name, lvl, writer)
}
-// Wrapper for (*Logger).Close (closes and removes all logwriters)
+// Wrapper for (*Logger).Close (closes and removes all logwriters )
func Close() {
Global.Close()
}