diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/perfcounter/AvailableJmxMetricLogger.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/perfcounter/AvailableJmxMetricLogger.java index c5291ff0058..7455948b760 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/perfcounter/AvailableJmxMetricLogger.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/perfcounter/AvailableJmxMetricLogger.java @@ -22,12 +22,11 @@ package com.microsoft.applicationinsights.agent.internal.perfcounter; import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; +import static java.util.Collections.singleton; import static java.util.Collections.singletonList; import java.lang.management.ManagementFactory; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -119,62 +118,51 @@ private static Map> getAvailableJmxAttributes() { Map> availableJmxMetrics = new HashMap<>(); for (ObjectName objectName : objectNames) { String name = objectName.toString(); + Set attrs; try { - Set attrs = getJmxAttributes(server, objectName); - if (!attrs.isEmpty()) { - availableJmxMetrics.put(name, attrs); + attrs = getAttributeDescriptions(server, objectName); + if (attrs.isEmpty()) { + attrs.add(""); } } catch (Exception e) { + attrs = singleton(" getJmxAttributes(MBeanServer server, ObjectName objectName) + private static Set getAttributeDescriptions(MBeanServer server, ObjectName objectName) throws Exception { MBeanInfo mbeanInfo = server.getMBeanInfo(objectName); - Set attributeNames = new HashSet<>(); + Set numericAttributeNames = new HashSet<>(); for (MBeanAttributeInfo attribute : mbeanInfo.getAttributes()) { - if (attribute.isReadable()) { - try { - Object value = server.getAttribute(objectName, attribute.getName()); - attributeNames.addAll(getNumericAttributes(attribute, value)); - } catch (Exception e) { - // log exception at trace level since this is expected in several cases, e.g. - // "java.lang.UnsupportedOperationException: CollectionUsage threshold is not supported" - // and available jmx metrics are already only logged at debug - logger.trace(e.getMessage(), e); - } + if (!attribute.isReadable()) { + numericAttributeNames.add(attribute.getName() + " (not readable)"); + continue; + } + try { + Object value = server.getAttribute(objectName, attribute.getName()); + numericAttributeNames.addAll(getAttributeDescriptions(attribute, value)); + } catch (Exception e) { + // log exception at trace level since this is expected in several cases, e.g. + // "java.lang.UnsupportedOperationException: CollectionUsage threshold is not supported" + // and available jmx metrics are already only logged at debug + logger.trace(e.getMessage(), e); } } - return attributeNames; + return numericAttributeNames; } - private static List getNumericAttributes(MBeanAttributeInfo attribute, Object value) { + private static List getAttributeDescriptions( + MBeanAttributeInfo attribute, @Nullable Object value) { + String attributeType = attribute.getType(); - if (NUMERIC_ATTRIBUTE_TYPES.contains(attributeType) && value instanceof Number) { - return singletonList(attribute.getName()); - } - if (BOOLEAN_ATTRIBUTE_TYPES.contains(attributeType) && value instanceof Boolean) { - return singletonList(attribute.getName()); - } - if (attributeType.equals("java.lang.Object") && value instanceof Number) { - return singletonList(attribute.getName()); - } - if (attributeType.equals("java.lang.String") && value instanceof String) { - try { - Double.parseDouble((String) value); - return singletonList(attribute.getName()); - } catch (NumberFormatException e) { - // this is expected for non-numeric attributes - return emptyList(); - } - } + if (attributeType.equals(CompositeData.class.getName())) { Object openType = attribute.getDescriptor().getFieldValue("openType"); CompositeType compositeType = null; @@ -187,7 +175,8 @@ private static List getNumericAttributes(MBeanAttributeInfo attribute, O return getCompositeTypeAttributeNames(attribute, value, compositeType); } } - return emptyList(); + + return singletonList(attribute.getName() + "(" + attributeType + "/" + valueType(value)); } private static List getCompositeTypeAttributeNames( @@ -223,6 +212,24 @@ private static List getCompositeTypeAttributeNames( return attributeNames; } + private static String valueType(@Nullable Object value) { + if (value instanceof Number) { + return "Number"; + } + if (value instanceof Boolean) { + return "Boolean"; + } + if (value instanceof String) { + try { + Double.parseDouble((String) value); + return "Number"; + } catch (NumberFormatException e) { + return "String"; + } + } + return value == null ? null : value.getClass().getName(); + } + // visible for testing static Map> difference( Map> map1, Map> map2) {