-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrate_log.go
127 lines (110 loc) · 3.49 KB
/
rate_log.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package rateLog
import (
"fmt"
"io"
"sync"
"time"
)
//
type ILogger interface {
Output(string) error
}
type RateLogger struct {
mu sync.Mutex // ensures atomic writes; protects the following fields
prefix string // prefix to write at beginning of each line
flag string // properties,time.Time.Format的参数
out io.Writer // destination for output
buf []byte // for accumulating text to write
timeMu sync.Mutex // 保护下面两个属性
duration time.Duration // 写log的周期,例如1秒
lastTime time.Time // 最后写log的时间
}
// New creates a new Logger. The out variable sets the
// destination to which log data will be written.
// The prefix appears at the beginning of each generated log line.
// The flag argument defines the logging properties. 如time.RFC3339
/*
ANSIC = "Mon Jan _2 15:04:05 2006"
UnixDate = "Mon Jan _2 15:04:05 MST 2006"
RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
RFC822 = "02 Jan 06 15:04 MST"
RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
RFC3339 = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
Kitchen = "3:04PM"
// Handy time stamps.
Stamp = "Jan _2 15:04:05"
StampMilli = "Jan _2 15:04:05.000"
StampMicro = "Jan _2 15:04:05.000000"
StampNano = "Jan _2 15:04:05.000000000"
*/
func New(out io.Writer, prefix string, flag string) *RateLogger {
return &RateLogger{out: out, prefix: prefix, flag: flag, duration: time.Second}
}
func (l *RateLogger) formatHeader(buf *[]byte, t time.Time) {
if l.prefix != "" {
*buf = append(*buf, l.prefix...)
*buf = append(*buf, ' ')
}
if l.flag != "" {
*buf = append(*buf, t.Format(l.flag)...)
*buf = append(*buf, ' ')
}
}
func (l *RateLogger) Output(s string) error {
now := time.Now() // get this early.
l.timeMu.Lock()
if l.lastTime.Add(l.duration).After(now) {
l.timeMu.Unlock()
return nil
}
l.lastTime = now
l.timeMu.Unlock()
l.mu.Lock()
defer l.mu.Unlock()
l.buf = l.buf[:0]
l.formatHeader(&l.buf, now)
l.buf = append(l.buf, s...)
if len(s) == 0 || s[len(s)-1] != '\n' {
l.buf = append(l.buf, '\n')
}
_, err := l.out.Write(l.buf)
return err
}
// Printf calls l.Output to print to the logger.
// Arguments are handled in the manner of fmt.Printf.
func (l *RateLogger) Printf(format string, v ...interface{}) {
l.Output(fmt.Sprintf(format, v...))
}
// Print calls l.Output to print to the logger.
// Arguments are handled in the manner of fmt.Print.
func (l *RateLogger) Print(v ...interface{}) { l.Output(fmt.Sprint(v...)) }
// Println calls l.Output to print to the logger.
// Arguments are handled in the manner of fmt.Println.
func (l *RateLogger) Println(v ...interface{}) { l.Output(fmt.Sprintln(v...)) }
func (l *RateLogger) SetDuration(duration time.Duration) {
l.timeMu.Lock()
defer l.timeMu.Unlock()
l.duration = duration
}
// SetFlags sets the output flags for the logger.
func (l *RateLogger) SetFlags(flag string) {
l.mu.Lock()
defer l.mu.Unlock()
l.flag = flag
}
// SetPrefix sets the output prefix for the logger.
func (l *RateLogger) SetPrefix(prefix string) {
l.mu.Lock()
defer l.mu.Unlock()
l.prefix = prefix
}
// SetOutput sets the output destination for the logger.
func (l *RateLogger) SetOutput(w io.Writer) {
l.mu.Lock()
defer l.mu.Unlock()
l.out = w
}