diff --git a/util/eventlog/log.go b/util/eventlog/log.go index 4f9757bd1..c0a4a8fe3 100644 --- a/util/eventlog/log.go +++ b/util/eventlog/log.go @@ -2,14 +2,19 @@ package eventlog import ( "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context" - logging "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-logging" - "github.com/jbenet/go-ipfs/util" + + prelog "github.com/jbenet/go-ipfs/util/prefixlog" ) // EventLogger extends the StandardLogger interface to allow for log items // containing structured metadata type EventLogger interface { - StandardLogger + prelog.StandardLogger + + // Prefix is like PrefixLogger.Prefix. We override it here + // because the type changes (we return EventLogger). + // It's what happens when you wrap interfaces. + Prefix(fmt string, args ...interface{}) EventLogger // Event merges structured data from the provided inputs into a single // machine-readable log event. @@ -27,43 +32,27 @@ type EventLogger interface { Event(ctx context.Context, event string, m ...Loggable) } -// StandardLogger provides API compatibility with standard printf loggers -// eg. go-logging -type StandardLogger interface { - Critical(args ...interface{}) - Criticalf(format string, args ...interface{}) - Debug(args ...interface{}) - Debugf(format string, args ...interface{}) - Error(args ...interface{}) - Errorf(format string, args ...interface{}) - Fatal(args ...interface{}) - Fatalf(format string, args ...interface{}) - Info(args ...interface{}) - Infof(format string, args ...interface{}) - Notice(args ...interface{}) - Noticef(format string, args ...interface{}) - Panic(args ...interface{}) - Panicf(format string, args ...interface{}) - Warning(args ...interface{}) - Warningf(format string, args ...interface{}) -} - // Logger retrieves an event logger by name func Logger(system string) EventLogger { // TODO if we would like to adjust log levels at run-time. Store this event // logger in a map (just like the util.Logger impl) - - return &eventLogger{system: system, Logger: util.Logger(system)} + return &eventLogger{system: system, PrefixLogger: prelog.Logger(system)} } // eventLogger implements the EventLogger and wraps a go-logging Logger type eventLogger struct { - *logging.Logger + prelog.PrefixLogger + system string // TODO add log-level } +func (el *eventLogger) Prefix(fmt string, args ...interface{}) EventLogger { + l := el.PrefixLogger.Prefix(fmt, args...) + return &eventLogger{system: el.system, PrefixLogger: l} +} + func (el *eventLogger) Event(ctx context.Context, event string, metadata ...Loggable) { // Collect loggables for later logging diff --git a/util/prefixlog/prefixlog.go b/util/prefixlog/prefixlog.go new file mode 100644 index 000000000..1ab90bad2 --- /dev/null +++ b/util/prefixlog/prefixlog.go @@ -0,0 +1,151 @@ +package eventlog + +import ( + "strings" + + "github.com/jbenet/go-ipfs/util" +) + +// StandardLogger provides API compatibility with standard printf loggers +// eg. go-logging +type StandardLogger interface { + Critical(args ...interface{}) + Criticalf(format string, args ...interface{}) + Debug(args ...interface{}) + Debugf(format string, args ...interface{}) + Error(args ...interface{}) + Errorf(format string, args ...interface{}) + Fatal(args ...interface{}) + Fatalf(format string, args ...interface{}) + Info(args ...interface{}) + Infof(format string, args ...interface{}) + Notice(args ...interface{}) + Noticef(format string, args ...interface{}) + Panic(args ...interface{}) + Panicf(format string, args ...interface{}) + Warning(args ...interface{}) + Warningf(format string, args ...interface{}) +} + +// StandardLogger provides API compatibility with standard printf loggers +// eg. go-logging +type PrefixLogger interface { + StandardLogger + + Format() string + Args() []interface{} + + Prefix(fmt string, args ...interface{}) PrefixLogger +} + +// Logger retrieves an event logger by name +func Logger(system string) PrefixLogger { + + // TODO if we would like to adjust log levels at run-time. Store this event + // logger in a map (just like the util.Logger impl) + + logger := util.Logger(system) + return Prefix(logger, "") +} + +func Prefix(l StandardLogger, format string, args ...interface{}) PrefixLogger { + return &prefixLogger{logger: l, format: format, args: args} +} + +type prefixLogger struct { + logger StandardLogger + format string + args []interface{} +} + +func (pl *prefixLogger) Format() string { + return pl.format +} + +func (pl *prefixLogger) Args() []interface{} { + return pl.args +} + +func (pl *prefixLogger) Prefix(fmt string, args ...interface{}) PrefixLogger { + return Prefix(pl, fmt, args...) +} + +func (pl *prefixLogger) prepend(fmt string, args []interface{}) (string, []interface{}) { + together := make([]interface{}, 0, len(pl.args)+len(args)) + together = append(together, pl.args...) + together = append(together, args...) + if len(pl.format) > 0 { + fmt = pl.format + " " + fmt + } + return fmt, together +} + +func valfmtn(count int) string { + s := strings.Repeat("%v ", count) + s = s[:len(s)-1] // remove last space + return s +} + +type logFunc func(args ...interface{}) +type logFuncf func(fmt string, args ...interface{}) + +func (pl *prefixLogger) logFunc(f logFuncf, args ...interface{}) { + // need to actually use the format version, with extra fmt strings appended + fmt := valfmtn(len(args)) + pl.logFuncf(f, fmt, args...) +} + +func (pl *prefixLogger) logFuncf(f logFuncf, format string, args ...interface{}) { + format, args = pl.prepend(format, args) + f(format, args...) +} + +func (pl *prefixLogger) Critical(args ...interface{}) { + pl.logFunc(pl.logger.Criticalf, args...) +} +func (pl *prefixLogger) Debug(args ...interface{}) { + pl.logFunc(pl.logger.Debugf, args...) +} +func (pl *prefixLogger) Error(args ...interface{}) { + pl.logFunc(pl.logger.Errorf, args...) +} +func (pl *prefixLogger) Fatal(args ...interface{}) { + pl.logFunc(pl.logger.Fatalf, args...) +} +func (pl *prefixLogger) Info(args ...interface{}) { + pl.logFunc(pl.logger.Infof, args...) +} +func (pl *prefixLogger) Notice(args ...interface{}) { + pl.logFunc(pl.logger.Noticef, args...) +} +func (pl *prefixLogger) Panic(args ...interface{}) { + pl.logFunc(pl.logger.Panicf, args...) +} +func (pl *prefixLogger) Warning(args ...interface{}) { + pl.logFunc(pl.logger.Warningf, args...) +} + +func (pl *prefixLogger) Criticalf(format string, args ...interface{}) { + pl.logFuncf(pl.logger.Criticalf, format, args...) +} +func (pl *prefixLogger) Debugf(format string, args ...interface{}) { + pl.logFuncf(pl.logger.Debugf, format, args...) +} +func (pl *prefixLogger) Errorf(format string, args ...interface{}) { + pl.logFuncf(pl.logger.Errorf, format, args...) +} +func (pl *prefixLogger) Fatalf(format string, args ...interface{}) { + pl.logFuncf(pl.logger.Fatalf, format, args...) +} +func (pl *prefixLogger) Infof(format string, args ...interface{}) { + pl.logFuncf(pl.logger.Infof, format, args...) +} +func (pl *prefixLogger) Noticef(format string, args ...interface{}) { + pl.logFuncf(pl.logger.Noticef, format, args...) +} +func (pl *prefixLogger) Panicf(format string, args ...interface{}) { + pl.logFuncf(pl.logger.Panicf, format, args...) +} +func (pl *prefixLogger) Warningf(format string, args ...interface{}) { + pl.logFuncf(pl.logger.Warningf, format, args...) +}