Skip to content

Commit

Permalink
[WFLY-11578] Distinguish WildFly metrics types
Browse files Browse the repository at this point in the history
* In microprofile-metrics-smallrye extension, when attributes that
  corresponds to metrics are collected, check whether the attribute
  access has the COUNTER_METRIC flag to register it in Prometheus
  collector as a counter. Otherwise, the metric is registered as a
  gauge.
* Append _total to the Prometheus name for counters.

JIRA: https://issues.jboss.org/browse/WFLY-11578
  • Loading branch information
jmesnil committed Jan 24, 2019
1 parent 58b9abc commit 0da4091
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 21 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -91,12 +91,18 @@ The [helloworld-rs quickstart](https://github.com/wildfly/quickstart/tree/master
that can be deployed in WildFly. that can be deployed in WildFly.
A corresponding metric will be exposed for it with the name and labels: A corresponding metric will be exposed for it with the name and labels:


* `wildfly_undertow_request_count{deployment="helloworld-rs.war",servlet="org.jboss.as.quickstarts.rshelloworld.JAXActivator",subdeployment="helloworld-rs.war"}` * `wildfly_undertow_request_count_total{deployment="helloworld-rs.war",servlet="org.jboss.as.quickstarts.rshelloworld.JAXActivator",subdeployment="helloworld-rs.war"}`


[NOTE]
Some subsystems (such as `undertow` or `messaing-activemq`) do not enable their statistics by default
as they have an impact on performance and memory usage. These subsystems provides a `statistics-enabled` attribute that must
be set to `true` to enable them.
For convenience, WildFly standalone configuration provides expression to enable the statistics by setting a
System property `-Dwildfly.statistics-enabled=true` to enable statistics on the subsystems provided by the configuration.


== Component Reference == Component Reference


The Eclipse MicroProfile Health is implemented by the SmallRye Health project. The Eclipse MicroProfile Metrics is implemented by the SmallRye Metrics project.


**** ****
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;


import io.prometheus.client.Collector; import io.prometheus.client.Collector.MetricFamilySamples;
import io.prometheus.client.CollectorRegistry; import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.CounterMetricFamily;
import io.prometheus.client.GaugeMetricFamily; import io.prometheus.client.GaugeMetricFamily;
import org.jboss.as.controller.LocalModelControllerClient; import org.jboss.as.controller.LocalModelControllerClient;
import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.PathAddress;
Expand Down Expand Up @@ -101,10 +102,16 @@ private void collectResourceMetrics0(final Resource current,
} }
PathAddress resourceAddress = resourceAddressResolver.apply(address); PathAddress resourceAddress = resourceAddressResolver.apply(address);
MeasurementUnit unit = attributeAccess.getAttributeDefinition().getMeasurementUnit(); MeasurementUnit unit = attributeAccess.getAttributeDefinition().getMeasurementUnit();
MetricMetadata metricMetadata = new MetricMetadata(attributeName, resourceAddress, unit, globalPrefix); boolean counter = attributeAccess.getFlags().contains(AttributeAccess.Flag.COUNTER_METRIC);
MetricMetadata metricMetadata = new MetricMetadata(attributeName, resourceAddress, unit, globalPrefix, counter);
String attributeDescription = resourceDescription.get(ATTRIBUTES, attributeName, DESCRIPTION).asStringOrNull(); String attributeDescription = resourceDescription.get(ATTRIBUTES, attributeName, DESCRIPTION).asStringOrNull();
GaugeMetricFamily gaugeMetricFamily = new GaugeMetricFamily(metricMetadata.metricName, attributeDescription, metricMetadata.labelNames); final MetricFamilySamples metricFamilySamples;
Supplier<Optional<Collector.MetricFamilySamples.Sample>> sampleSupplier = () -> { if (counter) {
metricFamilySamples = new CounterMetricFamily(metricMetadata.metricName, attributeDescription, metricMetadata.labelNames);
} else {
metricFamilySamples = new GaugeMetricFamily(metricMetadata.metricName, attributeDescription, metricMetadata.labelNames);
}
Supplier<Optional<MetricFamilySamples.Sample>> sampleSupplier = () -> {
final ModelNode readAttributeOp = new ModelNode(); final ModelNode readAttributeOp = new ModelNode();
readAttributeOp.get(OP).set(READ_ATTRIBUTE_OPERATION); readAttributeOp.get(OP).set(READ_ATTRIBUTE_OPERATION);
readAttributeOp.get(OP_ADDR).set(resourceAddress.toModelNode()); readAttributeOp.get(OP_ADDR).set(resourceAddress.toModelNode());
Expand All @@ -120,14 +127,14 @@ private void collectResourceMetrics0(final Resource current,
try { try {
double initialValue = result.asDouble(); double initialValue = result.asDouble();
double scaledValue = UnitConverter.scaleToBase(initialValue, unit); double scaledValue = UnitConverter.scaleToBase(initialValue, unit);
return Optional.of(new Collector.MetricFamilySamples.Sample(metricMetadata.metricName, metricMetadata.labelNames, metricMetadata.labelValues, scaledValue)); return Optional.of(new MetricFamilySamples.Sample(metricMetadata.metricName, metricMetadata.labelNames, metricMetadata.labelValues, scaledValue));
} catch (Exception e) { } catch (Exception e) {
throw LOGGER.unableToConvertAttribute(attributeName, address, e); throw LOGGER.unableToConvertAttribute(attributeName, address, e);
} }
} }
return Optional.empty(); return Optional.empty();
}; };
prometheusCollector.addMetricFamilySampleSupplier(gaugeMetricFamily, sampleSupplier); prometheusCollector.addMetricFamilySampleSupplier(metricFamilySamples, sampleSupplier);
registration.addUnregistrationTask(() -> prometheusCollector.removeMetricFamilySampleSupplier(metricMetadata.metricName, sampleSupplier)); registration.addUnregistrationTask(() -> prometheusCollector.removeMetricFamilySampleSupplier(metricMetadata.metricName, sampleSupplier));
} }


Expand Down Expand Up @@ -179,10 +186,16 @@ private void collectMetricFamilies(ImmutableManagementResourceRegistration manag
DescriptionProvider modelDescription = managementResourceRegistration.getModelDescription(address); DescriptionProvider modelDescription = managementResourceRegistration.getModelDescription(address);
resourceDescription = modelDescription.getModelDescription(Locale.getDefault()); resourceDescription = modelDescription.getModelDescription(Locale.getDefault());
} }
MetricMetadata metricMetadata = new MetricMetadata(attributeName, address, attributeAccess.getAttributeDefinition().getMeasurementUnit(), globalPrefix); boolean counter = attributeAccess.getFlags().contains(AttributeAccess.Flag.COUNTER_METRIC);
MetricMetadata metricMetadata = new MetricMetadata(attributeName, address, attributeAccess.getAttributeDefinition().getMeasurementUnit(), globalPrefix, counter);
String attributeDescription = resourceDescription.get(ATTRIBUTES, attributeName, DESCRIPTION).asStringOrNull(); String attributeDescription = resourceDescription.get(ATTRIBUTES, attributeName, DESCRIPTION).asStringOrNull();
GaugeMetricFamily gaugeMetricFamily = new GaugeMetricFamily(metricMetadata.metricName, attributeDescription, metricMetadata.labelNames); final MetricFamilySamples metricFamilySamples;
collector.addMetricFamilySamples(gaugeMetricFamily); if (counter) {
metricFamilySamples = new CounterMetricFamily(metricMetadata.metricName, attributeDescription, metricMetadata.labelNames);
} else {
metricFamilySamples = new GaugeMetricFamily(metricMetadata.metricName, attributeDescription, metricMetadata.labelNames);
}
collector.addMetricFamilySamples(metricFamilySamples);
} }


for (PathElement childAddress : managementResourceRegistration.getChildAddresses(address)) { for (PathElement childAddress : managementResourceRegistration.getChildAddresses(address)) {
Expand Down Expand Up @@ -237,7 +250,7 @@ private static class MetricMetadata {
private final List<String> labelNames; private final List<String> labelNames;
private final List<String> labelValues; private final List<String> labelValues;


MetricMetadata(String attributeName, PathAddress address, MeasurementUnit unit, String globalPrefix) { MetricMetadata(String attributeName, PathAddress address, MeasurementUnit unit, String globalPrefix, boolean counter) {
String metricPrefix = ""; String metricPrefix = "";
labelNames = new ArrayList<>(); labelNames = new ArrayList<>();
labelValues = new ArrayList<>(); labelValues = new ArrayList<>();
Expand All @@ -249,7 +262,7 @@ private static class MetricMetadata {
metricPrefix += value + "_"; metricPrefix += value + "_";
continue; continue;
} }
labelNames.add(getPrometheusMetricName(key, null)); labelNames.add(getPrometheusMetricName(key, null, false));
labelValues.add(value); labelValues.add(value);
} }
// if the resource address defines a deployment (without subdeployment), // if the resource address defines a deployment (without subdeployment),
Expand All @@ -260,13 +273,14 @@ private static class MetricMetadata {
if (globalPrefix != null && !globalPrefix.isEmpty()) { if (globalPrefix != null && !globalPrefix.isEmpty()) {
metricPrefix = globalPrefix + "_" + metricPrefix; metricPrefix = globalPrefix + "_" + metricPrefix;
} }
metricName = getPrometheusMetricName(metricPrefix + attributeName, unit); metricName = getPrometheusMetricName(metricPrefix + attributeName, unit, counter);
} }


private static String getPrometheusMetricName(String name, MeasurementUnit unit) { private static String getPrometheusMetricName(String name, MeasurementUnit unit, boolean counter) {
String out = (name + unitSuffix(unit)).replaceAll("[^\\w]+","_"); String prometheusName = name + unitSuffix(unit) + (counter ? "_total" : "");
out = decamelize(out); prometheusName =prometheusName.replaceAll("[^\\w]+","_");
return out; prometheusName = decamelize(prometheusName);
return prometheusName;
} }




Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@


import io.prometheus.client.Collector; import io.prometheus.client.Collector;
import io.prometheus.client.Collector.MetricFamilySamples.Sample; import io.prometheus.client.Collector.MetricFamilySamples.Sample;
import io.prometheus.client.GaugeMetricFamily;


public class PrometheusCollector extends Collector implements Collector.Describable { public class PrometheusCollector extends Collector implements Collector.Describable {


Expand All @@ -26,7 +25,7 @@ public void addMetricFamilySamples(MetricFamilySamples mfs) {
} }
} }


void addMetricFamilySampleSupplier(GaugeMetricFamily mfs, Supplier<Optional<Sample>> sampleSupplier) { void addMetricFamilySampleSupplier(MetricFamilySamples mfs, Supplier<Optional<Sample>> sampleSupplier) {
if (!metricNames.containsKey(mfs.name)) { if (!metricNames.containsKey(mfs.name)) {
addMetricFamilySamples(mfs); addMetricFamilySamples(mfs);
} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ private static String performCall(URL url) throws Exception {
} }


private void checkRequestCount(int expectedCount, boolean deploymentMetricMustExist) throws IOException { private void checkRequestCount(int expectedCount, boolean deploymentMetricMustExist) throws IOException {
String prometheusMetricName = "wildfly_undertow_request_count"; String prometheusMetricName = "wildfly_undertow_request_count_total";


String metrics = getPrometheusMetrics(managementClient, "", true); String metrics = getPrometheusMetrics(managementClient, "", true);
for (String line : metrics.split("\\R")) { for (String line : metrics.split("\\R")) {
Expand Down

0 comments on commit 0da4091

Please sign in to comment.