6
6
package io .opentelemetry .contrib .jmxscraper ;
7
7
8
8
import io .opentelemetry .api .GlobalOpenTelemetry ;
9
- import io .opentelemetry .contrib .jmxscraper .config .ConfigurationException ;
10
9
import io .opentelemetry .contrib .jmxscraper .config .JmxScraperConfig ;
10
+ import io .opentelemetry .contrib .jmxscraper .config .PropertiesCustomizer ;
11
+ import io .opentelemetry .contrib .jmxscraper .config .PropertiesSupplier ;
11
12
import io .opentelemetry .instrumentation .jmx .engine .JmxMetricInsight ;
12
13
import io .opentelemetry .instrumentation .jmx .engine .MetricConfiguration ;
13
14
import io .opentelemetry .instrumentation .jmx .yaml .RuleParser ;
15
+ import io .opentelemetry .sdk .autoconfigure .AutoConfiguredOpenTelemetrySdk ;
16
+ import io .opentelemetry .sdk .autoconfigure .spi .ConfigurationException ;
14
17
import java .io .DataInputStream ;
15
18
import java .io .IOException ;
16
19
import java .io .InputStream ;
19
22
import java .util .Arrays ;
20
23
import java .util .Collections ;
21
24
import java .util .List ;
25
+ import java .util .Map ;
22
26
import java .util .Optional ;
23
27
import java .util .Properties ;
24
28
import java .util .concurrent .atomic .AtomicBoolean ;
29
+ import java .util .logging .Level ;
25
30
import java .util .logging .Logger ;
26
31
import javax .management .MBeanServerConnection ;
27
32
import javax .management .remote .JMXConnector ;
@@ -30,8 +35,6 @@ public class JmxScraper {
30
35
private static final Logger logger = Logger .getLogger (JmxScraper .class .getName ());
31
36
private static final String CONFIG_ARG = "-config" ;
32
37
33
- private static final String OTEL_AUTOCONFIGURE = "otel.java.global-autoconfigure.enabled" ;
34
-
35
38
private final JmxConnectorBuilder client ;
36
39
private final JmxMetricInsight service ;
37
40
private final JmxScraperConfig config ;
@@ -43,69 +46,88 @@ public class JmxScraper {
43
46
*
44
47
* @param args - must be of the form "-config {jmx_config_path,'-'}"
45
48
*/
46
- @ SuppressWarnings ({ "SystemOut" , " SystemExitOutsideMain"} )
49
+ @ SuppressWarnings (" SystemExitOutsideMain" )
47
50
public static void main (String [] args ) {
48
51
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" );
54
54
55
55
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 );
61
71
62
72
JmxMetricInsight service =
63
73
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 ());
66
77
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 );
69
80
70
- JmxScraper jmxScraper = new JmxScraper (connectorBuilder , service , config );
81
+ JmxScraper jmxScraper = new JmxScraper (connectorBuilder , service , scraperConfig );
71
82
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 (
76
89
"Usage: java -jar <path_to_jmxscraper.jar> "
77
90
+ "-config <path_to_config.properties or - for stdin>" );
78
91
System .exit (1 );
79
- } catch (ConfigurationException e ) {
80
- System .err .println (e .getMessage ());
81
- System .exit (1 );
82
92
} catch (IOException e ) {
83
- System . err . println ( "Unable to connect " + e . getMessage () );
93
+ logger . log ( Level . SEVERE , "Unable to connect " , e );
84
94
System .exit (2 );
85
95
} catch (RuntimeException e ) {
86
- e . printStackTrace ( System . err );
96
+ logger . log ( Level . SEVERE , e . getMessage (), e );
87
97
System .exit (3 );
88
98
}
89
99
}
90
100
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
+
91
114
/**
92
115
* Create {@link Properties} from command line options
93
116
*
94
117
* @param args application commandline arguments
95
118
*/
96
- static Properties parseArgs (List <String > args )
97
- throws ArgumentsParsingException , ConfigurationException {
119
+ static Properties parseArgs (List <String > args ) throws InvalidArgumentException {
98
120
99
121
if (args .isEmpty ()) {
100
122
// empty properties from stdin or external file
101
123
// config could still be provided through JVM system properties
102
124
return new Properties ();
103
125
}
104
126
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 ());
106
128
}
107
129
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 + "'" );
109
131
}
110
132
111
133
String path = args .get (1 );
@@ -116,27 +138,30 @@ static Properties parseArgs(List<String> args)
116
138
}
117
139
}
118
140
119
- private static Properties loadPropertiesFromStdin () throws ConfigurationException {
141
+ private static Properties loadPropertiesFromStdin () throws InvalidArgumentException {
120
142
Properties properties = new Properties ();
121
143
try (InputStream is = new DataInputStream (System .in )) {
122
144
properties .load (is );
123
145
return properties ;
124
146
} 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 );
126
149
}
127
150
}
128
151
129
- private static Properties loadPropertiesFromPath (String path ) throws ConfigurationException {
152
+ private static Properties loadPropertiesFromPath (String path ) throws InvalidArgumentException {
130
153
Properties properties = new Properties ();
131
154
try (InputStream is = Files .newInputStream (Paths .get (path ))) {
132
155
properties .load (is );
133
156
return properties ;
134
157
} 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 );
136
160
}
137
161
}
138
162
139
- JmxScraper (JmxConnectorBuilder client , JmxMetricInsight service , JmxScraperConfig config ) {
163
+ private JmxScraper (
164
+ JmxConnectorBuilder client , JmxMetricInsight service , JmxScraperConfig config ) {
140
165
this .client = client ;
141
166
this .service = service ;
142
167
this .config = config ;
0 commit comments