Skip to content

Commit a9b35f4

Browse files
Delay warning about missing x-pack (#54265)
Currently, when monitoring is enabled in a freshly-installed cluster, the non-master nodes log a warning message indicating that master may not have x-pack installed. The message is often printed even when the master does have x-pack installed but takes some time to setup the local exporter for monitoring. This commit adds the local exporter setting `wait_master.timeout` which defaults to 30 seconds. The setting configures the time that the non-master nodes should wait for master to setup monitoring. After the time elapses, they log a message to the user about possible missing x-pack installation on master. The logging of this warning was moved from `resolveBulk()` to `openBulk()` since `resolveBulk()` is called only on cluster updates and the message might not be logged until a new cluster update occurs. Closes #40898 Co-authored-by: Elastic Machine <[email protected]>
1 parent 30d8e1f commit a9b35f4

File tree

3 files changed

+46
-9
lines changed

3 files changed

+46
-9
lines changed

docs/reference/settings/monitoring-settings.asciidoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ Whether to create cluster alerts for this cluster. The default value is `true`.
153153
To use this feature, {watcher} must be enabled. If you have a basic license,
154154
cluster alerts are not displayed.
155155

156+
`wait_master.timeout`::
157+
158+
(<<time-units,time value>>) Time to wait for the master node to setup `local` exporter for monitoring.
159+
After that, the non-master nodes will warn the user for possible missing X-Pack configuration. Defaults to `30s`.
160+
156161
[float]
157162
[[http-exporter-settings]]
158163
==== HTTP Exporter Settings

x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/Exporters.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ public static List<Setting.AffixSetting<?>> getSettings() {
254254
List<Setting.AffixSetting<?>> settings = new ArrayList<>();
255255
settings.addAll(Exporter.getSettings());
256256
settings.addAll(HttpExporter.getSettings());
257+
settings.addAll(LocalExporter.getSettings());
257258
return settings;
258259
}
259260

x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/local/LocalExporter.java

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@
2828
import org.elasticsearch.common.bytes.BytesArray;
2929
import org.elasticsearch.common.bytes.BytesReference;
3030
import org.elasticsearch.common.regex.Regex;
31+
import org.elasticsearch.common.settings.Setting;
32+
import org.elasticsearch.common.settings.Setting.Property;
3133
import org.elasticsearch.common.time.DateFormatter;
3234
import org.elasticsearch.common.unit.TimeValue;
3335
import org.elasticsearch.common.util.concurrent.ThreadContext;
3436
import org.elasticsearch.common.xcontent.XContentType;
37+
import org.elasticsearch.gateway.GatewayService;
3538
import org.elasticsearch.index.IndexNotFoundException;
3639
import org.elasticsearch.ingest.IngestMetadata;
3740
import org.elasticsearch.ingest.PipelineConfiguration;
@@ -86,6 +89,16 @@ public class LocalExporter extends Exporter implements ClusterStateListener, Cle
8689

8790
public static final String TYPE = "local";
8891

92+
/**
93+
* Time to wait for the master node to setup local exporter for monitoring.
94+
* After that, the non-master nodes will warn the user for possible missing configuration.
95+
*/
96+
public static final Setting.AffixSetting<TimeValue> WAIT_MASTER_TIMEOUT_SETTING = Setting.affixKeySetting(
97+
"xpack.monitoring.exporters.",
98+
"wait_master.timeout",
99+
(key) -> Setting.timeSetting(key, TimeValue.timeValueSeconds(30), Property.Dynamic, Property.NodeScope)
100+
);
101+
89102
private final Client client;
90103
private final ClusterService clusterService;
91104
private final XPackLicenseState licenseState;
@@ -96,8 +109,10 @@ public class LocalExporter extends Exporter implements ClusterStateListener, Cle
96109

97110
private final AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
98111
private final AtomicBoolean installingSomething = new AtomicBoolean(false);
99-
private final AtomicBoolean waitedForSetup = new AtomicBoolean(false);
100112
private final AtomicBoolean watcherSetup = new AtomicBoolean(false);
113+
private final AtomicBoolean stateInitialized = new AtomicBoolean(false);
114+
115+
private long stateInitializedTime;
101116

102117
public LocalExporter(Exporter.Config config, Client client, CleanerService cleanerService) {
103118
super(config);
@@ -116,6 +131,13 @@ public LocalExporter(Exporter.Config config, Client client, CleanerService clean
116131

117132
@Override
118133
public void clusterChanged(ClusterChangedEvent event) {
134+
// Save the time right after the cluster state is initialized/recovered
135+
// to use it later for LocalExporter#WAIT_MASTER_TIMEOUT_SETTING
136+
if (event.state().blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK) == false) {
137+
if (stateInitialized.getAndSet(true) == false) {
138+
stateInitializedTime = client.threadPool().relativeTimeInMillis();
139+
}
140+
}
119141
if (state.get() == State.INITIALIZED) {
120142
resolveBulk(event.state(), true);
121143
}
@@ -144,6 +166,17 @@ boolean isExporterReady() {
144166
@Override
145167
public void openBulk(final ActionListener<ExportBulk> listener) {
146168
if (state.get() != State.RUNNING) {
169+
// wait for some time before informing the user for possible missing x-pack configuration on master
170+
final TimeValue masterTimeout = WAIT_MASTER_TIMEOUT_SETTING.getConcreteSettingForNamespace(config.name())
171+
.get(config.settings());
172+
TimeValue timeElapsed = TimeValue.timeValueMillis(client.threadPool().relativeTimeInMillis() - stateInitializedTime);
173+
if (timeElapsed.compareTo(masterTimeout) > 0) {
174+
logger.info(
175+
"waiting for elected master node [{}] to setup local exporter [{}] (does it have x-pack installed?)",
176+
clusterService.state().nodes().getMasterNode(),
177+
config.name()
178+
);
179+
}
147180
listener.onResponse(null);
148181
} else {
149182
try {
@@ -179,14 +212,8 @@ LocalBulk resolveBulk(ClusterState clusterState, boolean clusterStateChange) {
179212
// elected master node needs to setup templates; non-master nodes need to wait for it to be setup
180213
if (clusterService.state().nodes().isLocalNodeElectedMaster()) {
181214
setup = setupIfElectedMaster(clusterState, templates, clusterStateChange);
182-
} else if (setupIfNotElectedMaster(clusterState, templates.keySet()) == false) {
183-
// the first pass will be false so that we don't bother users if the master took one-go to setup
184-
if (waitedForSetup.getAndSet(true)) {
185-
logger.info("waiting for elected master node [{}] to setup local exporter [{}] (does it have x-pack installed?)",
186-
clusterService.state().nodes().getMasterNode(), config.name());
187-
}
188-
189-
setup = false;
215+
} else {
216+
setup = setupIfNotElectedMaster(clusterState, templates.keySet());
190217
}
191218

192219
// any failure/delay to setup the local exporter stops it until the next pass (10s by default)
@@ -651,4 +678,8 @@ public void onFailure(Exception e) {
651678

652679
}
653680

681+
public static List<Setting.AffixSetting<?>> getSettings() {
682+
return List.of(WAIT_MASTER_TIMEOUT_SETTING);
683+
}
684+
654685
}

0 commit comments

Comments
 (0)