func DiscardLogging() {
	LogHandle = ioutil.Discard
	initialize()
}
Disables logging for the entire JWW system
package jwalterweatherman
import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"sync/atomic"
)
type Level int
type NotePad struct {
	Handle  io.Writer
	Level   Level
	Prefix  string
	Logger  **log.Logger
	counter uint64
}
func (n *NotePad) incr() {
	atomic.AddUint64(&n.counter, 1)
}
func (n *NotePad) resetCounter() {
	atomic.StoreUint64(&n.counter, 0)
}
func (n *NotePad) getCount() uint64 {
	return atomic.LoadUint64(&n.counter)
}
type countingWriter struct {
	incrFunc func()
}
func (cw *countingWriter) Write(p []byte) (n int, err error) {
	cw.incrFunc()
	return 0, nil
}
type Feedback struct{}
const (
	LevelTrace Level = iota
	LevelDebug
	LevelInfo
	LevelWarn
	LevelError
	LevelCritical
	LevelFatal
	DefaultLogThreshold    = LevelWarn
	DefaultStdoutThreshold = LevelError
)
var (
	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
	LogHandle  io.Writer  = ioutil.Discard
	OutHandle  io.Writer  = os.Stdout
	BothHandle io.Writer  = io.MultiWriter(LogHandle, OutHandle)
	NotePads   []*NotePad = []*NotePad{trace, debug, info, warn, err, critical, fatal}
	trace           *NotePad = &NotePad{Level: LevelTrace, Handle: os.Stdout, Logger: &TRACE, Prefix: "TRACE: "}
	debug           *NotePad = &NotePad{Level: LevelDebug, Handle: os.Stdout, Logger: &DEBUG, Prefix: "DEBUG: "}
	info            *NotePad = &NotePad{Level: LevelInfo, Handle: os.Stdout, Logger: &INFO, Prefix: "INFO: "}
	warn            *NotePad = &NotePad{Level: LevelWarn, Handle: os.Stdout, Logger: &WARN, Prefix: "WARN: "}
	err             *NotePad = &NotePad{Level: LevelError, Handle: os.Stdout, Logger: &ERROR, Prefix: "ERROR: "}
	critical        *NotePad = &NotePad{Level: LevelCritical, Handle: os.Stdout, Logger: &CRITICAL, Prefix: "CRITICAL: "}
	fatal           *NotePad = &NotePad{Level: LevelFatal, Handle: os.Stdout, Logger: &FATAL, Prefix: "FATAL: "}
	logThreshold    Level    = DefaultLogThreshold
	outputThreshold Level    = DefaultStdoutThreshold
)
const (
	DATE  = log.Ldate
	TIME  = log.Ltime
	SFILE = log.Lshortfile
	LFILE = log.Llongfile
	MSEC  = log.Lmicroseconds
)
var logFlags = DATE | TIME | SFILE
func init() {
	SetStdoutThreshold(DefaultStdoutThreshold)
}
func initialize() {
	BothHandle = io.MultiWriter(LogHandle, OutHandle)
	for _, n := range NotePads {
		if n.Level < outputThreshold && n.Level < logThreshold {
			n.Handle = ioutil.Discard
		} else if n.Level >= outputThreshold && n.Level >= logThreshold {
			n.Handle = BothHandle
		} else if n.Level >= outputThreshold && n.Level < logThreshold {
			n.Handle = OutHandle
		} else {
			n.Handle = LogHandle
		}
	}
	for _, n := range NotePads {
		n.Handle = io.MultiWriter(n.Handle, &countingWriter{n.incr})
		*n.Logger = log.New(n.Handle, n.Prefix, logFlags)
	}
	LOG = log.New(LogHandle,
		"LOG:   ",
		logFlags)
}
func SetLogFlag(flags int) {
	logFlags = flags
	initialize()
}
func LogThreshold() Level {
	return logThreshold
}
func StdoutThreshold() Level {
	return outputThreshold
}
func levelCheck(level Level) Level {
	switch {
	case level <= LevelTrace:
		return LevelTrace
	case level >= LevelFatal:
		return LevelFatal
	default:
		return level
	}
}
func SetLogThreshold(level Level) {
	logThreshold = levelCheck(level)
	initialize()
}
func SetStdoutThreshold(level Level) {
	outputThreshold = levelCheck(level)
	initialize()
}
func SetLogFile(path string) {
	file, err := os.OpenFile(path, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		CRITICAL.Println("Failed to open log file:", path, err)
		os.Exit(-1)
	}
	INFO.Println("Logging to", file.Name())
	LogHandle = file
	initialize()
}
func UseTempLogFile(prefix string) {
	file, err := ioutil.TempFile(os.TempDir(), prefix)
	if err != nil {
		CRITICAL.Println(err)
	}
	INFO.Println("Logging to", file.Name())
	LogHandle = file
	initialize()
}
func LogCountForLevel(l Level) uint64 {
	for _, np := range NotePads {
		if np.Level == l {
			return np.getCount()
		}
	}
	return 0
}
func LogCountForLevelsGreaterThanorEqualTo(threshold Level) uint64 {
	var cnt uint64
	for _, np := range NotePads {
		if np.Level >= threshold {
			cnt += np.getCount()
		}
	}
	return cnt
}
func ResetLogCounters() {
	for _, np := range NotePads {
		np.resetCounter()
	}
}