better client identification at logs and some performances improves

This commit is contained in:
Máximo Cuadros Ortiz
2014-10-08 02:19:20 +02:00
parent 96d044dce4
commit 6586ac4653
12 changed files with 370 additions and 139 deletions

View File

@@ -2,27 +2,40 @@
package logger
import (
"fmt"
"log"
"os"
)
type Logger struct {
logger *log.Logger
debug bool
trace bool
logger *log.Logger
debug bool
trace bool
logLabel string
fatalLabel string
debugLabel string
traceLabel string
}
func NewStdLogger(time, debug, trace bool) *Logger {
func NewStdLogger(time, debug, trace, colors bool) *Logger {
flags := 0
if time {
flags = log.LstdFlags
}
return &Logger{
l := &Logger{
logger: log.New(os.Stderr, "", flags),
debug: debug,
trace: trace,
}
if colors {
setColoredLabelFormats(l)
} else {
setPlainLabelFormats(l)
}
return l
}
func NewFileLogger(filename string, time, debug, trace bool) *Logger {
@@ -37,29 +50,47 @@ func NewFileLogger(filename string, time, debug, trace bool) *Logger {
flags = log.LstdFlags
}
return &Logger{
l := &Logger{
logger: log.New(f, "", flags),
debug: debug,
trace: trace,
}
setPlainLabelFormats(l)
return l
}
func setPlainLabelFormats(l *Logger) {
l.logLabel = "[LOG] "
l.debugLabel = "[DBG] "
l.fatalLabel = "[ERR] "
l.traceLabel = "[TRA] "
}
func setColoredLabelFormats(l *Logger) {
colorFormat := "[\x1b[%dm%s\x1b[0m] "
l.logLabel = fmt.Sprintf(colorFormat, 32, "LOG")
l.debugLabel = fmt.Sprintf(colorFormat, 36, "DBG")
l.fatalLabel = fmt.Sprintf(colorFormat, 31, "ERR")
l.traceLabel = fmt.Sprintf(colorFormat, 33, "TRA")
}
func (l *Logger) Log(format string, v ...interface{}) {
l.logger.Printf(format, v...)
l.logger.Printf(l.logLabel+format, v...)
}
func (l *Logger) Fatal(format string, v ...interface{}) {
l.logger.Fatalf(format, v)
l.logger.Fatalf(l.fatalLabel+format, v)
}
func (l *Logger) Debug(format string, v ...interface{}) {
if l.debug == true {
l.Log(format, v...)
l.logger.Printf(l.debugLabel+format, v...)
}
}
func (l *Logger) Trace(format string, v ...interface{}) {
if l.trace == true {
l.Log(format, v...)
l.logger.Printf(l.traceLabel+format, v...)
}
}

View File

@@ -10,7 +10,7 @@ import (
)
func TestStdLogger(t *testing.T) {
logger := NewStdLogger(false, false, false)
logger := NewStdLogger(false, false, false, false)
flags := logger.logger.Flags()
if flags != 0 {
@@ -27,7 +27,7 @@ func TestStdLogger(t *testing.T) {
}
func TestStdLoggerWithDebugTraceAndTime(t *testing.T) {
logger := NewStdLogger(true, true, true)
logger := NewStdLogger(true, true, true, false)
flags := logger.logger.Flags()
if flags != log.LstdFlags {
@@ -45,35 +45,42 @@ func TestStdLoggerWithDebugTraceAndTime(t *testing.T) {
func TestStdLoggerLog(t *testing.T) {
expectOutput(t, func() {
logger := NewStdLogger(false, false, false)
logger := NewStdLogger(false, false, false, false)
logger.Log("foo")
}, "foo\n")
}, "[LOG] foo\n")
}
func TestStdLoggerLogWithColor(t *testing.T) {
expectOutput(t, func() {
logger := NewStdLogger(false, false, false, true)
logger.Log("foo")
}, "[\x1b[32mLOG\x1b[0m] foo\n")
}
func TestStdLoggerDebug(t *testing.T) {
expectOutput(t, func() {
logger := NewStdLogger(false, true, false)
logger := NewStdLogger(false, true, false, false)
logger.Debug("foo %s", "bar")
}, "foo bar\n")
}, "[DBG] foo bar\n")
}
func TestStdLoggerDebugWithOutDebug(t *testing.T) {
expectOutput(t, func() {
logger := NewStdLogger(false, false, false)
logger := NewStdLogger(false, false, false, false)
logger.Debug("foo")
}, "")
}
func TestStdLoggerTrace(t *testing.T) {
expectOutput(t, func() {
logger := NewStdLogger(false, false, true)
logger := NewStdLogger(false, false, true, false)
logger.Trace("foo")
}, "foo\n")
}, "[TRA] foo\n")
}
func TestStdLoggerTraceWithOutDebug(t *testing.T) {
expectOutput(t, func() {
logger := NewStdLogger(false, false, false)
logger := NewStdLogger(false, false, false, false)
logger.Trace("foo")
}, "")
}
@@ -99,13 +106,13 @@ func TestFileLogger(t *testing.T) {
t.Fatal("Expected a non-zero length logfile")
}
if string(buf) != "foo\n" {
t.Fatalf("Expected '%s', received '%s'\n", "foo", string(buf))
if string(buf) != "[LOG] foo\n" {
t.Fatalf("Expected '%s', received '%s'\n", "[LOG] foo", string(buf))
}
}
func expectOutput(t *testing.T, f func(), expect string) {
old := os.Stdout // keep backup of the real stdout
func expectOutput(t *testing.T, f func(), expected string) {
old := os.Stderr // keep backup of the real stdout
r, w, _ := os.Pipe()
os.Stderr = w
@@ -122,7 +129,7 @@ func expectOutput(t *testing.T, f func(), expect string) {
os.Stderr.Close()
os.Stderr = old // restoring the real stdout
out := <-outC
if out != expect {
t.Fatalf("Expected '%s', received '%s'\n", expect, out)
if out != expected {
t.Fatalf("Expected '%s', received '%s'\n", expected, out)
}
}

View File

@@ -48,13 +48,13 @@ func (l *SysLogger) Fatal(format string, v ...interface{}) {
}
func (l *SysLogger) Debug(format string, v ...interface{}) {
if l.debug == true {
if l.debug {
l.writer.Debug(fmt.Sprintf(format, v...))
}
}
func (l *SysLogger) Trace(format string, v ...interface{}) {
if l.trace == true {
if l.trace {
l.writer.Info(fmt.Sprintf(format, v...))
}
}

135
logger/syslog_test.go Normal file
View File

@@ -0,0 +1,135 @@
package logger
import (
"log"
"net"
"strings"
"testing"
"time"
)
var serverAddr string
func TestSysLogger(t *testing.T) {
logger := NewSysLogger(false, false)
if logger.debug != false {
t.Fatalf("Expected %b, received %b\n", false, logger.debug)
}
if logger.trace != false {
t.Fatalf("Expected %b, received %b\n", false, logger.trace)
}
}
func TestSysLoggerWithDebugAndTrace(t *testing.T) {
logger := NewSysLogger(true, true)
if logger.debug != true {
t.Fatalf("Expected %b, received %b\n", true, logger.debug)
}
if logger.trace != true {
t.Fatalf("Expected %b, received %b\n", true, logger.trace)
}
}
func TestRemoteSysLogger(t *testing.T) {
done := make(chan string)
startServer(done)
logger := NewRemoteSysLogger("udp", serverAddr, true, true)
if logger.debug != true {
t.Fatalf("Expected %b, received %b\n", true, logger.debug)
}
if logger.trace != true {
t.Fatalf("Expected %b, received %b\n", true, logger.trace)
}
}
func TestRemoteSysLoggerLog(t *testing.T) {
done := make(chan string)
startServer(done)
logger := NewRemoteSysLogger("udp", serverAddr, true, true)
logger.Log("foo %s", "bar")
expectSyslogOutput(t, <-done, "foo bar\n")
}
func TestRemoteSysLoggerDebug(t *testing.T) {
done := make(chan string)
startServer(done)
logger := NewRemoteSysLogger("udp", serverAddr, true, true)
logger.Debug("foo %s", "qux")
expectSyslogOutput(t, <-done, "foo qux\n")
}
func TestRemoteSysLoggerDebugDisabled(t *testing.T) {
done := make(chan string)
startServer(done)
logger := NewRemoteSysLogger("udp", serverAddr, false, false)
logger.Debug("foo %s", "qux")
rcvd := <-done
if rcvd != "" {
t.Fatalf("Unexpected syslog response %s\n", rcvd)
}
}
func TestRemoteSysLoggerTrace(t *testing.T) {
done := make(chan string)
startServer(done)
logger := NewRemoteSysLogger("udp", serverAddr, true, true)
logger.Trace("foo %s", "qux")
expectSyslogOutput(t, <-done, "foo qux\n")
}
func TestRemoteSysLoggerTraceDisabled(t *testing.T) {
done := make(chan string)
startServer(done)
logger := NewRemoteSysLogger("udp", serverAddr, true, false)
logger.Trace("foo %s", "qux")
rcvd := <-done
if rcvd != "" {
t.Fatalf("Unexpected syslog response %s\n", rcvd)
}
}
func expectSyslogOutput(t *testing.T, line string, expected string) {
data := strings.Split(line, "]: ")
if len(data) != 2 {
t.Fatalf("Unexpected syslog line %s\n", line)
}
if data[1] != expected {
t.Fatalf("Expected '%s', received '%s'\n", expected, data[1])
}
}
func runSyslog(c net.PacketConn, done chan<- string) {
var buf [4096]byte
var rcvd string = ""
for {
n, _, err := c.ReadFrom(buf[:])
if err != nil || n == 0 {
break
}
rcvd += string(buf[:n])
}
done <- rcvd
}
func startServer(done chan<- string) {
c, e := net.ListenPacket("udp", "127.0.0.1:0")
if e != nil {
log.Fatalf("net.ListenPacket failed udp :0 %v", e)
}
serverAddr = c.LocalAddr().String()
c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
go runSyslog(c, done)
}