66package io .opentelemetry .contrib .jmxscraper ;
77
88import io .opentelemetry .api .GlobalOpenTelemetry ;
9- import io .opentelemetry .contrib .jmxscraper .config .ConfigurationException ;
109import io .opentelemetry .contrib .jmxscraper .config .JmxScraperConfig ;
10+ import io .opentelemetry .contrib .jmxscraper .config .PropertiesCustomizer ;
11+ import io .opentelemetry .contrib .jmxscraper .config .PropertiesSupplier ;
1112import io .opentelemetry .instrumentation .jmx .engine .JmxMetricInsight ;
1213import io .opentelemetry .instrumentation .jmx .engine .MetricConfiguration ;
1314import io .opentelemetry .instrumentation .jmx .yaml .RuleParser ;
15+ import io .opentelemetry .sdk .autoconfigure .AutoConfiguredOpenTelemetrySdk ;
16+ import io .opentelemetry .sdk .autoconfigure .spi .ConfigurationException ;
1417import java .io .DataInputStream ;
1518import java .io .IOException ;
1619import java .io .InputStream ;
1922import java .util .Arrays ;
2023import java .util .Collections ;
2124import java .util .List ;
25+ import java .util .Map ;
2226import java .util .Optional ;
2327import java .util .Properties ;
2428import java .util .concurrent .atomic .AtomicBoolean ;
29+ import java .util .logging .Level ;
2530import java .util .logging .Logger ;
2631import javax .management .MBeanServerConnection ;
2732import javax .management .remote .JMXConnector ;
@@ -30,8 +35,6 @@ public class JmxScraper {
3035 private static final Logger logger = Logger .getLogger (JmxScraper .class .getName ());
3136 private static final String CONFIG_ARG = "-config" ;
3237
33- private static final String OTEL_AUTOCONFIGURE = "otel.java.global-autoconfigure.enabled" ;
34-
3538 private final JmxConnectorBuilder client ;
3639 private final JmxMetricInsight service ;
3740 private final JmxScraperConfig config ;
@@ -43,69 +46,88 @@ public class JmxScraper {
4346 *
4447 * @param args - must be of the form "-config {jmx_config_path,'-'}"
4548 */
46- @ SuppressWarnings ({ "SystemOut" , " SystemExitOutsideMain"} )
49+ @ SuppressWarnings (" SystemExitOutsideMain" )
4750 public static void main (String [] args ) {
4851
49- // enable SDK auto-configure if not explicitly set by user
50- // TODO: refactor this to use AutoConfiguredOpenTelemetrySdk
51- if (System .getProperty (OTEL_AUTOCONFIGURE ) == null ) {
52- System .setProperty (OTEL_AUTOCONFIGURE , "true" );
53- }
52+ // set log format
53+ System .setProperty ("java.util.logging.SimpleFormatter.format" , "%1$tF %1$tT %4$s %5$s%n" );
5454
5555 try {
56- JmxScraperConfig config =
57- JmxScraperConfig .fromProperties (parseArgs (Arrays .asList (args )), System .getProperties ());
58- // propagate effective user-provided configuration to JVM system properties
59- // this also enables SDK auto-configuration to use those properties
60- config .propagateSystemProperties ();
56+ Properties argsConfig = parseArgs (Arrays .asList (args ));
57+ propagateToSystemProperties (argsConfig );
58+
59+ // auto-configure and register SDK
60+ PropertiesCustomizer configCustomizer = new PropertiesCustomizer ();
61+ AutoConfiguredOpenTelemetrySdk .builder ()
62+ .addPropertiesSupplier (new PropertiesSupplier (argsConfig ))
63+ .addPropertiesCustomizer (configCustomizer )
64+ .setResultAsGlobal ()
65+ .build ();
66+
67+ JmxScraperConfig scraperConfig = configCustomizer .getScraperConfig ();
68+
69+ long exportSeconds = scraperConfig .getSamplingInterval ().toMillis () / 1000 ;
70+ logger .log (Level .INFO , "metrics export interval (seconds) = " + exportSeconds );
6171
6272 JmxMetricInsight service =
6373 JmxMetricInsight .createService (
64- GlobalOpenTelemetry .get (), config .getIntervalMilliseconds ());
65- JmxConnectorBuilder connectorBuilder = JmxConnectorBuilder .createNew (config .getServiceUrl ());
74+ GlobalOpenTelemetry .get (), scraperConfig .getSamplingInterval ().toMillis ());
75+ JmxConnectorBuilder connectorBuilder =
76+ JmxConnectorBuilder .createNew (scraperConfig .getServiceUrl ());
6677
67- Optional .ofNullable (config .getUsername ()).ifPresent (connectorBuilder ::withUser );
68- Optional .ofNullable (config .getPassword ()).ifPresent (connectorBuilder ::withPassword );
78+ Optional .ofNullable (scraperConfig .getUsername ()).ifPresent (connectorBuilder ::withUser );
79+ Optional .ofNullable (scraperConfig .getPassword ()).ifPresent (connectorBuilder ::withPassword );
6980
70- JmxScraper jmxScraper = new JmxScraper (connectorBuilder , service , config );
81+ JmxScraper jmxScraper = new JmxScraper (connectorBuilder , service , scraperConfig );
7182 jmxScraper .start ();
72-
73- } catch (ArgumentsParsingException e ) {
74- System .err .println ("ERROR: " + e .getMessage ());
75- System .err .println (
83+ } catch (ConfigurationException e ) {
84+ logger .log (Level .SEVERE , "invalid configuration " , e );
85+ System .exit (1 );
86+ } catch (InvalidArgumentException e ) {
87+ logger .log (Level .SEVERE , "invalid configuration provided through arguments" , e );
88+ logger .info (
7689 "Usage: java -jar <path_to_jmxscraper.jar> "
7790 + "-config <path_to_config.properties or - for stdin>" );
7891 System .exit (1 );
79- } catch (ConfigurationException e ) {
80- System .err .println (e .getMessage ());
81- System .exit (1 );
8292 } catch (IOException e ) {
83- System . err . println ( "Unable to connect " + e . getMessage () );
93+ logger . log ( Level . SEVERE , "Unable to connect " , e );
8494 System .exit (2 );
8595 } catch (RuntimeException e ) {
86- e . printStackTrace ( System . err );
96+ logger . log ( Level . SEVERE , e . getMessage (), e );
8797 System .exit (3 );
8898 }
8999 }
90100
101+ // package private for testing
102+ static void propagateToSystemProperties (Properties properties ) {
103+ for (Map .Entry <Object , Object > entry : properties .entrySet ()) {
104+ String key = entry .getKey ().toString ();
105+ String value = entry .getValue ().toString ();
106+ if (key .startsWith ("javax.net.ssl.keyStore" ) || key .startsWith ("javax.net.ssl.trustStore" )) {
107+ if (System .getProperty (key ) == null ) {
108+ System .setProperty (key , value );
109+ }
110+ }
111+ }
112+ }
113+
91114 /**
92115 * Create {@link Properties} from command line options
93116 *
94117 * @param args application commandline arguments
95118 */
96- static Properties parseArgs (List <String > args )
97- throws ArgumentsParsingException , ConfigurationException {
119+ static Properties parseArgs (List <String > args ) throws InvalidArgumentException {
98120
99121 if (args .isEmpty ()) {
100122 // empty properties from stdin or external file
101123 // config could still be provided through JVM system properties
102124 return new Properties ();
103125 }
104126 if (args .size () != 2 ) {
105- throw new ArgumentsParsingException ("Exactly two arguments expected, got " + args .size ());
127+ throw new InvalidArgumentException ("Exactly two arguments expected, got " + args .size ());
106128 }
107129 if (!args .get (0 ).equalsIgnoreCase (CONFIG_ARG )) {
108- throw new ArgumentsParsingException ("Unexpected first argument must be '" + CONFIG_ARG + "'" );
130+ throw new InvalidArgumentException ("Unexpected first argument must be '" + CONFIG_ARG + "'" );
109131 }
110132
111133 String path = args .get (1 );
@@ -116,27 +138,30 @@ static Properties parseArgs(List<String> args)
116138 }
117139 }
118140
119- private static Properties loadPropertiesFromStdin () throws ConfigurationException {
141+ private static Properties loadPropertiesFromStdin () throws InvalidArgumentException {
120142 Properties properties = new Properties ();
121143 try (InputStream is = new DataInputStream (System .in )) {
122144 properties .load (is );
123145 return properties ;
124146 } catch (IOException e ) {
125- throw new ConfigurationException ("Failed to read config properties from stdin" , e );
147+ // an IO error is very unlikely here
148+ throw new InvalidArgumentException ("Failed to read config properties from stdin" , e );
126149 }
127150 }
128151
129- private static Properties loadPropertiesFromPath (String path ) throws ConfigurationException {
152+ private static Properties loadPropertiesFromPath (String path ) throws InvalidArgumentException {
130153 Properties properties = new Properties ();
131154 try (InputStream is = Files .newInputStream (Paths .get (path ))) {
132155 properties .load (is );
133156 return properties ;
134157 } catch (IOException e ) {
135- throw new ConfigurationException ("Failed to read config properties file: '" + path + "'" , e );
158+ throw new InvalidArgumentException (
159+ "Failed to read config properties file: '" + path + "'" , e );
136160 }
137161 }
138162
139- JmxScraper (JmxConnectorBuilder client , JmxMetricInsight service , JmxScraperConfig config ) {
163+ private JmxScraper (
164+ JmxConnectorBuilder client , JmxMetricInsight service , JmxScraperConfig config ) {
140165 this .client = client ;
141166 this .service = service ;
142167 this .config = config ;
0 commit comments