123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- // Copyright © 2016 Steve Francia <spf@spf13.com>.
- //
- // Use of this source code is governed by an MIT-style
- // license that can be found in the LICENSE file.
-
- package jwalterweatherman
-
- import (
- "fmt"
- "io"
- "log"
- )
-
- type Threshold int
-
- func (t Threshold) String() string {
- return prefixes[t]
- }
-
- const (
- LevelTrace Threshold = iota
- LevelDebug
- LevelInfo
- LevelWarn
- LevelError
- LevelCritical
- LevelFatal
- )
-
- var prefixes map[Threshold]string = map[Threshold]string{
- LevelTrace: "TRACE",
- LevelDebug: "DEBUG",
- LevelInfo: "INFO",
- LevelWarn: "WARN",
- LevelError: "ERROR",
- LevelCritical: "CRITICAL",
- LevelFatal: "FATAL",
- }
-
- // Notepad is where you leave a note!
- type Notepad struct {
- TRACE *log.Logger
- DEBUG *log.Logger
- INFO *log.Logger
- WARN *log.Logger
- ERROR *log.Logger
- CRITICAL *log.Logger
- FATAL *log.Logger
-
- LOG *log.Logger
- FEEDBACK *Feedback
-
- loggers [7]**log.Logger
- logHandle io.Writer
- outHandle io.Writer
- logThreshold Threshold
- stdoutThreshold Threshold
- prefix string
- flags int
-
- // One per Threshold
- logCounters [7]*logCounter
- }
-
- // NewNotepad create a new notepad.
- func NewNotepad(outThreshold Threshold, logThreshold Threshold, outHandle, logHandle io.Writer, prefix string, flags int) *Notepad {
- n := &Notepad{}
-
- n.loggers = [7]**log.Logger{&n.TRACE, &n.DEBUG, &n.INFO, &n.WARN, &n.ERROR, &n.CRITICAL, &n.FATAL}
- n.outHandle = outHandle
- n.logHandle = logHandle
- n.stdoutThreshold = outThreshold
- n.logThreshold = logThreshold
-
- if len(prefix) != 0 {
- n.prefix = "[" + prefix + "] "
- } else {
- n.prefix = ""
- }
-
- n.flags = flags
-
- n.LOG = log.New(n.logHandle,
- "LOG: ",
- n.flags)
- n.FEEDBACK = &Feedback{out: log.New(outHandle, "", 0), log: n.LOG}
-
- n.init()
- return n
- }
-
- // init creates the loggers for each level depending on the notepad thresholds.
- func (n *Notepad) init() {
- logAndOut := io.MultiWriter(n.outHandle, n.logHandle)
-
- for t, logger := range n.loggers {
- threshold := Threshold(t)
- counter := &logCounter{}
- n.logCounters[t] = counter
- prefix := n.prefix + threshold.String() + " "
-
- switch {
- case threshold >= n.logThreshold && threshold >= n.stdoutThreshold:
- *logger = log.New(io.MultiWriter(counter, logAndOut), prefix, n.flags)
-
- case threshold >= n.logThreshold:
- *logger = log.New(io.MultiWriter(counter, n.logHandle), prefix, n.flags)
-
- case threshold >= n.stdoutThreshold:
- *logger = log.New(io.MultiWriter(counter, n.outHandle), prefix, n.flags)
-
- default:
- // counter doesn't care about prefix and flags, so don't use them
- // for performance.
- *logger = log.New(counter, "", 0)
- }
- }
- }
-
- // SetLogThreshold changes the threshold above which messages are written to the
- // log file.
- func (n *Notepad) SetLogThreshold(threshold Threshold) {
- n.logThreshold = threshold
- n.init()
- }
-
- // SetLogOutput changes the file where log messages are written.
- func (n *Notepad) SetLogOutput(handle io.Writer) {
- n.logHandle = handle
- n.init()
- }
-
- // GetStdoutThreshold returns the defined Treshold for the log logger.
- func (n *Notepad) GetLogThreshold() Threshold {
- return n.logThreshold
- }
-
- // SetStdoutThreshold changes the threshold above which messages are written to the
- // standard output.
- func (n *Notepad) SetStdoutThreshold(threshold Threshold) {
- n.stdoutThreshold = threshold
- n.init()
- }
-
- // GetStdoutThreshold returns the Treshold for the stdout logger.
- func (n *Notepad) GetStdoutThreshold() Threshold {
- return n.stdoutThreshold
- }
-
- // SetPrefix changes the prefix used by the notepad. Prefixes are displayed between
- // brackets at the beginning of the line. An empty prefix won't be displayed at all.
- func (n *Notepad) SetPrefix(prefix string) {
- if len(prefix) != 0 {
- n.prefix = "[" + prefix + "] "
- } else {
- n.prefix = ""
- }
- n.init()
- }
-
- // SetFlags choose which flags the logger will display (after prefix and message
- // level). See the package log for more informations on this.
- func (n *Notepad) SetFlags(flags int) {
- n.flags = flags
- n.init()
- }
-
- // Feedback writes plainly to the outHandle while
- // logging with the standard extra information (date, file, etc).
- type Feedback struct {
- out *log.Logger
- log *log.Logger
- }
-
- func (fb *Feedback) Println(v ...interface{}) {
- fb.output(fmt.Sprintln(v...))
- }
-
- func (fb *Feedback) Printf(format string, v ...interface{}) {
- fb.output(fmt.Sprintf(format, v...))
- }
-
- func (fb *Feedback) Print(v ...interface{}) {
- fb.output(fmt.Sprint(v...))
- }
-
- func (fb *Feedback) output(s string) {
- if fb.out != nil {
- fb.out.Output(2, s)
- }
- if fb.log != nil {
- fb.log.Output(2, s)
- }
- }
|