func (b *Beat) launch(bt Creator) error { err := b.handleFlags() if err != nil { return err } svc.BeforeRun() defer svc.Cleanup() if err := b.configure(); err != nil { return err } // load the beats config section var sub *common.Config configName := strings.ToLower(b.Name) if b.RawConfig.HasField(configName) { sub, err = b.RawConfig.Child(configName, -1) if err != nil { return err } } else { sub = common.NewConfig() } logp.Info("Setup Beat: %s; Version: %s", b.Name, b.Version) processors, err := processors.New(b.Config.Processors) if err != nil { return fmt.Errorf("error initializing processors: %v", err) } debugf("Initializing output plugins") publisher, err := publisher.New(b.Name, b.Config.Output, b.Config.Shipper, processors) if err != nil { return fmt.Errorf("error initializing publisher: %v", err) } // TODO: some beats race on shutdown with publisher.Stop -> do not call Stop yet, // but refine publisher to disconnect clients on stop automatically // defer publisher.Stop() b.Publisher = publisher beater, err := bt(b, sub) if err != nil { return err } // If -configtest was specified, exit now prior to run. if cfgfile.IsTestConfig() { fmt.Println("Config OK") return GracefulExit } svc.HandleSignals(beater.Stop) logp.Info("%s start running.", b.Name) defer logp.Info("%s stopped.", b.Name) return beater.Run(b) }
// Stop calls the beater Stop action. // It can happen that this function is called more then once. func (b *Beat) Stop() { logp.Info("Stopping Beat") b.BT.Stop() service.Cleanup() logp.Info("Cleaning up %s before shutting down.", b.Name) // Call beater cleanup function err := b.BT.Cleanup(b) if err != nil { logp.Err("Cleanup returned an error: %v", err) } }
// Stop calls the beater Stop action. // It can happen that this function is called more then once. func (b *Beat) Stop() { logp.Info("Stopping Beat") if b.getState() == RunState { b.BT.Stop() } service.Cleanup() logp.Info("Cleaning up %s before shutting down.", b.Name) if b.getState() > StopState { // Call beater cleanup function err := b.BT.Cleanup(b) if err != nil { logp.Err("Cleanup returned an error: %v", err) } } b.setState(StopState) }
// Run calls the beater Setup and Run methods. In case of errors // during the setup phase, it exits the process. func (b *Beat) Run() error { // Setup beater object err := b.BT.Setup(b) if err != nil { logp.Critical("Setup returned an error: %v", err) os.Exit(1) } // Up to here was the initialization, now about running if cfgfile.IsTestConfig() { // all good, exit with 0 os.Exit(0) } service.BeforeRun() // Callback is called if the processes is asked to stop. // This needs to be called before the main loop is started so that // it can register the signals that stop or query (on Windows) the loop. service.HandleSignals(b.Exit) logp.Info("%s sucessfully setup. Start running.", b.Name) // Run beater specific stuff err = b.BT.Run(b) if err != nil { logp.Critical("Running the beat returned an error: %v", err) } service.Cleanup() logp.Info("Cleaning up %s before shutting down.", b.Name) // Call beater cleanup function err = b.BT.Cleanup(b) if err != nil { logp.Err("Cleanup returned an error: %v", err) } return err }
// cleanup is invoked prior to exit for the purposes of performing any final // clean-up. This method is guaranteed to be invoked on shutdown if the beat // reaches the setup stage. func (bc *instance) cleanup() error { logp.Info("%s cleanup", bc.data.Name) defer svc.Cleanup() return bc.beater.Cleanup(bc.data) }