11package log
22
33import (
4+ "bufio"
45 "bytes"
56 "fmt"
67 "os"
@@ -9,19 +10,30 @@ import (
910 "time"
1011)
1112
13+ type pos struct {
14+ file string
15+ function string
16+ }
17+
1218type Logger struct {
13- out * os.File
14- level LogLevel
15- color bool
16- mu sync.Mutex
19+ rolling bool
20+ fileName string
21+ fileTime time.Time
22+ file * os.File
23+ out * bufio.Writer
24+ level LogLevel
25+ color bool
26+ posCache map [uintptr ]pos
27+ mu sync.Mutex
1728}
1829
1930//NewLogger 创建日志对象.
2031func NewLogger () * Logger {
2132 return & Logger {
22- out : os .Stdout ,
23- level : LogDebug ,
24- color : true ,
33+ out : bufio .NewWriter (os .Stdout ),
34+ level : LogDebug ,
35+ color : true ,
36+ posCache : make (map [uintptr ]pos ),
2537 }
2638}
2739
@@ -31,38 +43,46 @@ func (l *Logger) SetColor(on bool) *Logger {
3143 return l
3244}
3345
34- //SetLevel 设置日志级别.
35- func (l * Logger ) SetLevel (level LogLevel ) {
36- l .level = level
46+ //SetRolling 每天生成一个文件.
47+ func (l * Logger ) SetRolling (on bool ) * Logger {
48+ l .rolling = on
49+ return l
3750}
3851
39- //SetLevelByString 设置字符串格式的日志级别.
40- func (l * Logger ) SetLevelByString (level string ) {
41- l .level = StringToLogLevel (level )
42- }
52+ //SetOutputFile 初始化时设置输出文件.
53+ func (l * Logger ) SetOutputFile (path string ) * Logger {
54+ f , err := os .OpenFile (path , os .O_APPEND | os .O_CREATE | os .O_WRONLY , 0644 )
55+ if err != nil {
56+ panic (fmt .Sprintf ("open %s error:%v" , path , err .Error ()))
57+ }
4358
44- type pos struct {
45- file string
46- line int
47- name string
59+ now , _ := time .ParseInLocation ("20060102" , time .Now ().Format ("20060102" ), time .Local )
60+ l .fileTime = now .Add (time .Hour * 24 )
61+ l .file = f
62+ l .fileName = path
63+ l .out = bufio .NewWriter (f )
64+
65+ return l
4866}
4967
50- type posCache struct {
51- ps map [uintptr ]pos
52- sync.RWMutex
68+ //SetLevel 设置日志级别.
69+ func (l * Logger ) SetLevel (level LogLevel ) * Logger {
70+ l .level = level
71+ return l
5372}
5473
55- var mpc = posCache {ps : make (map [uintptr ]pos )}
74+ //SetLevelByString 设置字符串格式的日志级别.
75+ func (l * Logger ) SetLevelByString (level string ) * Logger {
76+ l .level = StringToLogLevel (level )
77+ return l
78+ }
5679
57- func (l * Logger ) caller () (string , int , string ) {
80+ func (l * Logger ) caller () (string , string ) {
5881 pc , file , line , _ := runtime .Caller (3 )
5982
60- mpc .RLock ()
61- p , ok := mpc .ps [pc ]
62- mpc .RUnlock ()
63-
83+ p , ok := l .posCache [pc ]
6484 if ok {
65- return p .file , p .line , p . name
85+ return p .file , p .function
6686 }
6787
6888 name := runtime .FuncForPC (pc ).Name ()
@@ -73,40 +93,69 @@ func (l *Logger) caller() (string, int, string) {
7393 file = file [i + 1 :]
7494 }
7595
76- mpc .Lock ()
77- mpc .ps [pc ] = pos {file : file , line : line , name : name }
78- mpc .Unlock ()
96+ p = pos {file : fmt .Sprintf ("%s:%d" , file , line ), function : name }
97+ l .posCache [pc ] = p
98+
99+ return p .file , p .function
100+ }
101+
102+ func (l * Logger ) rotate (now time.Time ) {
103+ if ! l .rolling || l .file == nil || now .Before (l .fileTime ) {
104+ return
105+ }
106+
107+ l .out .Flush ()
108+ l .file .Close ()
109+
110+ oldFile := l .fileName + time .Now ().Format ("20060102" )
111+
112+ os .Rename (l .fileName , oldFile )
79113
80- return file , line , name
114+ l . SetOutputFile ( l . fileName )
81115}
82116
83117func (l * Logger ) write (t LogLevel , format string , argv ... interface {}) {
84118 if t > l .level {
85119 return
86120 }
87121
88- date := time .Now ().Format ("2006/01/02 15:04:05" )
122+ l .mu .Lock ()
123+ defer l .mu .Unlock ()
89124
90- file , line , name := l .caller ()
125+ now := time .Now ()
126+ l .rotate (now )
127+ date := now .Format ("2006/01/02 15:04:05" )
128+
129+ file , function := l .caller ()
130+
131+ //时间,源码文件和行号
132+ l .out .WriteString (date )
133+ l .out .WriteString (" " )
134+ l .out .WriteString (file )
135+ l .out .WriteString (" " )
91136
92- //时间,源码文件,源码列
93- fmt .Fprintf (l .out , "%s %s:%d " , date , file , line )
94137 if l .color {
95138 //颜色开始
96- fmt . Fprint ( l .out , t .Color ())
139+ l .out . WriteString ( t .Color ())
97140 }
98141
142+ //日志级别
143+ l .out .WriteString (t .String ())
144+
99145 //函数名
100- fmt . Fprintf ( l .out , "%s %s " , t . String (), name )
146+ l .out . WriteString ( function )
101147
148+ //日志正文
102149 fmt .Fprintf (l .out , format , argv ... )
103150
104151 if l .color {
105152 //颜色结束
106- fmt . Fprint ( l .out , "\033 [0m" )
153+ l .out . WriteString ( "\033 [0m" )
107154 }
108155
109156 l .out .WriteString ("\n " )
157+
158+ l .out .Flush ()
110159}
111160
112161func (l * Logger ) Info (v ... interface {}) {
0 commit comments