// Service setup.
//   Define service config.
//   Create the service.
//   Setup the logger.
//   Handle service controls (optional).
//   Run the service.
func main() {

	svcFlag := flag.String("service", "", "Control the system service.")
	flag.Parse()

	if !service.Interactive() {
		root, _ := osext.ExecutableFolder()

		f, err := os.OpenFile(root+"/output.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()
		log.SetOutput(f)
	}

	svcConfig := &service.Config{
		Name:        "FPL Checker",
		DisplayName: "FPL Checker",
		Description: "Free Post Code Lottery daily winner checker",
	}

	prg := &program{}
	s, err := service.New(prg, svcConfig)
	if err != nil {
		log.Fatal(err)
	}
	errs := make(chan error, 5)
	logger, err = s.Logger(errs)
	if err != nil {
		log.Fatal(err)
	}

	go func() {
		for {
			err := <-errs
			if err != nil {
				log.Print(err)
			}
		}
	}()

	if len(*svcFlag) != 0 {
		err := service.Control(s, *svcFlag)
		if err != nil {
			log.Printf("Valid actions: %q\n", service.ControlAction)
			log.Fatal(err)
		}
		return
	}
	err = s.Run()
	if err != nil {
		logger.Error(err)
	}
}
Example #2
0
func (p *program) Stop(s service.Service) error {
	close(p.exit)
	logger.Info("Stopping ", p.DisplayName)
	if p.cmd.ProcessState.Exited() == false {
		p.cmd.Process.Kill()
	}
	if service.Interactive() {
		os.Exit(0)
	}
	return nil
}
Example #3
0
func (p *program) Start(s service.Service) error {
	if service.Interactive() {
		logger.Info("Running in terminal.")
	} else {
		logger.Info("Running under service manager.")
	}
	p.exit = make(chan struct{})

	// Start should not block. Do the actual work async.
	go p.run()
	return nil
}
Example #4
0
func (p *program) run() {
	logger.Info("Starting ", p.DisplayName)
	defer func() {
		if service.Interactive() {
			p.Stop(p.service)
		} else {
			p.service.Stop()
		}
	}()

	if p.Stderr != "" {
		f, err := os.OpenFile(p.Stderr, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0777)
		if err != nil {
			logger.Warningf("Failed to open std err %q: %v", p.Stderr, err)
			return
		}
		defer f.Close()
		p.cmd.Stderr = f
	}
	if p.Stdout != "" {
		f, err := os.OpenFile(p.Stdout, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0777)
		if err != nil {
			logger.Warningf("Failed to open std out %q: %v", p.Stdout, err)
			return
		}
		defer f.Close()
		p.cmd.Stdout = f
	}

	err := p.cmd.Run()
	if err != nil {
		logger.Warningf("Error running: %v", err)
	}

	return
}
Example #5
0
func reloadLoop(stop chan struct{}, s service.Service) {
	defer func() {
		if service.Interactive() {
			os.Exit(0)
		}
		return
	}()
	reload := make(chan bool, 1)
	reload <- true
	for <-reload {
		reload <- false
		flag.Usage = func() { usageExit(0) }
		flag.Parse()
		args := flag.Args()

		var inputFilters []string
		if *fInputFilters != "" {
			inputFilter := strings.TrimSpace(*fInputFilters)
			inputFilters = strings.Split(":"+inputFilter+":", ":")
		}
		var outputFilters []string
		if *fOutputFilters != "" {
			outputFilter := strings.TrimSpace(*fOutputFilters)
			outputFilters = strings.Split(":"+outputFilter+":", ":")
		}

		if len(args) > 0 {
			switch args[0] {
			case "version":
				v := fmt.Sprintf("Telegraf - version %s", version)
				fmt.Println(v)
				return
			case "config":
				config.PrintSampleConfig(inputFilters, outputFilters)
				return
			}
		}

		// switch for flags which just do something and exit immediately
		switch {
		case *fOutputList:
			fmt.Println("Available Output Plugins:")
			for k, _ := range outputs.Outputs {
				fmt.Printf("  %s\n", k)
			}
			return
		case *fInputList:
			fmt.Println("Available Input Plugins:")
			for k, _ := range inputs.Inputs {
				fmt.Printf("  %s\n", k)
			}
			return
		case *fVersion:
			v := fmt.Sprintf("Telegraf - version %s", version)
			fmt.Println(v)
			return
		case *fSampleConfig:
			config.PrintSampleConfig(inputFilters, outputFilters)
			return
		case *fUsage != "":
			if err := config.PrintInputConfig(*fUsage); err != nil {
				if err2 := config.PrintOutputConfig(*fUsage); err2 != nil {
					log.Fatalf("%s and %s", err, err2)
				}
			}
			return
		case *fService != "" && runtime.GOOS == "windows":
			if *fConfig != "" {
				(*svcConfig).Arguments = []string{"-config", *fConfig}
			}
			err := service.Control(s, *fService)
			if err != nil {
				log.Fatal(err)
			}
			return
		}

		// If no other options are specified, load the config file and run.
		c := config.NewConfig()
		c.OutputFilters = outputFilters
		c.InputFilters = inputFilters
		err := c.LoadConfig(*fConfig)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		if *fConfigDirectory != "" {
			err = c.LoadDirectory(*fConfigDirectory)
			if err != nil {
				log.Fatal(err)
			}
		}
		if len(c.Outputs) == 0 {
			log.Fatalf("Error: no outputs found, did you provide a valid config file?")
		}
		if len(c.Inputs) == 0 {
			log.Fatalf("Error: no inputs found, did you provide a valid config file?")
		}

		ag, err := agent.NewAgent(c)
		if err != nil {
			log.Fatal(err)
		}

		if *fDebug {
			ag.Config.Agent.Debug = true
		}

		if *fQuiet {
			ag.Config.Agent.Quiet = true
		}

		if *fTest {
			err = ag.Test()
			if err != nil {
				log.Fatal(err)
			}
			return
		}

		err = ag.Connect()
		if err != nil {
			log.Fatal(err)
		}

		shutdown := make(chan struct{})
		signals := make(chan os.Signal)
		signal.Notify(signals, os.Interrupt, syscall.SIGHUP)
		go func() {
			select {
			case sig := <-signals:
				if sig == os.Interrupt {
					close(shutdown)
				}
				if sig == syscall.SIGHUP {
					log.Printf("Reloading Telegraf config\n")
					<-reload
					reload <- true
					close(shutdown)
				}
			case <-stop:
				close(shutdown)
			}
		}()

		log.Printf("Starting Telegraf (version %s)\n", version)
		log.Printf("Loaded outputs: %s", strings.Join(c.OutputNames(), " "))
		log.Printf("Loaded inputs: %s", strings.Join(c.InputNames(), " "))
		log.Printf("Tags enabled: %s", c.ListTags())

		if *fPidfile != "" {
			f, err := os.Create(*fPidfile)
			if err != nil {
				log.Fatalf("Unable to create pidfile: %s", err)
			}

			fmt.Fprintf(f, "%d\n", os.Getpid())

			f.Close()
		}

		ag.Run(shutdown)
	}
}
Example #6
0
func reloadLoop(stop chan struct{}, s service.Service) {
	defer func() {
		if service.Interactive() {
			os.Exit(0)
		}
		return
	}()
	reload := make(chan bool, 1)
	reload <- true
	for <-reload {
		reload <- false
		flag.Parse()
		args := flag.Args()

		var inputFilters []string
		if *fInputFilters != "" {
			inputFilter := strings.TrimSpace(*fInputFilters)
			inputFilters = strings.Split(":"+inputFilter+":", ":")
		}
		var outputFilters []string
		if *fOutputFilters != "" {
			outputFilter := strings.TrimSpace(*fOutputFilters)
			outputFilters = strings.Split(":"+outputFilter+":", ":")
		}
		var aggregatorFilters []string
		if *fAggregatorFilters != "" {
			aggregatorFilter := strings.TrimSpace(*fAggregatorFilters)
			aggregatorFilters = strings.Split(":"+aggregatorFilter+":", ":")
		}
		var processorFilters []string
		if *fProcessorFilters != "" {
			processorFilter := strings.TrimSpace(*fProcessorFilters)
			processorFilters = strings.Split(":"+processorFilter+":", ":")
		}

		if len(args) > 0 {
			switch args[0] {
			case "version":
				fmt.Printf("Telegraf v%s (git: %s %s)\n", version, branch, commit)
				return
			case "config":
				config.PrintSampleConfig(
					inputFilters,
					outputFilters,
					aggregatorFilters,
					processorFilters,
				)
				return
			}
		}

		// switch for flags which just do something and exit immediately
		switch {
		case *fOutputList:
			fmt.Println("Available Output Plugins:")
			for k, _ := range outputs.Outputs {
				fmt.Printf("  %s\n", k)
			}
			return
		case *fInputList:
			fmt.Println("Available Input Plugins:")
			for k, _ := range inputs.Inputs {
				fmt.Printf("  %s\n", k)
			}
			return
		case *fVersion:
			fmt.Printf("Telegraf v%s (git: %s %s)\n", version, branch, commit)
			return
		case *fSampleConfig:
			config.PrintSampleConfig(
				inputFilters,
				outputFilters,
				aggregatorFilters,
				processorFilters,
			)
			return
		case *fUsage != "":
			if err := config.PrintInputConfig(*fUsage); err != nil {
				if err2 := config.PrintOutputConfig(*fUsage); err2 != nil {
					log.Fatalf("E! %s and %s", err, err2)
				}
			}
			return
		}

		// If no other options are specified, load the config file and run.
		c := config.NewConfig()
		c.OutputFilters = outputFilters
		c.InputFilters = inputFilters
		err := c.LoadConfig(*fConfig)
		if err != nil {
			log.Fatal("E! " + err.Error())
		}

		if *fConfigDirectory != "" {
			err = c.LoadDirectory(*fConfigDirectory)
			if err != nil {
				log.Fatal("E! " + err.Error())
			}
		}
		if len(c.Outputs) == 0 {
			log.Fatalf("E! Error: no outputs found, did you provide a valid config file?")
		}
		if len(c.Inputs) == 0 {
			log.Fatalf("E! Error: no inputs found, did you provide a valid config file?")
		}

		ag, err := agent.NewAgent(c)
		if err != nil {
			log.Fatal("E! " + err.Error())
		}

		// Setup logging
		logger.SetupLogging(
			ag.Config.Agent.Debug || *fDebug,
			ag.Config.Agent.Quiet || *fQuiet,
			ag.Config.Agent.Logfile,
		)

		if *fTest {
			err = ag.Test()
			if err != nil {
				log.Fatal("E! " + err.Error())
			}
			return
		}

		err = ag.Connect()
		if err != nil {
			log.Fatal("E! " + err.Error())
		}

		shutdown := make(chan struct{})
		signals := make(chan os.Signal)
		signal.Notify(signals, os.Interrupt, syscall.SIGHUP)
		go func() {
			select {
			case sig := <-signals:
				if sig == os.Interrupt {
					close(shutdown)
				}
				if sig == syscall.SIGHUP {
					log.Printf("I! Reloading Telegraf config\n")
					<-reload
					reload <- true
					close(shutdown)
				}
			case <-stop:
				close(shutdown)
			}
		}()

		log.Printf("I! Starting Telegraf (version %s)\n", version)
		log.Printf("I! Loaded outputs: %s", strings.Join(c.OutputNames(), " "))
		log.Printf("I! Loaded inputs: %s", strings.Join(c.InputNames(), " "))
		log.Printf("I! Tags enabled: %s", c.ListTags())

		if *fPidfile != "" {
			f, err := os.Create(*fPidfile)
			if err != nil {
				log.Fatalf("E! Unable to create pidfile: %s", err)
			}

			fmt.Fprintf(f, "%d\n", os.Getpid())

			f.Close()
		}

		ag.Run(shutdown)
	}
}
Example #7
0
// program start
func main() {
	var err error

	sconf := service.Config{
		Name:        "BabelPoxy",
		DisplayName: "Babel Proxy",
		Description: "babelproxy converts RESTful calls into Babel calls.",
	}

	// Parse flags from command-line
	flag.Parse()

	// Parser flags from config
	flagcfg.AddDefaults()
	flagcfg.Parse()

	// Parse flags from environment (using github.com/facebookgo/flagenv)
	flagenv.Prefix = "BABELPROXY_"
	flagenv.Parse()

	// show help if asked
	if help {
		fmt.Fprintln(os.Stderr, `Usage of babelproxy:
  babelproxy [options] <filepatterns>

"For the faasti RESTafarians! (Feel no way, we maas.)"

Example:
  babelproxy *.babel

Options include:`)
		flag.PrintDefaults()
		fmt.Fprintln(os.Stderr, `
All of the options can be overridden in the configuration file. To override
the location of the configuration file, set the BABELPROXY_CONFIG environment
variable. When running as a service, all options must be specified in the
configuration file or environment variables.`)
		return
	}

	// show version if asked
	if ver {
		fmt.Printf("babelproxy Version %s\n", BABELPROXY_VERSION)
		return
	}

	// default the pubaddr
	if strings.TrimSpace(conf.PubAddr) == "" {
		conf.PubAddr = conf.RestAddr
	}

	// handle kill signals
	go func() {
		// setup cpu profiling if desired
		var f io.WriteCloser
		var err error
		if conf.CpuProfile != "" {
			f, err = os.Create(conf.CpuProfile)
			if err != nil {
				log.Fatal(err)
			}
			pprof.StartCPUProfile(f)
		}

		// Set up channel on which to send signal notifications.
		// We must use a buffered channel or risk missing the signal
		// if we're not ready to receive when the signal is sent.
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, os.Kill)

		// Block until a signal is received.
		s := <-c
		log.Print("Got signal ", s, ", canceling work")

		if conf.CpuProfile != "" {
			log.Print("Writing CPU profile to ", conf.CpuProfile)
			pprof.StopCPUProfile()
			f.Close()
		}

		// write memory profile if configured
		if conf.MemProfile != "" {
			f, err := os.Create(conf.MemProfile)
			if err != nil {
				log.Print(err)
			} else {
				log.Print("Writing memory profile to ", conf.MemProfile)
				pprof.WriteHeapProfile(f)
				f.Close()
			}
		}
		os.Exit(0)
	}()

	// setup number of CPUs
	runtime.GOMAXPROCS(conf.Cpus)

	// set working directory
	if conf.WorkingDir != "" {
		err = os.Chdir(conf.WorkingDir)
		if err != nil {
			log.Fatal(err)
		}
	}

	// override configured arguments (file list) with command line
	if flag.NArg() > 0 {
		conf.Args = flag.Args()
	}

	var i svcImpl
	svcBroxy, err = service.New(&i, &sconf)
	if err != nil {
		log.Fatal(err)
	}
	/*
		svcLogger, err = svcBroxy.Logger(nil)
		if err != nil {
			log.Fatal(err)
		}
	*/
	if control != "" {
		err = service.Control(svcBroxy, control)
		if err != nil {
			log.Fatal(err)
		}
		return
	}

	if service.Interactive() {
		i.doWork()
	} else {
		err = svcBroxy.Run()
		if err != nil {
			//svcLogger.Error(err.Error())
			log.Println(err)
		}
	}
}