55
66package io .opentelemetry .contrib .jmxscraper ;
77
8+ import io .opentelemetry .api .GlobalOpenTelemetry ;
89import io .opentelemetry .contrib .jmxscraper .config .ConfigurationException ;
910import io .opentelemetry .contrib .jmxscraper .config .JmxScraperConfig ;
11+ import io .opentelemetry .instrumentation .jmx .engine .JmxMetricInsight ;
12+ import io .opentelemetry .instrumentation .jmx .engine .MetricConfiguration ;
13+ import io .opentelemetry .instrumentation .jmx .yaml .RuleParser ;
1014import java .io .DataInputStream ;
1115import java .io .IOException ;
1216import java .io .InputStream ;
1317import java .nio .file .Files ;
1418import java .nio .file .Paths ;
1519import java .util .Arrays ;
20+ import java .util .Collections ;
1621import java .util .List ;
1722import java .util .Properties ;
23+ import java .util .concurrent .atomic .AtomicBoolean ;
1824import java .util .logging .Logger ;
1925import javax .management .MBeanServerConnection ;
2026import javax .management .remote .JMXConnector ;
@@ -23,10 +29,13 @@ public class JmxScraper {
2329 private static final Logger logger = Logger .getLogger (JmxScraper .class .getName ());
2430 private static final String CONFIG_ARG = "-config" ;
2531
32+ private static final String OTEL_AUTOCONFIGURE = "otel.java.global-autoconfigure.enabled" ;
33+
2634 private final JmxConnectorBuilder client ;
35+ private final JmxMetricInsight service ;
36+ private final JmxScraperConfig config ;
2737
28- // TODO depend on instrumentation 2.9.0 snapshot
29- // private final JmxMetricInsight service;
38+ private final AtomicBoolean running = new AtomicBoolean (false );
3039
3140 /**
3241 * Main method to create and run a {@link JmxScraper} instance.
@@ -35,15 +44,23 @@ public class JmxScraper {
3544 */
3645 @ SuppressWarnings ({"SystemOut" , "SystemExitOutsideMain" })
3746 public static void main (String [] args ) {
47+
48+ // enable SDK auto-configure if not explicitly set by user
49+ if (System .getProperty (OTEL_AUTOCONFIGURE ) == null ) {
50+ System .setProperty (OTEL_AUTOCONFIGURE , "true" );
51+ }
52+
3853 try {
3954 JmxScraperConfig config =
4055 JmxScraperConfig .fromProperties (parseArgs (Arrays .asList (args )), System .getProperties ());
4156 // propagate effective user-provided configuration to JVM system properties
57+ // this also enables SDK auto-configuration to use those properties
4258 config .propagateSystemProperties ();
43- // TODO: depend on instrumentation 2.9.0 snapshot
44- // service = JmxMetricInsight.createService(GlobalOpenTelemetry.get(),
45- // config.getIntervalMilliseconds());
46- JmxScraper jmxScraper = new JmxScraper (JmxConnectorBuilder .createNew (config .getServiceUrl ()));
59+
60+ JmxMetricInsight service = JmxMetricInsight .createService (GlobalOpenTelemetry .get (),
61+ config .getIntervalMilliseconds ());
62+ JmxScraper jmxScraper = new JmxScraper (JmxConnectorBuilder .createNew (config .getServiceUrl ()),
63+ service , config );
4764 jmxScraper .start ();
4865
4966 } catch (ArgumentsParsingException e ) {
@@ -109,29 +126,63 @@ private static Properties loadPropertiesFromPath(String path) throws Configurati
109126 }
110127 }
111128
112- JmxScraper (JmxConnectorBuilder client ) {
129+ JmxScraper (JmxConnectorBuilder client , JmxMetricInsight service , JmxScraperConfig config ) {
113130 this .client = client ;
131+ this .service = service ;
132+ this .config = config ;
114133 }
115134
116135 private void start () throws IOException {
136+ Runtime .getRuntime ().addShutdownHook (new Thread (() -> {
137+ logger .info ("JMX scraping stopped" );
138+ running .set (false );
139+ }));
140+
141+ try (JMXConnector connector = client .build ()) {
142+ MBeanServerConnection connection = connector .getMBeanServerConnection ();
143+ service .startRemote (getMetricConfig (config ), () -> Collections .singletonList (connection ));
144+
145+ running .set (true );
146+ logger .info ("JMX scraping started" );
147+
148+ while (running .get ()) {
149+ try {
150+ Thread .sleep (100 );
151+ } catch (InterruptedException e ) {
152+ // silenty ignored
153+ }
154+ }
155+ }
156+ }
117157
118- JMXConnector connector = client .build ();
119-
120- @ SuppressWarnings ("unused" )
121- MBeanServerConnection connection = connector .getMBeanServerConnection ();
122-
123- // TODO: depend on instrumentation 2.9.0 snapshot
124- // MetricConfiguration metricConfig = new MetricConfiguration();
125- // TODO create JMX insight config from scraper config
126- // service.startRemote(metricConfig, () -> Collections.singletonList(connection));
158+ private static MetricConfiguration getMetricConfig (JmxScraperConfig scraperConfig ) {
159+ MetricConfiguration config = new MetricConfiguration ();
160+ for (String system : scraperConfig .getTargetSystems ()) {
161+ try {
162+ addRulesForSystem (system , config );
163+ } catch (RuntimeException e ) {
164+ logger .warning ("unable to load rules for system " + system + ": " + e .getMessage ());
165+ }
166+ }
167+ // TODO : add ability for user to provide custom yaml configurations
127168
128- logger .info ("JMX scraping started" );
169+ return config ;
170+ }
129171
130- // TODO: wait a bit to keep the JVM running, this won't be needed once calling jmx insight
131- try {
132- Thread .sleep (5000 );
133- } catch (InterruptedException e ) {
134- throw new IllegalStateException (e );
172+ private static void addRulesForSystem (String system , MetricConfiguration conf ) {
173+ String yamlResource = system + ".yaml" ;
174+ try (InputStream inputStream =
175+ JmxScraper .class .getClassLoader ().getResourceAsStream (yamlResource )) {
176+ if (inputStream != null ) {
177+ RuleParser parserInstance = RuleParser .get ();
178+ parserInstance .addMetricDefsTo (conf , inputStream , system );
179+ } else {
180+ throw new IllegalStateException ("no support for " + system );
181+ }
182+ } catch (Exception e ) {
183+ throw new IllegalStateException ("error while loading rules for system " + system , e );
135184 }
136185 }
186+
187+
137188}
0 commit comments