예제 #1
0
func New(
	logger *gosteno.Logger,
	host string,
	config *doppler_config.Config,
	storeAdapter storeadapter.StoreAdapter,
	messageDrainBufferSize uint,
	dropsondeOrigin string,
	websocketWriteTimeout time.Duration,
	dialTimeout time.Duration,
) (*Doppler, error) {
	doppler := &Doppler{
		Logger:                     logger,
		storeAdapter:               storeAdapter,
		dropsondeVerifiedBytesChan: make(chan []byte),
	}

	keepAliveInterval := 30 * time.Second

	appStoreCache := cache.NewAppServiceCache()
	doppler.appStoreWatcher, doppler.newAppServiceChan, doppler.deletedAppServiceChan = store.NewAppServiceStoreWatcher(storeAdapter, appStoreCache, logger)

	doppler.batcher = initializeMetrics(config.MetricBatchIntervalMilliseconds)

	doppler.envelopeChan = make(chan *events.Envelope)

	doppler.udpListener, doppler.dropsondeBytesChan = listeners.NewUDPListener(
		fmt.Sprintf("%s:%d", host, config.IncomingUDPPort),
		doppler.batcher,
		logger,
		"udpListener",
	)

	var err error
	if config.EnableTLSTransport {
		tlsConfig := &config.TLSListenerConfig
		addr := fmt.Sprintf("%s:%d", host, tlsConfig.Port)
		contextName := "tlsListener"
		doppler.tlsListener, err = listeners.NewTCPListener(contextName, addr, tlsConfig, doppler.envelopeChan, doppler.batcher, logger)
		if err != nil {
			return nil, err
		}
	}

	addr := fmt.Sprintf("%s:%d", host, config.IncomingTCPPort)
	contextName := "tcpListener"
	doppler.tcpListener, err = listeners.NewTCPListener(contextName, addr, nil, doppler.envelopeChan, doppler.batcher, logger)

	doppler.signatureVerifier = signature.NewVerifier(logger, config.SharedSecret)

	doppler.dropsondeUnmarshallerCollection = dropsonde_unmarshaller.NewDropsondeUnmarshallerCollection(logger, config.UnmarshallerCount)

	blacklist := blacklist.New(config.BlackListIps, logger)
	metricTTL := time.Duration(config.ContainerMetricTTLSeconds) * time.Second
	sinkTimeout := time.Duration(config.SinkInactivityTimeoutSeconds) * time.Second
	sinkIOTimeout := time.Duration(config.SinkIOTimeoutSeconds) * time.Second
	doppler.sinkManager = sinkmanager.New(
		config.MaxRetainedLogMessages,
		config.SinkSkipCertVerify,
		blacklist,
		logger,
		messageDrainBufferSize,
		dropsondeOrigin,
		sinkTimeout,
		sinkIOTimeout,
		metricTTL,
		dialTimeout,
	)

	doppler.Infof("Listening for GRPC connections on %d", config.GRPCPort)
	grpcListener, err := net.Listen("tcp", fmt.Sprintf(":%d", config.GRPCPort))
	if err != nil {
		return nil, err
	}
	grpcServer := grpc.NewServer()
	plumbing.RegisterDopplerServer(grpcServer, doppler.sinkManager)
	go grpcServer.Serve(grpcListener)

	doppler.messageRouter = sinkserver.NewMessageRouter(doppler.sinkManager, logger)

	doppler.websocketServer, err = websocketserver.New(
		fmt.Sprintf(":%d", config.OutgoingPort),
		doppler.sinkManager,
		websocketWriteTimeout,
		keepAliveInterval,
		config.MessageDrainBufferSize,
		dropsondeOrigin,
		doppler.batcher,
		logger,
	)
	if err != nil {
		return nil, fmt.Errorf("Failed to create the websocket server: %s", err.Error())
	}

	monitorInterval := time.Duration(config.MonitorIntervalSeconds) * time.Second
	doppler.openFileMonitor = monitor.NewLinuxFD(monitorInterval, logger)
	doppler.uptimeMonitor = monitor.NewUptime(monitorInterval)

	return doppler, nil
}
예제 #2
0
)

const initialFDs = 4

var _ = Describe("OpenFD", func() {
	var (
		openFDMonitor *monitor.LinuxFileDescriptor
		logger        *gosteno.Logger
	)

	BeforeEach(func() {
		fakeEventEmitter.Reset()
		interval := 100 * time.Millisecond
		logger = loggertesthelper.Logger()

		openFDMonitor = monitor.NewLinuxFD(interval, logger)
		go openFDMonitor.Start()
	})

	AfterEach(func() {
		openFDMonitor.Stop()
	})

	It("emits a metric with the number of open file handles", func() {
		Eventually(func() int { return len(fakeEventEmitter.GetMessages()) }).Should(BeNumerically(">", 0))
		Expect(fakeEventEmitter.GetMessages()[0].Event.(*events.ValueMetric)).To(Equal(&events.ValueMetric{
			Name:  proto.String("LinuxFileDescriptor"),
			Value: proto.Float64(initialFDs),
			Unit:  proto.String("File"),
		}))
예제 #3
0
func main() {
	flag.Parse()

	config, err := config.ParseConfig(*logLevel, *configFile)
	if err != nil {
		panic(fmt.Errorf("Unable to parse config: %s", err))
	}

	httpsetup.SetInsecureSkipVerify(config.SkipCertVerify)

	ipAddress, err := localip.LocalIP()
	if err != nil {
		panic(fmt.Errorf("Unable to resolve own IP address: %s", err))
	}

	log := logger.NewLogger(*logLevel, *logFilePath, "loggregator trafficcontroller", config.Syslog)
	log.Info("Startup: Setting up the loggregator traffic controller")

	batcher, err := initializeMetrics("LoggregatorTrafficController", net.JoinHostPort(config.MetronHost, strconv.Itoa(config.MetronPort)))
	if err != nil {
		log.Errorf("Error initializing dropsonde: %s", err)
	}

	go func() {
		err := http.ListenAndServe(net.JoinHostPort("localhost", pprofPort), nil)
		if err != nil {
			log.Errorf("Error starting pprof server: %s", err.Error())
		}
	}()

	monitorInterval := time.Duration(config.MonitorIntervalSeconds) * time.Second
	uptimeMonitor := monitor.NewUptime(monitorInterval)
	go uptimeMonitor.Start()
	defer uptimeMonitor.Stop()

	openFileMonitor := monitor.NewLinuxFD(monitorInterval, log)
	go openFileMonitor.Start()
	defer openFileMonitor.Stop()

	etcdAdapter := defaultStoreAdapterProvider(config)
	err = etcdAdapter.Connect()
	if err != nil {
		panic(fmt.Errorf("Unable to connect to ETCD: %s", err))
	}

	logAuthorizer := authorization.NewLogAccessAuthorizer(*disableAccessControl, config.ApiHost)

	uaaClient := uaa_client.NewUaaClient(config.UaaHost, config.UaaClient, config.UaaClientSecret)
	adminAuthorizer := authorization.NewAdminAccessAuthorizer(*disableAccessControl, &uaaClient)

	// TODO: The preferredProtocol of udp tells the finder to pull out the Doppler URLs from the legacy ETCD endpoint.
	// Eventually we'll have a separate websocket client pool
	finder := dopplerservice.NewFinder(etcdAdapter, int(config.DopplerPort), []string{"udp"}, "", log)
	finder.Start()
	// Draining the finder's events channel in order to not block the finder from handling etcd events.
	go func() {
		for {
			finder.Next()
		}
	}()

	var accessMiddleware, legacyAccessMiddleware func(middleware.HttpHandler) *middleware.AccessHandler
	if config.SecurityEventLog != "" {
		accessLog, err := os.OpenFile(config.SecurityEventLog, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
		if err != nil {
			panic(fmt.Errorf("Unable to open access log: %s", err))
		}
		defer func() {
			accessLog.Sync()
			accessLog.Close()
		}()
		accessLogger := accesslogger.New(accessLog, log)
		accessMiddleware = middleware.Access(accessLogger, ipAddress, config.OutgoingDropsondePort, log)
		legacyAccessMiddleware = middleware.Access(accessLogger, ipAddress, config.OutgoingPort, log)
	}

	dopplerCgc := channel_group_connector.NewChannelGroupConnector(finder, newDropsondeWebsocketListener, marshaller.DropsondeLogMessage, batcher, log)
	dopplerHandler := http.Handler(dopplerproxy.NewDopplerProxy(logAuthorizer, adminAuthorizer, dopplerCgc, dopplerproxy.TranslateFromDropsondePath, "doppler."+config.SystemDomain, log))
	if accessMiddleware != nil {
		dopplerHandler = accessMiddleware(dopplerHandler)
	}
	startOutgoingProxy(net.JoinHostPort(ipAddress, strconv.FormatUint(uint64(config.OutgoingDropsondePort), 10)), dopplerHandler)

	legacyCgc := channel_group_connector.NewChannelGroupConnector(finder, newLegacyWebsocketListener, marshaller.LoggregatorLogMessage, batcher, log)
	legacyHandler := http.Handler(dopplerproxy.NewDopplerProxy(logAuthorizer, adminAuthorizer, legacyCgc, dopplerproxy.TranslateFromLegacyPath, "loggregator."+config.SystemDomain, log))
	if legacyAccessMiddleware != nil {
		legacyHandler = legacyAccessMiddleware(legacyHandler)
	}
	startOutgoingProxy(net.JoinHostPort(ipAddress, strconv.FormatUint(uint64(config.OutgoingPort), 10)), legacyHandler)

	killChan := signalmanager.RegisterKillSignalChannel()
	dumpChan := signalmanager.RegisterGoRoutineDumpSignalChannel()

	for {
		select {
		case <-dumpChan:
			signalmanager.DumpGoRoutine()
		case <-killChan:
			log.Info("Shutting down")
			return
		}
	}
}