1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
package main
import (
"context"
"fmt"
"io"
"gopkg.in/alecthomas/kingpin.v2"
)
// A LogSourceFactory provides a repository of log sources that can be
// instantiated from command line flags.
type LogSourceFactory interface {
// Init adds the factory's struct fields as flags in the
// application.
Init(*kingpin.Application)
// New attempts to create a new log source. This is called after
// flags have been parsed. Returning `nil, nil`, means the user
// didn't want this log source.
New(context.Context) (LogSourceCloser, error)
}
type LogSourceCloser interface {
io.Closer
LogSource
}
var logSourceFactories []LogSourceFactory
// RegisterLogSourceFactory can be called from module `init` functions
// to register factories.
func RegisterLogSourceFactory(lsf LogSourceFactory) {
logSourceFactories = append(logSourceFactories, lsf)
}
// InitLogSourceFactories runs Init on all factories. The
// initialization order is arbitrary, except `fileLogSourceFactory` is
// always last (the fallback). The file log source must be last since
// it's enabled by default.
func InitLogSourceFactories(app *kingpin.Application) {
RegisterLogSourceFactory(&fileLogSourceFactory{})
for _, f := range logSourceFactories {
f.Init(app)
}
}
// NewLogSourceFromFactories iterates through the factories and
// attempts to instantiate a log source. The first factory to return
// success wins.
func NewLogSourceFromFactories(ctx context.Context) (LogSourceCloser, error) {
for _, f := range logSourceFactories {
src, err := f.New(ctx)
if err != nil {
return nil, err
}
if src != nil {
return src, nil
}
}
return nil, fmt.Errorf("no log source configured")
}
|