Issue 7212 - Allow multiple YAML configuration files for JMX rules (#7284)
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
This commit is contained in:
parent
16272753cc
commit
c4ceaaa8d9
|
@ -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
|
||||
---
|
||||
|
|
|
@ -16,9 +16,10 @@ 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;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
/** An {@link AgentListener} that enables JMX metrics during agent startup. */
|
||||
@AutoService(AgentListener.class)
|
||||
|
@ -59,7 +60,7 @@ public class JmxMetricInsightInstaller implements AgentListener {
|
|||
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);
|
||||
}
|
||||
|
@ -70,9 +71,7 @@ public class JmxMetricInsightInstaller implements AgentListener {
|
|||
|
||||
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);
|
||||
}
|
||||
|
@ -80,14 +79,16 @@ public class JmxMetricInsightInstaller implements AgentListener {
|
|||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,17 +51,22 @@ public class RuleParser {
|
|||
*
|
||||
* @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());
|
||||
|
|
Loading…
Reference in New Issue