afedulov commented on a change in pull request #11195: [FLINK-16222][runtime]
Use plugins mechanism for initializing MetricReporters
URL: https://github.com/apache/flink/pull/11195#discussion_r395365114
##########
File path:
flink-runtime/src/main/java/org/apache/flink/runtime/metrics/ReporterSetup.java
##########
@@ -210,17 +213,31 @@ private static ReporterSetup createReporterSetup(String
reporterName, MetricConf
return namedOrderedReporters;
}
- private static Map<String, MetricReporterFactory>
loadReporterFactories() {
- final ServiceLoader<MetricReporterFactory> serviceLoader =
ServiceLoader.load(MetricReporterFactory.class);
-
+ private static Map<String, MetricReporterFactory>
loadAvailableReporterFactories(PluginManager pluginManager) {
final Map<String, MetricReporterFactory> reporterFactories =
new HashMap<>(2);
- final Iterator<MetricReporterFactory> factoryIterator =
serviceLoader.iterator();
+ final Iterator<MetricReporterFactory> factoryIterator =
getAllReporterFactories(pluginManager);
+ LOG.info("Prepare reporter factories (from both SPIs and
Plugins):");
// do not use streams or for-each loops here because they do
not allow catching individual ServiceConfigurationErrors
// such an error might be caused if the META-INF/services
contains an entry to a non-existing factory class
while (factoryIterator.hasNext()) {
try {
MetricReporterFactory factory =
factoryIterator.next();
-
reporterFactories.put(factory.getClass().getName(), factory);
+ String factoryClassName =
factory.getClass().getName();
+ MetricReporterFactory existingFactory =
reporterFactories.get(factoryClassName);
+ if (existingFactory == null){
+ reporterFactories.put(factoryClassName,
factory);
+ LOG.info("Found reporter factory {} at
{} ",
+ factoryClassName,
+ new
File(factory.getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getCanonicalPath());
+ } else {
+ //TODO: use path information below,
when Plugin Classloader stops always prioritizing factories from /lib
+// String jarPath1 = new
File(existingFactory.getClass().getProtectionDomain().getCodeSource().getLocation()
+// .toURI()).getCanonicalPath();
+// String jarPath2 = new
File(factory.getClass().getProtectionDomain().getCodeSource().getLocation()
+// .toURI()).getCanonicalPath();
+// LOG.warn("Multiple implementations of
the same reporter were found: \n {} and \n{}", jarPath1, jarPath2);
+ LOG.warn("Multiple implementations of
the same reporter were found in 'lib' and/or 'plugins' directories for {}. It
is recommended to remove redundant reporter JARs to resolve used versions'
ambiguity.", factoryClassName);
Review comment:
I thing the problem is that we have too many variants to describe with a
single coordinating conjunction like "or" (plus "or" can unfortunately be both
inclusive and exclusive). Cases:
(xx) _ ()
() _ (xx)
(x) _ (x)
(xx) _ (xx)
Alternatives like "a or b or both" also do not work, because in this
particular case they can be easily be interpreted as if the "(x) _ (x)" case is
not an issue (because of "Multiple" in the beginning). Seems to me like the
best case to indicate this ambiguity is is to use "and/or" so that people will
be aware for what kinds of problem potentially to look for.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services