Before you do that, have a think about whether a framework is necessary.
For example, the author of an application can create a Logger interface that contains the methods they need, e.g. in the simple case:
type Logger interface{
Printf(format string, v ...interface{})
}
Then they write their types like this:
type Processor struct {
Logger Logger
}
func (p *Processor) DoSomething() {
p.Logger.Printf("it's happening")
}
Now automatically any logging package that provides a logger with that method can be used by the application. In this case it includes the standard library logger and a bunch of others. They have complete choice. If they want to use a logging package that doesn't support Printf then a simple adapter that delegates can be written:
type LogAdapter struct {
logger OtherLogger
}
func (la *LogAdapter) Printf(format string, v ...interface{}) {
la.logger.Infof(format, v...)
}
Ian