logging/backend.go

220 lines
4.2 KiB
Go
Raw Normal View History

2013-06-21 18:35:47 +02:00
package logging
import (
2013-06-24 17:37:46 +02:00
"errors"
"fmt"
2013-06-21 18:35:47 +02:00
"io"
"log/syslog"
2013-06-21 18:35:47 +02:00
"os"
"strings"
2013-06-21 18:35:47 +02:00
)
type Backend interface {
Write(*Record) error
SetFormatter(*Formatter)
2013-06-24 17:37:46 +02:00
SetLevel(Level)
Level() Level
2014-12-04 20:25:49 +01:00
Reopen() error
2013-06-21 18:35:47 +02:00
}
2013-06-24 17:37:46 +02:00
//
// Backend to write in file-like objects
//
type FileBackend struct {
2013-06-21 18:35:47 +02:00
l io.Writer
formatter *Formatter
2013-06-24 17:37:46 +02:00
level Level
2014-12-04 20:25:49 +01:00
filepath string
2013-06-21 18:35:47 +02:00
}
2013-06-24 17:37:46 +02:00
// Creates a new backend to write the logs on the standard output
func NewStdoutBackend() (b *FileBackend) {
b = &FileBackend{
2013-06-21 18:35:47 +02:00
l: os.Stdout,
formatter: &defaultFormatter,
}
return
}
2013-06-24 17:37:46 +02:00
// Creates a new backend to write the logs on the error output
func NewStderrBackend() (b *FileBackend) {
b = &FileBackend{
l: os.Stderr,
formatter: &defaultFormatter,
}
return
}
// Creates a new backend to write the logs in a given file
func NewFileBackend(filename string) (b *FileBackend, e error) {
filename_fd, err := os.OpenFile(filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
if err != nil {
e = errors.New(fmt.Sprintf("Cannot open log file %s (%s)", filename, err.Error()))
}
b = &FileBackend{
l: filename_fd,
formatter: &defaultFormatter,
2014-12-04 20:25:49 +01:00
filepath: filename,
2013-06-24 17:37:46 +02:00
}
return
}
// Creates a new backend to write the logs in a given io.Writer
func NewIoBackend(buf io.Writer) (b *FileBackend) {
return &FileBackend{
l: buf,
formatter: &defaultFormatter,
}
}
2013-06-24 17:37:46 +02:00
func (b FileBackend) Write(r *Record) error {
text := (*b.formatter)(r)
_, err := io.WriteString(b.l, text)
return err
2013-06-21 18:35:47 +02:00
}
2013-06-24 17:37:46 +02:00
func (b *FileBackend) SetLevel(l Level) {
2013-06-21 18:35:47 +02:00
b.level = l
}
2013-06-24 17:37:46 +02:00
func (b *FileBackend) Level() Level {
return b.level
}
func (b *FileBackend) SetFormatter(f *Formatter) {
2013-06-21 18:35:47 +02:00
b.formatter = f
}
2014-12-04 20:25:49 +01:00
func (b *FileBackend) Reopen() error {
if b.filepath == "" {
return nil
}
filename_fd, err := os.OpenFile(b.filepath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
if err != nil {
return errors.New(fmt.Sprintf("Cannot open log file %s (%s)", b.filepath, err.Error()))
} else {
b.l = filename_fd
}
return nil
}
//
// Syslog Backend
//
type SyslogBackend struct {
w *syslog.Writer
formatter *Formatter
level Level
}
func NewSyslogBackend(facilityName string, tag string) (Backend, error) {
f, err := facility(facilityName)
if err != nil {
return nil, err
}
w, err := syslog.New(f, tag)
if err != nil {
return nil, err
}
sb := &SyslogBackend{
w: w,
formatter: &basicFormatter,
}
return sb, nil
}
func (sb *SyslogBackend) Write(r *Record) (err error) {
text := (*sb.formatter)(r)
switch r.Level {
case DEBUG:
err = sb.w.Debug(text)
case INFO:
err = sb.w.Info(text)
case WARNING:
err = sb.w.Warning(text)
case ERROR:
err = sb.w.Err(text)
case CRITICAL:
err = sb.w.Crit(text)
case FATAL:
err = sb.w.Emerg(text)
}
return err
}
func (sb *SyslogBackend) SetFormatter(f *Formatter) {
sb.formatter = f
}
func (sb *SyslogBackend) SetLevel(level Level) {
sb.level = level
}
func (sb *SyslogBackend) Level() Level {
return sb.level
}
2014-12-04 20:25:49 +01:00
func (sb *SyslogBackend) Reopen() error {
return nil
}
var facilities = map[string]syslog.Priority{
"kern": syslog.LOG_KERN,
"user": syslog.LOG_USER,
"mail": syslog.LOG_MAIL,
"daemon": syslog.LOG_DAEMON,
"auth": syslog.LOG_AUTH,
"syslog": syslog.LOG_SYSLOG,
"lpr": syslog.LOG_LPR,
"news": syslog.LOG_NEWS,
"uucp": syslog.LOG_UUCP,
"cron": syslog.LOG_CRON,
"authpriv": syslog.LOG_AUTHPRIV,
"ftp": syslog.LOG_FTP,
"local0": syslog.LOG_LOCAL0,
"local1": syslog.LOG_LOCAL1,
"local2": syslog.LOG_LOCAL2,
"local3": syslog.LOG_LOCAL3,
"local4": syslog.LOG_LOCAL4,
"local5": syslog.LOG_LOCAL5,
"local6": syslog.LOG_LOCAL6,
"local7": syslog.LOG_LOCAL7,
}
func facility(name string) (syslog.Priority, error) {
if p, ok := facilities[strings.ToLower(name)]; !ok {
return 0, fmt.Errorf("Facility '%s' does not exist", name)
} else {
return p, nil
}
}
2014-10-22 12:35:14 +02:00
//
// Noop Backend
//
type NoopBackend struct{}
func NewNoopBackend() (Backend, error) {
return &NoopBackend{}, nil
}
func (nb *NoopBackend) Write(r *Record) error {
return nil
}
func (nb *NoopBackend) SetFormatter(f *Formatter) {}
func (nb *NoopBackend) SetLevel(level Level) {}
func (nb *NoopBackend) Level() Level {
return FATAL
}
2014-12-04 20:25:49 +01:00
func (nb *NoopBackend) Reopen() error {
return nil
}