This is an automated email from the ASF dual-hosted git repository. jcabrerizo pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
The following commit(s) were added to refs/heads/master by this push: new c4b95c9 Support multi-phrase query new c33f70d Merge pull request #1208 from algairim/logbook-search-improvements c4b95c9 is described below commit c4b95c98dfdd91ceb4da7fa23aa15ba05af961fb Author: Mykola Mandra <mykola.man...@cloudsoft.io> AuthorDate: Mon Jul 19 18:33:19 2021 +0100 Support multi-phrase query Signed-off-by: Mykola Mandra <mykola.man...@cloudsoft.io> --- .../util/core/logbook/LogBookQueryParams.java | 10 +++---- .../brooklyn/util/core/logbook/LogStore.java | 1 - .../util/core/logbook/file/FileLogStore.java | 18 ++++++++++-- .../logbook/opensearch/OpenSearchLogStore.java | 8 ++++-- .../util/core/logbook/file/FileLogStoreTest.java | 32 ++++++++++++++++++++-- .../logbook/opensearch/OpenSearchLogStoreTest.java | 18 ++++++++++-- 6 files changed, 71 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/org/apache/brooklyn/util/core/logbook/LogBookQueryParams.java b/core/src/main/java/org/apache/brooklyn/util/core/logbook/LogBookQueryParams.java index 4b9c698..5219224 100644 --- a/core/src/main/java/org/apache/brooklyn/util/core/logbook/LogBookQueryParams.java +++ b/core/src/main/java/org/apache/brooklyn/util/core/logbook/LogBookQueryParams.java @@ -41,7 +41,7 @@ public class LogBookQueryParams { private String dateTimeTo; /** The search phrase to look log items with */ - private String searchPhrase; + private List<String> searchPhrases; public Integer getNumberOfItems() { return numberOfItems; @@ -83,11 +83,11 @@ public class LogBookQueryParams { this.dateTimeTo = dateTimeTo; } - public String getSearchPhrase() { - return searchPhrase; + public List<String> getSearchPhrases() { + return searchPhrases; } - public void setSearchPhrase(String searchPhrase) { - this.searchPhrase = searchPhrase; + public void setSearchPhrases(List<String> searchPhrases) { + this.searchPhrases = searchPhrases; } } diff --git a/core/src/main/java/org/apache/brooklyn/util/core/logbook/LogStore.java b/core/src/main/java/org/apache/brooklyn/util/core/logbook/LogStore.java index 83e88be..d08f71c 100644 --- a/core/src/main/java/org/apache/brooklyn/util/core/logbook/LogStore.java +++ b/core/src/main/java/org/apache/brooklyn/util/core/logbook/LogStore.java @@ -29,5 +29,4 @@ public interface LogStore { * @throws IOException */ List<BrooklynLogEntry> query(LogBookQueryParams query) throws IOException; - } diff --git a/core/src/main/java/org/apache/brooklyn/util/core/logbook/file/FileLogStore.java b/core/src/main/java/org/apache/brooklyn/util/core/logbook/file/FileLogStore.java index e25428c..2d154c0 100644 --- a/core/src/main/java/org/apache/brooklyn/util/core/logbook/file/FileLogStore.java +++ b/core/src/main/java/org/apache/brooklyn/util/core/logbook/file/FileLogStore.java @@ -105,6 +105,7 @@ public class FileLogStore implements LogStore { Date dateTimeFrom = Strings.isNonBlank(params.getDateTimeFrom()) ? Time.parseDate(params.getDateTimeFrom()) : null; Date dateTimeTo = Strings.isNonBlank(params.getDateTimeTo()) ? Time.parseDate(params.getDateTimeTo()) : null; + boolean isSearchPhrasesPresent = !Objects.isNull(params.getSearchPhrases()) && !params.getSearchPhrases().isEmpty(); Predicate<BrooklynLogEntry> filter = brooklynLogEntry -> { @@ -140,9 +141,9 @@ public class FileLogStore implements LogStore { } } - // Check the search phrase. - if (Strings.isNonBlank(params.getSearchPhrase()) && Strings.isNonBlank(brooklynLogEntry.getMessage())) { - isSearchPhraseMatch = brooklynLogEntry.getMessage().contains(params.getSearchPhrase()); + // Check search phrases. + if (isSearchPhrasesPresent && Strings.isNonBlank(brooklynLogEntry.getMessage())) { + isSearchPhraseMatch = containsSearchPhrases(brooklynLogEntry.getMessage(), params.getSearchPhrases()); } return isLogLevelMatch && isDateTimeFromMatch && isDateTimeToMatch && isSearchPhraseMatch; @@ -200,4 +201,15 @@ public class FileLogStore implements LogStore { } return entry; } + + public static boolean containsSearchPhrases(String logMessage, List<String> searchPhrases) { + boolean found = true; + for (String searchPhrase : searchPhrases) { + if (!logMessage.contains(searchPhrase)) { + found = false; + break; + } + } + return found; + } } diff --git a/core/src/main/java/org/apache/brooklyn/util/core/logbook/opensearch/OpenSearchLogStore.java b/core/src/main/java/org/apache/brooklyn/util/core/logbook/opensearch/OpenSearchLogStore.java index 2e813a6..1ebc4c3 100644 --- a/core/src/main/java/org/apache/brooklyn/util/core/logbook/opensearch/OpenSearchLogStore.java +++ b/core/src/main/java/org/apache/brooklyn/util/core/logbook/opensearch/OpenSearchLogStore.java @@ -62,6 +62,7 @@ import java.security.NoSuchAlgorithmException; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import static org.apache.brooklyn.util.core.logbook.LogbookConfig.BASE_NAME_LOGBOOK; @@ -220,6 +221,8 @@ public class OpenSearchLogStore implements LogStore { // The `query.bool.must` part of the open-search query. ImmutableList.Builder<Object> queryBoolMustListBuilder = ImmutableList.builder(); + ImmutableList<String> searchPhrases = params.getSearchPhrases() == null ? ImmutableList.of() : + ImmutableList.copyOf(params.getSearchPhrases().stream().filter(Strings::isNonBlank).collect(Collectors.toList())); // Apply log levels. if (!params.getLevels().isEmpty() && !params.getLevels().contains("ALL")) { @@ -251,9 +254,8 @@ public class OpenSearchLogStore implements LogStore { } // Apply search phrase. - if (Strings.isNonBlank(params.getSearchPhrase())) { - queryBoolMustListBuilder.add(ImmutableMap.of("match_phrase", ImmutableMap.of("message", params.getSearchPhrase()))); - } + searchPhrases.forEach(searchPhrase -> + queryBoolMustListBuilder.add(ImmutableMap.of("match_phrase", ImmutableMap.of("message", searchPhrase)))); ImmutableList<Object> queryBoolMustList = queryBoolMustListBuilder.build(); diff --git a/core/src/test/java/org/apache/brooklyn/util/core/logbook/file/FileLogStoreTest.java b/core/src/test/java/org/apache/brooklyn/util/core/logbook/file/FileLogStoreTest.java index 21131d6..1d84a06 100644 --- a/core/src/test/java/org/apache/brooklyn/util/core/logbook/file/FileLogStoreTest.java +++ b/core/src/test/java/org/apache/brooklyn/util/core/logbook/file/FileLogStoreTest.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.testng.annotations.*; import java.io.File; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.TimeZone; @@ -239,7 +240,7 @@ public class FileLogStoreTest extends TestCase { } @Test - public void testQueryLogSampleWithSearchPhrase() { + public void testQueryLogSampleWithSearchSinglePhrase() { File file = new File(Objects.requireNonNull(getClass().getClassLoader().getResource(JAVA_LOG_SAMPLE_PATH)).getFile()); ManagementContextInternal mgmt = LocalManagementContextForTests.newInstance(); mgmt.getBrooklynProperties().put(LOGBOOK_LOG_STORE_PATH.getName(), file.getAbsolutePath()); @@ -247,7 +248,7 @@ public class FileLogStoreTest extends TestCase { logBookQueryParams.setNumberOfItems(2); // Request first two only. logBookQueryParams.setTail(false); logBookQueryParams.setLevels(ImmutableList.of()); - logBookQueryParams.setSearchPhrase("Cannot register component"); // Request search phrase. + logBookQueryParams.setSearchPhrases(ImmutableList.of("Cannot register component")); // Request search phrase. FileLogStore fileLogStore = new FileLogStore(mgmt); List<BrooklynLogEntry> brooklynLogEntries = fileLogStore.query(logBookQueryParams); assertEquals(1, brooklynLogEntries.size()); @@ -267,6 +268,33 @@ public class FileLogStoreTest extends TestCase { } @Test + public void testQueryLogSampleWithSearchMultiplePhrases() { + File file = new File(Objects.requireNonNull(getClass().getClassLoader().getResource(JAVA_LOG_SAMPLE_PATH)).getFile()); + ManagementContextInternal mgmt = LocalManagementContextForTests.newInstance(); + mgmt.getBrooklynProperties().put(LOGBOOK_LOG_STORE_PATH.getName(), file.getAbsolutePath()); + LogBookQueryParams logBookQueryParams = new LogBookQueryParams(); + logBookQueryParams.setNumberOfItems(2); // Request first two only. + logBookQueryParams.setTail(false); + logBookQueryParams.setLevels(ImmutableList.of()); + logBookQueryParams.setSearchPhrases(ImmutableList.of("bundle")); // Request search phrase. + FileLogStore fileLogStore = new FileLogStore(mgmt); + List<BrooklynLogEntry> brooklynLogEntries = fileLogStore.query(logBookQueryParams); + assertEquals(2, brooklynLogEntries.size()); + + // Search phrase appears in ERROR and WARN log lines. + assertEquals("ERROR", brooklynLogEntries.get(0).getLevel()); + assertEquals("WARN", brooklynLogEntries.get(1).getLevel()); + + // Now request multiple search phrases + logBookQueryParams.setSearchPhrases(ImmutableList.of("bundle", "is waiting for dependencies")); + brooklynLogEntries = fileLogStore.query(logBookQueryParams); + assertEquals(1, brooklynLogEntries.size()); + + // 2 phrases appear in WARN log line only + assertEquals("WARN", brooklynLogEntries.get(0).getLevel()); + } + + @Test public void testQueryLogSampleWithZeroNumberOfLInes() { File file = new File(Objects.requireNonNull(getClass().getClassLoader().getResource(JAVA_LOG_SAMPLE_PATH)).getFile()); ManagementContextInternal mgmt = LocalManagementContextForTests.newInstance(); diff --git a/core/src/test/java/org/apache/brooklyn/util/core/logbook/opensearch/OpenSearchLogStoreTest.java b/core/src/test/java/org/apache/brooklyn/util/core/logbook/opensearch/OpenSearchLogStoreTest.java index 6063889..82fdcaa 100644 --- a/core/src/test/java/org/apache/brooklyn/util/core/logbook/opensearch/OpenSearchLogStoreTest.java +++ b/core/src/test/java/org/apache/brooklyn/util/core/logbook/opensearch/OpenSearchLogStoreTest.java @@ -22,6 +22,8 @@ import com.google.common.collect.ImmutableList; import org.apache.brooklyn.util.core.logbook.LogBookQueryParams; import org.junit.Test; +import java.util.Collections; + import static org.apache.brooklyn.test.Asserts.assertEquals; public class OpenSearchLogStoreTest { @@ -122,14 +124,26 @@ public class OpenSearchLogStoreTest { } @Test - public void queryWithSearchPhrase() { + public void queryWithSearchSinglePhrase() { OpenSearchLogStore cut = new OpenSearchLogStore(); LogBookQueryParams p = new LogBookQueryParams(); p.setNumberOfItems(10); p.setTail(false); p.setLevels(ImmutableList.of()); - p.setSearchPhrase("some phrase"); + p.setSearchPhrases(ImmutableList.of("some phrase")); String query = cut.getJSONQuery(p); assertEquals(query, "{\"sort\":{\"timestamp\":\"asc\"},\"size\":10,\"query\":{\"bool\":{\"must\":[{\"match_phrase\":{\"message\":\"some phrase\"}}]}}}"); } + + @Test + public void queryWithSearchMultiplePhrases() { + OpenSearchLogStore cut = new OpenSearchLogStore(); + LogBookQueryParams p = new LogBookQueryParams(); + p.setNumberOfItems(10); + p.setTail(false); + p.setLevels(ImmutableList.of()); + p.setSearchPhrases(ImmutableList.of("some phrase", "another phrase")); + String query = cut.getJSONQuery(p); + assertEquals(query, "{\"sort\":{\"timestamp\":\"asc\"},\"size\":10,\"query\":{\"bool\":{\"must\":[{\"match_phrase\":{\"message\":\"some phrase\"}},{\"match_phrase\":{\"message\":\"another phrase\"}}]}}}"); + } } \ No newline at end of file