Example #1
0
package config_test

import (
	"syslog_drain_binder/config"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("ParseConfig", func() {
	Context("with a file that doesn't exist", func() {
		It("returns an error", func() {
			_, err := config.ParseConfig("fixtures/bad_file_path.json")
			Expect(err).To(HaveOccurred())
			Expect(err.Error()).To(Equal("open fixtures/bad_file_path.json: no such file or directory"))
		})
	})

	Context("with a file that contains bad json", func() {
		It("returns an error", func() {
			_, err := config.ParseConfig("fixtures/bad_json.json")
			Expect(err).To(HaveOccurred())
			Expect(err.Error()).To(Equal("invalid character '@' looking for beginning of value"))
		})
	})

	Context("without metron address", func() {
		It("returns an error", func() {
			_, err := config.ParseConfig("fixtures/no_metron_address.json")
			Expect(err).To(HaveOccurred())
			Expect(err.Error()).To(Equal("Need Metron address (host:port)"))
Example #2
0
func main() {
	flag.Parse()
	conf, err := config.ParseConfig(*configFile)
	if err != nil {
		panic(err)
	}
	log := logger.NewLogger(*debug, *logFilePath, "syslog_drain_binder", conf.Syslog)

	dropsonde.Initialize(conf.MetronAddress, "syslog_drain_binder")

	workPool, err := workpool.NewWorkPool(conf.EtcdMaxConcurrentRequests)
	if err != nil {
		panic(err)
	}

	options := &etcdstoreadapter.ETCDOptions{
		ClusterUrls: conf.EtcdUrls,
	}
	if conf.EtcdRequireTLS {
		options.IsSSL = true
		options.CertFile = conf.EtcdTLSClientConfig.CertFile
		options.KeyFile = conf.EtcdTLSClientConfig.KeyFile
		options.CAFile = conf.EtcdTLSClientConfig.CAFile
	}
	adapter, err := etcdstoreadapter.New(options, workPool)
	if err != nil {
		panic(err)
	}

	updateInterval := time.Duration(conf.UpdateIntervalSeconds) * time.Second
	politician := elector.NewElector(conf.InstanceName, adapter, updateInterval, log)

	drainTTL := time.Duration(conf.DrainUrlTtlSeconds) * time.Second
	store := etcd_syslog_drain_store.NewEtcdSyslogDrainStore(adapter, drainTTL, log)

	dumpChan := registerGoRoutineDumpSignalChannel()
	ticker := time.NewTicker(updateInterval)
	for {
		select {
		case <-dumpChan:
			signalmanager.DumpGoRoutine()
		case <-ticker.C:
			if politician.IsLeader() {
				err = politician.StayAsLeader()
				if err != nil {
					log.Errorf("Error when staying leader: %s", err.Error())
					politician.Vacate()
					continue
				}
			} else {
				err = politician.RunForElection()

				if err != nil {
					log.Errorf("Error when running for leader: %s", err.Error())
					politician.Vacate()
					continue
				}
			}

			log.Debugf("Polling %s for updates", conf.CloudControllerAddress)
			drainUrls, err := Poll(conf.CloudControllerAddress, conf.BulkApiUsername, conf.BulkApiPassword, conf.PollingBatchSize, conf.SkipCertVerify)
			if err != nil {
				log.Errorf("Error when polling cloud controller: %s", err.Error())
				politician.Vacate()
				continue
			}

			metrics.IncrementCounter("pollCount")

			var totalDrains int
			for _, drainList := range drainUrls {
				totalDrains += len(drainList)
			}

			metrics.SendValue("totalDrains", float64(totalDrains), "drains")

			log.Debugf("Updating drain URLs for %d application(s)", len(drainUrls))
			err = store.UpdateDrains(drainUrls)
			if err != nil {
				log.Errorf("Error when updating ETCD: %s", err.Error())
				politician.Vacate()
				continue
			}
		}
	}
}