jmx scraper align custom yaml config (#1678)
This commit is contained in:
parent
4cd6a0a777
commit
1615862cee
|
@ -16,7 +16,7 @@ Minimal configuration required
|
|||
|
||||
- `otel.jmx.service.url` for example `service:jmx:rmi:///jndi/rmi://server:9999/jmxrmi` for `server`
|
||||
host on port `9999` with RMI JMX connector.
|
||||
- `otel.jmx.target.system` or `otel.jmx.custom.scraping.config`
|
||||
- `otel.jmx.target.system` or `otel.jmx.config`
|
||||
|
||||
Configuration can be provided through:
|
||||
|
||||
|
@ -36,13 +36,13 @@ For example the `otel.jmx.service.url` option can be set with the `OTEL_JMX_SERV
|
|||
|
||||
## Configuration reference
|
||||
|
||||
| config option | description |
|
||||
|-----------------------------------|----------------------------------------------------------------------------------------------|
|
||||
| `otel.jmx.service.url` | mandatory JMX URL to connect to the remote JVM |
|
||||
| `otel.jmx.target.system` | comma-separated list of systems to monitor, mandatory unless a custom configuration is used |
|
||||
| `otel.jmx.custom.scraping.config` | path to a custom YAML metrics definition, mandatory when `otel.jmx.target.system` is not set |
|
||||
| `otel.jmx.username` | user name for JMX connection, mandatory when JMX authentication is enabled on target JVM |
|
||||
| `otel.jmx.password` | password for JMX connection, mandatory when JMX authentication is enabled on target JVM |
|
||||
| config option | description |
|
||||
|--------------------------|---------------------------------------------------------------------------------------------------------------------|
|
||||
| `otel.jmx.service.url` | mandatory JMX URL to connect to the remote JVM |
|
||||
| `otel.jmx.target.system` | comma-separated list of systems to monitor, mandatory unless a custom configuration is used |
|
||||
| `otel.jmx.config` | comma-separated list of paths to custom YAML metrics definition, mandatory when `otel.jmx.target.system` is not set |
|
||||
| `otel.jmx.username` | user name for JMX connection, mandatory when JMX authentication is enabled on target JVM |
|
||||
| `otel.jmx.password` | password for JMX connection, mandatory when JMX authentication is enabled on target JVM |
|
||||
|
||||
Supported values for `otel.jmx.target.system`:
|
||||
|
||||
|
|
|
@ -8,16 +8,20 @@ package io.opentelemetry.contrib.jmxscraper.config;
|
|||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/** This class keeps application settings */
|
||||
public class JmxScraperConfig {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(JmxScraperConfig.class.getName());
|
||||
|
||||
// metric sdk configuration
|
||||
static final String METRIC_EXPORT_INTERVAL = "otel.metric.export.interval";
|
||||
|
||||
|
@ -25,8 +29,13 @@ public class JmxScraperConfig {
|
|||
static final String JMX_INTERVAL_LEGACY = "otel.jmx.interval.milliseconds";
|
||||
|
||||
static final String JMX_SERVICE_URL = "otel.jmx.service.url";
|
||||
// TODO: align with instrumentation 'otel.jmx.config' + support list of values
|
||||
static final String JMX_CUSTOM_CONFIG = "otel.jmx.custom.scraping.config";
|
||||
|
||||
// the same as config option defined in instrumentation
|
||||
static final String JMX_CONFIG = "otel.jmx.config";
|
||||
|
||||
// not documented on purpose as it's deprecated
|
||||
static final String JMX_CONFIG_LEGACY = "otel.jmx.custom.scraping.config";
|
||||
|
||||
static final String JMX_TARGET_SYSTEM = "otel.jmx.target.system";
|
||||
|
||||
static final String JMX_USERNAME = "otel.jmx.username";
|
||||
|
@ -55,7 +64,7 @@ public class JmxScraperConfig {
|
|||
|
||||
private String serviceUrl = "";
|
||||
|
||||
@Nullable private String customJmxScrapingConfigPath;
|
||||
private List<String> jmxConfig = Collections.emptyList();
|
||||
|
||||
private Set<String> targetSystems = Collections.emptySet();
|
||||
|
||||
|
@ -76,9 +85,8 @@ public class JmxScraperConfig {
|
|||
return serviceUrl;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getCustomJmxScrapingConfigPath() {
|
||||
return customJmxScrapingConfigPath;
|
||||
public List<String> getJmxConfig() {
|
||||
return jmxConfig;
|
||||
}
|
||||
|
||||
public Set<String> getTargetSystems() {
|
||||
|
@ -136,12 +144,25 @@ public class JmxScraperConfig {
|
|||
}
|
||||
scraperConfig.serviceUrl = serviceUrl;
|
||||
|
||||
// TODO: we could support multiple values
|
||||
String customConfig = config.getString(JMX_CUSTOM_CONFIG, "");
|
||||
List<String> jmxConfig = config.getList(JMX_CONFIG);
|
||||
List<String> targetSystem = config.getList(JMX_TARGET_SYSTEM);
|
||||
if (targetSystem.isEmpty() && customConfig.isEmpty()) {
|
||||
|
||||
// providing compatibility with the deprecated 'otel.jmx.custom.scraping.config' config option
|
||||
String jmxConfigDeprecated = config.getString(JMX_CONFIG_LEGACY);
|
||||
if (jmxConfigDeprecated != null) {
|
||||
logger.warning(
|
||||
JMX_CONFIG_LEGACY
|
||||
+ " deprecated option is used, replacing with '"
|
||||
+ JMX_CONFIG
|
||||
+ "' is recommended");
|
||||
List<String> list = new ArrayList<>(jmxConfig);
|
||||
list.add(jmxConfigDeprecated);
|
||||
jmxConfig = list;
|
||||
}
|
||||
|
||||
if (targetSystem.isEmpty() && jmxConfig.isEmpty()) {
|
||||
throw new ConfigurationException(
|
||||
"at least one of '" + JMX_TARGET_SYSTEM + "' or '" + JMX_CUSTOM_CONFIG + "' must be set");
|
||||
"at least one of '" + JMX_TARGET_SYSTEM + "' or '" + JMX_CONFIG + "' must be set");
|
||||
}
|
||||
targetSystem.forEach(
|
||||
s -> {
|
||||
|
@ -149,8 +170,9 @@ public class JmxScraperConfig {
|
|||
throw new ConfigurationException("unsupported target system: '" + s + "'");
|
||||
}
|
||||
});
|
||||
scraperConfig.customJmxScrapingConfigPath = customConfig;
|
||||
scraperConfig.targetSystems = new HashSet<>(targetSystem);
|
||||
|
||||
scraperConfig.jmxConfig = Collections.unmodifiableList(jmxConfig);
|
||||
scraperConfig.targetSystems = Collections.unmodifiableSet(new HashSet<>(targetSystem));
|
||||
|
||||
scraperConfig.username = config.getString("otel.jmx.username");
|
||||
scraperConfig.password = config.getString("otel.jmx.password");
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
package io.opentelemetry.contrib.jmxscraper.config;
|
||||
|
||||
import static io.opentelemetry.contrib.jmxscraper.config.JmxScraperConfig.JMX_CUSTOM_CONFIG;
|
||||
import static io.opentelemetry.contrib.jmxscraper.config.JmxScraperConfig.JMX_CONFIG;
|
||||
import static io.opentelemetry.contrib.jmxscraper.config.JmxScraperConfig.JMX_CONFIG_LEGACY;
|
||||
import static io.opentelemetry.contrib.jmxscraper.config.JmxScraperConfig.JMX_PASSWORD;
|
||||
import static io.opentelemetry.contrib.jmxscraper.config.JmxScraperConfig.JMX_REALM;
|
||||
import static io.opentelemetry.contrib.jmxscraper.config.JmxScraperConfig.JMX_REGISTRY_SSL;
|
||||
|
@ -22,6 +23,8 @@ import java.time.Duration;
|
|||
import java.util.Properties;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
class JmxScraperConfigTest {
|
||||
private static Properties validProperties;
|
||||
|
@ -31,7 +34,7 @@ class JmxScraperConfigTest {
|
|||
validProperties = new Properties();
|
||||
validProperties.setProperty(
|
||||
JMX_SERVICE_URL, "jservice:jmx:rmi:///jndi/rmi://localhost:9010/jmxrmi");
|
||||
validProperties.setProperty(JMX_CUSTOM_CONFIG, "/path/to/config.yaml");
|
||||
validProperties.setProperty(JMX_CONFIG, "/path/to/config.yaml");
|
||||
validProperties.setProperty(JMX_TARGET_SYSTEM, "tomcat, activemq");
|
||||
validProperties.setProperty(JMX_REGISTRY_SSL, "true");
|
||||
validProperties.setProperty(JMX_USERNAME, "some-user");
|
||||
|
@ -50,7 +53,7 @@ class JmxScraperConfigTest {
|
|||
// Then
|
||||
assertThat(config.getServiceUrl())
|
||||
.isEqualTo("jservice:jmx:rmi:///jndi/rmi://localhost:9010/jmxrmi");
|
||||
assertThat(config.getCustomJmxScrapingConfigPath()).isEqualTo("/path/to/config.yaml");
|
||||
assertThat(config.getJmxConfig()).containsExactly("/path/to/config.yaml");
|
||||
assertThat(config.getTargetSystems()).containsExactlyInAnyOrder("tomcat", "activemq");
|
||||
assertThat(config.getSamplingInterval()).isEqualTo(Duration.ofSeconds(10));
|
||||
assertThat(config.getUsername()).isEqualTo("some-user");
|
||||
|
@ -59,12 +62,17 @@ class JmxScraperConfigTest {
|
|||
assertThat(config.getRealm()).isEqualTo("some-realm");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCreateMinimalValidConfiguration() {
|
||||
@ParameterizedTest(name = "custom yaml = {arguments}")
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void shouldCreateMinimalValidConfiguration(boolean customYaml) {
|
||||
// Given
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(JMX_SERVICE_URL, "jservice:jmx:rmi:///jndi/rmi://localhost:9010/jmxrmi");
|
||||
properties.setProperty(JMX_CUSTOM_CONFIG, "/file.properties");
|
||||
if (customYaml) {
|
||||
properties.setProperty(JMX_CONFIG, "/file.yaml");
|
||||
} else {
|
||||
properties.setProperty(JMX_TARGET_SYSTEM, "tomcat");
|
||||
}
|
||||
|
||||
// When
|
||||
JmxScraperConfig config = fromConfig(TestUtil.configProperties(properties));
|
||||
|
@ -72,8 +80,15 @@ class JmxScraperConfigTest {
|
|||
// Then
|
||||
assertThat(config.getServiceUrl())
|
||||
.isEqualTo("jservice:jmx:rmi:///jndi/rmi://localhost:9010/jmxrmi");
|
||||
assertThat(config.getCustomJmxScrapingConfigPath()).isEqualTo("/file.properties");
|
||||
assertThat(config.getTargetSystems()).isEmpty();
|
||||
|
||||
if (customYaml) {
|
||||
assertThat(config.getJmxConfig()).containsExactly("/file.yaml");
|
||||
assertThat(config.getTargetSystems()).isEmpty();
|
||||
} else {
|
||||
assertThat(config.getJmxConfig()).isEmpty();
|
||||
assertThat(config.getTargetSystems()).containsExactly("tomcat");
|
||||
}
|
||||
|
||||
assertThat(config.getSamplingInterval())
|
||||
.describedAs("default sampling interval must align to default metric export interval")
|
||||
.isEqualTo(Duration.ofMinutes(1));
|
||||
|
@ -83,6 +98,21 @@ class JmxScraperConfigTest {
|
|||
assertThat(config.getRealm()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void legacyCustomScrapingConfig() {
|
||||
// Given
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(JMX_SERVICE_URL, "jservice:jmx:rmi:///jndi/rmi://localhost:9010/jmxrmi");
|
||||
properties.setProperty(JMX_CONFIG_LEGACY, "/file.yaml");
|
||||
properties.setProperty(JMX_CONFIG, "/another.yaml");
|
||||
|
||||
// When
|
||||
JmxScraperConfig config = fromConfig(TestUtil.configProperties(properties));
|
||||
|
||||
// Then
|
||||
assertThat(config.getJmxConfig()).containsOnly("/file.yaml", "/another.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailValidation_missingServiceUrl() {
|
||||
// Given
|
||||
|
@ -99,14 +129,13 @@ class JmxScraperConfigTest {
|
|||
void shouldFailValidation_missingConfigPathAndTargetSystem() {
|
||||
// Given
|
||||
Properties properties = (Properties) validProperties.clone();
|
||||
properties.remove(JMX_CUSTOM_CONFIG);
|
||||
properties.remove(JMX_CONFIG);
|
||||
properties.remove(JMX_TARGET_SYSTEM);
|
||||
|
||||
// When and Then
|
||||
assertThatThrownBy(() -> fromConfig(TestUtil.configProperties(properties)))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessage(
|
||||
"at least one of 'otel.jmx.target.system' or 'otel.jmx.custom.scraping.config' must be set");
|
||||
.hasMessage("at least one of 'otel.jmx.target.system' or 'otel.jmx.config' must be set");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
otel.jmx.service.url=service:jmx:rmi:///jndi/rmi://myhost:12345/jmxrmi
|
||||
otel.jmx.custom.scraping.config=/my/scraping-config.yaml
|
||||
otel.jmx.config=/my/scraping-config.yaml
|
||||
otel.jmx.target.system=jvm,cassandra
|
||||
otel.metrics.exporter=otlp
|
||||
otel.metric.export.interval=1000
|
||||
|
|
Loading…
Reference in New Issue