func (tm *TaskManager) updateUnits(unitCfg *config.UnitConfig, taskCfg *config.TaskConfig) error { id := fullId(taskCfg, unitCfg.Identity) log.Info("fullId = ", id) newUnit, err := units.NewUnit(unitCfg, taskCfg) if err != nil { return err } tm.m.Lock() defer tm.m.Unlock() if !tm.running { return nil } oldUnit, ok := tm.units[id] if ok { isMatch := (oldUnit.EqualTo(newUnit)) log.Debug("is match = ", isMatch) if !isMatch { go newUnit.Start(tm.publisher.Queue) oldUnit.Stop() // delete(tm.units, id) } } else { go newUnit.Start(tm.publisher.Queue) tm.units[id] = newUnit } log.Info("units = ", tm.units) return nil }
func (tm *TaskManager) stop(removeUnits bool) { log.Info("Stoping task manager...") defer log.Info("Task manager stopped.") tm.m.Lock() tasks := []Task{} for _, task := range tm.tasks { tasks = append(tasks, task) } tm.m.Unlock() var wg sync.WaitGroup wg.Add(len(tasks)) for _, task := range tasks { go func(ts Task) { ts.Stop() wg.Done() }(task) } wg.Wait() tm.m.Lock() defer tm.m.Unlock() if removeUnits { tm.removeUnits(nil) } tm.running = false }
func notifyReload() { pid_b, err := utils.ReadFile(PID_FILE) if err != nil { log.Fatalln("Error reading the file of this process id:", err) } pid_s := string(pid_b) log.Debug("This process id is ", pid_s) if strings.TrimSpace(pid_s) == "" { log.Fatalln("The file of this process id is empty.") } pid, err := strconv.Atoi(pid_s) if err != nil { log.Fatalf("String to int error: %s", err) } _, err = utils.ExecCommand(false, "kill", "-HUP", pid_s) if err != nil { log.Fatalf("Execute commmand <kill -HUP %s> error: %s", pid_s, err) } err = syscall.Kill(pid, syscall.SYS_READ) if err != nil { log.Fatalf("Kill signal send failed. Pid: %s, error: %s", pid_s, err) } else { log.Info("Configuration file is reloading...") } }
func NewUnit(unitCfg *config.UnitConfig, taskCfg *config.TaskConfig) (Unit, error) { /* var fac UnitFactory switch taskCfg.TaskName { case UNIT_NAME_CONTAINER: fac = new(ContainerUnitFactory) default: switch unitCfg.UnitName { case UNIT_NAME_HOST_CPU: fac = new(HostCpuUnitFactory) case UNIT_NAME_HOST_MEM: // fac = new(HostMemUnitFactory) case UNIT_NAME_HOST_DISKIO: case UNIT_NAME_HOST_NETWORK: } } */ var facKey string if taskCfg.TaskName == UNIT_NAME_CONTAINER { facKey = taskCfg.TaskName } else { facKey = unitCfg.UnitName } log.Info("factory key = ", facKey) fac, ok := UnitFactories[facKey] if !ok { return nil, errors.New("Unrecognized unit name: " + facKey) } var u Unit u = fac.createUnit() u.SetInterval(unitCfg.FetchInterval) return Unit(u), nil }
func (this *HostCpuUnit) Fetch(ch chan<- model.Metric) { log.Info("in host cpu unit fetch...") if this.lastCPUUsage[7] == 0 { return } delta_total := this.newCPUUsage[7] - this.lastCPUUsage[7] for i := 0; i < 7; i++ { this.metrics[i]. SetValue((this.newCPUUsage[i] - this.lastCPUUsage[i]) * 100.0 / delta_total). SetTimestamp(time.Now()).Collect(ch) } }
func (tm *TaskManager) Run() { log.Info("Starting task manager...") identities := map[string]struct{}{} for taskCfg, task := range tm.tasks { log.Infof("taskCfg = %v", taskCfg) ch := make(chan *config.UnitConfig) // Every task has a batch of units. go tm.handleUnitUpdates(taskCfg, ch) for _, id := range task.Identity() { id = fullId(taskCfg, id) identities[id] = struct{}{} } defer func(t Task, c chan *config.UnitConfig) { go t.Run(c) }(task, ch) } log.Info("before removeUnits") tm.m.Lock() defer tm.m.Unlock() tm.removeUnits(func(id string) bool { if _, ok := identities[id]; ok { return false } return true }) tm.running = true log.Info("Run finished.") }
func main() { flag.Parse() if *versionFlag { fmt.Println(VERSION) os.Exit(0) } if *logstashFlag { log.ChangeToLogstashFormater(APP_NAME) } log.SetLogFile(LOG_FILE) if *reloadFlag { notifyReload() os.Exit(0) } pid := os.Getpid() // This process's pid. log.Infof("The process id is %d", pid) // Save the pid into the pid file. err := utils.WriteFile(PID_FILE, []byte(strconv.Itoa(pid)), 0644) if err != nil { log.Fatalln("Error writing this process id:", err) } defer os.Remove(PID_FILE) publisher := outputs.NewPublisherType() taskManager := fetch.NewTaskManager(publisher) if !reloadConfig(*cfgFileFlag, publisher, taskManager) { os.Exit(1) } // Wait for receive a singal to reload configuration file. hupCh := make(chan os.Signal) hupReady := make(chan bool) signal.Notify(hupCh, syscall.SIGHUP) go func() { <-hupReady for range hupCh { reloadConfig(*cfgFileFlag, publisher, taskManager) } }() go taskManager.Run() defer taskManager.Stop() defer publisher.StopPublish() close(hupReady) // Wait for quit signal to exit this process. sigCh := make(chan os.Signal) signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM, os.Kill, syscall.SIGKILL) select { case s := <-sigCh: // Block until a signal is received. log.Warnf("Caught Signal: %v, shuting down gracefully...", s) } close(hupCh) log.Info("See you again!") return }
func (this *ContainerUnit) Fetch(ch chan<- model.Metric) { log.Info("in container fetch...") }
func (this *PublisherType) StopPublish() { log.Info("Stoping publish...") close(this.publistStop) // stop publishFromQueue goroutine }