All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.welen.jmole.microprofile.JMoleMetric Maven / Gradle / Ivy

package net.welen.jmole.microprofile;

/*-
 * #%L
 * JMole, https://bitbucket.org/awelen/jmole
 * %%
 * Copyright (C) 2015 - 2020 Anders Welén, [email protected]
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.ReflectionException;

import org.eclipse.microprofile.metrics.Gauge;
import org.eclipse.microprofile.metrics.Metadata;
import org.eclipse.microprofile.metrics.MetadataBuilder;
import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.MetricType;
import org.eclipse.microprofile.metrics.annotation.RegistryType;

import net.welen.jmole.JMole;
import net.welen.jmole.cdi.JMoleReconfigured;
import net.welen.jmole.cdi.JMoleStarted;
import net.welen.jmole.cdi.JMoleStopped;
import net.welen.jmole.cdi.LifecycleBean;
import net.welen.jmole.presentation.PresentationInformation;

@ApplicationScoped
public class JMoleMetric {

	private final static Logger LOG = Logger.getLogger(JMoleMetric.class.getName());
	private static final String SEP = "/";
	
	private static final String REGISTRY = "jmole.protocol.microprofile.metric.registry";
	
	@Inject
	LifecycleBean lifecycleBean;

	@Inject
	@RegistryType(type=MetricRegistry.Type.BASE)
	MetricRegistry baseRegistry;

	@Inject
	@RegistryType(type=MetricRegistry.Type.VENDOR)
	MetricRegistry vendorRegistry;

	@Inject
	@RegistryType(type=MetricRegistry.Type.APPLICATION)
	MetricRegistry applicationRegistry;
	
	MetricRegistry choosenRegistry = null;
	
	private List metricNames = new ArrayList();

	private class JMoleGaugeImpl implements Gauge {

		private String category;
		private String name;
		private String attribute;

		private JMoleGaugeImpl(String category, String name, String attribute) {
			this.category = category;
			this.name = name;
			this.attribute = attribute;
		}
		
		@Override
		public Double getValue() {
			try {				
				Object value = lifecycleBean.getJMoleInstance().collectMeasurement(category, name, attribute);
				if (value instanceof Double) { 
					return (Double) value;
				} else {
					return Double.valueOf(value.toString());
				}
			} catch (Exception e) {				
				throw new RuntimeException("Problem collecting data for " + category + SEP + name + SEP + attribute, e);
			}
		}		
		
	}
	
	private void register(@Observes @JMoleStarted String message) {

		choosenRegistry = applicationRegistry;
		String registry = System.getProperty(REGISTRY);		
		if (registry!= null) {
			if (registry.equals("BASE")) {
				choosenRegistry = baseRegistry;
			} else if (registry.equals("VENDOR")) {
				choosenRegistry = vendorRegistry;
			} else if (registry.equals("APPLICATION")) {
				choosenRegistry = applicationRegistry;
			} else {
				LOG.log(Level.WARNING, "Registry " + registry + " isn't found. Using default application instead.");				
			}
		}	
		
		try {
			registerMetrics();
		} catch (Exception e) {
			LOG.log(Level.SEVERE, e.getMessage(), e);
		}
	}
	
	private void registerMetrics() throws InstanceNotFoundException, AttributeNotFoundException, ReflectionException, MBeanException {		
		synchronized (metricNames) {
			LOG.log(Level.FINE, "Registring Metrics");
			
			JMole jmole = lifecycleBean.getJMoleInstance();		
			
			Map presentationInformationMap = new HashMap();
			for (Entry>>> categoryEntry : jmole.collectMeasurements(presentationInformationMap).entrySet()) {
				Iterator>> iter = categoryEntry.getValue().iterator();
				while (iter.hasNext()) {
					for (Entry> nameEntry : iter.next().entrySet()) {
						for (Entry attributeEntry : nameEntry.getValue().entrySet()) {
							String piKey = categoryEntry.getKey() + nameEntry.getKey();
							PresentationInformation presentationInformation = presentationInformationMap.get(piKey);
							if (presentationInformation == null) {						
								LOG.severe("No presentation information found for: " + piKey + ", Skipping it");
								continue;
							}
							try {
								registerMetric(categoryEntry.getKey(), nameEntry.getKey(), attributeEntry.getKey(), presentationInformation);
							} catch (Exception e) {
								LOG.log(Level.SEVERE, e.getMessage() + ": " + categoryEntry.getKey() + SEP
										+ nameEntry.getKey() + SEP + attributeEntry.getKey(), e);
							}
						}
					}
				}
			}	
		}
	}
	
	private void registerMetric(String category, String name, String attribute, PresentationInformation presentationInformation) {
		String metricName = category + SEP + name + SEP + attribute;
		String description = presentationInformation.getDescription();
		String unit = presentationInformation.getUnit();
						
		Metadata metadata = new MetadataBuilder()
				.withName(metricName).withDisplayName(metricName)
				.withDescription(description == null ? "" : description)
				.withType(MetricType.GAUGE).withUnit(unit).build();		
		Gauge gauge = new JMoleGaugeImpl(category, name, attribute);

		LOG.log(Level.FINE, "Register: " + category + SEP + name + SEP + attribute);		
		choosenRegistry.register(metadata, gauge);
		metricNames.add(metricName);
	}

	private void unregister(@Observes @JMoleStopped String message) {
		synchronized (metricNames) {
			LOG.log(Level.FINE, "Unregistring Metrics");
			for (String metricName : metricNames ) {
				LOG.log(Level.FINE, "Removing: " + metricNames);
				choosenRegistry.remove(metricName);
			}
			metricNames.clear();
		}
	}

	@SuppressWarnings("unused")
	private void reRegister(@Observes @JMoleReconfigured String message) {
		LOG.log(Level.FINE, "Reconfiguring Metrics due to JMole reconfiguring");
		unregister(null);
		register(null);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy