diff --git a/circle.yml b/circle.yml index c237040a2..283c63ad0 100644 --- a/circle.yml +++ b/circle.yml @@ -4,9 +4,9 @@ machine: post: - sudo service zookeeper stop - go version - - go version | grep 1.7.5 || sudo rm -rf /usr/local/go - - wget https://storage.googleapis.com/golang/go1.7.5.linux-amd64.tar.gz - - sudo tar -C /usr/local -xzf go1.7.5.linux-amd64.tar.gz + - sudo rm -rf /usr/local/go + - wget https://storage.googleapis.com/golang/go1.8rc3.linux-amd64.tar.gz + - sudo tar -C /usr/local -xzf go1.8rc3.linux-amd64.tar.gz - go version dependencies: diff --git a/cmd/telegraf/telegraf.go b/cmd/telegraf/telegraf.go index 16f7845d0..b6ef61a09 100644 --- a/cmd/telegraf/telegraf.go +++ b/cmd/telegraf/telegraf.go @@ -6,6 +6,9 @@ import ( "log" "os" "os/signal" + "path" + "path/filepath" + "plugin" "runtime" "strings" "syscall" @@ -13,12 +16,14 @@ import ( "github.com/influxdata/telegraf/agent" "github.com/influxdata/telegraf/internal/config" "github.com/influxdata/telegraf/logger" + _ "github.com/influxdata/telegraf/plugins/aggregators/all" "github.com/influxdata/telegraf/plugins/inputs" _ "github.com/influxdata/telegraf/plugins/inputs/all" "github.com/influxdata/telegraf/plugins/outputs" _ "github.com/influxdata/telegraf/plugins/outputs/all" _ "github.com/influxdata/telegraf/plugins/processors/all" + "github.com/kardianos/service" ) @@ -50,6 +55,8 @@ var fUsage = flag.String("usage", "", "print usage for a plugin, ie, 'telegraf -usage mysql'") var fService = flag.String("service", "", "operate on the service") +var fPlugins = flag.String("plugins", "", + "path to directory containing external plugins") // Telegraf version, populated linker. // ie, -ldflags "-X main.version=`git describe --always --tags`" @@ -246,11 +253,53 @@ func (p *program) Stop(s service.Service) error { return nil } +// loadExternalPlugins loads external plugins from shared libraries (.so, .dll, etc.) +// in the specified directory. +func loadExternalPlugins(rootDir string) error { + return filepath.Walk(rootDir, func(pth string, info os.FileInfo, err error) error { + // Stop if there was an error. + if err != nil { + return err + } + + // Ignore directories. + if info.IsDir() { + return nil + } + + // Ignore files that aren't shared libraries. + ext := strings.ToLower(path.Ext(pth)) + if ext != ".so" && ext != ".dll" { + return nil + } + + // Load plugin. + _, err = plugin.Open(pth) + if err != nil { + return fmt.Errorf("error loading [%s]: %s", pth, err) + } + + return nil + }) +} + func main() { flag.Usage = func() { usageExit(0) } flag.Parse() args := flag.Args() + // Load external plugins, if requested. + if *fPlugins != "" { + pluginsDir, err := filepath.Abs(*fPlugins) + if err != nil { + log.Fatal("E! " + err.Error()) + } + log.Printf("I! Loading external plugins from: %s\n", pluginsDir) + if err := loadExternalPlugins(*fPlugins); err != nil { + log.Fatal("E! " + err.Error()) + } + } + inputFilters, outputFilters := []string{}, []string{} if *fInputFilters != "" { inputFilters = strings.Split(":"+strings.TrimSpace(*fInputFilters)+":", ":")