|
9 | 9 | import io.opentelemetry.contrib.jmxscraper.config.JmxScraperConfig;
|
10 | 10 | import io.opentelemetry.contrib.jmxscraper.config.JmxScraperConfigFactory;
|
11 | 11 | import io.opentelemetry.contrib.jmxscraper.jmx.JmxClient;
|
| 12 | +import java.io.DataInputStream; |
| 13 | +import java.io.IOException; |
| 14 | +import java.io.InputStream; |
12 | 15 | import java.net.MalformedURLException;
|
| 16 | +import java.nio.file.Files; |
| 17 | +import java.nio.file.Paths; |
13 | 18 | import java.util.Arrays;
|
| 19 | +import java.util.List; |
| 20 | +import java.util.Properties; |
14 | 21 | import java.util.concurrent.Executors;
|
15 | 22 | import java.util.concurrent.ScheduledExecutorService;
|
16 | 23 | import java.util.concurrent.TimeUnit;
|
17 | 24 | import java.util.logging.Logger;
|
18 | 25 |
|
19 | 26 | public class JmxScraper {
|
20 | 27 | private static final Logger logger = Logger.getLogger(JmxScraper.class.getName());
|
| 28 | + private static final int EXECUTOR_TERMINATION_TIMEOUT_MS = 5000; |
21 | 29 | private final ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
|
22 | 30 | private final JmxScraperConfig config;
|
23 | 31 |
|
24 |
| - JmxScraper(JmxScraperConfig config) { |
| 32 | + /** |
| 33 | + * Main method to create and run a {@link JmxScraper} instance. |
| 34 | + * |
| 35 | + * @param args - must be of the form "-config {jmx_config_path,'-'}" |
| 36 | + */ |
| 37 | + @SuppressWarnings({"SystemOut", "SystemExitOutsideMain"}) |
| 38 | + public static void main(String[] args) { |
| 39 | + try { |
| 40 | + JmxScraperConfigFactory factory = new JmxScraperConfigFactory(); |
| 41 | + JmxScraperConfig config = JmxScraper.createConfigFromArgs(Arrays.asList(args), factory); |
| 42 | + |
| 43 | + JmxScraper jmxScraper = new JmxScraper(config); |
| 44 | + jmxScraper.start(); |
| 45 | + |
| 46 | + Runtime.getRuntime() |
| 47 | + .addShutdownHook( |
| 48 | + new Thread() { |
| 49 | + @Override |
| 50 | + public void run() { |
| 51 | + jmxScraper.shutdown(); |
| 52 | + } |
| 53 | + }); |
| 54 | + } catch (ArgumentsParsingException e) { |
| 55 | + System.err.println( |
| 56 | + "Usage: java -jar <path_to_jmxscraper.jar> " |
| 57 | + + "-config <path_to_config.properties or - for stdin>"); |
| 58 | + System.exit(1); |
| 59 | + } catch (ConfigurationException e) { |
| 60 | + System.err.println(e.getMessage()); |
| 61 | + System.exit(1); |
| 62 | + } |
| 63 | + } |
| 64 | + |
| 65 | + /** |
| 66 | + * Create {@link JmxScraperConfig} object basing on command line options |
| 67 | + * |
| 68 | + * @param args application commandline arguments |
| 69 | + */ |
| 70 | + static JmxScraperConfig createConfigFromArgs(List<String> args, JmxScraperConfigFactory factory) |
| 71 | + throws ArgumentsParsingException, ConfigurationException { |
| 72 | + if (!args.isEmpty() && (args.size() != 2 || !args.get(0).equalsIgnoreCase("-config"))) { |
| 73 | + throw new ArgumentsParsingException(); |
| 74 | + } |
| 75 | + |
| 76 | + Properties loadedProperties = new Properties(); |
| 77 | + if (args.size() == 2) { |
| 78 | + String path = args.get(1); |
| 79 | + if (path.trim().equals("-")) { |
| 80 | + loadPropertiesFromStdin(loadedProperties); |
| 81 | + } else { |
| 82 | + loadPropertiesFromPath(loadedProperties, path); |
| 83 | + } |
| 84 | + } |
| 85 | + |
| 86 | + return factory.createConfig(loadedProperties); |
| 87 | + } |
| 88 | + |
| 89 | + private static void loadPropertiesFromStdin(Properties props) throws ConfigurationException { |
| 90 | + try (InputStream is = new DataInputStream(System.in)) { |
| 91 | + props.load(is); |
| 92 | + } catch (IOException e) { |
| 93 | + throw new ConfigurationException("Failed to read config properties from stdin", e); |
| 94 | + } |
| 95 | + } |
| 96 | + |
| 97 | + private static void loadPropertiesFromPath(Properties props, String path) |
| 98 | + throws ConfigurationException { |
| 99 | + try (InputStream is = Files.newInputStream(Paths.get(path))) { |
| 100 | + props.load(is); |
| 101 | + } catch (IOException e) { |
| 102 | + throw new ConfigurationException("Failed to read config properties file: '" + path + "'", e); |
| 103 | + } |
| 104 | + } |
| 105 | + |
| 106 | + JmxScraper(JmxScraperConfig config) throws ConfigurationException { |
25 | 107 | this.config = config;
|
26 | 108 |
|
27 | 109 | try {
|
@@ -51,28 +133,23 @@ private void start() {
|
51 | 133 |
|
52 | 134 | private void shutdown() {
|
53 | 135 | logger.info("Shutting down JmxScraper and exporting final metrics.");
|
| 136 | + // Prevent new tasks to be submitted |
54 | 137 | exec.shutdown();
|
55 |
| - } |
56 |
| - |
57 |
| - /** |
58 |
| - * Main method to create and run a {@link JmxScraper} instance. |
59 |
| - * |
60 |
| - * @param args - must be of the form "-config {jmx_config_path,'-'}" |
61 |
| - */ |
62 |
| - public static void main(String[] args) { |
63 |
| - JmxScraperConfigFactory factory = new JmxScraperConfigFactory(); |
64 |
| - JmxScraperConfig config = factory.createConfigFromArgs(Arrays.asList(args)); |
65 |
| - |
66 |
| - JmxScraper jmxScraper = new JmxScraper(config); |
67 |
| - jmxScraper.start(); |
68 |
| - |
69 |
| - Runtime.getRuntime() |
70 |
| - .addShutdownHook( |
71 |
| - new Thread() { |
72 |
| - @Override |
73 |
| - public void run() { |
74 |
| - jmxScraper.shutdown(); |
75 |
| - } |
76 |
| - }); |
| 138 | + try { |
| 139 | + // Wait a while for existing tasks to terminate |
| 140 | + if (!exec.awaitTermination(EXECUTOR_TERMINATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { |
| 141 | + // Cancel currently executing tasks |
| 142 | + exec.shutdownNow(); |
| 143 | + // Wait a while for tasks to respond to being cancelled |
| 144 | + if (!exec.awaitTermination(EXECUTOR_TERMINATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { |
| 145 | + logger.warning("Thread pool did not terminate in time: " + exec); |
| 146 | + } |
| 147 | + } |
| 148 | + } catch (InterruptedException e) { |
| 149 | + // (Re-)Cancel if current thread also interrupted |
| 150 | + exec.shutdownNow(); |
| 151 | + // Preserve interrupt status |
| 152 | + Thread.currentThread().interrupt(); |
| 153 | + } |
77 | 154 | }
|
78 | 155 | }
|
0 commit comments