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") }
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 }
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") }
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, } }
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 }
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) }
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) }
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") } } }
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), } }
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) }
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) {
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 } } }
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 } } }
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 } } }
) 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) {