Documentation ¶
Overview ¶
Package log is a drop-in replacement for the standard Go logging library "log" which is fully source code compatible support all the standard library API while at the same time offering advanced logging features through an extended API.
The design goals of gonelog was:
- Standard library source level compatibility with mostly preserved behaviour.
- Leveled logging with syslog levels.
- Structured key/value logging
- Hierarchical contextable logging to have k/v data in context logged automatically.
- Low resource usage to allow more (debug) log-statements even if they don't result in output.
- Light syntax to encourage logging on INFO/DEBUG level. (and low cost of doing so)
- Flexibility in how log events are output.
- A fast simple lightweight default in systemd newdaemon style only outputting <level>message to standard output.
- Facilitating configuring logging for libraries by the application.
Synopsis ¶
Out of the box the default logger with package level methods works like the standard library *log.Logger with all the standard flags and methods:
import "github.com/One-com/gonelog/log" log.Println("Hello log") mylog := log.New(os.Stdout,"PFX:",LstdFlags) mylog.Fatal("Arggh")
Under the hood the default *log.Logger is however a log context object which can have key/value data and which generate log events with a syslog level and hands them of to a log Handler for formatting and output.
The default Logger supports all this as well, using log level constants source code compatible with the "log/syslog" package through the github.com/One-com/gone/log/syslog package:
package syslog const ( // Severity. // From /usr/include/sys/syslog.h. // These are the same on Linux, BSD, and OS X. LOG_EMERG Priority = iota LOG_ALERT LOG_CRIT LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_DEBUG )
Logging with key/value data is (in its most simple form) done by calling level specific functions. First argument is the message, subsequenct arguments key/value data:
log.DEBUG("hi", "key", "value") log.INFO("hi again") log.NOTICE("more insisting hi") log.WARN("Hi?") log.ERROR("Hi!", "key1","value1", "key2", "value2") log.CRIT("HI! ") log.ALERT("HEY THERE, WAKE UP!")
Earch *log.Logger object has a current "log level" which determines the maximum log level for which events are actually generated. Logging above that level will be ignored. This log level can be controlled:
log.SetLevel(syslog.LOG_WARN) log.DecLevel() log.IncLevel()
Calling Fatal*() and Panic*() will in addition to Fataling/panicing log at level ALERT.
The Print*() methods will log events with a configurable "default" log level - which default to INFO.
Per default the Logger *will* generate log event for Print*() calls even though the log level is lower. The Logger can be set to respect the actual log level also for Print*() statements by the second argument to SetPrintLevel()
log.SetPrintLevel(syslog.LOG_NOTICE,true)
A new custom Logger with its own behavior and formatting handler can be created:
h := log.NewStdFormatter(os.Stdout,"",log.LstdFlags|log.Llevel|log.Lpid|log.Lshortfile) l := log.NewLogger(syslog.LOG_ERROR, h) l.DoTime(true) l.DoCodeInfo(true)
A customer Logger will not per default spend time timestamping events or registring file/line information. You have to enable that explicitly (it's not enabled by setting the flags on a formatting handler).
When having key/value data which you need to have logged in all log events, but don't want to remember to put into every log statement, you can create a "child" Logger:
reqlog := l.With( "session", uuid.NewUUID() ) reqlog.ERROR("Invalid session")
To simply set the standard logger in a minimal mode where it only outputs <level>message to STDOUT and let an external daemon supervisor/log system do the rest (including timestamping) just do:
log.Minimal()
Having many log statements can be expensive. Especially if the arguments to be logged are resource intensive to compute and there's no log events generated anyway.
There are 2 ways to get around that. The first is do do Lazy evaluation of arguments:
log.WARN("heavy", "fib123", log.Lazy(func() interface{} {return fib(123)} ))
The other is to pick an comma-ok style log function:
if f,ok := l.DEBUGok(); ok { f("heavy", "fib123", fib(123)) }
Sometimes it can be repetitive to make a lot of log statements logging many attributes of the same kinda of object by explicitly accessing every attribute. To make that simpler, every object can implement the Logable interface by creating a LogValues() function returning the attributes to be logged (with keys). The object can then be logged by directly providing it as an argument to a log function:
type Request struct { IP string Method string } func (r *Request) LogValues() log.KeyValues { return []interface{}{ "ip", r.IP, "meth", r.Method, } } req := &Request{ IP : "127.0.0.1", Method : "GET"} log.NOTICE("Got request", req)
Loggers can have names, placing them in a global "/" separated hierarchy.
It's recommended to create a Logger by mentioning it by name using GetLogger("logger/name") - instead of creating unnamed Loggers with NewLogger(). If such a logger exists you will get it returned, so you can configure it and set the formatter/output. Otherwise a new logger by that name is created. Libraries are encouraged to published the names of their Loggers and to name Loggers after their Go package. This works exactly like the Python "logging" library - with one exception: When Logging an event at a Logger the tree of Loggers by name are only traversed towards to root to find the first Logger having a Handler attached, not returning an error. The log-event is then sent to that handler. If that handler returns an error, the parent Logger and its Handler is tried. This allows to contruct a "Last Resort" parent for errors in the default log Handler. The Python behaviour is to send the event to all Handlers found in the Logger tree. This is not the way it's done here. Only one Handler will be given the event to log. If you wan't more Handlers getting the event, use a MultiHandler.
package main import ( "mylib" // which logs to a gonelog *log.Logger "github.com/One-com/gone/log" "github.com/One-com/gone/log/syslog" "os" ) func main() { log.SetLevel(syslog.WARN) // application will log at warn level log.GetLogger("mylib").SetLevel(syslog.LOG_ERROR) // mylib will log at error level log.SetOutput(os.Stderr) // Log events from mylib will be propagated up mylib.FuncWhichLogsOnError() }
Happy logging.
Index ¶
- Constants
- Variables
- func ALERT(msg string, kv ...interface{})
- func AutoColoring()
- func CRIT(msg string, kv ...interface{})
- func DEBUG(msg string, kv ...interface{})
- func DecLevel() bool
- func ERROR(msg string, kv ...interface{})
- func Fatal(v ...interface{})
- func Fatalf(format string, v ...interface{})
- func Fatalln(v ...interface{})
- func Flags() int
- func INFO(msg string, kv ...interface{})
- func IncLevel() bool
- func Level() syslog.Priority
- func Log(level syslog.Priority, msg string, kv ...interface{})
- func Minimal()
- func NOTICE(msg string, kv ...interface{})
- func NewJSONFormatter(w io.Writer, options ...HandlerOption) *jsonformatter
- func NewMinFormatter(w io.Writer, options ...HandlerOption) *stdformatter
- func NewStdFormatter(w io.Writer, prefix string, flag int) *stdformatter
- func NewStdlibAdapter(logger *Logger, level syslog.Priority, options ...StdlibAdapterOption) io.Writer
- func Output(calldepth int, s string) error
- func Panic(v ...interface{})
- func Panicf(format string, v ...interface{})
- func Panicln(v ...interface{})
- func Prefix() string
- func Print(v ...interface{})
- func Printf(format string, v ...interface{})
- func Println(v ...interface{})
- func SetFlags(flag int)
- func SetLevel(level syslog.Priority) bool
- func SetOutput(w io.Writer)
- func SetPrefix(prefix string)
- func SetPrintLevel(level syslog.Priority, respect bool) bool
- func SyncWriter(w io.Writer) io.Writer
- func WARN(msg string, kv ...interface{})
- func WriterFunc(fn func(b []byte) (n int, err error)) io.Writer
- type CloneableHandler
- type EvWriter
- type Event
- type EventKeyNames
- type Handler
- type HandlerOption
- type KV
- type KeyValues
- type Lazy
- type LevelLogger
- type LogFunc
- type Logable
- type Logger
- func (l *Logger) ALERT(msg string, kv ...interface{})
- func (l *Logger) ALERTok() (LogFunc, bool)
- func (l *Logger) ApplyHandlerOptions(opt ...HandlerOption)
- func (l *Logger) AutoColoring()
- func (l *Logger) CRIT(msg string, kv ...interface{})
- func (l *Logger) CRITok() (LogFunc, bool)
- func (l *Logger) DEBUG(msg string, kv ...interface{})
- func (l *Logger) DEBUGok() (LogFunc, bool)
- func (l *Logger) DecLevel() bool
- func (l *Logger) DefaultLevel() syslog.Priority
- func (l *Logger) Do(level syslog.Priority) bool
- func (l *Logger) DoCodeInfo(doCode bool) bool
- func (l *Logger) DoTime(doTime bool) bool
- func (l *Logger) Does(level syslog.Priority) bool
- func (l *Logger) DoingCodeInfo() bool
- func (l *Logger) DoingDefaultLevel() (syslog.Priority, bool)
- func (l *Logger) DoingPrintLevel() (syslog.Priority, bool)
- func (l *Logger) DoingTime() bool
- func (l *Logger) ERROR(msg string, kv ...interface{})
- func (l *Logger) ERRORok() (LogFunc, bool)
- func (l *Logger) Fatal(v ...interface{})
- func (l *Logger) Fatalf(format string, v ...interface{})
- func (l *Logger) Fatalln(v ...interface{})
- func (l *Logger) Flags() int
- func (l *Logger) INFO(msg string, kv ...interface{})
- func (l *Logger) INFOok() (LogFunc, bool)
- func (l *Logger) IncLevel() bool
- func (l *Logger) Level() syslog.Priority
- func (l *Logger) Log(level syslog.Priority, msg string, kv ...interface{}) (err error)
- func (l *Logger) LogFromCaller(calldepth int, level syslog.Priority, msg string, kv ...interface{}) error
- func (l *Logger) NOTICE(msg string, kv ...interface{})
- func (l *Logger) NOTICEok() (LogFunc, bool)
- func (l *Logger) Output(calldepth int, s string) error
- func (l *Logger) Panic(v ...interface{})
- func (l *Logger) Panicf(format string, v ...interface{})
- func (l *Logger) Panicln(v ...interface{})
- func (l *Logger) Prefix() string
- func (l *Logger) Print(v ...interface{})
- func (l *Logger) PrintLevel() syslog.Priority
- func (l *Logger) Printf(format string, v ...interface{})
- func (l *Logger) Println(v ...interface{})
- func (l *Logger) SetFlags(flag int)
- func (l *Logger) SetHandler(h Handler)
- func (l *Logger) SetLevel(level syslog.Priority) bool
- func (l *Logger) SetOutput(w io.Writer)
- func (l *Logger) SetPrefix(prefix string)
- func (l *Logger) SetPrintLevel(level syslog.Priority, respect bool) bool
- func (l *Logger) WARN(msg string, kv ...interface{})
- func (l *Logger) WARNok() (LogFunc, bool)
- func (l *Logger) With(kv ...interface{}) *Logger
- type MaybeTtyWriter
- type StdFormatter
- type StdLogger
- type StdLoggerFull
- type StdMutableFormatter
- type StdlibAdapter
- type StdlibAdapterOption
- type StdlibWriter
Examples ¶
Constants ¶
const ( // Bits or'ed together to control what's printed. // There is no control the format they present (as described in the comments). // The prefix is followed by a colon only when Llongfile or Lshortfile // is specified. // For example, flags Ldate | Ltime (or LstdFlags) produce, // 2009/01/23 01:23:23 message // while flags Ldate | Ltime | Lmicroseconds | Llongfile produce, // 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message Ldate = 1 << iota // the date in the local time zone: 2009/01/23 Ltime // the time in the local time zone: 01:23:23 Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime. Llongfile // full file name and line number: /a/b/c/d.go:23 Lshortfile // final file name element and line number: d.go:23. overrides Llongfile LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone Llevel // prefix the log line with a syslog level <L> Lpid // Include the process ID Lcolor // Do color logging to terminals Lname // Log the name of the Logger generating the event LstdFlags = Ldate | Ltime // stdlib compatible LminFlags = Llevel // Simple systemd/syslog compatible level spec. Let external log system take care of timestamps etc. )
These flags define which text to prefix to each log entry generated by the Logger. Extension of the std log library
const LvlDEFAULT syslog.Priority = syslog.LOG_INFO
LvlDEFAULT is the default log level at which Print*() functions will log. Leveled logging is provided with the 8 syslog levels Additional 2 pseudo-levels ("Fatal"/ "Panic") which log at Alert-level, but have side-effects like the stdlogger. (os.Exit(1)/panic()) Print*() functions will produce log-events with a "default" level.
Variables ¶
var ErrNotLogged = errors.New("No handler found to log event")
ErrNotLogged is returned by some Log functions (Log()/Output()) if no Handler was found to log an event.
Functions ¶
func ALERT ¶
func ALERT(msg string, kv ...interface{})
ALERT - Requests the default logger to create a log event
func AutoColoring ¶
func AutoColoring()
AutoColoring turns on coloring for the default logger if the output Writer is connected to a TTY
func CRIT ¶
func CRIT(msg string, kv ...interface{})
CRIT - Requests the default logger to create a log event
func DEBUG ¶
func DEBUG(msg string, kv ...interface{})
DEBUG - Requests the default logger to create a log event
func ERROR ¶
func ERROR(msg string, kv ...interface{})
ERROR - Requests the default logger to create a log event
func Fatalf ¶
func Fatalf(format string, v ...interface{})
Fatalf - Compatible with the standard library
func INFO ¶
func INFO(msg string, kv ...interface{})
INFO - Requests the default logger to create a log event
func Minimal ¶
func Minimal()
Minimal sets the default logger to the minimal mode, where it doesn't log timestamps But only emits systemd/syslog-compatible "<level>message" lines.
Example ¶
package main import ( "github.com/One-com/gone/log" ) func main() { log.Minimal() // change default Logger to not be stdlib compatible but minimal log.ERROR("fejl") }
Output: <3>fejl
func NOTICE ¶
func NOTICE(msg string, kv ...interface{})
NOTICE - Requests the default logger to create a log event
func NewJSONFormatter ¶
func NewJSONFormatter(w io.Writer, options ...HandlerOption) *jsonformatter
NewJSONFormatter creates a new formatting Handler writing log events as JSON to the supplied Writer.
func NewMinFormatter ¶
func NewMinFormatter(w io.Writer, options ...HandlerOption) *stdformatter
NewMinFormatter creates a standard formatter and applied the supplied options It will default log.LminFlags to provide simple <level>message logging
Example ¶
package main import ( "github.com/One-com/gone/log" "github.com/One-com/gone/log/syslog" "os" ) func main() { h := log.NewMinFormatter(log.SyncWriter(os.Stdout), log.PrefixOpt("PFX:")) l := log.NewLogger(syslog.LOG_WARNING, h) l.ERROR("fejl") }
Output: <3>PFX:fejl
func NewStdFormatter ¶
NewStdFormatter creates a standard formatter capable of simulating the standard library logger.
func NewStdlibAdapter ¶
func NewStdlibAdapter(logger *Logger, level syslog.Priority, options ...StdlibAdapterOption) io.Writer
NewStdlibAdapter returns a new StdlibAdapter wrapper around the passed logger. It's designed to be passed to the standard library's log.SetOutput()
func Output ¶
Output compatible with the standard library
Example ¶
package main import ( "github.com/One-com/gone/log" "os" ) func output(l *log.Logger, msg string) { l.Output(2, msg) } func main() { l := log.New(os.Stdout, "", log.Lshortfile) l.DoCodeInfo(true) log.SetOutput(os.Stdout) log.SetFlags(log.Lshortfile) log.SetPrefix("") output(l, "output1") log.Output(1, "output2") }
Output: api_test.go:22: output1 api_test.go:23: output2
func Panicf ¶
func Panicf(format string, v ...interface{})
Panicf - Compatible with the standard library
func Printf ¶
func Printf(format string, v ...interface{})
Printf - Compatible with the standard library
func SetPrintLevel ¶
SetPrintLevel sets the log level used by Print*() calls. If the second argument is true, Println(), Printf(), Print() will respect the Logger log level. If the second argument is false, log event will be generated regardless of Logger log level. Handlers and Writers may still filter the event out.
Example ¶
package main import ( "github.com/One-com/gone/log" "github.com/One-com/gone/log/syslog" "os" ) func main() { l := log.GetLogger("my/lib") h := log.NewStdFormatter(log.SyncWriter(os.Stdout), "", log.Llevel|log.Lname) l.SetHandler(h) l.AutoColoring() l.SetLevel(syslog.LOG_ERROR) l.SetPrintLevel(syslog.LOG_NOTICE, false) l.Print("ignoring level") }
Output: <5>(my/lib) ignoring level
func SyncWriter ¶
SyncWriter encapsulates an io.Writer in a Mutex, so only one Write operation is done at a time.
Types ¶
type CloneableHandler ¶
type CloneableHandler interface { Handler Clone(options ...HandlerOption) CloneableHandler }
CloneableHandler allows you to call ApplyHandlerOptions() on a Logger to swap in a new Handler modified by the provided HandlerOptions
type EvWriter ¶
EvWriter is a Writer which wants to know the original event of the []byte buffer (for filtering) Is has to also be a io.Writer, else it can't be used in a formatter.
func EventWriter ¶
EventWriter creates a dummy EvWriter from an io.Writer
func EventWriterFunc ¶
EventWriterFunc created a new EvWriter from a function taking the event and a formattet logline. Such functions need to be aware that e can be nil
func LevelFilterWriter ¶
LevelFilterWriter creates a filtering EventWriter which writes whats below (or equal) max level to The underlying io.Writer
func MultiEventWriter ¶
MultiEventWriter creates a writer that duplicates its writes to all the provided writers, similar to the Unix tee(1) command, providing all with the original event to do filtering.
type Event ¶
type Event struct {
// contains filtered or unexported fields
}
Event is the basic log event type. Exported to be able to implement Handler interface for external packages.
func (Event) KvData ¶
func (e Event) KvData() KeyValues
KvData returns the structured list of key/value data
func (Event) LoggerName ¶
func (e Event) LoggerName() string
LoggerName returns the name of the logger logging the event.
type EventKeyNames ¶
EventKeyNames holds keynames for fixed event fields, when needed (such as in JSON)
type Handler ¶
Handler is the interface needed to be a part of the Handler chain.
Events are sent from a logger down a chain of Handlers. The final Handler (which doesn't call other handlers) is called a Formatter. Formatters turn the event into something else (like a log-line) and are also Handlers. Formatters implement this interface to receive events.
Some Handlers pass the Event to further handlers while doing things like filtering, which is harder to do on formatted log-lines.
In other words: Once Events has been created, a Handler can ensure it's shipped to the log system. Formatters are a special kind og Handlers which ends the handler pipeline and convert the *Event to []byte (and does something with the bytes)
Example ¶
package main import ( "github.com/One-com/gone/log" "os" ) func main() { h := log.NewMinFormatter(log.SyncWriter(os.Stdout), log.PrefixOpt("PFX:")) l := log.GetLogger("mylog") l.SetHandler(h) l.ERROR("fejl") l.ApplyHandlerOptions(log.FlagsOpt(log.Llevel | log.Lname)) l.WARN("advarsel") }
Output: <3>PFX:fejl <4>PFX:(mylog) advarsel
func FilterHandler ¶
FilterHandler lets a function evaluate whether to discard the Event or pass it on to a next Handler
func HandlerFunc ¶
HandlerFunc generates a Handler from a function, by calling it when Log is called.
func LvlFilterHandler ¶
LvlFilterHandler discards events with a level above maxLvl
func MultiHandler ¶
MultiHandler distributes the event to several Handlers if an error happen the last error is returned.
type HandlerOption ¶
type HandlerOption func(CloneableHandler)
HandlerOption is an option-function provided by the package of a Handler
func FlagsOpt ¶
func FlagsOpt(flags int) HandlerOption
FlagsOpt - Standard Formatter Option to set flags
func KeyNamesOpt ¶
func KeyNamesOpt(keys *EventKeyNames) HandlerOption
KeyNamesOpt is a JSON Formatter Option to set flags
func LevelPrefixOpt ¶
func LevelPrefixOpt(arr *[8]string) HandlerOption
LevelPrefixOpt - Standard Formatter option to set LevelPrefixes
func OutputOpt ¶
func OutputOpt(w io.Writer) HandlerOption
OutputOpt - Standard Formatter option so set Output
func PrefixOpt ¶
func PrefixOpt(prefix string) HandlerOption
PrefixOpt - Standard Formatter option to set Prefix
func TimeFormatOpt ¶
func TimeFormatOpt(layout string) HandlerOption
TimeFormatOpt is a JSON Formatter Option to set timestamp formatting
type KV ¶
type KV map[string]interface{}
KV is a map of key/value pairs to pass to a Logger context or to a log function for structured logging. Value can be any stringable object, or a Valuer which resolves to a stringable object.
type KeyValues ¶
type KeyValues []interface{}
KeyValues is a slice of interfaces alternating between key and value for data to be logged. Keys are at even numbered indexes and must be string. Values can be any stringable object or a Valuer which resolves to a stringable object.
type Lazy ¶
type Lazy func() interface{}
Lazy evaluation of values to log returns stringable objects
type LevelLogger ¶
type LevelLogger interface { // Will generate a log event with this level if the Logger log level is // high enough. // The event will have the given log message and key/value structured data. Log(level syslog.Priority, message string, kv ...interface{}) error // further interfaces StdLogger }
LevelLogger makes available methods compatible with the stdlib logger and an extended API for leveled logging. LevelLogger is implemented by *log.Logger
type LogFunc ¶
type LogFunc func(msg string, kv ...interface{})
LogFunc is the type of the function returned by *ok() methods, which will log at the level queried about if called.
func ALERTok ¶
ALERTok - If the default Logger is logging at the requested level a function creating such a log event will be returned.
func CRITok ¶
CRITok - If the default Logger is logging at the requested level a function creating such a log event will be returned.
func DEBUGok ¶
DEBUGok - If the default Logger is logging at the requested level a function creating such a log event will be returned.
func ERRORok ¶
ERRORok - If the default Logger is logging at the requested level a function creating such a log event will be returned.
func INFOok ¶
INFOok - If the default Logger is logging at the requested level a function creating such a log event will be returned.
type Logable ¶
type Logable interface {
LogValues() KeyValues
}
Logable is the interface needed for an object to be provided as a value to a nil key and then being allowed to generate it's k/v log values it self by returning them from LogValues()
Example ¶
package main import ( "bytes" "fmt" "github.com/One-com/gone/log" ) type MyObj struct { Key1 string Key2 string } func (o *MyObj) LogValues() log.KeyValues { return []interface{}{"key1", o.Key1, "key2", o.Key2} } func main() { obj := &MyObj{"foo", "bar"} var b bytes.Buffer l := log.New(&b, "", 0) l.With(log.KV{"orange": "apple"}, "a", "b").ERROR("An", obj, "pif", "paf") fmt.Println(b.String()) }
Output: An orange=apple a=b key1=foo key2=bar pif=paf
type Logger ¶
type Logger struct {
// contains filtered or unexported fields
}
Logger implements a stdlib *log.Logger source code compatible interface and extra methods for supporting leveled, structured and context logging.
Don't create these your self. Use a constructor function. Once created, its member attributes cannot be changed (to avoid races), Exceptions are: * Changing the config, which goes through atomic operations * Changing the handler, which can be atomically replaced.
There's a race between changing both, so beware! If you swap in a handler which does file/line-recording without changing config to DoCodeInfo() first, there will no code-info in the log-events during the race. Repeat: There's no way to change handler and config atomically together. So don't enable a handler using something the config doesn't support (timestamps/codeinfo) unless you can live with potentially a few log lines with wrong content. All attributes are reference-like attributes. Copying them will not gain you anything, but effectively just having two "pointers" to the same logger. Copying values of this type is discouraged, but in principle legal, since the direct members never change. The new copy will behave like the old, and modifications to one of them will affect the other.
Logger allows for contextual logging, by keeping K/V data to be logged with all events and to create sub child loggers with additional K/V data.
func Default ¶
func Default() *Logger
Default returns the default Logger - which is also the root of the name hierarchy.
func GetLogger ¶
GetLogger creates a new Logger or returns an already existing with the given name.
Example ¶
package main import ( "github.com/One-com/gone/log" "os" ) func main() { l := log.GetLogger("my/lib") h := log.NewStdFormatter(log.SyncWriter(os.Stdout), "", log.Llevel|log.Lname) l.SetHandler(h) l2 := log.GetLogger("my/lib/module") l3 := l2.With("k", "v") l3.NOTICE("notice") }
Output: <5>(my/lib/module) notice k=v
func New ¶
New will instantiate a logger with the same functionality (and limitations) as the std lib logger.
Example ¶
Compatible with std lib
package main import ( "github.com/One-com/gone/log" "os" ) func main() { l := log.New(os.Stdout, "", log.Llevel) l.Println("notice") }
Output: <6>notice
func NewLogger ¶
NewLogger creates a new unamed Logger out side of the named Logger hierarchy.
Example ¶
package main import ( "github.com/One-com/gone/log" "github.com/One-com/gone/log/syslog" "os" ) func main() { h := log.NewStdFormatter(log.SyncWriter(os.Stdout), "", log.Llevel) l := log.NewLogger(syslog.LOG_WARNING, h) l.SetPrintLevel(syslog.LOG_NOTICE, false) // Traditional. // Evaluates arguments unless Lazy is used, but doesn't generate // Events above log level l.DEBUG("hej") l.INFO("hej") l.NOTICE("hej") l.WARN("hej") l.ERROR("hej") l.CRIT("hej") l.ALERT("hej") // Optimal // Doesn't do anything but checking the log level unless // something should be logged // A filtering handler would still be able to discard log events // based on level. Use Lazy to only evaluate just before formatting // Even by doing so a filtering writer might still discard the log line if f, ok := l.DEBUGok(); ok { f("dav") } if f, ok := l.INFOok(); ok { f("dav") } if f, ok := l.NOTICEok(); ok { f("dav") } if f, ok := l.WARNok(); ok { f("dav") } if f, ok := l.ERRORok(); ok { f("dav") } if f, ok := l.CRITok(); ok { f("dav") } if f, ok := l.ALERTok(); ok { f("dav") } // Primitive ... Allows for dynamically choosing log level. // Otherwise behaves like Traditional l.Log(syslog.LOG_DEBUG, "hop") l.Log(syslog.LOG_INFO, "hop") l.Log(syslog.LOG_NOTICE, "hop") l.Log(syslog.LOG_WARN, "hop") l.Log(syslog.LOG_ERROR, "hop") l.Log(syslog.LOG_CRIT, "hop") l.Log(syslog.LOG_ALERT, "hop") // Std logger compatible. // Will log with the default-level (default "INFO") - if that log-level is enabled. l.Print("default") // Fatal and Panic logs with level "ALERT" l.Fatal("fatal") }
Output:
func With ¶
func With(kv ...interface{}) *Logger
With will create a sub-context K/V logger of the default logger with additional key/value context.
Example ¶
package main import ( "github.com/One-com/gone/log" "github.com/One-com/gone/log/syslog" "os" ) func main() { l := log.GetLogger("my/lib") h := log.NewStdFormatter(log.SyncWriter(os.Stdout), "", log.Llevel|log.Lname) l.SetHandler(h) l.SetLevel(syslog.LOG_ERROR) l2 := l.With("key", "value") l3 := l2.With("more", "data") l3.ERROR("message") }
Output: <3>(my/lib) message more=data key=value
func (*Logger) ALERTok ¶
ALERTok will return whether the logger generates events at this level, and a function which will do the logging when called.
func (*Logger) ApplyHandlerOptions ¶
func (l *Logger) ApplyHandlerOptions(opt ...HandlerOption)
ApplyHandlerOptions clones the current Handles and tries to apply the supplied HandlerOptions to the clone - then swaps in the clone atomically to not loose Log events. Supplied HandlerOptions must be compatible with the current Handler, or the Handler will/(should) reject it and treat it as a No-Op. If the attached Handler does not support Cloning or HandlerOptions and/or you are using a more complex Handler hierarchy, you should probably create the new Handler Manually and use SetHandler()
func (*Logger) AutoColoring ¶
func (l *Logger) AutoColoring()
AutoColoring asks the current Handler to test if there's a TTY attached to an output and if so, apply coloring to the formatter.
func (*Logger) CRITok ¶
CRITok will return whether the logger generates events at this level, and a function which will do the logging when called.
func (*Logger) DEBUGok ¶
DEBUGok will return whether the logger generates events at this level, and a function which will do the logging when called.
func (*Logger) DefaultLevel ¶
DefaultLevel returns the current log level of Print*() methods. Deprecated, use PrintLevel()
func (*Logger) DoCodeInfo ¶
DoCodeInfo tries to turn on or off registering the file and line of the log call. Formatters which try to log this info will not give meaningful info if this is turned off. It can fail if some other go-routine simultaneous is manipulating the config. Returning whether the change was successful
func (*Logger) DoTime ¶
DoTime tries to turn on or off timestamping. It can fail if some other go-routine simultaneous is manipulating the config. If the generated log-events are not timestamped on creation some formatters will create their own timestamp anyway. Having this global option saves time.Now() calls if no one is using the time info (which is the case for minimal logging). It also enables using a single timestamp for all formatting of the log event. Returning whether the change was successful
func (*Logger) Does ¶
Does returns whether the Logger would generate an event at this level? This can be used for optimal performance logging
func (*Logger) DoingCodeInfo ¶
DoingCodeInfo returns whether the Logger is currently recording file/line info for all log events
func (*Logger) DoingDefaultLevel ¶
DoingDefaultLevel returns whether a log.Println() would actually generate a log event with the current config. It's equivalent to l.Does(l.DefaultLevel()) - but atomically Deprecated, use DoingPrintLevel()
func (*Logger) DoingPrintLevel ¶
DoingPrintLevel returns whether a log.Println() would actually generate a log event with the current config. It's equivalent to l.Does(l.PrintLevel()) - but atomically
func (*Logger) DoingTime ¶
DoingTime returns whether the Logger is currently timestamping all events on creation
func (*Logger) ERRORok ¶
ERRORok will return whether the logger generates events at this level, and a function which will do the logging when called.
func (*Logger) Fatal ¶
func (l *Logger) Fatal(v ...interface{})
Fatal compatible with the standard lib logger
func (*Logger) Fatalln ¶
func (l *Logger) Fatalln(v ...interface{})
Fatalln compatible with the standard lib logger
func (*Logger) INFOok ¶
INFOok will return whether the logger generates events at this level, and a function which will do the logging when called.
func (*Logger) LogFromCaller ¶
func (l *Logger) LogFromCaller(calldepth int, level syslog.Priority, msg string, kv ...interface{}) error
LogFromCaller is like Log() but lets you offset the calldepth used to compute CodeInfo (file/line) from stack info, the same way as the stdlib log.Output() function does.
func (*Logger) NOTICEok ¶
NOTICEok will return whether the logger generates events at this level, and a function which will do the logging when called.
func (*Logger) Panic ¶
func (l *Logger) Panic(v ...interface{})
Panic compatible with the standard lib logger
func (*Logger) Panicln ¶
func (l *Logger) Panicln(v ...interface{})
Panicln compatible with the standard lib logger
func (*Logger) Print ¶
func (l *Logger) Print(v ...interface{})
Print compatible with the standard lib logger
func (*Logger) PrintLevel ¶
PrintLevel returns the current log level of Print*() methods
func (*Logger) Println ¶
func (l *Logger) Println(v ...interface{})
Println compatible with the standard lib logger
func (*Logger) SetHandler ¶
SetHandler atomically swaps in a different root of the Handler tree
func (*Logger) SetPrintLevel ¶
SetPrintLevel sets the level which Print*() methods are logging with. "respect" indicated whether Print*() statements will respect the Logger loglevel or generate events anyway. (with the default log level). Without "respect" the logger can generate events above its loglevel. Such events can however still be filtered out by filter-handler, or filter-writers, or by external systems like syslog. returns success
type MaybeTtyWriter ¶
MaybeTtyWriter is a writer which know whether the underlying writer is a TTY
type StdFormatter ¶
StdFormatter allows quering a formatting handler for flags and prefix compatible with the stdlib log library
type StdLogger ¶
type StdLogger interface { Fatal(v ...interface{}) Fatalf(format string, v ...interface{}) Fatalln(v ...interface{}) Panic(v ...interface{}) Panicf(format string, v ...interface{}) Panicln(v ...interface{}) Print(v ...interface{}) Printf(format string, v ...interface{}) Println(v ...interface{}) }
StdLogger is the interface used by the standard lib *log.Logger This is the API for actually logging stuff.
type StdLoggerFull ¶
type StdLoggerFull interface { StdLogger StdMutableFormatter Output(calldepth int, s string) error }
StdLoggerFull is mostly for documentation purposes. This is the full set of methods supported by the standard logger. You would only use the extra methods when you know exactly which kind of logger you are dealing with anyway.
type StdMutableFormatter ¶
type StdMutableFormatter interface { StdFormatter SetFlags(flag int) SetPrefix(prefix string) SetOutput(w io.Writer) }
StdMutableFormatter is the interface for a Logger which directly can change the stdlib flags, prefix and output io.Writer attributes in a synchronized manner. Since gonelog Handlers are immutable, it's not used for Formatters.
type StdlibAdapter ¶
type StdlibAdapter struct {
// contains filtered or unexported fields
}
StdlibAdapter wraps a Logger and allows it to be passed to the stdlib logger's SetOutput. It will extract date/timestamps, filenames, and messages, and place them under relevant keys. It uses regular expressions to parse the output of the standard logger to parse it in structured form to the gonelog logger. This is not an ideal solution. Prefer to use a Gonelogger directly
type StdlibAdapterOption ¶
type StdlibAdapterOption func(*StdlibAdapter)
StdlibAdapterOption sets a parameter for the StdlibAdapter.
func FileKey ¶
func FileKey(key string) StdlibAdapterOption
FileKey sets the key for the file and line field. By default, it's "file".
func MessageKey ¶
func MessageKey(key string) StdlibAdapterOption
MessageKey sets the key for the actual log message. By default, it's "msg".
func Parse ¶
func Parse() StdlibAdapterOption
Parse instruct the adapter to try parse the stdlib log message to pick out fields
func TimestampKey ¶
func TimestampKey(key string) StdlibAdapterOption
TimestampKey sets the key for the timestamp field. By default, it's "ts".
type StdlibWriter ¶
type StdlibWriter struct{}
StdlibWriter implements io.Writer by invoking the stdlib log.Print. It's designed to be passed to a Formatting Handler as the Writer, for cases where it's necessary to redirect all gonelog log output to the stdlib logger.