// Run the multiplexer. // Fetch messags from the consumers and pass them to all producers. func (plex multiplexer) run() { if len(plex.consumers) == 0 { Log.Error.Print("No consumers configured.") Log.SetWriter(os.Stdout) return // ### return, nothing to do ### } if len(plex.producers) == 0 { Log.Error.Print("No producers configured.") Log.SetWriter(os.Stdout) return // ### return, nothing to do ### } defer plex.shutdown() // Launch producers plex.state = multiplexerStateStartProducers for _, producer := range plex.producers { producer := producer Log.Debug.Print("Starting ", reflect.TypeOf(producer)) go shared.DontPanic(func() { producer.Produce(plex.producerWorker) }) } // If there are intenal log listeners switch to stream mode if core.StreamRegistry.IsStreamRegistered(core.LogInternalStreamID) { Log.Debug.Print("Binding log to ", reflect.TypeOf(plex.consumers[0])) Log.SetWriter(plex.consumers[0].(*core.LogConsumer)) } else { Log.SetWriter(os.Stdout) } // Launch consumers plex.state = multiplexerStateStartConsumers for _, consumer := range plex.consumers { consumer := consumer Log.Debug.Print("Starting ", reflect.TypeOf(consumer)) go shared.DontPanic(func() { consumer.Consume(plex.consumerWorker) }) } // Main loop - wait for exit // Apache is using SIG_USR1 in some cases to signal child processes. // This signal is not available on windows plex.signal = newSignalHandler() Log.Note.Print("We be nice to them, if they be nice to us. (startup)") measure := time.Now() timer := time.NewTicker(5 * time.Second) for { select { case <-timer.C: duration := time.Since(measure) measure = time.Now() // Sampling values messageCount, droppedCount, discardedCount, filteredCount, noRouteCount := core.GetAndResetMessageCount() messageSec := float64(messageCount) / duration.Seconds() shared.Metric.SetF(metricMessagesSec, messageSec) shared.Metric.SetF(metricDroppedSec, float64(droppedCount)/duration.Seconds()) shared.Metric.SetF(metricDiscardedSec, float64(discardedCount)/duration.Seconds()) shared.Metric.SetF(metricFilteredSec, float64(filteredCount)/duration.Seconds()) shared.Metric.SetF(metricNoRouteSec, float64(noRouteCount)/duration.Seconds()) shared.Metric.Add(metricMessages, int64(messageCount)) shared.Metric.Add(metricDropped, int64(droppedCount)) shared.Metric.Add(metricDiscarded, int64(discardedCount)) shared.Metric.Add(metricFiltered, int64(filteredCount)) shared.Metric.Add(metricNoRoute, int64(noRouteCount)) if plex.profile { Log.Note.Printf("Processed %.2f msg/sec", messageSec) } // Blocked producers numBlockedProducers := 0 for _, prod := range plex.producers { if prod.IsBlocked() { numBlockedProducers++ } } shared.Metric.SetI(metricBlockedProducers, numBlockedProducers) case sig := <-plex.signal: switch translateSignal(sig) { case signalExit: Log.Note.Print("Master betrayed us. Wicked. Tricksy, False. (signal)") plex.state = multiplexerStateShutdown return // ### return, exit requested ### case signalRoll: for _, consumer := range plex.consumers { consumer.Control() <- core.PluginControlRoll } for _, producer := range plex.producers { producer.Control() <- core.PluginControlRoll } default: } } } }
// Run the multiplexer. // Fetch messags from the consumers and pass them to all producers. func (plex multiplexer) run() { if len(plex.consumers) == 0 { Log.Error.Print("No consumers configured.") return // ### return, nothing to do ### } if len(plex.producers) == 0 { Log.Error.Print("No producers configured.") return // ### return, nothing to do ### } defer plex.shutdown() // Launch producers plex.state = multiplexerStateStartProducers for _, producer := range plex.producers { producer := producer go func() { defer shared.RecoverShutdown() producer.Produce(plex.producerWorker) }() } // If there are intenal log listeners switch to stream mode if core.StreamTypes.IsStreamRegistered(core.LogInternalStreamID) { Log.SetWriter(plex.consumers[0].(*core.LogConsumer)) } // Launch consumers plex.state = multiplexerStateStartConsumers for _, consumer := range plex.consumers { consumer := consumer go func() { defer shared.RecoverShutdown() consumer.Consume(plex.consumerWorker) }() } // Main loop - wait for exit // Apache is using SIG_USR1 in some cases to signal child processes. // This signal is not available on windows plex.signal = newSignalHandler() Log.Note.Print("We be nice to them, if they be nice to us. (startup)") measure := time.Now() timer := time.NewTicker(time.Duration(2) * time.Second) for { select { case <-timer.C: duration := time.Since(measure) measure = time.Now() // Sampling based values messageCount := core.GetAndResetMessageCount() value := float64(messageCount) / duration.Seconds() shared.Metric.SetF(metricMsgSec, value) shared.Metric.Add(metricMessages, int64(messageCount)) if plex.profile { Log.Note.Printf("Processed %.2f msg/sec", value) } // Global values timeSinceStart := time.Since(shared.ProcessStartTime) if totalMessages, err := shared.Metric.Get(metricMessages); err == nil { value = float64(totalMessages) / timeSinceStart.Seconds() shared.Metric.SetF(metricMsgSecAvg, value) } case sig := <-plex.signal: switch translateSignal(sig) { case signalExit: Log.Note.Print("Master betrayed us. Wicked. Tricksy, False. (signal)") plex.state = multiplexerStateShutdown return // ### return, exit requested ### case signalRoll: for _, consumer := range plex.consumers { consumer.Control() <- core.PluginControlRoll } for _, producer := range plex.producers { producer.Control() <- core.PluginControlRoll } default: } } } }