本文主要研究一下artemis的ActiveMQMetricsPlugin

ActiveMQMetricsPlugin

activemq-artemis-2.11.0/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/metrics/ActiveMQMetricsPlugin.java

public interface ActiveMQMetricsPlugin extends Serializable {

   ActiveMQMetricsPlugin init(Map<String, String> options);

   MeterRegistry getRegistry();
}
  • ActiveMQMetricsPlugin继承了Serializable,它定义了init方法以及getRegistry方法

SimpleMetricsPlugin

activemq-artemis-2.11.0/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/metrics/plugins/SimpleMetricsPlugin.java

public class SimpleMetricsPlugin implements ActiveMQMetricsPlugin {

   private transient MeterRegistry meterRegistry;

   private Map<String, String> options;

   @Override
   public ActiveMQMetricsPlugin init(Map<String, String> options) {
      this.meterRegistry = new SimpleMeterRegistry();
      this.options = options;
      return this;
   }

   @Override
   public MeterRegistry getRegistry() {
      return meterRegistry;
   }

   public Map<String, String> getOptions() {
      return options;
   }
}
  • SimpleMetricsPlugin实现了ActiveMQMetricsPlugin接口,其init方法创建了SimpleMeterRegistry

LoggingMetricsPlugin

activemq-artemis-2.11.0/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/metrics/plugins/LoggingMetricsPlugin.java

public class LoggingMetricsPlugin implements ActiveMQMetricsPlugin {

   private transient MeterRegistry meterRegistry;

   @Override
   public ActiveMQMetricsPlugin init(Map<String, String> options) {
      this.meterRegistry = new LoggingMeterRegistry();
      return this;
   }

   @Override
   public MeterRegistry getRegistry() {
      return meterRegistry;
   }
}
  • LoggingMetricsPlugin实现了ActiveMQMetricsPlugin接口,其init方法创建了LoggingMeterRegistry

FileConfigurationParser

activemq-artemis-2.11.0/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java

public final class FileConfigurationParser extends XMLConfigurationUtil {

   //......

   private ActiveMQMetricsPlugin parseMetricsPlugin(final Node item, final Configuration config) {
      final String clazz = item.getAttributes().getNamedItem("class-name").getNodeValue();

      Map<String, String> properties = getMapOfChildPropertyElements(item);

      ActiveMQMetricsPlugin metricsPlugin = AccessController.doPrivileged(new PrivilegedAction<ActiveMQMetricsPlugin>() {
         @Override
         public ActiveMQMetricsPlugin run() {
            return (ActiveMQMetricsPlugin) ClassloadingUtil.newInstanceFromClassLoader(FileConfigurationParser.class, clazz);
         }
      });

      ActiveMQServerLogger.LOGGER.initializingMetricsPlugin(clazz, properties.toString());
      config.setMetricsPlugin(metricsPlugin.init(properties));

      return metricsPlugin;
   }

   //......
}
  • FileConfigurationParser的parseMetricsPlugin方法会获取配置的clazz及properties,然后实例化metricsPlugin并执行metricsPlugin.init(properties)

MetricsManager

activemq-artemis-2.11.0/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/metrics/MetricsManager.java

public class MetricsManager {

   private final String brokerName;

   private final MeterRegistry meterRegistry;

   private final Map<String, List<Meter>> meters = new ConcurrentHashMap<>();

   public MetricsManager(String brokerName, ActiveMQMetricsPlugin metricsPlugin) {
      this.brokerName = brokerName;
      meterRegistry = metricsPlugin.getRegistry();
      Metrics.globalRegistry.add(meterRegistry);
      new JvmMemoryMetrics().bindTo(meterRegistry);
   }

   public MeterRegistry getMeterRegistry() {
      return meterRegistry;
   }

   @FunctionalInterface
   public interface MetricGaugeBuilder {

      void register(String metricName, Object state, ToDoubleFunction f, String description);
   }

   public void registerQueueGauge(String address, String queue, Consumer<MetricGaugeBuilder> builder) {
      final MeterRegistry meterRegistry = this.meterRegistry;
      if (meterRegistry == null) {
         return;
      }
      final List<Gauge.Builder> newMeters = new ArrayList<>();
      builder.accept((metricName, state, f, description) -> {
         Gauge.Builder meter = Gauge
            .builder("artemis." + metricName, state, f)
            .tag("broker", brokerName)
            .tag("address", address)
            .tag("queue", queue)
            .description(description);
         newMeters.add(meter);
      });
      final String resource = ResourceNames.QUEUE + queue;
      this.meters.compute(resource, (s, meters) -> {
         //the old meters are ignored on purpose
         meters = new ArrayList<>(newMeters.size());
         for (Gauge.Builder gauge : newMeters) {
            meters.add(gauge.register(meterRegistry));
         }
         return meters;
      });
   }

   public void registerAddressGauge(String address, Consumer<MetricGaugeBuilder> builder) {
      final MeterRegistry meterRegistry = this.meterRegistry;
      if (meterRegistry == null) {
         return;
      }
      final List<Gauge.Builder> newMeters = new ArrayList<>();
      builder.accept((metricName, state, f, description) -> {
         Gauge.Builder meter = Gauge
            .builder("artemis." + metricName, state, f)
            .tag("broker", brokerName)
            .tag("address", address)
            .description(description);
         newMeters.add(meter);
      });
      final String resource = ResourceNames.ADDRESS + address;
      this.meters.compute(resource, (s, meters) -> {
         //the old meters are ignored on purpose
         meters = new ArrayList<>(newMeters.size());
         for (Gauge.Builder gauge : newMeters) {
            meters.add(gauge.register(meterRegistry));
         }
         return meters;
      });
   }

   public void registerBrokerGauge(Consumer<MetricGaugeBuilder> builder) {
      final MeterRegistry meterRegistry = this.meterRegistry;
      if (meterRegistry == null) {
         return;
      }
      final List<Gauge.Builder> newMeters = new ArrayList<>();
      builder.accept((metricName, state, f, description) -> {
         Gauge.Builder meter = Gauge
            .builder("artemis." + metricName, state, f)
            .tag("broker", brokerName)
            .description(description);
         newMeters.add(meter);
      });
      final String resource = ResourceNames.BROKER + "." + brokerName;
      this.meters.compute(resource, (s, meters) -> {
         //the old meters are ignored on purpose
         meters = new ArrayList<>(newMeters.size());
         for (Gauge.Builder gauge : newMeters) {
            meters.add(gauge.register(meterRegistry));
         }
         return meters;
      });
   }

   public void remove(String component) {
      meters.computeIfPresent(component, (s, meters) -> {
         if (meters == null) {
            return null;
         }
         for (Meter meter : meters) {
            Meter removed = meterRegistry.remove(meter);
            if (ActiveMQServerLogger.LOGGER.isDebugEnabled()) {
               ActiveMQServerLogger.LOGGER.debug("Removed meter: " + removed.getId());
            }
         }
         return null;
      });
   }
}
  • MetricsManager的构造器接收brokerName以及metricsPlugin两个参数;之后定义了registerQueueGauge(QueueImpl使用)、registerAddressGauge(AddressInfo使用)、registerBrokerGauge(ActiveMQServerImpl使用)、remove方法(QueueImpl、AddressInfo、ActiveMQServerImpl使用)

小结

ActiveMQMetricsPlugin继承了Serializable,它定义了init方法以及getRegistry方法;FileConfigurationParser的parseMetricsPlugin方法会获取配置的clazz及properties,然后实例化metricsPlugin并执行metricsPlugin.init(properties);MetricsManager的构造器接收brokerName以及metricsPlugin两个参数;之后定义了registerQueueGauge(QueueImpl使用)、registerAddressGauge(AddressInfo使用)、registerBrokerGauge(ActiveMQServerImpl使用)、remove方法(QueueImpl、AddressInfo、ActiveMQServerImpl使用)

doc


codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...


引用和评论

0 条评论