예제 #1
0
func TestThatItWorksWithTwoLoggregators(t *testing.T) {
	listener1, dataChan1 := agentlistener.NewAgentListener("localhost:9998", logger)
	go listener1.Start()

	listener2, dataChan2 := agentlistener.NewAgentListener("localhost:9997", logger)
	go listener2.Start()

	loggregatorServers := []string{"localhost:9998", "localhost:9997"}
	hasher := hasher.NewHasher(loggregatorServers)
	rt, err := NewRouter("localhost:3457", hasher, newCfConfig(), logger)
	assert.NoError(t, err)

	go rt.Start(logger)
	time.Sleep(50 * time.Millisecond)

	logEmitter, _ := emitter.NewEmitter("localhost:3457", "ROUTER", "42", "secret", logger)
	logEmitter.Emit("2", "My message")

	receivedData := <-dataChan1
	receivedEnvelope := &logmessage.LogEnvelope{}
	proto.Unmarshal(receivedData, receivedEnvelope)

	assert.Equal(t, receivedEnvelope.GetLogMessage().GetAppId(), "2")
	assert.Equal(t, string(receivedEnvelope.GetLogMessage().GetMessage()), "My message")

	logEmitter.Emit("1", "Another message")

	receivedData = <-dataChan2
	receivedEnvelope = &logmessage.LogEnvelope{}
	proto.Unmarshal(receivedData, receivedEnvelope)

	assert.Equal(t, receivedEnvelope.GetLogMessage().GetAppId(), "1")
	assert.Equal(t, string(receivedEnvelope.GetLogMessage().GetMessage()), "Another message")
}
예제 #2
0
func NewRouter(host string, h *hasher, config cfcomponent.Config, logger *gosteno.Logger) (r *router, err error) {
	var instrumentables []instrumentation.Instrumentable
	loggregatorClients := make(map[string]loggregatorclient.LoggregatorClient, len(h.loggregatorServers()))

	for _, server := range h.loggregatorServers() {
		client := loggregatorclient.NewLoggregatorClient(server, logger, loggregatorclient.DefaultBufferSize)
		loggregatorClients[server] = client
		instrumentables = append(instrumentables, client)
	}

	al := agentlistener.NewAgentListener(host, logger)
	instrumentables = append(instrumentables, al)

	cfc, err := cfcomponent.NewComponent(
		0,
		"LoggregatorRouter",
		0,
		&LoggregatorRouterMonitor{},
		config.VarzPort,
		[]string{config.VarzUser, config.VarzPass},
		instrumentables,
	)

	if err != nil {
		return
	}

	r = &router{Component: cfc, h: h, lcs: loggregatorClients, agentListener: al, host: host}

	return
}
예제 #3
0
func TestThatItIgnoresBadMessages(t *testing.T) {
	listener, dataChannel := agentlistener.NewAgentListener("localhost:9996", logger)
	go listener.Start()

	loggregatorServers := []string{"localhost:9996"}
	hasher := hasher.NewHasher(loggregatorServers)
	r, err := NewRouter("localhost:3455", hasher, newCfConfig(), logger)
	assert.NoError(t, err)

	go r.Start(logger)
	time.Sleep(50 * time.Millisecond)

	lc := loggregatorclient.NewLoggregatorClient("localhost:3455", logger, loggregatorclient.DefaultBufferSize)
	lc.Send([]byte("This is poorly formatted"))

	logEmitter, _ := emitter.NewEmitter("localhost:3455", "ROUTER", "42", "secret", logger)
	logEmitter.Emit("my_awesome_app", "Hello World")

	received := <-dataChannel
	receivedEnvelope := &logmessage.LogEnvelope{}
	proto.Unmarshal(received, receivedEnvelope)

	assert.Equal(t, receivedEnvelope.GetLogMessage().GetAppId(), "my_awesome_app")
	assert.Equal(t, string(receivedEnvelope.GetLogMessage().GetMessage()), "Hello World")
}
예제 #4
0
func New(host string, config *Config, logger *gosteno.Logger) *Loggregator {
	cfcomponent.Logger = logger
	keepAliveInterval := 30 * time.Second
	listener, incomingLogChan := agentlistener.NewAgentListener(fmt.Sprintf("%s:%d", host, config.IncomingPort), logger)
	unmarshaller, messageChan := unmarshaller.NewLogMessageUnmarshaller(config.SharedSecret, incomingLogChan)
	blacklist := blacklist.New(config.BlackListIps)
	sinkManager, appStoreInputChan := sinkmanager.NewSinkManager(config.MaxRetainedLogMessages, config.SkipCertVerify, blacklist, logger)
	workerPool := workerpool.NewWorkerPool(config.EtcdMaxConcurrentRequests)

	storeAdapter := etcdstoreadapter.NewETCDStoreAdapter(config.EtcdUrls, workerPool)
	appStoreCache := cache.NewAppServiceCache()
	appStoreWatcher, newAppServiceChan, deletedAppServiceChan := store.NewAppServiceStoreWatcher(storeAdapter, appStoreCache)
	appStore := store.NewAppServiceStore(storeAdapter, appStoreWatcher)
	return &Loggregator{
		Logger:                logger,
		listener:              listener,
		unmarshaller:          unmarshaller,
		sinkManager:           sinkManager,
		messageChan:           messageChan,
		appStoreInputChan:     appStoreInputChan,
		appStore:              appStore,
		messageRouter:         sinkserver.NewMessageRouter(sinkManager, logger),
		websocketServer:       websocketserver.New(fmt.Sprintf("%s:%d", host, config.OutgoingPort), sinkManager, keepAliveInterval, config.WSMessageBufferSize, logger),
		newAppServiceChan:     newAppServiceChan,
		deletedAppServiceChan: deletedAppServiceChan,
		appStoreWatcher:       appStoreWatcher,
		storeAdapter:          storeAdapter,
	}
}
예제 #5
0
func NewRouter(host string, hasher *hasher.Hasher, config cfcomponent.Config, logger *gosteno.Logger) (r *Router, err error) {
	var instrumentables []instrumentation.Instrumentable
	servers := hasher.LoggregatorServers()
	loggregatorClients := make(map[string]loggregatorclient.LoggregatorClient, len(servers))

	for _, server := range servers {
		client := loggregatorclient.NewLoggregatorClient(server, logger, loggregatorclient.DefaultBufferSize)
		loggregatorClients[server] = client
		instrumentables = append(instrumentables, client)
	}

	agentListener, dataChan := agentlistener.NewAgentListener(host, logger)
	instrumentables = append(instrumentables, agentListener)

	cfc, err := cfcomponent.NewComponent(
		logger,
		"LoggregatorTrafficcontroller",
		0,
		&TrafficControllerMonitor{},
		config.VarzPort,
		[]string{config.VarzUser, config.VarzPass},
		instrumentables,
	)

	if err != nil {
		return
	}

	r = &Router{Component: cfc, hasher: hasher, loggregatorClients: loggregatorClients, agentListener: agentListener, dataChan: dataChan, host: host}

	return
}
예제 #6
0
func init() {
	logger := gosteno.NewLogger("TestLogger")

	listener := agentlistener.NewAgentListener("localhost:3456", logger)
	dataChannel := listener.Start()

	messageRouter := sinkserver.NewMessageRouter(10, false, nil, logger)
	go messageRouter.Start()
	httpServer := sinkserver.NewHttpServer(messageRouter, 30*time.Second, testhelpers.UnmarshallerMaker("secret"), 100, logger)
	go httpServer.Start(dataChannel, "localhost:8081")

	time.Sleep(50 * time.Millisecond)
}
예제 #7
0
func init() {
	logger := gosteno.NewLogger("TestLogger")

	listener := agentlistener.NewAgentListener("localhost:3456", logger)
	incomingLogChan := listener.Start()

	sinkManager := sinkserver.NewSinkManager(1024, false, nil, logger)
	go sinkManager.Start()

	messageRouter := sinkserver.NewMessageRouter(incomingLogChan, testhelpers.UnmarshallerMaker("secret"), sinkManager, 2048, logger)
	go messageRouter.Start()

	websocketServer := sinkserver.NewWebsocketServer("localhost:8083", sinkManager, 30*time.Second, 100, logger)
	go websocketServer.Start()

	time.Sleep(50 * time.Millisecond)
}
예제 #8
0
func main() {
	logger := loggertesthelper.Logger()

	flag.Parse()

	listener := agentlistener.NewAgentListener(*host, logger)
	dataChannel := listener.Start()

	for data := range dataChannel {
		if logMessage, err := extractLogMessage(data); err == nil {
			fmt.Printf("MESSAGE: %+v\n", logMessage)
		} else if logEnvelope, err := extractLogEnvelope(data); err == nil {
			validEnvelope := logEnvelope.VerifySignature(*secret)
			fmt.Printf("ENVELOPE (valid: %t): %+v\n", validEnvelope, logEnvelope)
		} else {
			fmt.Println("ERROR parsing protobuffer")
		}
	}
}
예제 #9
0
func New(host string, config *config.Config, logger *gosteno.Logger, storeAdapter storeadapter.StoreAdapter, messageDrainBufferSize uint, dropsondeOrigin string, dialTimeout time.Duration) *Doppler {
	cfcomponent.Logger = logger
	keepAliveInterval := 30 * time.Second

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

	dropsondeListener, dropsondeBytesChan := agentlistener.NewAgentListener(fmt.Sprintf("%s:%d", host, config.DropsondeIncomingMessagesPort), logger, "dropsondeListener")

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

	unmarshallerCollection := dropsonde_unmarshaller.NewDropsondeUnmarshallerCollection(logger, config.UnmarshallerCount)

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

	return &Doppler{
		Logger:                          logger,
		dropsondeListener:               dropsondeListener,
		sinkManager:                     sinkManager,
		messageRouter:                   sinkserver.NewMessageRouter(sinkManager, logger),
		websocketServer:                 websocketserver.New(fmt.Sprintf("%s:%d", host, config.OutgoingPort), sinkManager, keepAliveInterval, config.MessageDrainBufferSize, dropsondeOrigin, logger),
		newAppServiceChan:               newAppServiceChan,
		deletedAppServiceChan:           deletedAppServiceChan,
		appStoreWatcher:                 appStoreWatcher,
		storeAdapter:                    storeAdapter,
		dropsondeBytesChan:              dropsondeBytesChan,
		dropsondeUnmarshallerCollection: unmarshallerCollection,
		envelopeChan:                    make(chan *events.Envelope),
		wrappedEnvelopeChan:             make(chan *events.Envelope),
		signatureVerifier:               signatureVerifier,
		dropsondeVerifiedBytesChan:      make(chan []byte),
		uptimeMonitor:                   monitor.NewUptimeMonitor(time.Duration(config.MonitorIntervalSeconds) * time.Second),
	}
}
예제 #10
0
func TestEndtoEndMessage(t *testing.T) {
	logger := gosteno.NewLogger("TestLogger")
	listener := agentlistener.NewAgentListener("localhost:3456", logger)
	dataChannel := listener.Start()
	sinkServer := sinkserver.NewSinkServer(messagestore.NewMessageStore(10), logger, testhelpers.SuccessfulAuthorizer, 30*time.Second)
	go sinkServer.Start(dataChannel, "localhost:8081")
	time.Sleep(1 * time.Millisecond)

	receivedChan := make(chan []byte)
	ws, _, _ := testhelpers.AddWSSink(t, receivedChan, "8081", "/tail/?app=myApp", testhelpers.VALID_SPACE_AUTHENTICATION_TOKEN)
	defer ws.Close()
	time.Sleep(50 * time.Millisecond)

	connection, err := net.Dial("udp", "localhost:3456")

	expectedMessageString := "Some Data"
	expectedMessage := testhelpers.MarshalledLogMessage(t, expectedMessageString, "myApp")

	_, err = connection.Write(expectedMessage)
	assert.NoError(t, err)

	testhelpers.AssertProtoBufferMessageEquals(t, expectedMessageString, <-receivedChan)
}
예제 #11
0
func TestThatItWorksWithOneLoggregator(t *testing.T) {
	listener, dataChannel := agentlistener.NewAgentListener("localhost:9999", logger)
	go listener.Start()

	loggregatorServers := []string{"localhost:9999"}
	hasher := hasher.NewHasher(loggregatorServers)
	r, err := NewRouter("localhost:3456", hasher, newCfConfig(), logger)
	assert.NoError(t, err)

	go r.Start(logger)
	time.Sleep(50 * time.Millisecond)

	logEmitter, _ := emitter.NewEmitter("localhost:3456", "ROUTER", "42", "secret", logger)
	logEmitter.Emit("my_awesome_app", "Hello World")

	received := <-dataChannel

	receivedEnvelope := &logmessage.LogEnvelope{}
	proto.Unmarshal(received, receivedEnvelope)

	assert.Equal(t, receivedEnvelope.GetLogMessage().GetAppId(), "my_awesome_app")
	assert.Equal(t, string(receivedEnvelope.GetLogMessage().GetMessage()), "Hello World")
}
	"github.com/gogo/protobuf/proto"

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

var _ = Describe("AgentListener", func() {
	var listener agentlistener.AgentListener
	var dataChannel <-chan []byte
	var listenerStopped chan struct{}

	BeforeEach(func() {
		listenerStopped = make(chan struct{})
		loggertesthelper.TestLoggerSink.Clear()

		listener, dataChannel = agentlistener.NewAgentListener("127.0.0.1:3456", loggertesthelper.Logger(), "agentListener")
		go func() {
			listener.Start()
			close(listenerStopped)
		}()

		Eventually(loggertesthelper.TestLoggerSink.LogContents).Should(ContainSubstring("Listening on port 127.0.0.1:3456"))
	})

	AfterEach(func() {
		listener.Stop()
		<-listenerStopped
	})

	Context("with a listner running", func() {
		It("listens to the socket and forwards log lines", func(done Done) {
예제 #13
0
func main() {
	seed := time.Now().UnixNano()
	rand.Seed(seed)

	flag.Parse()

	if *version {
		fmt.Printf("version: %s\ngitSha: %s\nsourceUrl: https://github.com/cloudfoundry/loggregator/tree/%s\n\n",
			versionNumber, gitSha, gitSha)
		return
	}

	runtime.GOMAXPROCS(runtime.NumCPU())

	config, logger := parseConfig(logLevel, configFile, logFilePath)
	err := config.validate(logger)
	if err != nil {
		panic(err)
	}

	agentListener := agentlistener.NewAgentListener(fmt.Sprintf("0.0.0.0:%d", config.IncomingPort), logger)
	incomingLogChan := agentListener.Start()

	sinkManager := sinkserver.NewSinkManager(config.MaxRetainedLogMessages, config.SkipCertVerify, config.BlackListIps, logger)
	go sinkManager.Start()

	unmarshaller := func(data []byte) (*logmessage.Message, error) {
		return logmessage.ParseEnvelope(data, config.SharedSecret)
	}

	messageChannelLength := 2048
	messageRouter := sinkserver.NewMessageRouter(incomingLogChan, unmarshaller, sinkManager, messageChannelLength, logger)

	apiEndpoint := fmt.Sprintf("0.0.0.0:%d", config.OutgoingPort)
	keepAliveInterval := 30 * time.Second
	websocketServer := sinkserver.NewWebsocketServer(apiEndpoint, sinkManager, keepAliveInterval, config.WSMessageBufferSize, logger)

	cfc, err := cfcomponent.NewComponent(
		logger,
		"LoggregatorServer",
		config.Index,
		&LoggregatorServerHealthMonitor{},
		config.VarzPort,
		[]string{config.VarzUser, config.VarzPass},
		[]instrumentation.Instrumentable{agentListener, sinkManager, messageRouter},
	)

	if err != nil {
		panic(err)
	}

	cr := collectorregistrar.NewCollectorRegistrar(config.MbusClient, logger)
	err = cr.RegisterWithCollector(cfc)
	if err != nil {
		logger.Warnf("Unable to register with collector. Err: %v.", err)
	}

	go func() {
		err := cfc.StartMonitoringEndpoints()
		if err != nil {
			panic(err)
		}
	}()

	go messageRouter.Start()
	go websocketServer.Start()

	killChan := make(chan os.Signal)
	signal.Notify(killChan, os.Kill)

	for {
		select {
		case <-cfcomponent.RegisterGoRoutineDumpSignalChannel():
			cfcomponent.DumpGoRoutine()
		case <-killChan:
			break
		}
	}
}
예제 #14
0
func main() {
	seed := time.Now().UnixNano()
	rand.Seed(seed)

	flag.Parse()

	if *version {
		fmt.Printf("version: %s\ngitSha: %s\nsourceUrl: https://github.com/cloudfoundry/loggregator/tree/%s\n\n",
			versionNumber, gitSha, gitSha)
		return
	}

	runtime.GOMAXPROCS(runtime.NumCPU())

	config := &Config{IncomingPort: 3456, OutgoingPort: 8080}
	err := cfcomponent.ReadConfigInto(config, *configFile)
	if err != nil {
		panic(err)
	}

	logger := cfcomponent.NewLogger(*logLevel, *logFilePath, "loggregator", config.Config)
	logger.Info("Startup: Setting up the loggregator server")

	err = config.validate(logger)
	if err != nil {
		panic(err)
	}

	listener := agentlistener.NewAgentListener(fmt.Sprintf("0.0.0.0:%d", config.IncomingPort), logger)
	incomingData := listener.Start()

	messageRouter := sinkserver.NewMessageRouter(config.MaxRetainedLogMessages, logger)

	unmarshaller := func(data []byte) (*logmessage.Message, error) {
		return logmessage.ParseEnvelope(data, config.SharedSecret)
	}

	httpServer := sinkserver.NewHttpServer(messageRouter, 30*time.Second, unmarshaller, logger)

	cfc, err := cfcomponent.NewComponent(
		logger,
		"LoggregatorServer",
		config.Index,
		&LoggregatorServerHealthMonitor{},
		config.VarzPort,
		[]string{config.VarzUser, config.VarzPass},
		[]instrumentation.Instrumentable{listener, messageRouter},
	)

	if err != nil {
		panic(err)
	}

	cr := collectorregistrar.NewCollectorRegistrar(config.MbusClient, logger)
	err = cr.RegisterWithCollector(cfc)
	if err != nil {
		logger.Warnf("Unable to register with collector. Err: %v.", err)
	}

	go func() {
		err := cfc.StartMonitoringEndpoints()
		if err != nil {
			panic(err)
		}
	}()

	go messageRouter.Start()
	go httpServer.Start(incomingData, fmt.Sprintf("0.0.0.0:%d", config.OutgoingPort))

	killChan := make(chan os.Signal)
	signal.Notify(killChan, os.Kill)

	for {
		select {
		case <-cfcomponent.RegisterGoRoutineDumpSignalChannel():
			cfcomponent.DumpGoRoutine()
		case <-killChan:
			break
		}
	}
}
예제 #15
0
func main() {
	flag.Parse()

	if *version {
		fmt.Printf("\n\nversion: %s\ngitSha: %s\n\n", versionNumber, gitSha)
		return
	}

	runtime.GOMAXPROCS(runtime.NumCPU())

	logger := cfcomponent.NewLogger(*logLevel, *logFilePath, "loggregator")

	config := &Config{SourcePort: 3456, WebPort: 8080, UaaVerificationKeyFile: *uaaVerificationKeyFile}
	err := cfcomponent.ReadConfigInto(config, *configFile)
	if err != nil {
		panic(err)
	}
	err = config.validate(logger)
	if err != nil {
		panic(err)
	}

	listener := agentlistener.NewAgentListener(fmt.Sprintf("0.0.0.0:%d", config.SourcePort), logger)
	incomingData := listener.Start()

	authorizer := authorization.NewLogAccessAuthorizer(config.decoder, config.ApiHost)
	sinkServer := sinkserver.NewSinkServer(
		messagestore.NewMessageStore(config.MaxRetainedLogMessages),
		logger,
		authorizer,
		30*time.Second,
	)

	cfc, err := cfcomponent.NewComponent(
		config.WebPort,
		"LoggregatorServer",
		config.Index,
		&LoggregatorServerHealthMonitor{},
		config.VarzPort,
		[]string{config.VarzUser, config.VarzPass},
		[]instrumentation.Instrumentable{listener, sinkServer},
	)

	if err != nil {
		panic(err)
	}

	rr := routerregistrar.NewRouterRegistrar(config.MbusClient, logger)

	uri := servernamer.ServerName(
		net.JoinHostPort(cfc.IpAddress, strconv.Itoa(int(config.SourcePort))),
		"loggregator."+config.SystemDomain)
	err = rr.RegisterWithRouter(cfc.IpAddress, config.WebPort, []string{uri})
	if err != nil {
		logger.Fatalf("Did not get response from router when greeting. Using default keep-alive for now. Err: %v.", err)
	}

	cr := collectorregistrar.NewCollectorRegistrar(config.MbusClient, logger)
	err = cr.RegisterWithCollector(cfc)
	if err != nil {
		logger.Warnf("Unable to register with collector. Err: %v.", err)
	}

	go func() {
		err := cfc.StartMonitoringEndpoints()
		if err != nil {
			panic(err)
		}
	}()

	go sinkServer.Start(incomingData, fmt.Sprintf("0.0.0.0:%d", config.WebPort))

	killChan := make(chan os.Signal)
	signal.Notify(killChan, os.Kill)

	for {
		select {
		case <-cfcomponent.RegisterGoRoutineDumpSignalChannel():
			cfcomponent.DumpGoRoutine()
		case <-killChan:
			rr.UnregisterFromRouter(cfc.IpAddress, cfc.WebPort, []string{uri})
			break
		}
	}
}
예제 #16
0
)

var _ = Describe("AgentListener", func() {
	var listener agentlistener.AgentListener
	var dataChannel <-chan []byte
	var listenerStopped chan struct{}
	var agentAddress string

	BeforeEach(func() {
		listenerStopped = make(chan struct{})
		loggertesthelper.TestLoggerSink.Clear()

		port := 3456 + config.GinkgoConfig.ParallelNode
		agentAddress = net.JoinHostPort("127.0.0.1", strconv.Itoa(port))

		listener, dataChannel = agentlistener.NewAgentListener(agentAddress, loggertesthelper.Logger(), "agentListener")
		go func() {
			listener.Start()
			close(listenerStopped)
		}()

		Eventually(loggertesthelper.TestLoggerSink.LogContents).Should(ContainSubstring("Listening on port " + agentAddress))
	})

	AfterEach(func() {
		listener.Stop()
		<-listenerStopped
	})

	Context("with a listner running", func() {
		It("listens to the socket and forwards log lines", func(done Done) {