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

io.opentelemetry.instrumentation.jmx.yaml.MetricStructure Maven / Gradle / Ivy

/*
 * Copyright The OpenTelemetry Authors
 * SPDX-License-Identifier: Apache-2.0
 */

package io.opentelemetry.instrumentation.jmx.yaml;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.instrumentation.jmx.engine.MetricAttribute;
import io.opentelemetry.instrumentation.jmx.engine.MetricAttributeExtractor;
import io.opentelemetry.instrumentation.jmx.engine.MetricInfo;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * An abstract class containing skeletal info about Metrics:
 * 
  • the metric type *
  • the metric attributes *
  • the unit * *

    Known subclasses are {@link JmxRule} and {@link Metric}. */ abstract class MetricStructure { // Used by the YAML parser // // type: TYPE // metricAttribute: // KEY1: SPECIFICATION1 // KEY2: SPECIFICATION2 // unit: UNIT // // For state metrics // // type: state // metricAttribute: // KEY1: SPECIFICATION1 // state: // state1: [a,b] // state2: c // state3: '*' private Map metricAttribute; private StateMapping stateMapping = StateMapping.empty(); private static final String STATE_MAPPING_DEFAULT = "*"; private String unit; private MetricInfo.Type metricType; private List metricAttributes; MetricStructure() {} void setType(String t) { // Do not complain about case variations t = t.trim().toUpperCase(Locale.ROOT); this.metricType = MetricInfo.Type.valueOf(t); } public String getUnit() { return unit; } public void setUnit(String unit) { this.unit = validateUnit(unit.trim()); } private static void addMappedValue( StateMapping.Builder builder, String stateValue, String stateKey) { if (stateValue.equals(STATE_MAPPING_DEFAULT)) { builder.withDefaultState(stateKey); } else { builder.withMappedValue(stateValue, stateKey); } } @CanIgnoreReturnValue private String validateUnit(String unit) { requireNonEmpty(unit, "Metric unit is empty"); return unit; } /** * When the YAML parser sets the metric attributes, convert them immediately to MetricAttribute * objects. Any errors during conversion will show in the context of the parsed YAML file. * * @param map the mapping of metric attribute keys to evaluating snippets */ public void setMetricAttribute(Map map) { this.metricAttribute = map; // pre-build the MetricAttributes this.metricAttributes = addMetricAttributes(map); } // Used only for testing public Map getMetricAttribute() { return metricAttribute; } public MetricInfo.Type getMetricType() { return metricType; } protected List getAttributeList() { return metricAttributes; } protected void requireNonEmpty(String s, String msg) { if (s.isEmpty()) { throw new IllegalArgumentException(msg); } } private List addMetricAttributes(Map metricAttributeMap) { List list = new ArrayList<>(); for (String key : metricAttributeMap.keySet()) { Object value = metricAttributeMap.get(key); if (value == null) { throw new IllegalStateException("nothing specified for metric attribute key '" + key + "'"); } MetricAttribute attribute; if (value instanceof String) { attribute = buildMetricAttribute(key, ((String) value).trim()); } else if (value instanceof Map) { // here we use the structure to detect a state metric attribute and parse it. attribute = buildStateMetricAttribute(key, (Map) value); } else { throw new IllegalArgumentException("unexpected metric attribute: " + value); } list.add(attribute); } return list; } private static MetricAttribute buildMetricAttribute(String key, String target) { // The recognized forms of target are: // - param(STRING) // - beanattr(STRING) // - const(STRING) // where STRING is the name of the corresponding parameter key, attribute name, // or the direct value to use int k = target.indexOf(')'); // Check for one of the cases as above if (target.startsWith("param(")) { if (k > 0) { String jmxAttribute = target.substring(6, k).trim(); return new MetricAttribute( key, MetricAttributeExtractor.fromObjectNameParameter(jmxAttribute)); } } else if (target.startsWith("beanattr(")) { if (k > 0) { String jmxAttribute = target.substring(9, k).trim(); return new MetricAttribute(key, MetricAttributeExtractor.fromBeanAttribute(jmxAttribute)); } } else if (target.startsWith("const(")) { if (k > 0) { String constantValue = target.substring(6, k).trim(); return new MetricAttribute(key, MetricAttributeExtractor.fromConstant(constantValue)); } } String msg = "Invalid metric attribute specification for '" + key + "': " + target; throw new IllegalArgumentException(msg); } private MetricAttribute buildStateMetricAttribute(String key, Map stateMap) { if (stateMap.isEmpty()) { throw new IllegalArgumentException("state map is empty for key " + key); } if (!stateMapping.isEmpty()) { throw new IllegalStateException("only a single state map is expected"); } StateMapping.Builder builder = StateMapping.builder(); for (Map.Entry entry : stateMap.entrySet()) { if (!(entry.getKey() instanceof String)) { throw new IllegalArgumentException("unexpected state map key: " + entry.getKey()); } String stateKey = (String) entry.getKey(); Object objValue = entry.getValue(); if (objValue instanceof String) { addMappedValue(builder, (String) objValue, stateKey); } else if (objValue instanceof List) { for (Object listEntry : (List) objValue) { if (!(listEntry instanceof String)) { throw new IllegalArgumentException("unexpected state list value: " + stateKey); } addMappedValue(builder, (String) listEntry, stateKey); } } } stateMapping = builder.build(); return new MetricAttribute(key, null); } public StateMapping getStateMapping() { return stateMapping; } }





  • © 2015 - 2024 Weber Informatics LLC | Privacy Policy