-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Top n queries historical queries from local index and time range #84
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
4df0676
Added support for historical top n queries
LilyCaroline17 ab44811
Merge branch 'opensearch-project:main' into main
LilyCaroline17 bb3738f
Added unit tests
LilyCaroline17 8c2e929
Merge branch 'opensearch-project:main' into main
LilyCaroline17 1ba0c80
Update LocalIndexExporter.java
LilyCaroline17 d562b8f
Update LocalIndexReaderTests.java
LilyCaroline17 9e8f874
Update QueryInsightsReaderFactoryTests.java
LilyCaroline17 8b484ab
Address comments, change getTimeRange into getFrom and getTo, apply f…
LilyCaroline17 94205ec
Merge branch 'main' into main
LilyCaroline17 c24e9de
Fix test cases
LilyCaroline17 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
130 changes: 130 additions & 0 deletions
130
src/main/java/org/opensearch/plugin/insights/core/reader/LocalIndexReader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.plugin.insights.core.reader; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.joda.time.DateTime; | ||
import org.joda.time.DateTimeZone; | ||
import org.joda.time.format.DateTimeFormatter; | ||
import org.opensearch.action.search.SearchRequest; | ||
import org.opensearch.action.search.SearchResponse; | ||
import org.opensearch.client.Client; | ||
import org.opensearch.core.xcontent.NamedXContentRegistry; | ||
import org.opensearch.index.IndexNotFoundException; | ||
import org.opensearch.index.query.MatchQueryBuilder; | ||
import org.opensearch.index.query.QueryBuilder; | ||
import org.opensearch.index.query.QueryBuilders; | ||
import org.opensearch.index.query.RangeQueryBuilder; | ||
import org.opensearch.plugin.insights.rules.model.SearchQueryRecord; | ||
import org.opensearch.search.SearchHit; | ||
import org.opensearch.search.builder.SearchSourceBuilder; | ||
|
||
/** | ||
* Local index reader for reading query insights data from local OpenSearch indices. | ||
*/ | ||
public final class LocalIndexReader implements QueryInsightsReader { | ||
/** | ||
* Logger of the local index reader | ||
*/ | ||
private final Logger logger = LogManager.getLogger(); | ||
private final Client client; | ||
private DateTimeFormatter indexPattern; | ||
private final NamedXContentRegistry namedXContentRegistry; | ||
|
||
/** | ||
* Constructor of LocalIndexReader | ||
* | ||
* @param client OS client | ||
* @param indexPattern the pattern of index to read from | ||
* @param namedXContentRegistry for parsing purposes | ||
*/ | ||
public LocalIndexReader(final Client client, final DateTimeFormatter indexPattern, final NamedXContentRegistry namedXContentRegistry) { | ||
this.indexPattern = indexPattern; | ||
this.client = client; | ||
this.namedXContentRegistry = namedXContentRegistry; | ||
} | ||
|
||
/** | ||
* Getter of indexPattern | ||
* | ||
* @return indexPattern | ||
*/ | ||
public DateTimeFormatter getIndexPattern() { | ||
return indexPattern; | ||
} | ||
|
||
/** | ||
* Setter of indexPattern | ||
* | ||
* @param indexPattern index pattern | ||
* @return the current LocalIndexReader | ||
*/ | ||
public LocalIndexReader setIndexPattern(DateTimeFormatter indexPattern) { | ||
this.indexPattern = indexPattern; | ||
return this; | ||
} | ||
|
||
/** | ||
* Export a list of SearchQueryRecord from local index | ||
* | ||
* @param from start timestamp | ||
* @param to end timestamp | ||
* @return list of SearchQueryRecords whose timestamps fall between from and to | ||
*/ | ||
@Override | ||
public List<SearchQueryRecord> read(final String from, final String to) { | ||
List<SearchQueryRecord> records = new ArrayList<>(); | ||
if (from == null || to == null) { | ||
return records; | ||
} | ||
final DateTime start = DateTime.parse(from); | ||
DateTime end = DateTime.parse(to); | ||
if (end.compareTo(DateTime.now(DateTimeZone.UTC)) > 0) { | ||
end = DateTime.now(DateTimeZone.UTC); | ||
} | ||
DateTime curr = start; | ||
while (curr.compareTo(end.plusDays(1).withTimeAtStartOfDay()) < 0) { | ||
String index = getDateTimeFromFormat(curr); | ||
SearchRequest searchRequest = new SearchRequest(index); | ||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); | ||
MatchQueryBuilder excludeQuery = QueryBuilders.matchQuery("indices", "top_queries*"); | ||
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("timestamp").from(start.getMillis()).to(end.getMillis()); | ||
QueryBuilder query = QueryBuilders.boolQuery().must(rangeQuery).mustNot(excludeQuery); | ||
searchSourceBuilder.query(query); | ||
searchRequest.source(searchSourceBuilder); | ||
try { | ||
SearchResponse searchResponse = client.search(searchRequest).actionGet(); | ||
for (SearchHit hit : searchResponse.getHits()) { | ||
SearchQueryRecord record = SearchQueryRecord.getRecord(hit, namedXContentRegistry); | ||
records.add(record); | ||
} | ||
} catch (IndexNotFoundException ignored) {} catch (Exception e) { | ||
logger.error("Unable to parse search hit: ", e); | ||
} | ||
curr = curr.plusDays(1); | ||
|
||
} | ||
return records; | ||
} | ||
|
||
/** | ||
* Close the reader sink | ||
*/ | ||
@Override | ||
public void close() { | ||
logger.debug("Closing the LocalIndexReader.."); | ||
} | ||
|
||
private String getDateTimeFromFormat(DateTime current) { | ||
return indexPattern.print(current); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/java/org/opensearch/plugin/insights/core/reader/QueryInsightsReader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.plugin.insights.core.reader; | ||
|
||
import java.io.Closeable; | ||
import java.util.List; | ||
import org.opensearch.plugin.insights.rules.model.SearchQueryRecord; | ||
|
||
/** | ||
* Base interface for Query Insights readers | ||
*/ | ||
public interface QueryInsightsReader extends Closeable { | ||
/** | ||
* Reader a list of SearchQueryRecord | ||
* | ||
* @param from string | ||
* @param to string | ||
* @return List of SearchQueryRecord | ||
*/ | ||
List<SearchQueryRecord> read(final String from, final String to); | ||
} |
118 changes: 118 additions & 0 deletions
118
src/main/java/org/opensearch/plugin/insights/core/reader/QueryInsightsReaderFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.plugin.insights.core.reader; | ||
|
||
import static org.opensearch.plugin.insights.settings.QueryInsightsSettings.DEFAULT_TOP_N_QUERIES_INDEX_PATTERN; | ||
import static org.opensearch.plugin.insights.settings.QueryInsightsSettings.EXPORT_INDEX; | ||
|
||
import java.io.IOException; | ||
import java.util.HashSet; | ||
import java.util.Locale; | ||
import java.util.Set; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.joda.time.format.DateTimeFormat; | ||
import org.opensearch.client.Client; | ||
import org.opensearch.common.settings.Settings; | ||
import org.opensearch.core.xcontent.NamedXContentRegistry; | ||
|
||
/** | ||
* Factory class for validating and creating Readers based on provided settings | ||
*/ | ||
public class QueryInsightsReaderFactory { | ||
/** | ||
* Logger of the query insights Reader factory | ||
*/ | ||
private final Logger logger = LogManager.getLogger(); | ||
final private Client client; | ||
final private Set<QueryInsightsReader> Readers; | ||
|
||
/** | ||
* Constructor of QueryInsightsReaderFactory | ||
* | ||
* @param client OS client | ||
*/ | ||
public QueryInsightsReaderFactory(final Client client) { | ||
this.client = client; | ||
this.Readers = new HashSet<>(); | ||
} | ||
|
||
/** | ||
* Validate Reader sink config | ||
* | ||
* @param settings Reader sink config {@link Settings} | ||
* @throws IllegalArgumentException if provided Reader sink config settings are invalid | ||
*/ | ||
public void validateReaderConfig(final Settings settings) throws IllegalArgumentException { | ||
final String indexPattern = settings.get(EXPORT_INDEX, DEFAULT_TOP_N_QUERIES_INDEX_PATTERN); | ||
if (indexPattern.isEmpty()) { | ||
throw new IllegalArgumentException("Empty index pattern configured for the Reader"); | ||
} | ||
try { | ||
DateTimeFormat.forPattern(indexPattern); | ||
} catch (Exception e) { | ||
throw new IllegalArgumentException( | ||
String.format(Locale.ROOT, "Invalid index pattern [%s] configured for the Reader", indexPattern) | ||
); | ||
} | ||
} | ||
|
||
/** | ||
* Create a Reader based on provided parameters | ||
* | ||
* @param indexPattern the index pattern if creating an index Reader | ||
* @param namedXContentRegistry for parsing purposes | ||
* @return QueryInsightsReader the created Reader | ||
*/ | ||
public QueryInsightsReader createReader(String indexPattern, NamedXContentRegistry namedXContentRegistry) { | ||
QueryInsightsReader Reader = new LocalIndexReader(client, DateTimeFormat.forPattern(indexPattern), namedXContentRegistry); | ||
this.Readers.add(Reader); | ||
return Reader; | ||
} | ||
|
||
/** | ||
* Update a Reader based on provided parameters | ||
* | ||
* @param Reader The Reader to update | ||
* @param indexPattern the index pattern if creating an index Reader | ||
* @return QueryInsightsReader the updated Reader sink | ||
*/ | ||
public QueryInsightsReader updateReader(QueryInsightsReader Reader, String indexPattern) { | ||
if (Reader.getClass() == LocalIndexReader.class) { | ||
((LocalIndexReader) Reader).setIndexPattern(DateTimeFormat.forPattern(indexPattern)); | ||
} | ||
return Reader; | ||
} | ||
|
||
/** | ||
* Close a Reader | ||
* | ||
* @param Reader the Reader to close | ||
*/ | ||
public void closeReader(QueryInsightsReader Reader) throws IOException { | ||
if (Reader != null) { | ||
Reader.close(); | ||
this.Readers.remove(Reader); | ||
} | ||
} | ||
|
||
/** | ||
* Close all Readers | ||
* | ||
*/ | ||
public void closeAllReaders() { | ||
for (QueryInsightsReader Reader : Readers) { | ||
try { | ||
closeReader(Reader); | ||
} catch (IOException e) { | ||
logger.error("Fail to close query insights Reader, error: ", e); | ||
} | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/org/opensearch/plugin/insights/core/reader/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
/** | ||
* Query Insights reader | ||
*/ | ||
package org.opensearch.plugin.insights.core.reader; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: We are making assumptions on the index pattern that it will rollover every day. We should add this assumption with a check in the configuration API as well. And we should not allow user to change this rollover period and only allow them to change the prefix pattern. In that case
would become something like