"bytes"
"fmt"
"io"
- "log"
"os"
"path/filepath"
"runtime"
- "sync"
"time"
)
type Logger struct {
// params
filepath string
+ writer *os.File
level int
prefix string
- maxline int64
-
- // status
- mutex sync.Mutex
- out *os.File
- linenum int64
}
// New creates a new Logger, the path is the filepath of logfile,
// logv is an string in ['fatal','error','warn','info','debug'],
-// prefix is the content write after timestamp and before message,
-// maxline[default: 100000] create a new logfile if linenum exceed it.
+// prefix is the content write after timestamp and before message.
func New(path, logv, prefix string, options ...interface{}) *Logger {
+ var writer *os.File
+ if path != "" {
+ writer, _ = os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
+ }
+ if writer == nil {
+ writer = os.Stdout
+ }
+
level := Info
switch logv {
case "debug":
level = Fatal
}
- maxline := int64(100000)
- for _, option := range options {
- switch option.(type) {
- case int64:
- maxline = option.(int64)
- }
+ return &Logger{
+ filepath: writer.Name(),
+ writer: writer,
+ level: level,
+ prefix: prefix,
}
+}
- linenum := int64(0)
- if path != "" {
- if r, err := os.Open(path); err == nil {
- linenum, _ = lineCounter(r)
- }
+// NewWriter creates a new Logger, the writer is the *os.File of logfile,
+// logv is an string in ['fatal','error','warn','info','debug'],
+// prefix is the content write after timestamp and before message.
+func NewWriter(writer *os.File, logv, prefix string, options ...interface{}) *Logger {
+ if writer == nil {
+ writer = os.Stdout
}
+
+ level := Info
+ switch logv {
+ case "debug":
+ level = Debug
+ case "info":
+ level = Info
+ case "warn":
+ level = Warn
+ case "error":
+ level = Error
+ case "fatal":
+ level = Fatal
+ }
+
return &Logger{
- filepath: path,
+ filepath: writer.Name(),
+ writer: writer,
level: level,
prefix: prefix,
- maxline: maxline,
- out: nil,
- linenum: linenum,
}
}
-func (l *Logger) IOWriter() *os.File {
- return l.out
+func (l *Logger) Filepath() string {
+ return l.filepath
+}
+
+func (l *Logger) Writer() *os.File {
+ return l.writer
}
// Fatal calls output(Fatal, Sprint(v)) to print the log.
}
text := fmt.Sprintf("[%v] %v %v %v:%v: %v\n", ltype, timestamp, l.prefix, filepath.Base(file), line, msg)
- l.mutex.Lock()
- defer l.mutex.Unlock()
-
- // make a new logfile.
- if l.maxline <= l.linenum {
- if l.filepath != "" {
- if l.out != nil {
- l.out.Close()
- l.out = nil
- }
- newname := fmt.Sprintf("%v.%v", l.filepath, time.Now().Format("20060102"))
- if err := os.Rename(l.filepath, newname); err == nil {
- l.linenum = 0
- }
- } else {
- l.linenum = 0
- }
- }
- if l.out == nil {
- if l.filepath != "" {
- l.out, _ = os.OpenFile(l.filepath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
- } else {
- l.out = os.Stdout
- }
- }
- if l.out == nil {
- log.Println("logger's output is nil")
- }
-
// write to logfile.
buf := []byte(text)
- if _, err := l.out.Write(buf); err == nil {
- l.linenum++
- }
+ l.writer.Write(buf)
}
func lineCounter(r io.Reader) (int64, error) {