Skip to content

Commit 3eca5d0

Browse files
add regex extractor (#38)
* add regex extractor * Bump org.owasp.dependencycheck from 12.0.2 to 12.1.0 (#36) Bumps org.owasp.dependencycheck from 12.0.2 to 12.1.0. --- updated-dependencies: - dependency-name: org.owasp.dependencycheck dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump org.cyclonedx.bom from 2.1.0 to 2.2.0 (#37) Bumps org.cyclonedx.bom from 2.1.0 to 2.2.0. --- updated-dependencies: - dependency-name: org.cyclonedx.bom dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: EddeCCC <66794307+EddeCCC@users.noreply.github.com> * update spring --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1 parent be6c208 commit 3eca5d0

File tree

9 files changed

+84
-10
lines changed

9 files changed

+84
-10
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ dwh:
4848
# secret to access the /dwh endpoint
4949
token: my_secret
5050

51+
# extract the database from the query via regex
52+
derive-database-from-query: false
53+
5154
# the metrics and related queries to use and export
5255
metrics:
5356
- name: my-metric|${service}|${http_path}
@@ -76,6 +79,13 @@ It is important that **exactly** the tags used for parameterization in `name` ar
7679

7780
When the endpoint provided by the application is called, the exporter executes **all** configured queries and returns the corresponding result.
7881

82+
#### Derive database from query
83+
84+
If the property `dwh.derive-database-from-query` is set to true and no `database` was explicitly specified for a query,
85+
the service will try to extract the database via regex. By default, the property is set to false.
86+
If the `database` is specified, it will always be used for the particular query!
87+
The property should reduce the effort to specify the database for a long list of simple queries.
88+
7989
### Health Endpoint
8090

8191
The application provides an endpoint under `/actuator/health that can be used to check if the application is running and the InfluxDB is available.

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ plugins {
44
id 'org.springframework.boot' version "${springBootVersion}"
55
id 'java'
66
id 'idea'
7-
id "org.cyclonedx.bom" version "2.1.0"
8-
id "org.owasp.dependencycheck" version "12.0.2"
7+
id "org.cyclonedx.bom" version "2.2.0"
8+
id "org.owasp.dependencycheck" version "12.1.0"
99
id "com.github.ben-manes.versions" version "0.52.0"
1010
}
1111

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Spring Boot
2-
springBootVersion=3.4.2
2+
springBootVersion=3.4.3
33
# Spring integration for InfluxDBv2
44
influxdbSpringVersion=7.2.0
55

src/main/java/de/novatec/dwhexport/configuration/model/DwhExporterSettings.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ public class DwhExporterSettings {
1919
*/
2020
private String token = "";
2121

22+
/**
23+
* True, if the database for queries should be extracted via regex from the query body.
24+
* False, if the database should be explicitly specified for every query.
25+
*/
26+
private boolean deriveDatabaseFromQuery = false;
27+
2228
@NotNull
2329
private List<MetricQuery> metrics;
2430
}

src/main/java/de/novatec/dwhexport/configuration/model/MetricQuery.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package de.novatec.dwhexport.configuration.model;
22

3+
import jakarta.validation.constraints.NotNull;
34
import lombok.Data;
45

56
import jakarta.validation.constraints.NotBlank;
@@ -12,8 +13,8 @@ public class MetricQuery {
1213
private String name;
1314

1415
/** the database name - in InfluxDBv2 the bucket name */
15-
@NotBlank
16-
private String database;
16+
@NotNull
17+
private String database = "";
1718

1819
/** the InfluxQL query to collect metrics */
1920
@NotBlank

src/main/java/de/novatec/dwhexport/service/MetricsService.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
import de.novatec.dwhexport.data.Metric;
77
import de.novatec.dwhexport.service.influx.MetricsMapper;
88
import de.novatec.dwhexport.service.influx.MetricsQuerier;
9+
import de.novatec.dwhexport.service.influx.QueryExtractor;
910
import lombok.AllArgsConstructor;
1011
import lombok.extern.slf4j.Slf4j;
11-
import org.springframework.beans.factory.annotation.Autowired;
1212
import org.springframework.boot.convert.DurationStyle;
1313
import org.springframework.http.ResponseEntity;
1414
import org.springframework.stereotype.Service;
@@ -26,6 +26,8 @@ public class MetricsService {
2626

2727
private MetricsMapper mapper;
2828

29+
private QueryExtractor extractor;
30+
2931
private DwhExporterSettings metrics;
3032

3133
public ResponseEntity<?> processRangeOffsetRequest(String range, String offset, Duration intervalDur) {
@@ -63,13 +65,28 @@ private Collection<Metric> queryMetric(MetricQuery metric, Duration interval, lo
6365
try {
6466
long intervalMillis = interval.toMillis();
6567
long extendedStartTime = startTime - intervalMillis;
68+
String database = getDatabase(metric);
6669

67-
InfluxQLQueryResult data = querier.executeQuery(metric, extendedStartTime, endTime, interval);
70+
InfluxQLQueryResult data = querier.executeQuery(metric, database, extendedStartTime, endTime, interval);
6871

6972
return mapper.map(data, metric, startTime, endTime);
7073
} catch (Exception e) {
7174
log.error("Error fetching data for {}", metric.getName(), e);
7275
}
7376
return Collections.emptyList();
7477
}
78+
79+
/**
80+
* Get the database for the {@link com.influxdb.client.domain.InfluxQLQuery}.
81+
* If a database was specified explicitly, use the provided value.
82+
* If no database was specified AND the option to derive it from the query is enabled, extract the database from
83+
* the query body.
84+
*
85+
* @param metric the metric query
86+
* @return the database to use for the query
87+
*/
88+
private String getDatabase(MetricQuery metric) {
89+
if(metric.getDatabase().isBlank() && metrics.isDeriveDatabaseFromQuery()) return extractor.extractDatabase(metric.getQuery());
90+
else return metric.getDatabase();
91+
}
7592
}

src/main/java/de/novatec/dwhexport/service/influx/MetricsQuerier.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import lombok.extern.slf4j.Slf4j;
99
import org.apache.commons.text.StringSubstitutor;
1010
import org.apache.commons.text.lookup.StringLookup;
11-
import org.springframework.beans.factory.annotation.Autowired;
1211
import org.springframework.boot.convert.DurationStyle;
1312
import org.springframework.stereotype.Component;
1413

@@ -24,7 +23,7 @@ public class MetricsQuerier {
2423

2524
private InfluxDBClient influx;
2625

27-
public InfluxQLQueryResult executeQuery(MetricQuery metric, long startMillis, long endMillis, Duration interval) {
26+
public InfluxQLQueryResult executeQuery(MetricQuery metric, String database, long startMillis, long endMillis, Duration interval) {
2827
StringLookup lookup = buildVariableLookUp(startMillis, endMillis, interval);
2928
StringSubstitutor subst = new StringSubstitutor(lookup);
3029

@@ -33,7 +32,7 @@ public InfluxQLQueryResult executeQuery(MetricQuery metric, long startMillis, lo
3332
log.debug("Executing query: {}", queryString);
3433

3534
// We still use InfluxQL instead of Flux
36-
InfluxQLQuery influxQLQuery = new InfluxQLQuery(queryString, metric.getDatabase());
35+
InfluxQLQuery influxQLQuery = new InfluxQLQuery(queryString, database);
3736
return influx.getInfluxQLQueryApi().query(influxQLQuery);
3837
}
3938

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package de.novatec.dwhexport.service.influx;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.springframework.stereotype.Component;
5+
6+
import java.util.regex.Matcher;
7+
import java.util.regex.Pattern;
8+
9+
/**
10+
* Extracts information from InfluxQL queries via regex patterns.
11+
*/
12+
@Slf4j
13+
@Component
14+
public class QueryExtractor {
15+
16+
/**
17+
* Basically, extract the string after a FROM statement, which is enclosed by double quotes.
18+
* For example: SELECT * FROM "inspectit"."raw"."measure" --> inspectit
19+
*/
20+
private static final String DATABASE_PATTERN = "(?i)\\bFROM\\s+\"([^\"]+)";
21+
22+
/**
23+
* @param query the InfluxQL query body
24+
* @return the database
25+
* @throws IllegalArgumentException if no database could be extracted
26+
*/
27+
public String extractDatabase(String query) {
28+
Pattern pattern = Pattern.compile(DATABASE_PATTERN);
29+
Matcher matcher = pattern.matcher(query);
30+
31+
if (matcher.find()) {
32+
String database = matcher.group(1);
33+
log.debug("Extracted database from query: {}", database);
34+
return database;
35+
}
36+
else throw new IllegalArgumentException("No match found for database. You can specify the database directly as well");
37+
}
38+
}

src/main/resources/application.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ dwh:
3434
# secret to access the /dwh endpoint
3535
token: my_secret
3636

37+
# extract the database from the query via regex
38+
derive-database-from-query: false
39+
3740
# the metrics and related queries to use and export
3841
metrics:
3942
- name: my-metric|${service}|${http_path}

0 commit comments

Comments
 (0)