telegraf/cmd/telegraf/telegraf.go

294 lines
7.9 KiB
Go
Raw Normal View History

package main
import (
"context"
"errors"
2015-04-08 00:24:34 +08:00
"fmt"
2022-08-25 10:46:58 +08:00
"log" //nolint:revive
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/coreos/go-systemd/daemon"
"github.com/fatih/color"
"github.com/influxdata/tail/watch"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/agent"
"github.com/influxdata/telegraf/config"
"github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/logger"
"github.com/influxdata/telegraf/plugins/aggregators"
"github.com/influxdata/telegraf/plugins/inputs"
"github.com/influxdata/telegraf/plugins/outputs"
"github.com/influxdata/telegraf/plugins/parsers"
"github.com/influxdata/telegraf/plugins/processors"
"gopkg.in/tomb.v1"
)
2022-08-25 10:46:58 +08:00
var stop chan struct{}
2022-08-25 10:46:58 +08:00
type GlobalFlags struct {
config []string
configDir []string
testWait int
watchConfig string
pidFile string
plugindDir string
test bool
debug bool
once bool
quiet bool
}
2022-08-25 10:46:58 +08:00
type WindowFlags struct {
service string
serviceName string
serviceDisplayName string
serviceRestartDelay string
serviceAutoRestart bool
console bool
}
2022-08-25 10:46:58 +08:00
type App interface {
Init(<-chan error, Filters, GlobalFlags, WindowFlags)
Run() error
}
2016-01-08 06:21:10 +08:00
2022-08-25 10:46:58 +08:00
type Telegraf struct {
pprofErr <-chan error
inputFilters []string
outputFilters []string
GlobalFlags
WindowFlags
}
Telegraf support for built-in windows service. Updated windows dependencies Updated the windows dependencies so that the versions matched the dependencies for Mac OS and Linux. Additionally added some that were complained about being missing at compile time. Incorporated kardianos/service for management Incorporated the library github.com/kardianos/service to manage the service on the various platforms (including Windows). This required an alternate main function. The original main function was renamed to reloadLoop (as that is what the main loop in it does) (it also got a couple of parameters). The service management library calls it as the main body of the program. Merged service.go into telegraf.go Due to compilation issues on Windows, moved the code from service.go into telegraf.go and removed service.go entirely. Updated dependencies and fixed Windows service Updated the dependencies so that it builds properly on Windows, additionally, fixed the registered command for starting it as a service (needed to add the config file option). This currently standardizes it as a C:\telegraf\telegraf.conf on Windows. Added dependency for github.com/kardianos/service Removed the common dependencies from _windows file Removed all the common dependencies from the Godeps_windows file and modified Makefile to load Godeps and then Godeps_windows when building for Windows. This should reduce problems caused by the Godeps_windows file being forgotten when updating dependencies. Updated CHANGELOG.md with changes Ran `go fmt ./...` to format code Removed service library on all but Windows The service library [kardianos/service](github.com/kardianos/service) has been disabled on all platforms but windows, as there is already existing infrastructure for other platforms. Removed the dependency line for itself It appears that gdm accidentally added the project itself to the dependency list. This caused the dependency restoration to select an earlier version of the project during build. This only affected windows. This only affected builds after 020b2c70 Updated documentation for Windows Service Removed the documentation about using NSSM and added documentation on installing telegraf directly as a Windows Service. Added license info for kardianos/service Added the license information for github.com/kardianos/service which is licensed under the ZLib license, although that name is never mentioned the license text matches word for word. Changed the Windows Config file default location Updated the default location of the configuration file on Windows from C:\telegraf\telegraf.conf to C:\Program Files\Telegraf\telegraf.conf. With this change includes updating the directions, including directing that the executable be put into that same directory. Additionally, as noted in the instructions, the location of the config file for the service may be changed by specifying the location with the `-config` flag at install time. Fixed bug - Wrong data type: svcConfig svcConfig service.Config => svcConfig *service.Config (It needed to be a pointer)
2016-07-16 05:00:16 +08:00
func (t *Telegraf) Init(pprofErr <-chan error, f Filters, g GlobalFlags, w WindowFlags) {
t.pprofErr = pprofErr
t.inputFilters = f.input
t.outputFilters = f.output
t.GlobalFlags = g
t.WindowFlags = w
2022-08-25 10:46:58 +08:00
}
func (t *Telegraf) reloadLoop() error {
reload := make(chan bool, 1)
reload <- true
for <-reload {
reload <- false
ctx, cancel := context.WithCancel(context.Background())
signals := make(chan os.Signal, 1)
signal.Notify(signals, os.Interrupt, syscall.SIGHUP,
syscall.SIGTERM, syscall.SIGINT)
if t.watchConfig != "" {
for _, fConfig := range t.config {
if _, err := os.Stat(fConfig); err == nil {
go t.watchLocalConfig(signals, fConfig)
} else {
log.Printf("W! Cannot watch config %s: %s", fConfig, err)
}
}
}
go func() {
Telegraf support for built-in windows service. Updated windows dependencies Updated the windows dependencies so that the versions matched the dependencies for Mac OS and Linux. Additionally added some that were complained about being missing at compile time. Incorporated kardianos/service for management Incorporated the library github.com/kardianos/service to manage the service on the various platforms (including Windows). This required an alternate main function. The original main function was renamed to reloadLoop (as that is what the main loop in it does) (it also got a couple of parameters). The service management library calls it as the main body of the program. Merged service.go into telegraf.go Due to compilation issues on Windows, moved the code from service.go into telegraf.go and removed service.go entirely. Updated dependencies and fixed Windows service Updated the dependencies so that it builds properly on Windows, additionally, fixed the registered command for starting it as a service (needed to add the config file option). This currently standardizes it as a C:\telegraf\telegraf.conf on Windows. Added dependency for github.com/kardianos/service Removed the common dependencies from _windows file Removed all the common dependencies from the Godeps_windows file and modified Makefile to load Godeps and then Godeps_windows when building for Windows. This should reduce problems caused by the Godeps_windows file being forgotten when updating dependencies. Updated CHANGELOG.md with changes Ran `go fmt ./...` to format code Removed service library on all but Windows The service library [kardianos/service](github.com/kardianos/service) has been disabled on all platforms but windows, as there is already existing infrastructure for other platforms. Removed the dependency line for itself It appears that gdm accidentally added the project itself to the dependency list. This caused the dependency restoration to select an earlier version of the project during build. This only affected windows. This only affected builds after 020b2c70 Updated documentation for Windows Service Removed the documentation about using NSSM and added documentation on installing telegraf directly as a Windows Service. Added license info for kardianos/service Added the license information for github.com/kardianos/service which is licensed under the ZLib license, although that name is never mentioned the license text matches word for word. Changed the Windows Config file default location Updated the default location of the configuration file on Windows from C:\telegraf\telegraf.conf to C:\Program Files\Telegraf\telegraf.conf. With this change includes updating the directions, including directing that the executable be put into that same directory. Additionally, as noted in the instructions, the location of the config file for the service may be changed by specifying the location with the `-config` flag at install time. Fixed bug - Wrong data type: svcConfig svcConfig service.Config => svcConfig *service.Config (It needed to be a pointer)
2016-07-16 05:00:16 +08:00
select {
case sig := <-signals:
if sig == syscall.SIGHUP {
log.Printf("I! Reloading Telegraf config")
<-reload
reload <- true
Telegraf support for built-in windows service. Updated windows dependencies Updated the windows dependencies so that the versions matched the dependencies for Mac OS and Linux. Additionally added some that were complained about being missing at compile time. Incorporated kardianos/service for management Incorporated the library github.com/kardianos/service to manage the service on the various platforms (including Windows). This required an alternate main function. The original main function was renamed to reloadLoop (as that is what the main loop in it does) (it also got a couple of parameters). The service management library calls it as the main body of the program. Merged service.go into telegraf.go Due to compilation issues on Windows, moved the code from service.go into telegraf.go and removed service.go entirely. Updated dependencies and fixed Windows service Updated the dependencies so that it builds properly on Windows, additionally, fixed the registered command for starting it as a service (needed to add the config file option). This currently standardizes it as a C:\telegraf\telegraf.conf on Windows. Added dependency for github.com/kardianos/service Removed the common dependencies from _windows file Removed all the common dependencies from the Godeps_windows file and modified Makefile to load Godeps and then Godeps_windows when building for Windows. This should reduce problems caused by the Godeps_windows file being forgotten when updating dependencies. Updated CHANGELOG.md with changes Ran `go fmt ./...` to format code Removed service library on all but Windows The service library [kardianos/service](github.com/kardianos/service) has been disabled on all platforms but windows, as there is already existing infrastructure for other platforms. Removed the dependency line for itself It appears that gdm accidentally added the project itself to the dependency list. This caused the dependency restoration to select an earlier version of the project during build. This only affected windows. This only affected builds after 020b2c70 Updated documentation for Windows Service Removed the documentation about using NSSM and added documentation on installing telegraf directly as a Windows Service. Added license info for kardianos/service Added the license information for github.com/kardianos/service which is licensed under the ZLib license, although that name is never mentioned the license text matches word for word. Changed the Windows Config file default location Updated the default location of the configuration file on Windows from C:\telegraf\telegraf.conf to C:\Program Files\Telegraf\telegraf.conf. With this change includes updating the directions, including directing that the executable be put into that same directory. Additionally, as noted in the instructions, the location of the config file for the service may be changed by specifying the location with the `-config` flag at install time. Fixed bug - Wrong data type: svcConfig svcConfig service.Config => svcConfig *service.Config (It needed to be a pointer)
2016-07-16 05:00:16 +08:00
}
cancel()
case err := <-t.pprofErr:
2022-08-25 10:46:58 +08:00
log.Printf("E! pprof server failed: %v", err)
cancel()
Telegraf support for built-in windows service. Updated windows dependencies Updated the windows dependencies so that the versions matched the dependencies for Mac OS and Linux. Additionally added some that were complained about being missing at compile time. Incorporated kardianos/service for management Incorporated the library github.com/kardianos/service to manage the service on the various platforms (including Windows). This required an alternate main function. The original main function was renamed to reloadLoop (as that is what the main loop in it does) (it also got a couple of parameters). The service management library calls it as the main body of the program. Merged service.go into telegraf.go Due to compilation issues on Windows, moved the code from service.go into telegraf.go and removed service.go entirely. Updated dependencies and fixed Windows service Updated the dependencies so that it builds properly on Windows, additionally, fixed the registered command for starting it as a service (needed to add the config file option). This currently standardizes it as a C:\telegraf\telegraf.conf on Windows. Added dependency for github.com/kardianos/service Removed the common dependencies from _windows file Removed all the common dependencies from the Godeps_windows file and modified Makefile to load Godeps and then Godeps_windows when building for Windows. This should reduce problems caused by the Godeps_windows file being forgotten when updating dependencies. Updated CHANGELOG.md with changes Ran `go fmt ./...` to format code Removed service library on all but Windows The service library [kardianos/service](github.com/kardianos/service) has been disabled on all platforms but windows, as there is already existing infrastructure for other platforms. Removed the dependency line for itself It appears that gdm accidentally added the project itself to the dependency list. This caused the dependency restoration to select an earlier version of the project during build. This only affected windows. This only affected builds after 020b2c70 Updated documentation for Windows Service Removed the documentation about using NSSM and added documentation on installing telegraf directly as a Windows Service. Added license info for kardianos/service Added the license information for github.com/kardianos/service which is licensed under the ZLib license, although that name is never mentioned the license text matches word for word. Changed the Windows Config file default location Updated the default location of the configuration file on Windows from C:\telegraf\telegraf.conf to C:\Program Files\Telegraf\telegraf.conf. With this change includes updating the directions, including directing that the executable be put into that same directory. Additionally, as noted in the instructions, the location of the config file for the service may be changed by specifying the location with the `-config` flag at install time. Fixed bug - Wrong data type: svcConfig svcConfig service.Config => svcConfig *service.Config (It needed to be a pointer)
2016-07-16 05:00:16 +08:00
case <-stop:
cancel()
}
}()
err := t.runAgent(ctx)
if err != nil && err != context.Canceled {
2022-08-25 10:46:58 +08:00
return fmt.Errorf("[telegraf] Error running agent: %v", err)
}
}
2022-08-25 10:46:58 +08:00
return nil
}
func (t *Telegraf) watchLocalConfig(signals chan os.Signal, fConfig string) {
var mytomb tomb.Tomb
var watcher watch.FileWatcher
if t.watchConfig == "poll" {
watcher = watch.NewPollingFileWatcher(fConfig)
} else {
watcher = watch.NewInotifyFileWatcher(fConfig)
}
changes, err := watcher.ChangeEvents(&mytomb, 0)
if err != nil {
log.Printf("E! Error watching config: %s\n", err)
return
}
log.Println("I! Config watcher started")
select {
case <-changes.Modified:
log.Println("I! Config file modified")
case <-changes.Deleted:
// deleted can mean moved. wait a bit a check existence
<-time.After(time.Second)
if _, err := os.Stat(fConfig); err == nil {
log.Println("I! Config file overwritten")
} else {
log.Println("W! Config file deleted")
if err := watcher.BlockUntilExists(&mytomb); err != nil {
log.Printf("E! Cannot watch for config: %s\n", err.Error())
return
}
log.Println("I! Config file appeared")
}
case <-changes.Truncated:
log.Println("I! Config file truncated")
case <-mytomb.Dying():
log.Println("I! Config watcher ended")
return
}
mytomb.Done()
signals <- syscall.SIGHUP
}
func (t *Telegraf) runAgent(ctx context.Context) error {
// If no other options are specified, load the config file and run.
c := config.NewConfig()
c.OutputFilters = t.outputFilters
c.InputFilters = t.inputFilters
var err error
// providing no "config" flag should load default config
if len(t.config) == 0 {
err = c.LoadConfig("")
if err != nil {
return err
}
}
for _, fConfig := range t.config {
err = c.LoadConfig(fConfig)
if err != nil {
return err
}
}
for _, fConfigDirectory := range t.configDir {
err = c.LoadDirectory(fConfigDirectory)
if err != nil {
return err
}
}
if !(t.test || t.testWait != 0) && len(c.Outputs) == 0 {
return errors.New("Error: no outputs found, did you provide a valid config file?")
}
if t.plugindDir == "" && len(c.Inputs) == 0 {
return errors.New("Error: no inputs found, did you provide a valid config file?")
}
if int64(c.Agent.Interval) <= 0 {
return fmt.Errorf("Agent interval must be positive, found %v", c.Agent.Interval)
}
if int64(c.Agent.FlushInterval) <= 0 {
return fmt.Errorf("Agent flush_interval must be positive; found %v", c.Agent.Interval)
}
// Setup logging as configured.
telegraf.Debug = c.Agent.Debug || t.debug
2019-05-04 01:25:28 +08:00
logConfig := logger.LogConfig{
Debug: telegraf.Debug,
Quiet: c.Agent.Quiet || t.quiet,
LogTarget: c.Agent.LogTarget,
Logfile: c.Agent.Logfile,
RotationInterval: c.Agent.LogfileRotationInterval,
RotationMaxSize: c.Agent.LogfileRotationMaxSize,
RotationMaxArchives: c.Agent.LogfileRotationMaxArchives,
LogWithTimezone: c.Agent.LogWithTimezone,
2019-05-04 01:25:28 +08:00
}
logger.SetupLogging(logConfig)
2022-08-25 10:46:58 +08:00
log.Printf("I! Starting Telegraf %s%s", internal.Version, internal.Customized)
log.Printf("I! Available plugins: %d inputs, %d aggregators, %d processors, %d parsers, %d outputs",
len(inputs.Inputs),
len(aggregators.Aggregators),
len(processors.Processors),
len(parsers.Parsers),
len(outputs.Outputs),
)
log.Printf("I! Loaded inputs: %s", strings.Join(c.InputNames(), " "))
log.Printf("I! Loaded aggregators: %s", strings.Join(c.AggregatorNames(), " "))
log.Printf("I! Loaded processors: %s", strings.Join(c.ProcessorNames(), " "))
if !t.once && (t.test || t.testWait != 0) {
log.Print("W! " + color.RedString("Outputs are not used in testing mode!"))
} else {
log.Printf("I! Loaded outputs: %s", strings.Join(c.OutputNames(), " "))
}
log.Printf("I! Tags enabled: %s", c.ListTags())
if count, found := c.Deprecations["inputs"]; found && (count[0] > 0 || count[1] > 0) {
log.Printf("W! Deprecated inputs: %d and %d options", count[0], count[1])
}
if count, found := c.Deprecations["aggregators"]; found && (count[0] > 0 || count[1] > 0) {
log.Printf("W! Deprecated aggregators: %d and %d options", count[0], count[1])
}
if count, found := c.Deprecations["processors"]; found && (count[0] > 0 || count[1] > 0) {
log.Printf("W! Deprecated processors: %d and %d options", count[0], count[1])
}
if count, found := c.Deprecations["outputs"]; found && (count[0] > 0 || count[1] > 0) {
log.Printf("W! Deprecated outputs: %d and %d options", count[0], count[1])
}
ag, err := agent.NewAgent(c)
if err != nil {
return err
}
// Notify systemd that telegraf is ready
// SdNotify() only tries to notify if the NOTIFY_SOCKET environment is set, so it's safe to call when systemd isn't present.
// Ignore the return values here because they're not valid for platforms that don't use systemd.
// For platforms that use systemd, telegraf doesn't log if the notification failed.
_, _ = daemon.SdNotify(false, daemon.SdNotifyReady)
if t.once {
wait := time.Duration(t.testWait) * time.Second
return ag.Once(ctx, wait)
}
if t.test || t.testWait != 0 {
wait := time.Duration(t.testWait) * time.Second
return ag.Test(ctx, wait)
}
if t.pidFile != "" {
f, err := os.OpenFile(t.pidFile, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Printf("E! Unable to create pidfile: %s", err)
} else {
2022-08-25 10:46:58 +08:00
_, _ = fmt.Fprintf(f, "%d\n", os.Getpid())
2022-08-25 10:46:58 +08:00
err = f.Close()
if err != nil {
return err
}
defer func() {
err := os.Remove(t.pidFile)
if err != nil {
log.Printf("E! Unable to remove pidfile: %s", err)
}
}()
}
}
return ag.Run(ctx)
}