github.com/creichlin/pentaconta@v0.1.1-0.20170602155716-6b53e3be0bdb/logger/logger.go (about)

     1  package logger
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"time"
     7  )
     8  
     9  const (
    10  	STDOUT = iota
    11  	STDERR
    12  	PENTACONTA
    13  )
    14  
    15  var (
    16  	LEVELS      = []string{"OUT", "ERR", "PEN"}
    17  	ANSI_LEVELS = map[string]string{
    18  		"OUT": "\033[0;32OUT\033[0m",
    19  		"ERR": "\033[0;31ERR\033[0m",
    20  		"PEN": "\033[0;34PEN\033[0m",
    21  	}
    22  )
    23  
    24  type Logger interface {
    25  	Log(lg Log)
    26  }
    27  
    28  type Log struct {
    29  	Service  string
    30  	Instance int
    31  	Message  string
    32  	Level    int
    33  	Time     time.Time
    34  }
    35  
    36  func NewLog(level int, service string, instance int, message string) Log {
    37  	return Log{
    38  		Time:     time.Now(),
    39  		Service:  service,
    40  		Instance: instance,
    41  		Level:    level,
    42  		Message:  message,
    43  	}
    44  }
    45  
    46  type splitLogger struct {
    47  	targets []Logger
    48  }
    49  
    50  func NewSplitLogger(targets ...Logger) Logger {
    51  	return &splitLogger{
    52  		targets: targets,
    53  	}
    54  }
    55  
    56  func (l *splitLogger) Log(lg Log) {
    57  	for _, l := range l.targets {
    58  		l.Log(lg)
    59  	}
    60  }
    61  
    62  type callLogger struct {
    63  	logs     chan Log
    64  	callback func(time.Time, string, string, int, string)
    65  }
    66  
    67  func NewCallLogger(callback func(time.Time, string, string, int, string)) Logger {
    68  	l := &callLogger{
    69  		logs:     make(chan Log, 100),
    70  		callback: callback,
    71  	}
    72  	go l.start()
    73  	return l
    74  }
    75  
    76  func (l *callLogger) start() {
    77  	for lg := range l.logs {
    78  		l.callback(lg.Time, LEVELS[lg.Level], lg.Service, lg.Instance, strings.Trim(lg.Message, "\n"))
    79  	}
    80  }
    81  
    82  func (l *callLogger) Log(lg Log) {
    83  	l.logs <- lg
    84  }
    85  
    86  // stdoutLogger uses a channel to be able to log in correct order from different goroutines
    87  // will print all logs to stdout
    88  type stdoutLogger struct {
    89  	logs chan Log
    90  }
    91  
    92  func NewStdoutLogger() Logger {
    93  	l := &stdoutLogger{
    94  		logs: make(chan Log, 100),
    95  	}
    96  	go l.start()
    97  	return l
    98  }
    99  
   100  func (l *stdoutLogger) start() {
   101  	for lg := range l.logs {
   102  		timef := lg.Time.Format("2006-01-02 15:04 05.999999")
   103  		timef += strings.Repeat("0", 26-len(timef))
   104  		fmt.Printf("%v %v %v%v: %v\n", timef, ANSI_LEVELS[LEVELS[lg.Level]], lg.Service, lg.Instance, strings.Trim(lg.Message, "\n"))
   105  	}
   106  }
   107  
   108  func (l *stdoutLogger) Log(lg Log) {
   109  	l.logs <- lg
   110  }