Skip to content

Commit

Permalink
Issue 7212 - Allow multiple YAML configuration files for JMX rules (o…
Browse files Browse the repository at this point in the history
…pen-telemetry#7284)

Co-authored-by: Trask Stalnaker <[email protected]>
  • Loading branch information
PeterF778 and trask committed Nov 24, 2022
1 parent 1627275 commit c4ceaaa
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 18 deletions.
8 changes: 4 additions & 4 deletions instrumentation/jmx-metrics/javaagent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ No targets are enabled by default. The supported target environments are listed
- [wildfly](wildfly.md)
- [hadoop](hadoop.md)

## Configuration File
## Configuration Files

To provide your own metric definitions, create a YAML configuration file, and specify its location using the `otel.jmx.config` property. For example
To provide your own metric definitions, create one or more YAML configuration files, and specify their location using the `otel.jmx.config` property. Absolute or relative pathnames can be specified. For example

```bash
$ java -javaagent:path/to/opentelemetry-javaagent.jar \
-Dotel.jmx.config=path/to/config_file.yaml \
-Dotel.jmx.config=path/to/config_file.yaml,more_rules.yaml \
... \
-jar myapp.jar
```

### Basic Syntax

The configuration file can contain multiple entries (which we call _rules_), defining a number of metrics. Each rule must identify a set of MBeans and the name of the MBean attribute to query, along with additional information on how to report the values. Let's look at a simple example.
Each configuration file can contain multiple entries (which we call _rules_), defining a number of metrics. Each rule must identify a set of MBeans and the name of the MBean attribute to query, along with additional information on how to report the values. Let's look at a simple example.

```yaml
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
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;
import java.nio.file.Paths;
import java.util.List;

/** An {@link AgentListener} that enables JMX metrics during agent startup. */
@AutoService(AgentListener.class)
Expand Down Expand Up @@ -59,7 +60,7 @@ private static void addRulesForPlatform(String platform, MetricConfiguration con
if (inputStream != null) {
JmxMetricInsight.getLogger().log(FINE, "Opened input stream {0}", yamlResource);
RuleParser parserInstance = RuleParser.get();
parserInstance.addMetricDefsTo(conf, inputStream);
parserInstance.addMetricDefsTo(conf, inputStream, platform);
} else {
JmxMetricInsight.getLogger().log(INFO, "No support found for {0}", platform);
}
Expand All @@ -70,24 +71,24 @@ private static void addRulesForPlatform(String platform, MetricConfiguration con

private static void buildFromDefaultRules(
MetricConfiguration conf, ConfigProperties configProperties) {
String targetSystem = configProperties.getString("otel.jmx.target.system", "");
String[] platforms = targetSystem.isEmpty() ? new String[0] : targetSystem.split(",");

List<String> platforms = configProperties.getList("otel.jmx.target.system");
for (String platform : platforms) {
addRulesForPlatform(platform, conf);
}
}

private static void buildFromUserRules(
MetricConfiguration conf, ConfigProperties configProperties) {
String jmxDir = configProperties.getString("otel.jmx.config");
if (jmxDir != null) {
JmxMetricInsight.getLogger().log(FINE, "JMX config file name: {0}", jmxDir);
List<String> configFiles = configProperties.getList("otel.jmx.config");
for (String configFile : configFiles) {
JmxMetricInsight.getLogger().log(FINE, "JMX config file name: {0}", configFile);
RuleParser parserInstance = RuleParser.get();
try (InputStream inputStream = Files.newInputStream(new File(jmxDir.trim()).toPath())) {
parserInstance.addMetricDefsTo(conf, inputStream);
try (InputStream inputStream = Files.newInputStream(Paths.get(configFile))) {
parserInstance.addMetricDefsTo(conf, inputStream, configFile);
} catch (Exception e) {
JmxMetricInsight.getLogger().warning(e.getMessage());
// yaml parsing errors are caught and logged inside of addMetricDefsTo
// only file access related exceptions are expected here
JmxMetricInsight.getLogger().warning(e.toString());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,22 @@ public JmxConfig loadConfig(InputStream is) throws Exception {
*
* @param conf the metric configuration
* @param is the InputStream with the YAML rules
* @param id identifier of the YAML ruleset, such as a filename
*/
public void addMetricDefsTo(MetricConfiguration conf, InputStream is) {
public void addMetricDefsTo(MetricConfiguration conf, InputStream is, String id) {
try {

JmxConfig config = loadConfig(is);
if (config != null) {
logger.log(INFO, "Found {0} metric rules", config.getRules().size());
logger.log(
INFO, "{0}: found {1} metric rules", new Object[] {id, config.getRules().size()});
config.addMetricDefsTo(conf);
}
} catch (Exception exception) {
logger.log(WARNING, "Failed to parse YAML rules: " + rootCause(exception));
logger.log(
WARNING,
"Failed to parse YAML rules from {0}: {1}",
new Object[] {id, rootCause(exception)});
// It is essential that the parser exception is made visible to the user.
// It contains contextual information about any syntax issues found by the parser.
logger.log(WARNING, exception.toString());
Expand Down

0 comments on commit c4ceaaa

Please sign in to comment.