77import io .prometheus .client .Gauge ;
88import oracle .observability .ObservabilityExporter ;
99import org .springframework .web .bind .annotation .GetMapping ;
10+ import org .springframework .web .bind .annotation .RequestParam ;
1011import org .springframework .web .bind .annotation .RestController ;
1112
1213import org .slf4j .Logger ;
@@ -31,30 +32,38 @@ public class MetricsExporter extends ObservabilityExporter {
3132 public static final String LABELS = "labels" ;
3233 public static final String IGNOREZERORESULT = "ignorezeroresult" ;
3334 public static final String FALSE = "false" ;
34- public String LISTEN_ADDRESS = System .getenv ("LISTEN_ADDRESS" ); // ":9161"
35- public String TELEMETRY_PATH = System .getenv ("TELEMETRY_PATH" ); // "/metrics"
36- //Interval between each scrape. Default is to scrape on collect requests. scrape.interval
37- public String SCRAPE_INTERVAL = System .getenv ("scrape.interval" ); // "0s"
3835 public static final String ORACLEDB_METRIC_PREFIX = "oracledb_" ;
3936 Map <String , Gauge > gaugeMap = new HashMap <>();
37+ Map <String , CollectorRegistry > dnsToCollectorRegistryMap = new HashMap <>();
38+
39+
4040
4141 /**
4242 * The endpoint that prometheus will scrape
4343 * @return Prometheus metric
44- * @throws Exception
4544 */
4645 @ GetMapping (value = "/metrics" , produces = "text/plain" )
4746 public String metrics () throws Exception {
48- processMetrics ();
49- return getMetricsString ();
47+ processMetrics (DATA_SOURCE_NAME , CollectorRegistry .defaultRegistry );
48+ return getMetricsString (CollectorRegistry .defaultRegistry );
49+ }
50+ @ GetMapping (value = "/scrape" , produces = "text/plain" )
51+ public String scrape (@ RequestParam ("target" ) String target ) throws Exception {
52+ CollectorRegistry collectorRegistry = dnsToCollectorRegistryMap .get (target );
53+ if (collectorRegistry == null ) {
54+ collectorRegistry = new CollectorRegistry ();
55+ dnsToCollectorRegistryMap .put (target , collectorRegistry );
56+ }
57+ processMetrics (target , dnsToCollectorRegistryMap .get (target ));
58+ return getMetricsString (collectorRegistry );
5059 }
5160
5261 @ PostConstruct
5362 public void init () throws Exception {
54- processMetrics ();
63+ processMetrics (DATA_SOURCE_NAME , CollectorRegistry . defaultRegistry );
5564 }
5665
57- private void processMetrics () throws IOException , SQLException {
66+ private void processMetrics (String datasourceName , CollectorRegistry registry ) throws IOException , SQLException {
5867 File tomlfile = new File (DEFAULT_METRICS );
5968 TomlMapper mapper = new TomlMapper ();
6069 JsonNode jsonNode = mapper .readerFor (MetricsExporterConfigEntry .class ).readTree (new FileInputStream (tomlfile ));
@@ -65,15 +74,15 @@ private void processMetrics() throws IOException, SQLException {
6574 }
6675 Iterator <JsonNode > metrics = metric .iterator ();
6776 int isConnectionSuccessful = 0 ;
68- try (Connection connection = getPoolDataSource ().getConnection ()) {
77+ try (Connection connection = getPoolDataSource (datasourceName ).getConnection ()) {
6978 isConnectionSuccessful = 1 ;
7079 while (metrics .hasNext ()) {
71- processMetric (connection , metrics );
80+ processMetric (registry , connection , metrics );
7281 }
7382 } finally {
7483 Gauge gauge = gaugeMap .get (ORACLEDB_METRIC_PREFIX + UP );
7584 if (gauge == null ) {
76- Gauge upgauge = Gauge .build ().name (ORACLEDB_METRIC_PREFIX + UP ).help ("Whether the Oracle database server is up." ).register ();
85+ Gauge upgauge = Gauge .build ().name (ORACLEDB_METRIC_PREFIX + UP ).help ("Whether the Oracle database server is up." ).register (registry );
7786 upgauge .set (isConnectionSuccessful );
7887 gaugeMap .put (ORACLEDB_METRIC_PREFIX + UP , upgauge );
7988 } else gauge .set (isConnectionSuccessful );
@@ -91,7 +100,7 @@ private void processMetrics() throws IOException, SQLException {
91100 * Request string
92101 * IgnoreZeroResult bool
93102 */
94- private void processMetric (Connection connection , Iterator <JsonNode > metric ) {
103+ private void processMetric (CollectorRegistry registry , Connection connection , Iterator <JsonNode > metric ) {
95104 JsonNode next = metric .next ();
96105 String context = next .get (CONTEXT ).asText (); // eg context = "teq"
97106 String metricsType = next .get (METRICSTYPE ) == null ? "" :next .get (METRICSTYPE ).asText ();
@@ -120,34 +129,27 @@ private void processMetric(Connection connection, Iterator<JsonNode> metric) {
120129 try {
121130 resultSet = connection .prepareStatement (request ).executeQuery ();
122131 while (resultSet .next ()) {
123- translateQueryToPrometheusMetric (context , metricsDescMap , labelNames , resultSet );
132+ translateQueryToPrometheusMetric (registry , context , metricsDescMap , labelNames , resultSet );
124133 }
125134 } catch (SQLException e ) { //this can be due to table not existing etc.
126135 LOGGER .warn ("MetricsExporter.processMetric during:" + request + " exception:" + e );
127136 return ;
128137 }
129138 }
130139
131- private void translateQueryToPrometheusMetric (String context , Map <String , String > metricsDescMap ,
140+ private void translateQueryToPrometheusMetric (CollectorRegistry registry , String context , Map <String , String > metricsDescMap ,
132141 String [] labelNames ,
133142 ResultSet resultSet ) throws SQLException {
134143 String [] labelValues = new String [labelNames .length ];
135144 Map <String , Long > sqlQueryResults =
136- extractGaugesAndLabelValues (context , metricsDescMap , labelNames , resultSet , labelValues , resultSet .getMetaData ().getColumnCount ());
145+ extractGaugesAndLabelValues (registry , context , metricsDescMap , labelNames , resultSet , labelValues , resultSet .getMetaData ().getColumnCount ());
137146 setLabelValues (context , labelNames , labelValues , sqlQueryResults .entrySet ().iterator ());
138147 }
139148
140149 /**
141150 * Creates Gauges and gets label values
142- * @param context
143- * @param metricsDescMap
144- * @param labelNames
145- * @param resultSet
146- * @param labelValues
147- * @param columnCount
148- * @throws SQLException
149151 */
150- private Map <String , Long > extractGaugesAndLabelValues (
152+ private Map <String , Long > extractGaugesAndLabelValues (CollectorRegistry registry ,
151153 String context , Map <String , String > metricsDescMap , String [] labelNames , ResultSet resultSet ,
152154 String [] labelValues , int columnCount ) throws SQLException {
153155 Map <String , Long > sqlQueryResults = new HashMap <>();
@@ -166,8 +168,8 @@ private Map<String, Long> extractGaugesAndLabelValues(
166168 if (gauge == null ) {
167169 if (metricsDescMap .containsKey (columnName )) {
168170 if (labelNames .length > 0 ) {
169- gauge = Gauge .build ().name (gaugeName .toLowerCase ()).help (metricsDescMap .get (columnName )).labelNames (labelNames ).register ();
170- } else gauge = Gauge .build ().name (gaugeName .toLowerCase ()).help (metricsDescMap .get (columnName )).register ();
171+ gauge = Gauge .build ().name (gaugeName .toLowerCase ()).help (metricsDescMap .get (columnName )).labelNames (labelNames ).register (registry );
172+ } else gauge = Gauge .build ().name (gaugeName .toLowerCase ()).help (metricsDescMap .get (columnName )).register (registry );
171173 gaugeMap .put (gaugeName , gauge );
172174 }
173175 }
@@ -198,8 +200,7 @@ private void setLabelValues(String context, String[] labelNames, String[] labelV
198200 }
199201 }
200202
201- public static String getMetricsString () {
202- CollectorRegistry collectorRegistry = CollectorRegistry .defaultRegistry ;
203+ public static String getMetricsString (CollectorRegistry collectorRegistry ) {
203204 Enumeration <Collector .MetricFamilySamples > mfs = collectorRegistry .filteredMetricFamilySamples (new HashSet <>());
204205 return compose (mfs );
205206 }
0 commit comments