parent
88badfcf44
commit
8152713ad2
|
@ -0,0 +1,173 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
const LOG_OUTPUT_BUFFER = 1024
|
||||||
|
|
||||||
|
const (
|
||||||
|
LevelDebug = iota
|
||||||
|
LevelInfo
|
||||||
|
LevelNotice
|
||||||
|
LevelWarn
|
||||||
|
LevelError
|
||||||
|
)
|
||||||
|
|
||||||
|
type logMesg struct {
|
||||||
|
Level int
|
||||||
|
Mesg string
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoggerHandler interface {
|
||||||
|
Setup(config map[string]interface{}) error
|
||||||
|
Write(mesg *logMesg)
|
||||||
|
}
|
||||||
|
|
||||||
|
type GoDNSLogger struct {
|
||||||
|
level int
|
||||||
|
mesgs chan *logMesg
|
||||||
|
outputs map[string]LoggerHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogger() *GoDNSLogger {
|
||||||
|
logger := &GoDNSLogger{
|
||||||
|
mesgs: make(chan *logMesg, LOG_OUTPUT_BUFFER),
|
||||||
|
outputs: make(map[string]LoggerHandler),
|
||||||
|
}
|
||||||
|
go logger.Run()
|
||||||
|
return logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GoDNSLogger) SetLogger(handlerType string, config map[string]interface{}) {
|
||||||
|
var handler LoggerHandler
|
||||||
|
switch handlerType {
|
||||||
|
case "console":
|
||||||
|
handler = NewConsoleHandler()
|
||||||
|
case "file":
|
||||||
|
handler = NewFileHandler()
|
||||||
|
default:
|
||||||
|
panic("Unknown log handler.")
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.Setup(config)
|
||||||
|
l.outputs[handlerType] = handler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GoDNSLogger) SetLevel(level int) {
|
||||||
|
l.level = level
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GoDNSLogger) Run() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case mesg := <-l.mesgs:
|
||||||
|
for _, handler := range l.outputs {
|
||||||
|
handler.Write(mesg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GoDNSLogger) writeMesg(mesg string, level int) {
|
||||||
|
if l.level > level {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lm := &logMesg{
|
||||||
|
Level: level,
|
||||||
|
Mesg: mesg,
|
||||||
|
}
|
||||||
|
|
||||||
|
l.mesgs <- lm
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GoDNSLogger) Debug(format string, v ...interface{}) {
|
||||||
|
mesg := fmt.Sprintf("[DEBUG] "+format, v...)
|
||||||
|
l.writeMesg(mesg, LevelDebug)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GoDNSLogger) Info(format string, v ...interface{}) {
|
||||||
|
mesg := fmt.Sprintf("[INFO] "+format, v...)
|
||||||
|
l.writeMesg(mesg, LevelInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GoDNSLogger) Notice(format string, v ...interface{}) {
|
||||||
|
mesg := fmt.Sprintf("[NOTICE] "+format, v...)
|
||||||
|
l.writeMesg(mesg, LevelNotice)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GoDNSLogger) Warn(format string, v ...interface{}) {
|
||||||
|
mesg := fmt.Sprintf("[WARN] "+format, v...)
|
||||||
|
l.writeMesg(mesg, LevelWarn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GoDNSLogger) Error(format string, v ...interface{}) {
|
||||||
|
mesg := fmt.Sprintf("[ERROR] "+format, v...)
|
||||||
|
l.writeMesg(mesg, LevelError)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConsoleHandler struct {
|
||||||
|
level int
|
||||||
|
logger *log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConsoleHandler() LoggerHandler {
|
||||||
|
return new(ConsoleHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ConsoleHandler) Setup(config map[string]interface{}) error {
|
||||||
|
if _level, ok := config["level"]; ok {
|
||||||
|
level := _level.(int)
|
||||||
|
h.level = level
|
||||||
|
}
|
||||||
|
h.logger = log.New(os.Stdout, "", log.Ldate|log.Ltime)
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ConsoleHandler) Write(lm *logMesg) {
|
||||||
|
if h.level <= lm.Level {
|
||||||
|
h.logger.Println(lm.Mesg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileHandler struct {
|
||||||
|
level int
|
||||||
|
file string
|
||||||
|
logger *log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFileHandler() LoggerHandler {
|
||||||
|
return new(FileHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *FileHandler) Setup(config map[string]interface{}) error {
|
||||||
|
if level, ok := config["level"]; ok {
|
||||||
|
h.level = level.(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
if file, ok := config["file"]; ok {
|
||||||
|
h.file = file.(string)
|
||||||
|
output, err := os.Create(h.file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
h.logger = log.New(output, "", log.Ldate|log.Ltime)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *FileHandler) Write(lm *logMesg) {
|
||||||
|
if h.logger == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if h.level <= lm.Level {
|
||||||
|
h.logger.Println(lm.Mesg)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConsole(t *testing.T) {
|
||||||
|
logger := NewLogger()
|
||||||
|
logger.SetLogger("console", nil)
|
||||||
|
logger.SetLevel(LevelInfo)
|
||||||
|
|
||||||
|
logger.Debug("debug")
|
||||||
|
logger.Info("info")
|
||||||
|
logger.Notice("notiece")
|
||||||
|
logger.Warn("warn")
|
||||||
|
logger.Error("error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFile(t *testing.T) {
|
||||||
|
logger := NewLogger()
|
||||||
|
logger.SetLogger("file", map[string]interface{}{"file": "test.log"})
|
||||||
|
logger.SetLevel(LevelInfo)
|
||||||
|
|
||||||
|
logger.Debug("debug")
|
||||||
|
logger.Info("info")
|
||||||
|
logger.Notice("notiece")
|
||||||
|
logger.Warn("warn")
|
||||||
|
logger.Error("error")
|
||||||
|
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
|
f, err := os.Open("test.log")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
b := bufio.NewReader(f)
|
||||||
|
linenum := 0
|
||||||
|
for {
|
||||||
|
line, _, err := b.ReadLine()
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if len(line) > 0 {
|
||||||
|
linenum++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Convey("Test Log File Handler", t, func() {
|
||||||
|
Convey("file line nums should be 4", func() {
|
||||||
|
So(linenum, ShouldEqual, 4)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
os.Remove("test.log")
|
||||||
|
}
|
Loading…
Reference in New Issue