Esempio n. 1
0
func main() {
	var port uint
	var etcdAddr, bstalk, logLevel string

	// Command line flags
	flag.StringVarP(&bstalk, "beanstalk", "b", "127.0.0.1:11300", "address of beanstalkd server")
	flag.StringVarP(&logLevel, "log-level", "l", "warn", "log level")
	flag.StringVarP(&etcdAddr, "etcd", "e", "http://127.0.0.1:4001", "address of etcd server")
	flag.UintVarP(&port, "http", "p", 7544, "http port to publish metrics. set to 0 to disable")
	flag.Parse()

	// Set up logger
	if err := logx.DefaultSetup(logLevel); err != nil {
		log.WithFields(log.Fields{
			"error": err,
			"level": logLevel,
		}).Fatal("unable to to set up logrus")
	}

	etcdClient := etcd.NewClient([]string{etcdAddr})

	if !etcdClient.SyncCluster() {
		log.WithFields(log.Fields{
			"addr": etcdAddr,
		}).Fatal("unable to sync etcd cluster")
	}

	ctx := lochness.NewContext(etcdClient)

	log.WithField("address", bstalk).Info("connection to beanstalk")
	jobQueue, err := jobqueue.NewClient(bstalk, etcdClient)
	if err != nil {
		log.WithFields(log.Fields{
			"error":   err,
			"address": bstalk,
		}).Fatal("failed to create jobQueue client")
	}

	// Set up metrics
	m := setupMetrics(port)
	if m != nil {
	}

	agent := ctx.NewMistifyAgent()

	// Start consuming
	consume(jobQueue, agent, m)
}
Esempio n. 2
0
func main() {
	var port uint
	var etcdAddr, bstalk, logLevel string

	flag.StringVarP(&bstalk, "beanstalk", "b", "127.0.0.1:11300", "address of beanstalkd server")
	flag.StringVarP(&logLevel, "log-level", "l", "warn", "log level")
	flag.StringVarP(&etcdAddr, "etcd", "e", "http://127.0.0.1:4001", "address of etcd server")
	flag.UintVarP(&port, "http", "p", 7543, "address for http interface. set to 0 to disable")
	flag.Parse()

	// Set up logger
	if err := logx.DefaultSetup(logLevel); err != nil {
		log.WithFields(log.Fields{
			"error": err,
			"level": logLevel,
		}).Fatal("failed to set up logging")
	}

	etcdClient := etcd.NewClient([]string{etcdAddr})

	if !etcdClient.SyncCluster() {
		log.WithFields(log.Fields{
			"addr": etcdAddr,
		}).Fatal("unable to sync etcd cluster")
	}

	log.WithField("address", bstalk).Info("connection to beanstalk")
	jobQueue, err := jobqueue.NewClient(bstalk, etcdClient)
	if err != nil {
		log.WithFields(log.Fields{
			"error":   err,
			"address": bstalk,
		}).Fatal("failed to create jobQueue client")
	}

	// setup metrics
	ms := mapsink.New()
	conf := metrics.DefaultConfig("cplacerd")
	conf.EnableHostname = false
	m, _ := metrics.New(conf, ms)

	if port != 0 {

		http.Handle("/metrics", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
			w.WriteHeader(http.StatusOK)
			w.Header().Set("Content-Type", "application/json")
			if err := json.NewEncoder(w).Encode(ms); err != nil {
				log.WithField("error", err).Error(err)
			}
		}))

		go func() {
			if err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil); err != nil {
				log.WithFields(log.Fields{
					"error": err,
				}).Fatal("error serving")
			}
		}()

	}

	// XXX: we want to try to keep track of where a job is
	// in this pipeline? would have to persist in the job
	funcs := []TaskFunc{
		TaskFunc{
			name:     "check job status",
			function: checkJobStatus,
		},
		TaskFunc{
			name:     "check guest status",
			function: checkGuestStatus,
		},
		TaskFunc{
			name:     "select hypervisor candidate",
			function: selectHypervisor,
		},
		TaskFunc{
			name:     "update job action",
			function: changeJobAction,
		},
		TaskFunc{
			name:     "add task to worker",
			function: addJobToWorker,
		},
		TaskFunc{
			name:     "make task for deletion",
			function: deleteTask,
		},
	}

	for _, f := range funcs {
		f.label = strings.Split(runtime.FuncForPC(reflect.ValueOf(f.function).Pointer()).Name(), ".")[1]
	}

	for {
		task, err := jobQueue.NextCreateTask()
		if err != nil {
			if bCE, ok := err.(beanstalk.ConnError); ok {
				switch bCE {
				case beanstalk.ErrTimeout:
					// Empty queue, continue waiting
					continue
				case beanstalk.ErrDeadline:
					// See docs on beanstalkd deadline
					// We're just going to sleep to let the deadline'd job expire
					// and try to get another job
					m.IncrCounter([]string{"beanstalk", "error", "deadline"}, 1)
					log.Debug(beanstalk.ErrDeadline)
					time.Sleep(5 * time.Second)
					continue
				default:
					// You have failed me for the last time
					log.WithField("error", err).Fatal(err)
				}
			}
			log.WithFields(log.Fields{
				"task":  task,
				"error": err,
			}).Error("invalid task")

			if err := task.Delete(); err != nil {
				log.WithFields(log.Fields{
					"task":  task.ID,
					"error": err,
				}).Error("unable to delete")
			}
		}

		for _, f := range funcs {

			fields := log.Fields{
				"task": task,
			}

			log.WithFields(fields).Debug("running")

			start := time.Now()
			rm, err := f.function(jobQueue, task)

			m.MeasureSince([]string{f.label, "time"}, start)
			m.IncrCounter([]string{f.label, "count"}, 1)

			duration := int(time.Since(start).Seconds() * 1000)
			log.WithFields(fields).WithField("duration", duration).Info("done")

			if err != nil {

				m.IncrCounter([]string{f.label, "error"}, 1)

				log.WithFields(fields).WithField("error", err).Error("task error")

				task.Job.Status = jobqueue.JobStatusError
				task.Job.Error = err.Error()
				if err := task.Job.Save(24 * time.Hour); err != nil {
					log.WithFields(log.Fields{
						"task":  task,
						"error": err,
					}).Error("unable to save")
				}
			}

			if rm {
				if err := task.Delete(); err != nil {
					log.WithFields(log.Fields{
						"task":  task.ID,
						"error": err,
					}).Error("unable to delete")
				}
				break
			}
		}
	}
}
Esempio n. 3
0
func main() {
	var port uint
	var etcdAddr, bstalk, logLevel, statsd string

	flag.UintVarP(&port, "port", "p", 18000, "listen port")
	flag.StringVarP(&etcdAddr, "etcd", "e", defaultEtcdAddr, "address of etcd machine")
	flag.StringVarP(&bstalk, "beanstalk", "b", "127.0.0.1:11300", "address of beanstalkd server")
	flag.StringVarP(&logLevel, "log-level", "l", "warn", "log level")
	flag.StringVarP(&statsd, "statsd", "s", "", "statsd address")
	flag.Parse()

	if err := logx.DefaultSetup(logLevel); err != nil {
		log.WithFields(log.Fields{
			"error": err,
			"func":  "logx.DefaultSetup",
			"level": logLevel,
		}).Fatal("unable to set up logrus")
	}

	etcdClient := etcd.NewClient([]string{etcdAddr})

	if !etcdClient.SyncCluster() {
		log.WithFields(log.Fields{
			"error": nil,
			"func":  "etcd.SyncCluster",
			"addr":  etcdAddr,
		}).Fatal("unable to sync etcd cluster")
	}

	ctx := lochness.NewContext(etcdClient)

	log.WithField("address", bstalk).Info("connection to beanstalk")
	jobQueue, err := jobqueue.NewClient(bstalk, etcdClient)
	if err != nil {
		log.WithFields(log.Fields{
			"error":   err,
			"address": bstalk,
		}).Fatal("failed to create jobQueue client")
	}

	// setup metrics
	sink := mapsink.New()
	fanout := metrics.FanoutSink{sink}

	if statsd != "" {
		ss, _ := metrics.NewStatsdSink(statsd)
		fanout = append(fanout, ss)
	}
	conf := metrics.DefaultConfig("cguestd")
	conf.EnableHostname = false
	m, _ := metrics.New(conf, fanout)

	mctx := &metricsContext{
		sink:    sink,
		metrics: m,
		mmw:     mmw.New(m),
	}

	if err := Run(port, ctx, jobQueue, mctx); err != nil {
		log.WithFields(log.Fields{
			"error": err,
		}).Fatal("failed to run server")
	}
}