示例#1
0
func dumpFaultyPlugin(typeName string, pluginType reflect.Type) {
	Log.Error.Print("Failed to load plugin ", typeName, ": Does not qualify for consumer, producer or stream interface")

	consumerMatch, consumerMissing := shared.GetMissingMethods(pluginType, consumerInterface)
	producerMatch, producerMissing := shared.GetMissingMethods(pluginType, producerInterface)
	streamMatch, streamMissing := shared.GetMissingMethods(pluginType, streamInterface)

	if consumerMatch > producerMatch {
		if consumerMatch > streamMatch {
			Log.Error.Print("Plugin looks like a consumer:")
			for _, message := range consumerMissing {
				Log.Error.Print(message)
			}
		} else {
			Log.Error.Print("Plugin looks like a stream:")
			for _, message := range streamMissing {
				Log.Error.Print(message)
			}
		}
	} else if producerMatch > streamMatch {
		Log.Error.Print("Plugin looks like a producer:")
		for _, message := range producerMissing {
			Log.Error.Print(message)
		}
	} else {
		Log.Error.Print("Plugin looks like a stream:")
		for _, message := range streamMissing {
			Log.Error.Print(message)
		}
	}
}
示例#2
0
// Create a new multiplexer based on a given config file.
func newMultiplexer(conf *core.Config, profile bool) multiplexer {
	// Configure the multiplexer, create a byte pool and assign it to the log

	shared.Metric.New(metricMsgSec)
	shared.Metric.New(metricMsgSecAvg)
	shared.Metric.New(metricCons)
	shared.Metric.New(metricProds)
	shared.Metric.New(metricMessages)

	plex := multiplexer{
		consumers:      []core.Consumer{new(core.LogConsumer)},
		consumerWorker: new(sync.WaitGroup),
		producerWorker: new(sync.WaitGroup),
		profile:        profile,
		state:          multiplexerStateConfigure,
	}

	// Sort the plugins by interface type.

	var consumerConfig, producerConfig, streamConfig []core.PluginConfig
	consumerInterface := reflect.TypeOf((*core.Consumer)(nil)).Elem()
	producerInterface := reflect.TypeOf((*core.Producer)(nil)).Elem()
	streamInterface := reflect.TypeOf((*core.Stream)(nil)).Elem()

	for _, config := range conf.Plugins {
		if !config.Enable {
			continue // ### continue, disabled ###
		}

		pluginType := shared.RuntimeType.GetTypeOf(config.Typename)
		if pluginType == nil {
			Log.Error.Print("Failed to load plugin ", config.Typename, ": Type not found")
			continue // ### continue ###
		}

		validPlugin := false
		if pluginType.Implements(consumerInterface) {
			consumerConfig = append(consumerConfig, config)
			validPlugin = true
		}
		if pluginType.Implements(producerInterface) {
			producerConfig = append(producerConfig, config)
			validPlugin = true
		}
		if pluginType.Implements(streamInterface) {
			streamConfig = append(streamConfig, config)
			validPlugin = true
		}

		if !validPlugin {
			Log.Error.Print("Failed to load plugin ", config.Typename, ": Does not qualify for consumer, producer or stream interface")

			consumerMatch, consumerMissing := shared.GetMissingMethods(pluginType, consumerInterface)
			producerMatch, producerMissing := shared.GetMissingMethods(pluginType, producerInterface)
			streamMatch, streamMissing := shared.GetMissingMethods(pluginType, streamInterface)

			if consumerMatch > producerMatch {
				if consumerMatch > streamMatch {
					Log.Error.Print("Plugin looks like a consumer:")
					for _, message := range consumerMissing {
						Log.Error.Print(message)
					}
				} else {
					Log.Error.Print("Plugin looks like a stream:")
					for _, message := range streamMissing {
						Log.Error.Print(message)
					}
				}
			} else if producerMatch > streamMatch {
				Log.Error.Print("Plugin looks like a producer:")
				for _, message := range producerMissing {
					Log.Error.Print(message)
				}
			} else {
				Log.Error.Print("Plugin looks like a stream:")
				for _, message := range streamMissing {
					Log.Error.Print(message)
				}
			}
		}
	}

	// Initialize the plugins in the order of stream, producer, consumer to
	// match the order of reference between the different types.

	for _, config := range streamConfig {
		for _, streamName := range config.Stream {
			plugin, err := core.NewPlugin(config)
			if err != nil {
				Log.Error.Print("Failed to configure stream plugin ", config.Typename, ": ", err)
				continue // ### continue ###
			}
			core.StreamTypes.Register(plugin.(core.Stream), core.GetStreamID(streamName))
		}
	}

	// All producers are added to the wildcard stream so that consumers can send
	// to all producers if required. The wildcard producer list is required
	// to add producers listening to all streams to all streams that are used.

	wildcardStream := core.StreamTypes.GetStreamOrFallback(core.WildcardStreamID)

	for _, config := range producerConfig {
		for i := 0; i < config.Instances; i++ {
			plugin, err := core.NewPlugin(config)
			if err != nil {
				Log.Error.Print("Failed to configure producer plugin ", config.Typename, ": ", err)
				continue // ### continue ###
			}

			producer, _ := plugin.(core.Producer)
			streams := producer.Streams()

			if len(streams) == 0 {
				Log.Error.Print("Producer plugin ", config.Typename, " has no streams set")
				continue // ### continue ###
			}

			for _, streamID := range streams {
				if streamID == core.WildcardStreamID {
					core.StreamTypes.RegisterWildcardProducer(producer)
				} else {
					stream := core.StreamTypes.GetStreamOrFallback(streamID)
					stream.AddProducer(producer)
				}
			}

			// Do not add internal streams to wildcard stream

			for _, streamID := range streams {
				if streamID != core.LogInternalStreamID && streamID != core.DroppedStreamID {
					wildcardStream.AddProducer(producer)
					break
				}
			}

			plex.producers = append(plex.producers, producer)
			shared.Metric.Inc(metricProds)
		}
	}

	// Consumers are registered last so that the stream reference list can be
	// built. This eliminates lookups when sending to specific streams.

	logConsumer, _ := plex.consumers[0].(*core.LogConsumer)
	logConsumer.Configure(core.NewPluginConfig("core.LogConsumer"))

	for _, config := range consumerConfig {
		for i := 0; i < config.Instances; i++ {
			plugin, err := core.NewPlugin(config)
			if err != nil {
				Log.Error.Print("Failed to configure consumer plugin ", config.Typename, ": ", err)
				continue // ### continue ###
			}

			consumer, _ := plugin.(core.Consumer)
			plex.consumers = append(plex.consumers, consumer)
			shared.Metric.Inc(metricCons)
		}
	}

	// As consumers might create new fallback streams this is the first position
	// where we can add the wildcard producers to all streams. No new streams
	// created beyond this point must use StreamRegistry.AddWildcardProducersToStream.

	core.StreamTypes.ForEachStream(
		func(streamID core.MessageStreamID, stream core.Stream) {
			switch streamID {
			case core.LogInternalStreamID, core.WildcardStreamID, core.DroppedStreamID:
				// Internal streams are excluded for wildcard listeners
			default:
				core.StreamTypes.AddWildcardProducersToStream(stream)
			}
		})

	return plex
}