vendor/github.com/spf13/jwalterweatherman/notepad.go
changeset 242 2a9ec03fe5a1
child 251 1c52a0eeb952
equal deleted inserted replaced
241:e77dad242f4c 242:2a9ec03fe5a1
       
     1 // Copyright © 2016 Steve Francia <spf@spf13.com>.
       
     2 //
       
     3 // Use of this source code is governed by an MIT-style
       
     4 // license that can be found in the LICENSE file.
       
     5 
       
     6 package jwalterweatherman
       
     7 
       
     8 import (
       
     9 	"fmt"
       
    10 	"io"
       
    11 	"log"
       
    12 )
       
    13 
       
    14 type Threshold int
       
    15 
       
    16 func (t Threshold) String() string {
       
    17 	return prefixes[t]
       
    18 }
       
    19 
       
    20 const (
       
    21 	LevelTrace Threshold = iota
       
    22 	LevelDebug
       
    23 	LevelInfo
       
    24 	LevelWarn
       
    25 	LevelError
       
    26 	LevelCritical
       
    27 	LevelFatal
       
    28 )
       
    29 
       
    30 var prefixes map[Threshold]string = map[Threshold]string{
       
    31 	LevelTrace:    "TRACE",
       
    32 	LevelDebug:    "DEBUG",
       
    33 	LevelInfo:     "INFO",
       
    34 	LevelWarn:     "WARN",
       
    35 	LevelError:    "ERROR",
       
    36 	LevelCritical: "CRITICAL",
       
    37 	LevelFatal:    "FATAL",
       
    38 }
       
    39 
       
    40 // Notepad is where you leave a note!
       
    41 type Notepad struct {
       
    42 	TRACE    *log.Logger
       
    43 	DEBUG    *log.Logger
       
    44 	INFO     *log.Logger
       
    45 	WARN     *log.Logger
       
    46 	ERROR    *log.Logger
       
    47 	CRITICAL *log.Logger
       
    48 	FATAL    *log.Logger
       
    49 
       
    50 	LOG      *log.Logger
       
    51 	FEEDBACK *Feedback
       
    52 
       
    53 	loggers         [7]**log.Logger
       
    54 	logHandle       io.Writer
       
    55 	outHandle       io.Writer
       
    56 	logThreshold    Threshold
       
    57 	stdoutThreshold Threshold
       
    58 	prefix          string
       
    59 	flags           int
       
    60 
       
    61 	// One per Threshold
       
    62 	logCounters [7]*logCounter
       
    63 }
       
    64 
       
    65 // NewNotepad create a new notepad.
       
    66 func NewNotepad(outThreshold Threshold, logThreshold Threshold, outHandle, logHandle io.Writer, prefix string, flags int) *Notepad {
       
    67 	n := &Notepad{}
       
    68 
       
    69 	n.loggers = [7]**log.Logger{&n.TRACE, &n.DEBUG, &n.INFO, &n.WARN, &n.ERROR, &n.CRITICAL, &n.FATAL}
       
    70 	n.outHandle = outHandle
       
    71 	n.logHandle = logHandle
       
    72 	n.stdoutThreshold = outThreshold
       
    73 	n.logThreshold = logThreshold
       
    74 
       
    75 	if len(prefix) != 0 {
       
    76 		n.prefix = "[" + prefix + "] "
       
    77 	} else {
       
    78 		n.prefix = ""
       
    79 	}
       
    80 
       
    81 	n.flags = flags
       
    82 
       
    83 	n.LOG = log.New(n.logHandle,
       
    84 		"LOG:   ",
       
    85 		n.flags)
       
    86 	n.FEEDBACK = &Feedback{out: log.New(outHandle, "", 0), log: n.LOG}
       
    87 
       
    88 	n.init()
       
    89 	return n
       
    90 }
       
    91 
       
    92 // init creates the loggers for each level depending on the notepad thresholds.
       
    93 func (n *Notepad) init() {
       
    94 	logAndOut := io.MultiWriter(n.outHandle, n.logHandle)
       
    95 
       
    96 	for t, logger := range n.loggers {
       
    97 		threshold := Threshold(t)
       
    98 		counter := &logCounter{}
       
    99 		n.logCounters[t] = counter
       
   100 		prefix := n.prefix + threshold.String() + " "
       
   101 
       
   102 		switch {
       
   103 		case threshold >= n.logThreshold && threshold >= n.stdoutThreshold:
       
   104 			*logger = log.New(io.MultiWriter(counter, logAndOut), prefix, n.flags)
       
   105 
       
   106 		case threshold >= n.logThreshold:
       
   107 			*logger = log.New(io.MultiWriter(counter, n.logHandle), prefix, n.flags)
       
   108 
       
   109 		case threshold >= n.stdoutThreshold:
       
   110 			*logger = log.New(io.MultiWriter(counter, n.outHandle), prefix, n.flags)
       
   111 
       
   112 		default:
       
   113 			// counter doesn't care about prefix and flags, so don't use them
       
   114 			// for performance.
       
   115 			*logger = log.New(counter, "", 0)
       
   116 		}
       
   117 	}
       
   118 }
       
   119 
       
   120 // SetLogThreshold changes the threshold above which messages are written to the
       
   121 // log file.
       
   122 func (n *Notepad) SetLogThreshold(threshold Threshold) {
       
   123 	n.logThreshold = threshold
       
   124 	n.init()
       
   125 }
       
   126 
       
   127 // SetLogOutput changes the file where log messages are written.
       
   128 func (n *Notepad) SetLogOutput(handle io.Writer) {
       
   129 	n.logHandle = handle
       
   130 	n.init()
       
   131 }
       
   132 
       
   133 // GetStdoutThreshold returns the defined Treshold for the log logger.
       
   134 func (n *Notepad) GetLogThreshold() Threshold {
       
   135 	return n.logThreshold
       
   136 }
       
   137 
       
   138 // SetStdoutThreshold changes the threshold above which messages are written to the
       
   139 // standard output.
       
   140 func (n *Notepad) SetStdoutThreshold(threshold Threshold) {
       
   141 	n.stdoutThreshold = threshold
       
   142 	n.init()
       
   143 }
       
   144 
       
   145 // GetStdoutThreshold returns the Treshold for the stdout logger.
       
   146 func (n *Notepad) GetStdoutThreshold() Threshold {
       
   147 	return n.stdoutThreshold
       
   148 }
       
   149 
       
   150 // SetPrefix changes the prefix used by the notepad. Prefixes are displayed between
       
   151 // brackets at the beginning of the line. An empty prefix won't be displayed at all.
       
   152 func (n *Notepad) SetPrefix(prefix string) {
       
   153 	if len(prefix) != 0 {
       
   154 		n.prefix = "[" + prefix + "] "
       
   155 	} else {
       
   156 		n.prefix = ""
       
   157 	}
       
   158 	n.init()
       
   159 }
       
   160 
       
   161 // SetFlags choose which flags the logger will display (after prefix and message
       
   162 // level). See the package log for more informations on this.
       
   163 func (n *Notepad) SetFlags(flags int) {
       
   164 	n.flags = flags
       
   165 	n.init()
       
   166 }
       
   167 
       
   168 // Feedback writes plainly to the outHandle while
       
   169 // logging with the standard extra information (date, file, etc).
       
   170 type Feedback struct {
       
   171 	out *log.Logger
       
   172 	log *log.Logger
       
   173 }
       
   174 
       
   175 func (fb *Feedback) Println(v ...interface{}) {
       
   176 	fb.output(fmt.Sprintln(v...))
       
   177 }
       
   178 
       
   179 func (fb *Feedback) Printf(format string, v ...interface{}) {
       
   180 	fb.output(fmt.Sprintf(format, v...))
       
   181 }
       
   182 
       
   183 func (fb *Feedback) Print(v ...interface{}) {
       
   184 	fb.output(fmt.Sprint(v...))
       
   185 }
       
   186 
       
   187 func (fb *Feedback) output(s string) {
       
   188 	if fb.out != nil {
       
   189 		fb.out.Output(2, s)
       
   190 	}
       
   191 	if fb.log != nil {
       
   192 		fb.log.Output(2, s)
       
   193 	}
       
   194 }