func (l Logger) Errorf(format string, v ...interface{}) {
	worker := func() {
		msg := fmt.Sprintf(format, v...)
		if l.syslog != nil {
			l.syslog.Err(msg)
		} else {
			l.errorLog.Println(msg)
		}
	}
	l.nonBlockingEnqueue(worker)
}
Errorf emits messages at ERROR level with a printf style interface.
package log
import (
	"fmt"
	"log"
	"log/syslog"
	"os"
	"time"
)
const (
	defaultSyslogFacility = syslog.LOG_USER
	workQueueMaxBacklog = 25
)
type Logger struct {
	syslog   *syslog.Writer
	errorLog *log.Logger
	warnLog  *log.Logger
	infoLog  *log.Logger
	debugLog *log.Logger
	queue    chan func()
	debug    bool
}
type Config struct {
	Debug      bool
	Mountpoint string
	Syslog     bool
}
func New(component string, config Config) *Logger {
	name := fmt.Sprintf("%s[%s]", component, config.Mountpoint)
	flags := log.LstdFlags
	errorLog := log.New(os.Stderr, fmt.Sprintf("ERROR %v: ", name), flags)
	warnLog := log.New(os.Stderr, fmt.Sprintf("WARN %v: ", name), flags)
	infoLog := log.New(os.Stdout, fmt.Sprintf("INFO %v: ", name), flags)
	debugLog := log.New(os.Stdout, fmt.Sprintf("DEBUG %v: ", name), flags)
	var syslogWriter *syslog.Writer
	if config.Syslog {
		var err error
		syslogWriter, err = syslog.New(syslog.LOG_NOTICE|defaultSyslogFacility, name)
		if err != nil {
			errorLog.Printf("Error starting syslog logging, continuing: %v\n", err)
			syslogWriter = nil
		}
	}
	queue := make(chan func(), workQueueMaxBacklog)
	logger := &Logger{syslogWriter, errorLog, warnLog, infoLog, debugLog, queue, config.Debug}
	go logger.process()
	return logger
}
func (l Logger) nonBlockingEnqueue(worker func()) {
	select {
	case l.queue <- worker:
	default:
		fmt.Fprintf(
			os.Stderr,
			"** dropping log message at %s, buffer full (%d queued) **",
			time.Now().Format(time.UnixDate), len(l.queue))
	}
}
func (l Logger) process() {
	for {
		worker, more := <-l.queue
		if !more {
			return
		}
		worker()
	}
}