2013-05-23 19:53:58 +04:00
|
|
|
package logging
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"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...)}
|
|
|
|
}
|
|
|
|
|
|
|
|
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...)}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Fatalf(msg string, args ...interface{}) {
|
|
|
|
defaultLogBroker.Records <- Record{FATAL, l.Component, fmt.Sprintf(msg, args...)}
|
|
|
|
}
|
|
|
|
|
|
|
|
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.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) 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.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)
|
2013-05-28 16:07:06 +04:00
|
|
|
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")
|
|
|
|
// }
|
|
|
|
// }()
|
|
|
|
// }
|