diff options
Diffstat (limited to 'vendor/github.com/spf13/jwalterweatherman')
3 files changed, 438 insertions, 0 deletions
diff --git a/vendor/github.com/spf13/jwalterweatherman/LICENSE b/vendor/github.com/spf13/jwalterweatherman/LICENSE new file mode 100644 index 0000000..4527efb --- /dev/null +++ b/vendor/github.com/spf13/jwalterweatherman/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Steve Francia + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.
\ No newline at end of file diff --git a/vendor/github.com/spf13/jwalterweatherman/README.md b/vendor/github.com/spf13/jwalterweatherman/README.md new file mode 100644 index 0000000..c6f327c --- /dev/null +++ b/vendor/github.com/spf13/jwalterweatherman/README.md @@ -0,0 +1,161 @@ +jWalterWeatherman +================= + +Seamless printing to the terminal (stdout) and logging to a io.Writer +(file) that’s as easy to use as fmt.Println. + +![and_that__s_why_you_always_leave_a_note_by_jonnyetc-d57q7um](https://cloud.githubusercontent.com/assets/173412/11002937/ccd01654-847d-11e5-828e-12ebaf582eaf.jpg) +Graphic by [JonnyEtc](http://jonnyetc.deviantart.com/art/And-That-s-Why-You-Always-Leave-a-Note-315311422) + +JWW is primarily a wrapper around the excellent standard log library. It +provides a few advantages over using the standard log library alone. + +1. Ready to go out of the box. +2. One library for both printing to the terminal and logging (to files). +3. Really easy to log to either a temp file or a file you specify. + + +I really wanted a very straightforward library that could seamlessly do +the following things. + +1. Replace all the println, printf, etc statements thought my code with + something more useful +2. Allow the user to easily control what levels are printed to stdout +3. Allow the user to easily control what levels are logged +4. Provide an easy mechanism (like fmt.Println) to print info to the user + which can be easily logged as well +5. Due to 2 & 3 provide easy verbose mode for output and logs +6. Not have any unnecessary initialization cruft. Just use it. + +# Usage + +## Step 1. Use it +Put calls throughout your source based on type of feedback. +No initialization or setup needs to happen. Just start calling things. + +Available Loggers are: + + * TRACE + * DEBUG + * INFO + * WARN + * ERROR + * CRITICAL + * FATAL + +These each are loggers based on the log standard library and follow the +standard usage. Eg.. + +```go + import ( + jww "github.com/spf13/jwalterweatherman" + ) + + ... + + if err != nil { + + // This is a pretty serious error and the user should know about + // it. It will be printed to the terminal as well as logged under the + // default thresholds. + + jww.ERROR.Println(err) + } + + if err2 != nil { + // This error isn’t going to materially change the behavior of the + // application, but it’s something that may not be what the user + // expects. Under the default thresholds, Warn will be logged, but + // not printed to the terminal. + + jww.WARN.Println(err2) + } + + // Information that’s relevant to what’s happening, but not very + // important for the user. Under the default thresholds this will be + // discarded. + + jww.INFO.Printf("information %q", response) + +``` + +_Why 7 levels?_ + +Maybe you think that 7 levels are too much for any application... and you +are probably correct. Just because there are seven levels doesn’t mean +that you should be using all 7 levels. Pick the right set for your needs. +Remember they only have to mean something to your project. + +## Step 2. Optionally configure JWW + +Under the default thresholds : + + * Debug, Trace & Info goto /dev/null + * Warn and above is logged (when a log file/io.Writer is provided) + * Error and above is printed to the terminal (stdout) + +### Changing the thresholds + +The threshold can be changed at any time, but will only affect calls that +execute after the change was made. + +This is very useful if your application has a verbose mode. Of course you +can decide what verbose means to you or even have multiple levels of +verbosity. + + +```go + import ( + jww "github.com/spf13/jwalterweatherman" + ) + + if Verbose { + jww.SetLogThreshold(jww.LevelTrace) + jww.SetStdoutThreshold(jww.LevelInfo) + } +``` + +Note that JWW's own internal output uses log levels as well, so set the log +level before making any other calls if you want to see what it's up to. + +### Using a temp log file + +JWW conveniently creates a temporary file and sets the log Handle to +a io.Writer created for it. You should call this early in your application +initialization routine as it will only log calls made after it is executed. +When this option is used, the library will fmt.Println where to find the +log file. + +```go + import ( + jww "github.com/spf13/jwalterweatherman" + ) + + jww.UseTempLogFile("YourAppName") + +``` + +### Setting a log file + +JWW can log to any file you provide a path to (provided it’s writable). +Will only append to this file. + + +```go + import ( + jww "github.com/spf13/jwalterweatherman" + ) + + jww.SetLogFile("/path/to/logfile") + +``` + + +# More information + +This is an early release. I’ve been using it for a while and this is the +third interface I’ve tried. I like this one pretty well, but no guarantees +that it won’t change a bit. + +I wrote this for use in [hugo](http://hugo.spf13.com). If you are looking +for a static website engine that’s super fast please checkout Hugo. diff --git a/vendor/github.com/spf13/jwalterweatherman/thatswhyyoualwaysleaveanote.go b/vendor/github.com/spf13/jwalterweatherman/thatswhyyoualwaysleaveanote.go new file mode 100644 index 0000000..b64ed46 --- /dev/null +++ b/vendor/github.com/spf13/jwalterweatherman/thatswhyyoualwaysleaveanote.go @@ -0,0 +1,256 @@ +// 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" + "io/ioutil" + "log" + "os" + "sync/atomic" +) + +// Level describes the chosen log level between +// debug and critical. +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 +} + +// Feedback is special. It writes plainly to the output while +// logging with the standard extra information (date, file, etc) +// Only Println and Printf are currently provided for this +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) +} + +// initialize will setup the jWalterWeatherman standard approach of providing the user +// some feedback and logging a potentially different amount based on independent log and output thresholds. +// By default the output has a lower threshold than logged +// Don't use if you have manually set the Handles of the different levels as it will overwrite them. +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) +} + +// Set the log Flags (Available flag: DATE, TIME, SFILE, LFILE and MSEC) +func SetLogFlag(flags int) { + logFlags = flags + initialize() +} + +// Level returns the current global log threshold. +func LogThreshold() Level { + return logThreshold +} + +// Level returns the current global output threshold. +func StdoutThreshold() Level { + return outputThreshold +} + +// Ensures that the level provided is within the bounds of available levels +func levelCheck(level Level) Level { + switch { + case level <= LevelTrace: + return LevelTrace + case level >= LevelFatal: + return LevelFatal + default: + return level + } +} + +// Establishes a threshold where anything matching or above will be logged +func SetLogThreshold(level Level) { + logThreshold = levelCheck(level) + initialize() +} + +// Establishes a threshold where anything matching or above will be output +func SetStdoutThreshold(level Level) { + outputThreshold = levelCheck(level) + initialize() +} + +// Conveniently Sets the Log Handle to a io.writer created for the file behind the given filepath +// Will only append to this file +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() +} + +// Conveniently Creates a temporary file and sets the Log Handle to a io.writer created for it +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() +} + +// LogCountForLevel returns the number of log invocations for a given level. +func LogCountForLevel(l Level) uint64 { + for _, np := range NotePads { + if np.Level == l { + return np.getCount() + } + } + return 0 +} + +// LogCountForLevelsGreaterThanorEqualTo returns the number of log invocations +// greater than or equal to a given level threshold. +func LogCountForLevelsGreaterThanorEqualTo(threshold Level) uint64 { + var cnt uint64 + for _, np := range NotePads { + if np.Level >= threshold { + cnt += np.getCount() + } + } + return cnt +} + +// ResetLogCounters resets the invocation counters for all levels. +func ResetLogCounters() { + for _, np := range NotePads { + np.resetCounter() + } +} + +// Disables logging for the entire JWW system +func DiscardLogging() { + LogHandle = ioutil.Discard + initialize() +} + +// Feedback is special. It writes plainly to the output while +// logging with the standard extra information (date, file, etc) +// Only Println and Printf are currently provided for this +func (fb *Feedback) Println(v ...interface{}) { + s := fmt.Sprintln(v...) + fmt.Print(s) + LOG.Output(2, s) +} + +// Feedback is special. It writes plainly to the output while +// logging with the standard extra information (date, file, etc) +// Only Println and Printf are currently provided for this +func (fb *Feedback) Printf(format string, v ...interface{}) { + s := fmt.Sprintf(format, v...) + fmt.Print(s) + LOG.Output(2, s) +} |