Skip to content

Commit d94ff55

Browse files
committed
Fix stats in slow logs to be a escaped JSON (elastic#44642)
Fields in JSON logs should be an escaped JSON fields. It is a broken json value at the moment "stats": "["group1", "group2"]", -> "stats": "[\"group1\", \"group2\"]", This should later be refactored into a JSON array of strings (the same as types in 7.x)
1 parent a6adcec commit d94ff55

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

server/src/main/java/org/elasticsearch/common/logging/ESLogMessage.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919

2020
package org.elasticsearch.common.logging;
2121

22+
import com.fasterxml.jackson.core.io.JsonStringEncoder;
2223
import org.apache.logging.log4j.message.ParameterizedMessage;
2324
import org.elasticsearch.common.SuppressLoggerChecks;
2425

26+
import java.nio.charset.Charset;
2527
import java.util.Map;
2628
import java.util.stream.Collectors;
2729
import java.util.stream.Stream;
@@ -30,6 +32,7 @@
3032
* A base class for custom log4j logger messages. Carries additional fields which will populate JSON fields in logs.
3133
*/
3234
public abstract class ESLogMessage extends ParameterizedMessage {
35+
private static final JsonStringEncoder JSON_STRING_ENCODER = JsonStringEncoder.getInstance();
3336
private final Map<String, Object> fields;
3437

3538
/**
@@ -42,6 +45,11 @@ public ESLogMessage(Map<String, Object> fields, String messagePattern, Object...
4245
this.fields = fields;
4346
}
4447

48+
public static String escapeJson(String text) {
49+
byte[] sourceEscaped = JSON_STRING_ENCODER.quoteAsUTF8(text);
50+
return new String(sourceEscaped, Charset.defaultCharset());
51+
}
52+
4553
public String getValueFor(String key) {
4654
Object value = fields.get(key);
4755
return value!=null ? value.toString() : null;

server/src/main/java/org/elasticsearch/index/SearchSlowLog.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.index;
2121

22-
import com.fasterxml.jackson.core.io.JsonStringEncoder;
2322
import org.apache.logging.log4j.LogManager;
2423
import org.apache.logging.log4j.Logger;
2524
import org.elasticsearch.common.Strings;
@@ -33,7 +32,6 @@
3332
import org.elasticsearch.search.internal.SearchContext;
3433
import org.elasticsearch.tasks.Task;
3534

36-
import java.nio.charset.Charset;
3735
import java.util.Arrays;
3836
import java.util.Collections;
3937
import java.util.HashMap;
@@ -173,14 +171,13 @@ private static Map<String, Object> prepareMap(SearchContext context, long tookIn
173171
}
174172
String[] types = context.getQueryShardContext().getTypes();
175173
messageFields.put("types", asJsonArray(types != null ? Arrays.stream(types) : Stream.empty()));
176-
messageFields.put("stats", asJsonArray(context.groupStats() != null ? context.groupStats().stream() : Stream.empty()));
174+
messageFields.put("stats", escapeJson(asJsonArray(
175+
context.groupStats() != null ? context.groupStats().stream() : Stream.empty())));
177176
messageFields.put("search_type", context.searchType());
178177
messageFields.put("total_shards", context.numberOfShards());
179178

180179
if (context.request().source() != null) {
181-
byte[] sourceEscaped = JsonStringEncoder.getInstance()
182-
.quoteAsUTF8(context.request().source().toString(FORMAT_PARAMS));
183-
String source = new String(sourceEscaped, Charset.defaultCharset());
180+
String source = escapeJson(context.request().source().toString(FORMAT_PARAMS));
184181

185182
messageFields.put("source", source);
186183
} else {

server/src/test/java/org/elasticsearch/index/SearchSlowLogTests.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
import org.hamcrest.Matchers;
4343

4444
import java.io.IOException;
45+
import java.util.Arrays;
4546
import java.util.Collections;
47+
import java.util.List;
4648

4749
import static org.hamcrest.Matchers.containsString;
4850
import static org.hamcrest.Matchers.endsWith;
@@ -55,6 +57,9 @@
5557
public class SearchSlowLogTests extends ESSingleNodeTestCase {
5658
@Override
5759
protected SearchContext createSearchContext(IndexService indexService) {
60+
return createSearchContext(indexService, new String[]{});
61+
}
62+
protected SearchContext createSearchContext(IndexService indexService, String ... groupStats) {
5863
BigArrays bigArrays = indexService.getBigArrays();
5964
ThreadPool threadPool = indexService.getThreadPool();
6065
return new TestSearchContext(bigArrays, indexService) {
@@ -150,6 +155,12 @@ public String getClusterAlias() {
150155
return null;
151156
}
152157
};
158+
159+
@Override
160+
public List<String> groupStats() {
161+
return Arrays.asList(groupStats);
162+
}
163+
153164
@Override
154165
public ShardSearchRequest request() {
155166
return request;
@@ -177,6 +188,26 @@ public void testSlowLogHasJsonFields() throws IOException {
177188
assertThat(p.getValueFor("source"), equalTo("{\\\"query\\\":{\\\"match_all\\\":{\\\"boost\\\":1.0}}}"));
178189
}
179190

191+
public void testSlowLogsWithStats() throws IOException {
192+
IndexService index = createIndex("foo");
193+
SearchContext searchContext = createSearchContext(index,"group1");
194+
SearchSourceBuilder source = SearchSourceBuilder.searchSource().query(QueryBuilders.matchAllQuery());
195+
searchContext.request().source(source);
196+
searchContext.setTask(new SearchTask(0, "n/a", "n/a", "test", null,
197+
Collections.singletonMap(Task.X_OPAQUE_ID, "my_id")));
198+
199+
SearchSlowLog.SearchSlowLogMessage p = new SearchSlowLog.SearchSlowLogMessage(searchContext, 10);
200+
assertThat(p.getValueFor("stats"), equalTo("[\\\"group1\\\"]"));
201+
202+
searchContext = createSearchContext(index, "group1", "group2");
203+
source = SearchSourceBuilder.searchSource().query(QueryBuilders.matchAllQuery());
204+
searchContext.request().source(source);
205+
searchContext.setTask(new SearchTask(0, "n/a", "n/a", "test", null,
206+
Collections.singletonMap(Task.X_OPAQUE_ID, "my_id")));
207+
p = new SearchSlowLog.SearchSlowLogMessage(searchContext, 10);
208+
assertThat(p.getValueFor("stats"), equalTo("[\\\"group1\\\", \\\"group2\\\"]"));
209+
}
210+
180211
public void testSlowLogSearchContextPrinterToLog() throws IOException {
181212
IndexService index = createIndex("foo");
182213
SearchContext searchContext = createSearchContext(index);

0 commit comments

Comments
 (0)