-
Notifications
You must be signed in to change notification settings - Fork 244
Writing libraries with Seelog
You might ask: What's up with libraries! Nothing. You'd just better bear in mind that they are designed to be used in outer code, which may have its own logging policy. So, if you intend a library for external use, it's common practice to expose functions which allow to handily control log configuration of the library.
The most obvious features overwhelming majority of developers would like to see include:
- Disable log from a library.
- To be able to pass a custom logger to a library.
- Force a library's logger to push its log messages to the application's log writers.
- Use library's logger without importing Seelog package in external application.
To write a user- (developer)-friendly library, which uses Seelog inside, you may use the following template (it is convenient to put it in a separate file like 'log.go') and modify it as you need more options:
package yourlibrary
import (
seelog "github.com/cihub/seelog"
"io"
"errors"
)
var logger seelog.LoggerInterface
func init() {
// Disable logger by default.
DisableLog()
}
// DisableLog disables all library log output.
func DisableLog() {
logger = seelog.Disabled
}
// UseLogger uses a specified seelog.LoggerInterface to output library log.
// Use this func if you are using Seelog logging system in your app.
func UseLogger(newLogger seelog.LoggerInterface) {
logger = newLogger
}
// SetLogWriter uses a specified io.Writer to output library log.
// Use this func if you are not using Seelog logging system in your app.
func SetLogWriter(writer io.Writer) error {
if writer == nil {
return errors.New("Nil writer")
}
newLogger, err := seelog.LoggerFromWriterWithMinLevel(writer, seelog.TraceLvl)
if err != nil {
return err
}
UseLogger(newLogger)
return nil
}
// Call this before app shutdown
func FlushLog() {
logger.Flush()
}
Such technique allows users to do anything with your library log:
- Leave library's logger disabled.
- Replace it with a custom logger using 'yourLibrary.UseLogger(customLogger)' call.
- Utilize library log without importing Seelog using 'yourLibrary.SetLogWriter(customWriter)' call.
In version 'v2.5', a new feature was introduced: Custom receivers. Using custom receivers, you may connect Seelog to almost any other log system/log consumer. So if you are using Seelog v2.5 or above, the template above may be changed to something more flexible using seelog.LoggerFromWriterWithMinLevelAndFormat
or even seelog.LoggerFromCustomReceiver
.
Asynchronous use of your library in external applications can result in an unpredictable behavior of package level funcs (Trace, Debug, ... , UseConfig, ReplaceConfig, Flush, ...) as they are designed to be only used in final applications. Use library-level logger variables instead (see, example above).
Demonstration and recommendations given above are collected in seelog-examples/library. There you'll find there packages which implement:
- Library package,
- App that uses it with Seelog features,
- App that uses it without importing Seelog.