Skip to content

Writing libraries with Seelog

cihub edited this page May 17, 2012 · 6 revisions

Why?

You might ask: What is so special about the libraries. The short answer is they are designed to be used in other code, that may have its own log policy. So, if you design a library for external use, it's great practice to expose functions which allow to control log configuration of the library.

The most obvious features overwhelming majority of developers would like to see include:

  • Disabling log from a library
  • Make a special logger for a library
  • Force a library to run its log messages in the same log files as the application
  • Write library log without importing 'seelog'

How to write a library

To write a user-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'):

package yourlibrary 

import (
	seelog "github.com/cihub/seelog"
	"io"
	"errors"
)

var logger seelog.LoggerInterface

func init() {
	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()
}

By doing that you allow your library users to do anything they need about your library log:

  • Log is disabled by default
  • Specific logger can be passed to the library using a 'yourLibrary.UseLogger(...)' call
  • You can enable library log without importing Seelog with a 'yourLibrary.SetLogWriter(writer)' call

**Note:**Actually, this template should be almost the same for all libraries using Seelog, so you could just create 'log.go' file once and copy it to all your libraries (just change 'package' statement).

Avoid using package level funcs in libraries

Because it can result in a non-predictable behavior. Package level funcs (Trace, Debug, ... , UseConfig, ReplaceConfig, Flush, ...) are designed to be used in final applications. Use library-level logger variables like in example above.

Demonstration

There is a demonstration of recommendations, given above in seelog-examples/library. There are several packages there that implement the following:

  • Library package
  • App that uses it with Seelog features
  • App that uses it without importing Seelog