Skip to content

Commit af3366f

Browse files
Refactor to use SlowLogFieldProviders
1 parent b74ea91 commit af3366f

File tree

10 files changed

+125
-50
lines changed

10 files changed

+125
-50
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,9 @@ public interface SlowLogFieldProvider {
1919
* @param indexSettings settings for the index
2020
*/
2121
SlowLogFields create(IndexSettings indexSettings);
22+
23+
/**
24+
* Create a field provider without index level settings
25+
*/
26+
SlowLogFields create();
2227
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,13 @@ public interface SlowLogFields {
2727
* @return map of field name to value
2828
*/
2929
Map<String, String> searchFields();
30+
31+
32+
/**
33+
* Slow log fields for query
34+
* @return map of field name to value
35+
*/
36+
default Map<String, String> queryFields(){
37+
return Map.of();
38+
}
3039
}

server/src/main/java/org/elasticsearch/indices/IndicesServiceBuilder.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public class IndicesServiceBuilder {
8383
QueryRewriteInterceptor queryRewriteInterceptor = null;
8484
SlowLogFieldProvider slowLogFieldProvider = new SlowLogFieldProvider() {
8585
@Override
86-
public SlowLogFields create(IndexSettings indexSettings) {
86+
public SlowLogFields create() {
8787
return new SlowLogFields() {
8888
@Override
8989
public Map<String, String> indexFields() {
@@ -96,6 +96,12 @@ public Map<String, String> searchFields() {
9696
}
9797
};
9898
}
99+
100+
@Override
101+
public SlowLogFields create(IndexSettings indexSettings) {
102+
return create();
103+
}
104+
99105
};
100106

101107
public IndicesServiceBuilder settings(Settings settings) {

server/src/main/java/org/elasticsearch/node/NodeConstruction.java

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
import org.elasticsearch.index.IndexMode;
115115
import org.elasticsearch.index.IndexSettingProvider;
116116
import org.elasticsearch.index.IndexSettingProviders;
117+
import org.elasticsearch.index.IndexSettings;
117118
import org.elasticsearch.index.IndexingPressure;
118119
import org.elasticsearch.index.SlowLogFieldProvider;
119120
import org.elasticsearch.index.SlowLogFields;
@@ -825,28 +826,54 @@ private void construct(
825826
List<? extends SlowLogFieldProvider> slowLogFieldProviders = pluginsService.loadServiceProviders(SlowLogFieldProvider.class);
826827
// NOTE: the response of index/search slow log fields below must be calculated dynamically on every call
827828
// because the responses may change dynamically at runtime
828-
SlowLogFieldProvider slowLogFieldProvider = indexSettings -> {
829-
final List<SlowLogFields> fields = new ArrayList<>();
830-
for (var provider : slowLogFieldProviders) {
831-
fields.add(provider.create(indexSettings));
832-
}
833-
return new SlowLogFields() {
834-
@Override
835-
public Map<String, String> indexFields() {
836-
return fields.stream()
837-
.flatMap(f -> f.indexFields().entrySet().stream())
838-
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
829+
SlowLogFieldProvider slowLogFieldProvider = new SlowLogFieldProvider() {
830+
public SlowLogFields create() {
831+
final List<SlowLogFields> fields = new ArrayList<>();
832+
for (var provider : slowLogFieldProviders) {
833+
fields.add(provider.create());
839834
}
835+
return new SlowLogFields() {
836+
@Override
837+
public Map<String, String> indexFields() {
838+
return fields.stream()
839+
.flatMap(f -> f.indexFields().entrySet().stream())
840+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
841+
}
842+
843+
@Override
844+
public Map<String, String> searchFields() {
845+
return fields.stream()
846+
.flatMap(f -> f.searchFields().entrySet().stream())
847+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
848+
}
849+
};
850+
}
840851

841-
@Override
842-
public Map<String, String> searchFields() {
843-
return fields.stream()
844-
.flatMap(f -> f.searchFields().entrySet().stream())
845-
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
852+
public SlowLogFields create(IndexSettings indexSettings) {
853+
final List<SlowLogFields> fields = new ArrayList<>();
854+
for (var provider : slowLogFieldProviders) {
855+
fields.add(provider.create(indexSettings));
846856
}
847-
};
857+
return new SlowLogFields() {
858+
@Override
859+
public Map<String, String> indexFields() {
860+
return fields.stream()
861+
.flatMap(f -> f.indexFields().entrySet().stream())
862+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
863+
}
864+
865+
@Override
866+
public Map<String, String> searchFields() {
867+
return fields.stream()
868+
.flatMap(f -> f.searchFields().entrySet().stream())
869+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
870+
}
871+
};
872+
}
873+
848874
};
849875

876+
850877
IndicesService indicesService = new IndicesServiceBuilder().settings(settings)
851878
.pluginsService(pluginsService)
852879
.nodeEnvironment(nodeEnvironment)
@@ -933,7 +960,8 @@ public Map<String, String> searchFields() {
933960
dataStreamGlobalRetentionSettings,
934961
documentParsingProvider,
935962
taskManager,
936-
projectResolver
963+
projectResolver,
964+
slowLogFieldProviders
937965
);
938966

939967
Collection<?> pluginComponents = pluginsService.flatMap(plugin -> {

server/src/main/java/org/elasticsearch/node/PluginServiceInstances.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.elasticsearch.env.Environment;
2121
import org.elasticsearch.env.NodeEnvironment;
2222
import org.elasticsearch.features.FeatureService;
23+
import org.elasticsearch.index.SlowLogFieldProvider;
2324
import org.elasticsearch.indices.IndicesService;
2425
import org.elasticsearch.indices.SystemIndices;
2526
import org.elasticsearch.plugins.Plugin;
@@ -32,6 +33,8 @@
3233
import org.elasticsearch.watcher.ResourceWatcherService;
3334
import org.elasticsearch.xcontent.NamedXContentRegistry;
3435

36+
import java.util.List;
37+
3538
public record PluginServiceInstances(
3639
Client client,
3740
ClusterService clusterService,
@@ -53,5 +56,6 @@ public record PluginServiceInstances(
5356
DataStreamGlobalRetentionSettings dataStreamGlobalRetentionSettings,
5457
DocumentParsingProvider documentParsingProvider,
5558
TaskManager taskManager,
56-
ProjectResolver projectResolver
59+
ProjectResolver projectResolver,
60+
List<? extends SlowLogFieldProvider> slowLogFieldProviders
5761
) implements Plugin.PluginServices {}

server/src/main/java/org/elasticsearch/plugins/Plugin.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.elasticsearch.features.FeatureService;
3030
import org.elasticsearch.index.IndexModule;
3131
import org.elasticsearch.index.IndexSettingProvider;
32+
import org.elasticsearch.index.SlowLogFieldProvider;
3233
import org.elasticsearch.indices.IndicesService;
3334
import org.elasticsearch.indices.SystemIndices;
3435
import org.elasticsearch.plugins.internal.DocumentParsingProvider;
@@ -180,6 +181,11 @@ public interface PluginServices {
180181
* The project resolver for the cluster. This should be used to determine the active project against which a request should execute
181182
*/
182183
ProjectResolver projectResolver();
184+
185+
/**
186+
* Providers for additional SlowLog fields
187+
*/
188+
List<? extends SlowLogFieldProvider> slowLogFieldProviders();
183189
}
184190

185191
/**

server/src/test/java/org/elasticsearch/indices/IndicesServiceTests.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ static void setFields(Map<String, String> fields) {
213213
}
214214

215215
@Override
216-
public SlowLogFields create(IndexSettings indexSettings) {
216+
public SlowLogFields create() {
217217
return new SlowLogFields() {
218218
@Override
219219
public Map<String, String> indexFields() {
@@ -226,6 +226,12 @@ public Map<String, String> searchFields() {
226226
}
227227
};
228228
}
229+
230+
@Override
231+
public SlowLogFields create(IndexSettings indexSettings) {
232+
return create();
233+
}
234+
229235
}
230236

231237
public static class TestAnotherSlowLogFieldProvider implements SlowLogFieldProvider {
@@ -237,7 +243,7 @@ static void setFields(Map<String, String> fields) {
237243
}
238244

239245
@Override
240-
public SlowLogFields create(IndexSettings indexSettings) {
246+
public SlowLogFields create() {
241247
return new SlowLogFields() {
242248
@Override
243249
public Map<String, String> indexFields() {
@@ -250,6 +256,11 @@ public Map<String, String> searchFields() {
250256
}
251257
};
252258
}
259+
260+
@Override
261+
public SlowLogFields create(IndexSettings indexSettings) {
262+
return create();
263+
}
253264
}
254265

255266
@Override

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlPlugin.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import org.elasticsearch.xpack.core.XPackPlugin;
5252
import org.elasticsearch.xpack.core.action.XPackInfoFeatureAction;
5353
import org.elasticsearch.xpack.core.action.XPackUsageFeatureAction;
54-
import org.elasticsearch.xpack.core.security.SecurityContext;
5554
import org.elasticsearch.xpack.esql.EsqlInfoTransportAction;
5655
import org.elasticsearch.xpack.esql.EsqlUsageTransportAction;
5756
import org.elasticsearch.xpack.esql.action.EsqlAsyncGetResultAction;
@@ -172,10 +171,7 @@ public Collection<?> createComponents(PluginServices services) {
172171
new IndexResolver(services.client()),
173172
services.telemetryProvider().getMeterRegistry(),
174173
getLicenseState(),
175-
new EsqlSlowLog(
176-
services.clusterService().getClusterSettings(),
177-
new SecurityContext(Settings.EMPTY, services.threadPool().getThreadContext())
178-
)
174+
new EsqlSlowLog(services.clusterService().getClusterSettings(), services.slowLogFieldProviders())
179175
),
180176
new ExchangeService(
181177
services.clusterService().getSettings(),

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/slowlog/EsqlSlowLog.java

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212
import org.elasticsearch.common.logging.ESLogMessage;
1313
import org.elasticsearch.common.settings.ClusterSettings;
1414
import org.elasticsearch.core.TimeValue;
15+
import org.elasticsearch.index.SlowLogFieldProvider;
16+
import org.elasticsearch.index.SlowLogFields;
1517
import org.elasticsearch.xcontent.json.JsonStringEncoder;
16-
import org.elasticsearch.xpack.core.security.SecurityContext;
17-
import org.elasticsearch.xpack.core.security.user.User;
1818
import org.elasticsearch.xpack.esql.session.Result;
1919

2020
import java.nio.charset.StandardCharsets;
2121
import java.util.HashMap;
22+
import java.util.List;
2223
import java.util.Map;
2324
import java.util.function.Supplier;
2425

@@ -43,6 +44,7 @@ public final class EsqlSlowLog {
4344

4445
public static final String LOGGER_NAME = "esql.slowlog.query";
4546
private static final Logger queryLogger = LogManager.getLogger(LOGGER_NAME);
47+
private final List<SlowLogFields> additionalProviders;
4648

4749
private volatile long queryWarnThreshold;
4850
private volatile long queryInfoThreshold;
@@ -51,16 +53,14 @@ public final class EsqlSlowLog {
5153

5254
private volatile boolean includeUser;
5355

54-
private final SecurityContext security;
55-
56-
public EsqlSlowLog(ClusterSettings settings, SecurityContext security) {
56+
public EsqlSlowLog(ClusterSettings settings, List<? extends SlowLogFieldProvider> slowLogFieldProviders) {
5757
settings.initializeAndWatch(ESQL_SLOWLOG_THRESHOLD_QUERY_WARN_SETTING, this::setQueryWarnThreshold);
5858
settings.initializeAndWatch(ESQL_SLOWLOG_THRESHOLD_QUERY_INFO_SETTING, this::setQueryInfoThreshold);
5959
settings.initializeAndWatch(ESQL_SLOWLOG_THRESHOLD_QUERY_DEBUG_SETTING, this::setQueryDebugThreshold);
6060
settings.initializeAndWatch(ESQL_SLOWLOG_THRESHOLD_QUERY_TRACE_SETTING, this::setQueryTraceThreshold);
6161
settings.initializeAndWatch(ESQL_SLOWLOG_THRESHOLD_INCLUDE_USER_SETTING, this::setIncludeUser);
6262

63-
this.security = security;
63+
this.additionalProviders = slowLogFieldProviders.stream().map(SlowLogFieldProvider::create).toList();
6464
}
6565

6666
public EsqlSlowLog(ClusterSettings settings) {
@@ -72,11 +72,11 @@ public void onQueryPhase(Result esqlResult, String query) {
7272
return; // TODO review, it happens in some tests, not sure if it's a thing also in prod
7373
}
7474
long tookInNanos = esqlResult.executionInfo().overallTook().nanos();
75-
log(() -> Message.of(esqlResult, query, user()), tookInNanos);
75+
log(() -> Message.of(esqlResult, query, additionalProviders), tookInNanos);
7676
}
7777

7878
public void onQueryFailure(String query, Exception ex, long tookInNanos) {
79-
log(() -> Message.of(query, tookInNanos, ex, user()), tookInNanos);
79+
log(() -> Message.of(query, tookInNanos, ex, additionalProviders), tookInNanos);
8080
}
8181

8282
private void log(Supplier<ESLogMessage> logProducer, long tookInNanos) {
@@ -111,39 +111,36 @@ public void setIncludeUser(boolean includeUser) {
111111
this.includeUser = includeUser;
112112
}
113113

114-
private User user() {
115-
User user = null;
116-
if (includeUser && security != null) {
117-
user = security.getUser();
118-
}
119-
return user;
120-
}
121-
122114
static final class Message {
123115

124116
private static String escapeJson(String text) {
125117
byte[] sourceEscaped = JsonStringEncoder.getInstance().quoteAsUTF8(text);
126118
return new String(sourceEscaped, StandardCharsets.UTF_8);
127119
}
128120

129-
public static ESLogMessage of(Result esqlResult, String query, User user) {
121+
public static ESLogMessage of(Result esqlResult, String query, List<SlowLogFields> providers) {
130122
Map<String, Object> jsonFields = new HashMap<>();
131-
addGenericFields(jsonFields, query, true, user);
123+
addFromProviders(providers, jsonFields);
124+
addGenericFields(jsonFields, query, true);
132125
addResultFields(jsonFields, esqlResult);
133126
return new ESLogMessage().withFields(jsonFields);
134127
}
135128

136-
public static ESLogMessage of(String query, long took, Exception exception, User user) {
129+
public static ESLogMessage of(String query, long took, Exception exception, List<SlowLogFields> providers) {
137130
Map<String, Object> jsonFields = new HashMap<>();
138-
addGenericFields(jsonFields, query, false, user);
131+
addFromProviders(providers, jsonFields);
132+
addGenericFields(jsonFields, query, false);
139133
addErrorFields(jsonFields, took, exception);
140134
return new ESLogMessage().withFields(jsonFields);
141135
}
142136

143-
private static void addGenericFields(Map<String, Object> fieldMap, String query, boolean success, User user) {
144-
if (user != null) {
145-
fieldMap.put("user.name", user.principal());
137+
private static void addFromProviders(List<SlowLogFields> providers, Map<String, Object> jsonFields) {
138+
for (SlowLogFields provider : providers) {
139+
jsonFields.putAll(provider.queryFields());
146140
}
141+
}
142+
143+
private static void addGenericFields(Map<String, Object> fieldMap, String query, boolean success) {
147144
String source = escapeJson(query);
148145
fieldMap.put(ELASTICSEARCH_SLOWLOG_SUCCESS, success);
149146
fieldMap.put(ELASTICSEARCH_SLOWLOG_SEARCH_TYPE, "ESQL");

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/slowlog/SecuritySlowLogFieldProvider.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ private class SecuritySlowLogFields implements SlowLogFields {
3333
this.includeUserInIndexing = indexSettings.getValue(INDEX_INDEXING_SLOWLOG_INCLUDE_USER_SETTING);
3434
}
3535

36+
SecuritySlowLogFields() {
37+
}
38+
3639
@Override
3740
public Map<String, String> indexFields() {
3841
if (includeUserInIndexing) {
@@ -48,6 +51,11 @@ public Map<String, String> searchFields() {
4851
}
4952
return Map.of();
5053
}
54+
55+
@Override
56+
public Map<String, String> queryFields() {
57+
return plugin.getAuthContextForSlowLog();
58+
}
5159
}
5260

5361
public SecuritySlowLogFieldProvider() {
@@ -62,4 +70,9 @@ public SecuritySlowLogFieldProvider(Security plugin) {
6270
public SlowLogFields create(IndexSettings indexSettings) {
6371
return new SecuritySlowLogFields(indexSettings);
6472
}
73+
74+
@Override
75+
public SlowLogFields create() {
76+
return new SecuritySlowLogFields();
77+
}
6578
}

0 commit comments

Comments
 (0)