imposm3/logging/logger.go

252 lines
5.2 KiB
Go
Raw Normal View History

2013-05-23 19:53:58 +04:00
package logging
import (
"fmt"
2013-07-10 11:50:50 +04:00
"os"
2013-05-23 19:53:58 +04:00
"sync"
"time"
)
type Level int
const (
FATAL Level = iota
ERROR
WARNING
INFO
DEBUG
)
type Record struct {
Level Level
Component string
Message string
}
const (
CLEARLINE = "\x1b[2K"
)
func Debugf(msg string, args ...interface{}) {
defaultLogBroker.Records <- Record{DEBUG, "", fmt.Sprintf(msg, args...)}
}
func Infof(msg string, args ...interface{}) {
defaultLogBroker.Records <- Record{INFO, "", fmt.Sprintf(msg, args...)}
}
func Warnf(msg string, args ...interface{}) {
defaultLogBroker.Records <- Record{WARNING, "", fmt.Sprintf(msg, args...)}
}
func Errorf(msg string, args ...interface{}) {
defaultLogBroker.Records <- Record{ERROR, "", fmt.Sprintf(msg, args...)}
}
func Fatalf(msg string, args ...interface{}) {
defaultLogBroker.Records <- Record{FATAL, "", fmt.Sprintf(msg, args...)}
2013-07-10 11:50:50 +04:00
Shutdown()
os.Exit(1)
2013-05-23 19:53:58 +04:00
}
func Progress(msg string) {
defaultLogBroker.Progress <- msg
}
2013-05-29 16:19:47 +04:00
func SetQuiet(quiet bool) {
defaultLogBroker.SetQuiet(quiet)
}
2013-05-23 19:53:58 +04:00
type Logger struct {
Component string
}
2013-05-31 16:48:16 +04:00
func (l *Logger) Print(args ...interface{}) {
defaultLogBroker.Records <- Record{INFO, l.Component, fmt.Sprint(args...)}
}
2013-05-23 19:53:58 +04:00
func (l *Logger) Printf(msg string, args ...interface{}) {
defaultLogBroker.Records <- Record{INFO, l.Component, fmt.Sprintf(msg, args...)}
}
func (l *Logger) Fatal(args ...interface{}) {
defaultLogBroker.Records <- Record{FATAL, l.Component, fmt.Sprint(args...)}
2013-07-10 11:50:50 +04:00
Shutdown()
os.Exit(1)
2013-05-23 19:53:58 +04:00
}
func (l *Logger) Fatalf(msg string, args ...interface{}) {
defaultLogBroker.Records <- Record{FATAL, l.Component, fmt.Sprintf(msg, args...)}
2013-07-10 11:50:50 +04:00
Shutdown()
os.Exit(1)
2013-05-23 19:53:58 +04:00
}
func (l *Logger) Error(args ...interface{}) {
defaultLogBroker.Records <- Record{ERROR, l.Component, fmt.Sprint(args...)}
}
2013-05-23 19:53:58 +04:00
func (l *Logger) Errorf(msg string, args ...interface{}) {
defaultLogBroker.Records <- Record{ERROR, l.Component, fmt.Sprintf(msg, args...)}
}
2013-05-31 16:48:16 +04:00
func (l *Logger) Warn(args ...interface{}) {
defaultLogBroker.Records <- Record{WARNING, l.Component, fmt.Sprint(args...)}
}
2013-05-28 16:07:06 +04:00
func (l *Logger) Warnf(msg string, args ...interface{}) {
defaultLogBroker.Records <- Record{WARNING, l.Component, fmt.Sprintf(msg, args...)}
}
2013-05-23 19:53:58 +04:00
func (l *Logger) Printfl(level Level, msg string, args ...interface{}) {
defaultLogBroker.Records <- Record{level, l.Component, fmt.Sprintf(msg, args...)}
}
2013-05-28 16:07:06 +04:00
func (l *Logger) StartStep(msg string) string {
defaultLogBroker.StepStart <- Step{l.Component, msg}
return msg
}
func (l *Logger) StopStep(msg string) {
defaultLogBroker.StepStop <- Step{l.Component, msg}
}
2013-05-23 19:53:58 +04:00
func NewLogger(component string) *Logger {
return &Logger{component}
}
2013-05-28 16:07:06 +04:00
type Step struct {
Component string
Name string
}
2013-05-23 19:53:58 +04:00
type LogBroker struct {
2013-05-28 16:07:06 +04:00
Records chan Record
Progress chan string
StepStart chan Step
StepStop chan Step
2013-05-29 16:19:47 +04:00
quiet bool
2013-05-28 16:07:06 +04:00
quit chan bool
wg *sync.WaitGroup
newline bool
lastProgress string
2013-05-23 19:53:58 +04:00
}
2013-05-29 16:19:47 +04:00
func (l *LogBroker) SetQuiet(quiet bool) {
l.quiet = quiet
}
2013-05-23 19:53:58 +04:00
func (l *LogBroker) loop() {
l.wg.Add(1)
2013-05-28 16:07:06 +04:00
steps := make(map[Step]time.Time)
2013-05-27 13:22:58 +04:00
For:
2013-05-23 19:53:58 +04:00
for {
select {
case record := <-l.Records:
l.printRecord(record)
case progress := <-l.Progress:
2013-05-29 16:19:47 +04:00
if !l.quiet {
l.printProgress(progress)
}
2013-05-28 16:07:06 +04:00
case step := <-l.StepStart:
steps[step] = time.Now()
l.printProgress(step.Name)
case step := <-l.StepStop:
startTime := steps[step]
delete(steps, step)
duration := time.Since(startTime)
l.lastProgress = ""
2013-05-28 16:07:06 +04:00
l.printRecord(Record{INFO, step.Component, step.Name + " took: " + duration.String()})
2013-05-23 19:53:58 +04:00
case <-l.quit:
2013-05-27 13:22:58 +04:00
break For
2013-05-23 19:53:58 +04:00
}
}
2013-05-29 10:47:44 +04:00
Flush:
// after quit, print all records from chan
for {
select {
case record := <-l.Records:
l.printRecord(record)
default:
break Flush
}
}
2013-05-23 19:53:58 +04:00
l.wg.Done()
}
func (l *LogBroker) printPrefix() {
fmt.Print("[", time.Now().Format(time.Stamp), "] ")
}
func (l *LogBroker) printComponent(component string) {
if component != "" {
fmt.Print("[", component, "] ")
}
}
func (l *LogBroker) printLevel(level Level) {
switch level {
case INFO:
fmt.Print("[INFO] ")
case WARNING:
fmt.Print("[WARN] ")
case ERROR:
fmt.Print("[ERR] ")
}
}
2013-05-23 19:53:58 +04:00
func (l *LogBroker) printRecord(record Record) {
2013-05-28 16:07:06 +04:00
if !l.newline {
fmt.Print(CLEARLINE)
}
2013-05-23 19:53:58 +04:00
l.printPrefix()
l.printLevel(record.Level)
2013-05-23 19:53:58 +04:00
l.printComponent(record.Component)
fmt.Println(record.Message)
2013-05-28 16:07:06 +04:00
l.newline = true
if l.lastProgress != "" {
l.printProgress(l.lastProgress)
l.newline = false
}
2013-05-23 19:53:58 +04:00
}
func (l *LogBroker) printProgress(progress string) {
l.printPrefix()
fmt.Print(progress)
if l.quiet {
fmt.Print("\n")
l.lastProgress = ""
l.newline = true
} else {
fmt.Print("\r")
l.lastProgress = progress
l.newline = false
}
2013-05-23 19:53:58 +04:00
}
func Shutdown() {
defaultLogBroker.quit <- true
defaultLogBroker.wg.Wait()
}
var defaultLogBroker LogBroker
func init() {
defaultLogBroker = LogBroker{
2013-05-28 16:07:06 +04:00
Records: make(chan Record, 8),
Progress: make(chan string),
StepStart: make(chan Step),
StepStop: make(chan Step),
quit: make(chan bool),
wg: &sync.WaitGroup{},
2013-05-23 19:53:58 +04:00
}
go defaultLogBroker.loop()
}
// func init() {
// go func() {
// log := NewLogger("Tourette")
// for {
// time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
// log.Printfl(Level(rand.Intn(5)), "Bazinga")
// }
// }()
// }