add nullhandler and rotatingfilehandler
This commit is contained in:
parent
3042bf0c03
commit
454a429e10
|
@ -32,6 +32,21 @@ func (h *StreamHandler) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NullHandler struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNullHandler() (*NullHandler, error) {
|
||||||
|
return new(NullHandler), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *NullHandler) Write(b []byte) (n int, err error) {
|
||||||
|
return len(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *NullHandler) Close() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
type FileHandler struct {
|
type FileHandler struct {
|
||||||
fd *os.File
|
fd *os.File
|
||||||
}
|
}
|
||||||
|
@ -57,6 +72,71 @@ func (h *FileHandler) Close() error {
|
||||||
return h.fd.Close()
|
return h.fd.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RotatingFileHandler struct {
|
||||||
|
fd *os.File
|
||||||
|
|
||||||
|
fileName string
|
||||||
|
maxBytes int
|
||||||
|
backupCount int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRotatingFileHandler(fileName string, maxBytes int, backupCount int) (*RotatingFileHandler, error) {
|
||||||
|
h := new(RotatingFileHandler)
|
||||||
|
|
||||||
|
h.fileName = fileName
|
||||||
|
h.maxBytes = maxBytes
|
||||||
|
h.backupCount = backupCount
|
||||||
|
|
||||||
|
var err error
|
||||||
|
h.fd, err = os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return h, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *RotatingFileHandler) Write(p []byte) (n int, err error) {
|
||||||
|
h.doRollover()
|
||||||
|
return h.fd.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *RotatingFileHandler) Close() error {
|
||||||
|
if h.fd != nil {
|
||||||
|
return h.fd.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *RotatingFileHandler) doRollover() {
|
||||||
|
f, err := h.fd.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if h.maxBytes <= 0 {
|
||||||
|
return
|
||||||
|
} else if f.Size() < int64(h.maxBytes) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if h.backupCount > 0 {
|
||||||
|
h.fd.Close()
|
||||||
|
|
||||||
|
for i := h.backupCount - 1; i > 0; i-- {
|
||||||
|
sfn := fmt.Sprintf("%s.%d", h.fileName, i)
|
||||||
|
dfn := fmt.Sprintf("%s.%d", h.fileName, i+1)
|
||||||
|
|
||||||
|
os.Rename(sfn, dfn)
|
||||||
|
}
|
||||||
|
|
||||||
|
dfn := fmt.Sprintf("%s.1", h.fileName)
|
||||||
|
os.Rename(h.fileName, dfn)
|
||||||
|
|
||||||
|
h.fd, _ = os.OpenFile(h.fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//refer: http://docs.python.org/2/library/logging.handlers.html
|
//refer: http://docs.python.org/2/library/logging.handlers.html
|
||||||
//same like python TimedRotatingFileHandler
|
//same like python TimedRotatingFileHandler
|
||||||
|
|
||||||
|
|
|
@ -14,3 +14,39 @@ func TestStdStreamLog(t *testing.T) {
|
||||||
|
|
||||||
Info("hello world")
|
Info("hello world")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRotatingFileLog(t *testing.T) {
|
||||||
|
path := "./test_log"
|
||||||
|
os.RemoveAll(path)
|
||||||
|
|
||||||
|
os.Mkdir(path, 0777)
|
||||||
|
fileName := path + "/test"
|
||||||
|
|
||||||
|
h, err := NewRotatingFileHandler(fileName, 10, 2)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := make([]byte, 10)
|
||||||
|
|
||||||
|
h.Write(buf)
|
||||||
|
|
||||||
|
h.Write(buf)
|
||||||
|
|
||||||
|
if _, err := os.Stat(fileName + ".1"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(fileName + ".2"); err == nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
h.Write(buf)
|
||||||
|
if _, err := os.Stat(fileName + ".2"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
h.Close()
|
||||||
|
|
||||||
|
os.RemoveAll(path)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue