Skip to content

Commit

Permalink
Code refactoring and changes, moving to own module :instrumentation:jmx.
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterF778 committed Sep 28, 2022
1 parent 9dfe6aa commit 7cebb63
Show file tree
Hide file tree
Showing 44 changed files with 255 additions and 184 deletions.
File renamed without changes.
File renamed without changes.
10 changes: 10 additions & 0 deletions instrumentation/jmx/javaagent/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
plugins {
id("otel.javaagent-instrumentation")
}

dependencies {
implementation(project(":instrumentation:jmx:jmx-engine:library"))
implementation(project(":instrumentation:jmx:jmx-yaml:library"))

compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Here is the list of metrics based on MBeans exposed by Jetty.
| Metric Name | Type | Attributes | Description |
|--------------------------------|---------------|--------------|------------------------------------------------------|
| jetty.session.sessionsCreated | Counter | resource | The number of sessions established in total |
| jetty.session.sessionTimeTotal | UpDownCounter | resource | The total time sessions have been active |
| jetty.session.sessionTimeMax | UpDownCounter | resource | The maximum amount of time a session has been active |
| jetty.session.sessionTimeTotal | Counter | resource | The total time sessions have been active |
| jetty.session.sessionTimeMax | Gauge | resource | The maximum amount of time a session has been active |
| jetty.session.sessionTimeMean | Gauge | resource | The mean time sessions remain active |
| jetty.threads.busyThreads | UpDownCounter | | The current number of busy threads |
| jetty.threads.idleThreads | UpDownCounter | | The current number of idle threads |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Broker metrics:
| kafka.partition.offline | UpDownCounter | | The number of partitions offline |
| kafka.partition.underReplicated | UpDownCounter | | The number of under replicated partitions |
| kafka.isr.operation.count | UpDownCounter | operation | The number of in-sync replica shrink and expand operations |
| kafka.lag.max | Counter | | The max lag in messages between follower and leader replicas |
| kafka.lag.max | Gauge | | The max lag in messages between follower and leader replicas |
| kafka.controller.active.count | UpDownCounter | | The number of controllers active on the broker |
| kafka.leaderElection.count | Counter | | The leader election count |
| kafka.leaderElection.unclean.count | Counter | | Unclean leader election count - increasing indicates broker failures |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.javaagent.jmx;

import static java.util.logging.Level.CONFIG;
import static java.util.logging.Level.FINE;

import com.google.auto.service.AutoService;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.jmx.engine.JmxMetricInsight;
import io.opentelemetry.instrumentation.jmx.engine.MetricConfiguration;
import io.opentelemetry.instrumentation.jmx.yaml.RuleParser;
import io.opentelemetry.javaagent.extension.AgentListener;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;

/** An {@link AgentListener} that enables JMX metrics during agent startup. */
@AutoService(AgentListener.class)
public class JmxMetricInsightInstaller implements AgentListener {

@Override
public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) {
ConfigProperties config = autoConfiguredSdk.getConfig();

if (config.getBoolean("otel.jmx.enabled", true)) {
JmxMetricInsight service = JmxMetricInsight.createService(GlobalOpenTelemetry.get(), config);
MetricConfiguration conf = buildMetricConfiguration();
service.start(conf);
}
}

private static String resourceFor(String platform) {
return "/jmx/rules/" + platform + ".yaml";
}

private static void addRulesForPlatform(String platform, MetricConfiguration conf) {
String yamlResource = resourceFor(platform);
try (InputStream inputStream =
JmxMetricInsightInstaller.class.getResourceAsStream(yamlResource)) {
if (inputStream != null) {
JmxMetricInsight.getLogger().log(FINE, "Opened input stream {0}", yamlResource);
RuleParser parserInstance = RuleParser.get();
parserInstance.addMetricDefs(conf, inputStream);
} else {
JmxMetricInsight.getLogger().log(CONFIG, "No support found for {0}", platform);
}
} catch (Exception e) {
JmxMetricInsight.getLogger().warning(e.getMessage());
}
}

private static void buildFromDefaultRules(MetricConfiguration conf) {
String targetSystem = System.getProperty("otel.jmx.target.system", "").trim();
String[] platforms = targetSystem.length() == 0 ? new String[0] : targetSystem.split(",");

for (String platform : platforms) {
addRulesForPlatform(platform, conf);
}
}

private static void buildFromUserRules(MetricConfiguration conf) {
String jmxDir = System.getProperty("otel.jmx.config");
if (jmxDir != null) {
JmxMetricInsight.getLogger().log(CONFIG, "JMX config file name: {0}", jmxDir);
RuleParser parserInstance = RuleParser.get();
try (InputStream inputStream = Files.newInputStream(new File(jmxDir.trim()).toPath())) {
parserInstance.addMetricDefs(conf, inputStream);
} catch (Exception e) {
JmxMetricInsight.getLogger().warning(e.getMessage());
}
}
}

private static MetricConfiguration buildMetricConfiguration() {
MetricConfiguration conf = new MetricConfiguration();

buildFromDefaultRules(conf);

buildFromUserRules(conf);

return conf;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ rules:
type: counter
desc: The number of sessions established in total
sessionTimeTotal:
type: counter
desc: The total time sessions have been active
sessionTimeMax:
type: gauge
desc: The maximum amount of time a session has been active
sessionTimeMean:
type: gauge
Expand Down Expand Up @@ -51,4 +53,4 @@ rules:
LoggerCount:
type: updowncounter
unit: 1
desc: The number of registered loggers by name
desc: The number of registered loggers by name
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ rules:
mapping:
Value:
metric: kafka.lag.max
type: counter
desc: The max lag in messages between follower and leader replicas
unit: '{messages}'

Expand Down
File renamed without changes.
File renamed without changes.
10 changes: 10 additions & 0 deletions instrumentation/jmx/jmx-engine/library/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
plugins {
id("otel.library-instrumentation")
}

dependencies {

compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")

testImplementation(project(":testing-common"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.runtimemetrics.jmx;
package io.opentelemetry.instrumentation.jmx.engine;

/**
* A class holding relevant information about an MBean attribute which will be used for collecting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.runtimemetrics.jmx;
package io.opentelemetry.instrumentation.jmx.engine;

import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
Expand All @@ -23,6 +23,9 @@
* immutable.
*/
public class AttributeValueExtractor implements LabelExtractor {

private static final Logger logger = Logger.getLogger(AttributeValueExtractor.class.getName());

// The attribute name to be used during value extraction from MBean
private final String baseName;

Expand Down Expand Up @@ -95,9 +98,8 @@ String getAttributeName() {
* @return AttributeInfo if the attribute is properly recognized, or null
*/
AttributeInfo getAttributeInfo(MBeanServer server, ObjectName objectName) {
if (MetricService.logger.isLoggable(FINE)) {
MetricService.logger.log(
FINE, "Resolving {0} for {1}", new Object[] {getAttributeName(), objectName});
if (logger.isLoggable(FINE)) {
logger.log(FINE, "Resolving {0} for {1}", new Object[] {getAttributeName(), objectName});
}

try {
Expand All @@ -119,8 +121,8 @@ AttributeInfo getAttributeInfo(MBeanServer server, ObjectName objectName) {
// It is fairly normal to get null values, especially during startup,
// but it is much more suspicious to get non-numbers
Level logLevel = sampleValue == null ? FINE : INFO;
if (MetricService.logger.isLoggable(logLevel)) {
MetricService.logger.log(
if (logger.isLoggable(logLevel)) {
logger.log(
logLevel,
"Unusable value {0} for attribute {1} and ObjectName {2}",
new Object[] {
Expand All @@ -134,18 +136,18 @@ AttributeInfo getAttributeInfo(MBeanServer server, ObjectName objectName) {
}
}

if (MetricService.logger.isLoggable(FINE)) {
MetricService.logger.log(
if (logger.isLoggable(FINE)) {
logger.log(
FINE,
"Cannot find attribute {0} for ObjectName {1}",
new Object[] {baseName, objectName});
}

} catch (InstanceNotFoundException e) {
// Should not happen. The ObjectName we use has been provided by the MBeanServer we use.
MetricService.logger.log(INFO, "The MBeanServer does not find {0}", objectName);
logger.log(INFO, "The MBeanServer does not find {0}", objectName);
} catch (Exception e) {
MetricService.logger.log(
logger.log(
FINE,
"Exception {0} while inspecting attributes for ObjectName {1}",
new Object[] {e, objectName});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.runtimemetrics.jmx;
package io.opentelemetry.instrumentation.jmx.engine;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import java.util.ArrayList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.runtimemetrics.jmx;
package io.opentelemetry.instrumentation.jmx.engine;

import javax.management.ObjectName;
import javax.management.QueryExp;

/**
* A class describing a set of MBeans which can be used to collect values for a metric. Objects of
* this class are inmutable.
* this class are immutable.
*/
public class BeanPack {
// How to specify the MBean(s)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.runtimemetrics.jmx;
package io.opentelemetry.instrumentation.jmx.engine;

import java.util.Collection;
import javax.management.MBeanServer;
import javax.management.ObjectName;

/**
* A class encapsulating a set of ObjectNames and the MBeanServer that recognized them. Objects of
* this class are inmutable.
* this class are immutable.
*/
class DetectionStatus {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.jmx.engine;

import static java.util.logging.Level.CONFIG;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import java.util.logging.Logger;

/** Collecting and exporting JMX metrics. */
public class JmxMetricInsight {

private static final Logger logger = Logger.getLogger(JmxMetricInsight.class.getName());

private static final String INSTRUMENTATION_SCOPE = "io.opentelemetry.jmx";

private final OpenTelemetry openTelemetry;
private final ConfigProperties configProperties;

public static JmxMetricInsight createService(OpenTelemetry ot, ConfigProperties config) {
return new JmxMetricInsight(ot, config);
}

public static Logger getLogger() {
return logger;
}

private JmxMetricInsight(OpenTelemetry ot, ConfigProperties config) {
openTelemetry = ot;
configProperties = config;
}

public void start(MetricConfiguration conf) {
if (conf.isEmpty()) {
logger.log(
CONFIG,
"Empty JMX configuration, no metrics will be collected for InstrumentationScope "
+ INSTRUMENTATION_SCOPE);
} else {
MetricRegistrar registrar = new MetricRegistrar(openTelemetry, INSTRUMENTATION_SCOPE);
BeanFinder finder = new BeanFinder(registrar, configProperties);
finder.discoverBeans(conf);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.runtimemetrics.jmx;
package io.opentelemetry.instrumentation.jmx.engine;

import javax.management.MBeanServer;
import javax.management.ObjectName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.runtimemetrics.jmx;
package io.opentelemetry.instrumentation.jmx.engine;

/**
* A class providing the user visible characteristics (name, type, description and units) of a
* metric to be reported with OpenTelemetry.
*
* <p>Objects of this class are inmutable.
* <p>Objects of this class are immutable.
*/
public class MetricBanner {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.runtimemetrics.jmx;
package io.opentelemetry.instrumentation.jmx.engine;

import java.util.ArrayList;
import java.util.Collection;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.runtimemetrics.jmx;
package io.opentelemetry.instrumentation.jmx.engine;

/**
* A class providing a complete definition on how to create an Open Telemetry metric out of the JMX
* system: how to extract values from MBeans and how to model, name and label them using
* OpenTelemetry Metric API. Objects of this class are inmutable.
* OpenTelemetry Metric API. Objects of this class are immutable.
*
* <p>Example: The JVM provides an MBean with ObjectName "java.lang:type=Threading", and one of the
* MBean attributes is "ThreadCount". This MBean can be used to provide a metric showing the current
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.runtimemetrics.jmx;
package io.opentelemetry.instrumentation.jmx.engine;

/**
* A class holding the info needed to support a single metric: how to define it in OpenTelemetry and
Expand Down
Loading

0 comments on commit 7cebb63

Please sign in to comment.