Skip to content

Commit 2071f85

Browse files
author
Hendrik Muhs
committed
forward audits to logs (#52394)
audit messages are stored in the notifications index, so audit information is lost for integration tests. This change forwards audit messages to logs, so they can help to debug issues. relates: #51627
1 parent bdb2e72 commit 2071f85

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

x-pack/plugin/transform/qa/multi-node-tests/src/test/java/org/elasticsearch/xpack/transform/integration/TransformIntegTestCase.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66

77
package org.elasticsearch.xpack.transform.integration;
88

9+
import org.apache.logging.log4j.Level;
910
import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksRequest;
1011
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
1112
import org.elasticsearch.action.bulk.BulkRequest;
1213
import org.elasticsearch.action.bulk.BulkResponse;
1314
import org.elasticsearch.action.index.IndexRequest;
15+
import org.elasticsearch.action.search.SearchRequest;
16+
import org.elasticsearch.action.search.SearchResponse;
1417
import org.elasticsearch.client.RequestOptions;
1518
import org.elasticsearch.client.RestHighLevelClient;
1619
import org.elasticsearch.client.core.AcknowledgedResponse;
@@ -48,12 +51,17 @@
4851
import org.elasticsearch.common.xcontent.XContentHelper;
4952
import org.elasticsearch.common.xcontent.XContentParser;
5053
import org.elasticsearch.common.xcontent.XContentType;
54+
import org.elasticsearch.index.query.MatchAllQueryBuilder;
5155
import org.elasticsearch.index.query.QueryBuilder;
5256
import org.elasticsearch.index.query.QueryBuilders;
57+
import org.elasticsearch.search.SearchHit;
5358
import org.elasticsearch.search.SearchModule;
5459
import org.elasticsearch.search.aggregations.AggregatorFactories;
5560
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
61+
import org.elasticsearch.search.builder.SearchSourceBuilder;
62+
import org.elasticsearch.search.sort.SortOrder;
5663
import org.elasticsearch.test.rest.ESRestTestCase;
64+
import org.joda.time.Instant;
5765

5866
import java.io.IOException;
5967
import java.nio.charset.StandardCharsets;
@@ -62,6 +70,7 @@
6270
import java.util.Collections;
6371
import java.util.HashMap;
6472
import java.util.List;
73+
import java.util.Locale;
6574
import java.util.Map;
6675
import java.util.concurrent.TimeUnit;
6776

@@ -73,10 +82,36 @@ abstract class TransformIntegTestCase extends ESRestTestCase {
7382
private Map<String, TransformConfig> transformConfigs = new HashMap<>();
7483

7584
protected void cleanUp() throws IOException {
85+
logAudits();
7686
cleanUpTransforms();
7787
waitForPendingTasks();
7888
}
7989

90+
private void logAudits() throws IOException {
91+
RestHighLevelClient restClient = new TestRestHighLevelClient();
92+
93+
// using '*' to make this lenient and do not fail if the audit index does not exist
94+
SearchRequest searchRequest = new SearchRequest(".transform-notifications-*");
95+
searchRequest.source(new SearchSourceBuilder().query(new MatchAllQueryBuilder()).size(100).sort("timestamp", SortOrder.ASC));
96+
97+
restClient.indices().refresh(new RefreshRequest(searchRequest.indices()), RequestOptions.DEFAULT);
98+
99+
SearchResponse searchResponse = restClient.search(searchRequest, RequestOptions.DEFAULT);
100+
101+
for (SearchHit hit : searchResponse.getHits()) {
102+
Map<String, Object> source = hit.getSourceAsMap();
103+
String level = (String) source.getOrDefault("level", "info");
104+
logger.log(
105+
Level.getLevel(level.toUpperCase(Locale.ROOT)),
106+
"Transform audit: [{}] [{}] [{}] [{}]",
107+
Instant.ofEpochMilli((long) source.getOrDefault("timestamp", 0)),
108+
source.getOrDefault("transform_id", "n/a"),
109+
source.getOrDefault("message", "n/a"),
110+
source.getOrDefault("node_name", "n/a")
111+
);
112+
}
113+
}
114+
80115
protected void cleanUpTransforms() throws IOException {
81116
for (TransformConfig config : transformConfigs.values()) {
82117
stopTransform(config.getId());

x-pack/plugin/transform/qa/single-node-tests/src/test/java/org/elasticsearch/xpack/transform/integration/TransformRestTestCase.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.apache.http.HttpHost;
1010
import org.apache.http.entity.ContentType;
1111
import org.apache.http.entity.StringEntity;
12+
import org.apache.logging.log4j.Level;
1213
import org.elasticsearch.client.Request;
1314
import org.elasticsearch.client.RequestOptions;
1415
import org.elasticsearch.client.Response;
@@ -24,6 +25,7 @@
2425
import org.elasticsearch.test.rest.ESRestTestCase;
2526
import org.elasticsearch.xpack.core.transform.TransformField;
2627
import org.elasticsearch.xpack.core.transform.transforms.persistence.TransformInternalIndexConstants;
28+
import org.joda.time.Instant;
2729
import org.junit.After;
2830
import org.junit.AfterClass;
2931
import org.junit.BeforeClass;
@@ -32,6 +34,7 @@
3234
import java.util.Arrays;
3335
import java.util.Collections;
3436
import java.util.List;
37+
import java.util.Locale;
3538
import java.util.Map;
3639
import java.util.concurrent.TimeUnit;
3740
import java.util.stream.Collectors;
@@ -364,6 +367,7 @@ protected static void deleteTransform(String transformId) throws IOException {
364367

365368
@After
366369
public void waitForTransform() throws Exception {
370+
logAudits();
367371
if (preserveClusterUponCompletion() == false) {
368372
ensureNoInitializingShards();
369373
wipeTransforms();
@@ -468,4 +472,39 @@ protected void assertOnePivotValue(String query, double expected) throws IOExcep
468472
protected static String getTransformEndpoint() {
469473
return useDeprecatedEndpoints ? TransformField.REST_BASE_PATH_TRANSFORMS_DEPRECATED : TransformField.REST_BASE_PATH_TRANSFORMS;
470474
}
475+
476+
@SuppressWarnings("unchecked")
477+
private void logAudits() throws IOException {
478+
logger.info("writing audit messages to the log");
479+
Request searchRequest = new Request("GET", TransformInternalIndexConstants.AUDIT_INDEX + "/_search?ignore_unavailable=true");
480+
searchRequest.setJsonEntity(
481+
"{ \"size\": 100,"
482+
+ " \"sort\": ["
483+
+ " {"
484+
+ " \"timestamp\": {"
485+
+ " \"order\": \"asc\""
486+
+ " }"
487+
+ " }"
488+
+ " ] }"
489+
);
490+
491+
refreshIndex(TransformInternalIndexConstants.AUDIT_INDEX_PATTERN);
492+
493+
Response searchResponse = client().performRequest(searchRequest);
494+
Map<String, Object> searchResult = entityAsMap(searchResponse);
495+
List<Map<String, Object>> searchHits = (List<Map<String, Object>>) XContentMapValues.extractValue("hits.hits", searchResult);
496+
497+
for (Map<String, Object> hit : searchHits) {
498+
Map<String, Object> source = (Map<String, Object>) XContentMapValues.extractValue("_source", hit);
499+
String level = (String) source.getOrDefault("level", "info");
500+
logger.log(
501+
Level.getLevel(level.toUpperCase(Locale.ROOT)),
502+
"Transform audit: [{}] [{}] [{}] [{}]",
503+
Instant.ofEpochMilli((long) source.getOrDefault("timestamp", 0)),
504+
source.getOrDefault("transform_id", "n/a"),
505+
source.getOrDefault("message", "n/a"),
506+
source.getOrDefault("node_name", "n/a")
507+
);
508+
}
509+
}
471510
}

0 commit comments

Comments
 (0)