Documentation ¶
Overview ¶
Package log provides loglevel aware output methods.
Loglevel are predefined as Ltrace, Ldebug, Linfo, Lwarn, Lerror, and Lfatal. The default loglevel is Linfo. To create a logger named mylogger under the default stream:
var lg = log.DefaultStream.NewLogger("mylogger", log.Linfo)
A stream is a handle that controls the output destination and output format. The default output destination is stdout.
"stdout" : output to OS.Stdout.
Other supported output destination:
"file:filepath/filename" : output to file in append mode.
More output destinations to be added, see RegOutputterFactory() and fileFactory for an example.
Loggers can be created under a named stream if more output destinations are needed. In "main" package:
mystream := log.NewStream("mystream")
In subpackages:
var lg = log.GetStream("mystream").NewLogger("mylogger", log.Lwarn)
It is the main package's responsibility to set or change the global output destination. To change the output destination to file:
mystream.SetOutput("file:filepath/filename")
More than one loggers can be created on demand in one package, usually along with the package level logger itself, i.e. each "worker" can have its own logger instance, thus its loglevel can be changed separately. It is highly recommended that dynamic loggers are named in the URL like form "package/module/xxxx", eg. You have a package level logger lgsrv for awesomesrvice package:
lgsrv := log.DefaultStream.NewLogger("awesomesrvice", log.Lwarn)
Now inside awesomesrvice, you want each worker has its own logger instance so that later loglevel can be changed respectively for each worker:
lgworker := log.DefaultStream.NewLogger("awesomesrvice/worker123", log.Lwarn)
When you want to set loglevel to one of these loggers to debug level:
log.DefaultStream.SetLoglevel("awesomesrvice/worker123", log.Ldebug)
To set all awesomesrvice loggers to debug level:
log.DefaultStream.SetLoglevel("awesomesrvice*", log.Ldebug)
Dynamically created logger should be closed if not use any more.
lgworker.Close()
When a new logger instance is getting created, it will use the loglevel that has been set the lastime calling stream.SetLoglevel() if the namePattern matches, or use the default loglevel if not.
Timestamp is in format "[2006/01/02 15:04:05.000000]" by default, set it to "" will disable timestamp to be printed. SetTimeFormat can change the timestamp format, refer to standard time package for the possible formats.
mystream := log.NewStream("mystream") mystream.SetTimeFormat(time.RFC3339Nano)
Some APIs support wildcard matching to match logger name, and support multiple patterns separated by comma. The pattern uses simple * as the wildcard: eg.
"*" matches all "*bar*" matches bar, foobar, or foobarabc "foo*abc*" matches foobarabc, foobarabc123, or fooabc
The methods are concurrency safe under linux.
Index ¶
- Variables
- func RegOutputterFactory(keyword string, f OutputterFactory)
- type Flag
- type Logger
- func (lg *Logger) Close()
- func (lg *Logger) Debugf(format string, args ...interface{})
- func (lg *Logger) Debugln(args ...interface{})
- func (lg *Logger) Errorf(format string, args ...interface{})
- func (lg *Logger) Errorln(args ...interface{})
- func (lg *Logger) Fatalf(format string, args ...interface{})
- func (lg *Logger) Fatalln(args ...interface{})
- func (lg *Logger) Infof(format string, args ...interface{})
- func (lg *Logger) Infoln(args ...interface{})
- func (lg *Logger) SetLoglevel(level Loglevel)
- func (lg *Logger) Tracef(format string, args ...interface{})
- func (lg *Logger) Traceln(args ...interface{})
- func (lg *Logger) Warnf(format string, args ...interface{})
- func (lg *Logger) Warnln(args ...interface{})
- type Loglevel
- type Outputter
- type OutputterFactory
- type Stream
- func (s *Stream) AllLoggerNames() (names []string)
- func (s *Stream) Close()
- func (s *Stream) GetLogger(name string) *Logger
- func (s *Stream) NewLogger(name string, defaultLoglevel Loglevel) *Logger
- func (s *Stream) SetFlag(newFlag Flag)
- func (s *Stream) SetLoglevel(namePattern string, newLevel Loglevel)
- func (s *Stream) SetOutput(newOutputDest string) error
- func (s *Stream) SetOutputter(newOutputter io.Writer)
- func (s *Stream) SetTimeFormat(newFormat string)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultStream = NewStream("default")
DefaultStream is the builtin output stream instance
Functions ¶
func RegOutputterFactory ¶
func RegOutputterFactory(keyword string, f OutputterFactory)
RegOutputterFactory registers an output destination type. No lock here, use it in init().
Types ¶
type Flag ¶
type Flag uint32
Flag controls output format
const ( Ldefault Flag = 0 LUTC Flag = 1 << 0 // use UTC rather than the local time zone Lfileline Flag = 1 << 1 // the file and line in the source code that prints the message )
These flags define which text to prefix to each log entry generated by the Logger. Bits are or'ed together to control what's printed.
type Logger ¶
type Logger struct {
// contains filtered or unexported fields
}
Logger is the logger instance
func (*Logger) Debugln ¶
func (lg *Logger) Debugln(args ...interface{})
Debugln is like fmt.Println with loglevel debug
func (*Logger) Errorln ¶
func (lg *Logger) Errorln(args ...interface{})
Errorln is like fmt.Println with loglevel error
func (*Logger) Fatalf ¶
Fatalf writes the log entry followed by a panic, always adds a '\n' if no '\n' supplied by user
func (*Logger) Fatalln ¶
func (lg *Logger) Fatalln(args ...interface{})
Fatalln is like fmt.Println with loglevel fatal followed by a panic
func (*Logger) Infoln ¶
func (lg *Logger) Infoln(args ...interface{})
Infoln is like fmt.Println with loglevel info
Example ¶
lg := DefaultStream.NewLogger("demo", Linfo) defer lg.Close() // recreate the same name logger will panic //lg = DefaultStream.NewLogger("demo") DefaultStream.SetTimeFormat("") lg.Infoln("no need to put a new line") lg.Infoln("another line")
Output: [demo][INFO] no need to put a new line [demo][INFO] another line
func (*Logger) SetLoglevel ¶
SetLoglevel sets the log level of the logger instance.
func (*Logger) Traceln ¶
func (lg *Logger) Traceln(args ...interface{})
Traceln is like fmt.Println with loglevel trace
type Loglevel ¶
type Loglevel uint32
Loglevel is one of the predefined loglevels
const ( Linvalid Loglevel = 0 Ltrace Loglevel = 1 Ldebug Loglevel = 2 Linfo Loglevel = 3 Lwarn Loglevel = 4 Lerror Loglevel = 5 Lfatal Loglevel = 6 )
All predefined loglevels
func StringToLoglevel ¶
StringToLoglevel returns the loglevel described by the given string. Return Linvalid if loglevelName is none of case insensitive "trace", "debug", "info", "warn", "error", "fatal".
type Outputter ¶
Outputter outputs log lines. The old Outputter will be closed if it implements io.Closer when closing the stream or changing the stream's output destination.
type OutputterFactory ¶
OutputterFactory is an outputter type.
type Stream ¶
type Stream struct {
// contains filtered or unexported fields
}
Stream is a output stream handle, all loggers under a stream share one output destination and same log format, but can have separete loglevel.
func GetStream ¶
GetStream returns the Stream handle if it has been created with the same input non empty "name", returns nil if not. Usually used for a subpackage other than main to get the named Stream handle.
func NewStream ¶
NewStream creates a Stream instance. The Stream will be anonymous if input name is empty, therefore GetStream() can not find it.
func (*Stream) AllLoggerNames ¶
AllLoggerNames returns the logger names under the stream.
func (*Stream) NewLogger ¶
NewLogger returns a logger instance. In a project where all logs go to the same destination, using builtin DefaultStream is enough. In case multiple destinations are needed, use "named" stream returned by NewStream(). stream is the stream that the logger instance belongs to. name is the identifier of the logger, which is assembled to each log entry. defaultLoglevel sets the default loglevel of the returned logger instance, unless the name matches preconfigured namePattern, in which case loglevel sets to preconfigured loglevel. See Stream.SetLoglevel(). Returns nil if stream is nil or name is empty.
Example ¶
// in your main.go stream := NewStream("mystream") defer stream.Close() stream.SetTimeFormat("") // in your xxxpackage.go lg := GetStream("mystream").NewLogger("myexample", Linfo) defer lg.Close() i := 200 lg.normalLevelPrintf("hello world %d", i) // if you need to change loglevel in elsewhere.go GetStream("mystream").SetLoglevel("*", Ltrace) lg.normalLevelPrintf("hello world %d", i+1)
Output: [myexample][INFO] hello world 200 [myexample][WARN] hello world 200 [myexample][ERROR] hello world 200 [myexample][TRACE] hello world 201 [myexample][DEBUG] hello world 201 [myexample][INFO] hello world 201 [myexample][WARN] hello world 201 [myexample][ERROR] hello world 201
func (*Stream) SetLoglevel ¶
SetLoglevel set the loglevel for every logger instance if its name matches the namePattern. namePattern is a simple wildcard pattern, i.e. *foo*bar*, and supports multiple patterns, i.e. "*foo,bar*,worker123", patterns are separated by a comma.
Example ¶
stream := NewStream("examplePattern") defer stream.Close() stream.SetTimeFormat("") lg := stream.NewLogger("service", Linfo) defer lg.Close() var wg sync.WaitGroup type workerInfo struct { workerName string workerlg *Logger } freeInstance := func(wi *workerInfo, id int) { wi.workerlg.Debugln("free instance:", id) } handleworker := func(wi *workerInfo) { wi.workerlg.Infoln("doing something awaresome...") freeInstance(wi, 3) wi.workerlg.Infoln("work done") wi.workerlg.Close() lg.Infof("worker: %s closed", wi.workerName) wg.Done() } onworkerDetect := func(workerName string) { lg.Infof("creating a new routine to handle %s", workerName) wi := &workerInfo{workerName: workerName, workerlg: stream.NewLogger(fmt.Sprintf("service/%s", workerName), Linfo)} lg.Infoln("handling worker info...") go handleworker(wi) } wg.Add(3) //with pattern "service/worker123*", worker123456 and worker123999 match and are set to Ldebug level stream.SetLoglevel("service/worker123*", Ldebug) onworkerDetect("worker123456") onworkerDetect("worker123999") onworkerDetect("worker555666") wg.Wait()
Output: [service][INFO] creating a new routine to handle worker123456 [service][INFO] handling worker info... [service][INFO] creating a new routine to handle worker123999 [service][INFO] handling worker info... [service][INFO] creating a new routine to handle worker555666 [service][INFO] handling worker info... [service/worker555666][INFO] doing something awaresome... [service/worker555666][INFO] work done [service][INFO] worker: worker555666 closed [service/worker123999][INFO] doing something awaresome... [service/worker123999][DEBUG] free instance: 3 [service/worker123999][INFO] work done [service][INFO] worker: worker123999 closed [service/worker123456][INFO] doing something awaresome... [service/worker123456][DEBUG] free instance: 3 [service/worker123456][INFO] work done [service][INFO] worker: worker123456 closed
func (*Stream) SetOutput ¶
SetOutput sets the output destination to the new one, and close the old one. newOutputDest is in the form: "keyword:description". See supported output destination keywords.
Example ¶
mystream := NewStream("mystream") defer mystream.Close() //set log output to file, args with "file:<file path>" mystream.SetOutput("file:test/test.log") mystream.SetTimeFormat(time.RFC3339Nano)
Output:
func (*Stream) SetOutputter ¶
SetOutputter sets the outputter for this stream.
func (*Stream) SetTimeFormat ¶
SetTimeFormat can change the timestamp format, refer to standard time package for the possible formats. An empty string "" will disable timestamp to be printed.