Skip to content

Commit 1e07915

Browse files
authored
INFO logging of snapshot restore and completion (#88257)
But DEBUG (silent) logging of snapshot restore/completion when done in the context of CCR or searchable snapshots.
1 parent bb95041 commit 1e07915

File tree

17 files changed

+180
-15
lines changed

17 files changed

+180
-15
lines changed

docs/changelog/88257.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 88257
2+
summary: INFO logging of snapshot restore and completion
3+
area: Snapshot/Restore
4+
type: enhancement
5+
issues:
6+
- 86610

server/src/internalClusterTest/java/org/elasticsearch/cluster/ClusterStateDiffIT.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,7 @@ public ClusterState.Custom randomCreate(String name) {
727727
UUIDs.randomBase64UUID(),
728728
new Snapshot(randomName("repo"), new SnapshotId(randomName("snap"), UUIDs.randomBase64UUID())),
729729
RestoreInProgress.State.fromValue((byte) randomIntBetween(0, 3)),
730+
randomBoolean(),
730731
emptyList(),
731732
ImmutableOpenMap.of()
732733
)

server/src/internalClusterTest/java/org/elasticsearch/snapshots/RestoreSnapshotIT.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.elasticsearch.repositories.fs.FsRepository;
3232
import org.elasticsearch.rest.RestStatus;
3333
import org.elasticsearch.test.MockLogAppender;
34+
import org.elasticsearch.test.junit.annotations.TestLogging;
3435
import org.elasticsearch.xcontent.XContentFactory;
3536

3637
import java.nio.file.Path;
@@ -158,6 +159,67 @@ public void testParallelRestoreOperationsFromSingleSnapshot() throws Exception {
158159
assertThat(client.prepareGet(restoredIndexName2, sameSourceIndex ? docId : docId2).get().isExists(), equalTo(true));
159160
}
160161

162+
@TestLogging(
163+
reason = "testing the logging of the start and completion of a snapshot restore",
164+
value = "org.elasticsearch.snapshots.RestoreService:INFO"
165+
)
166+
public void testRestoreLogging() throws IllegalAccessException {
167+
final MockLogAppender mockLogAppender = new MockLogAppender();
168+
try {
169+
String indexName = "testindex";
170+
String repoName = "test-restore-snapshot-repo";
171+
String snapshotName = "test-restore-snapshot";
172+
Path absolutePath = randomRepoPath().toAbsolutePath();
173+
logger.info("Path [{}]", absolutePath);
174+
String restoredIndexName = indexName + "-restored";
175+
String expectedValue = "expected";
176+
177+
mockLogAppender.start();
178+
Loggers.addAppender(LogManager.getLogger(RestoreService.class), mockLogAppender);
179+
180+
mockLogAppender.addExpectation(
181+
new MockLogAppender.PatternSeenEventExpectation(
182+
"not seen start of snapshot restore",
183+
"org.elasticsearch.snapshots.RestoreService",
184+
Level.INFO,
185+
"started restore of snapshot \\[.*" + snapshotName + ".*\\] for indices \\[.*" + indexName + ".*\\]"
186+
)
187+
);
188+
189+
mockLogAppender.addExpectation(
190+
new MockLogAppender.PatternSeenEventExpectation(
191+
"not seen completion of snapshot restore",
192+
"org.elasticsearch.snapshots.RestoreService",
193+
Level.INFO,
194+
"completed restore of snapshot \\[.*" + snapshotName + ".*\\]"
195+
)
196+
);
197+
198+
Client client = client();
199+
// Write a document
200+
String docId = Integer.toString(randomInt());
201+
indexDoc(indexName, docId, "value", expectedValue);
202+
createRepository(repoName, "fs", absolutePath);
203+
createSnapshot(repoName, snapshotName, Collections.singletonList(indexName));
204+
205+
RestoreSnapshotResponse restoreSnapshotResponse = client.admin()
206+
.cluster()
207+
.prepareRestoreSnapshot(repoName, snapshotName)
208+
.setWaitForCompletion(false)
209+
.setRenamePattern(indexName)
210+
.setRenameReplacement(restoredIndexName)
211+
.get();
212+
213+
assertThat(restoreSnapshotResponse.status(), equalTo(RestStatus.ACCEPTED));
214+
ensureGreen(restoredIndexName);
215+
assertThat(client.prepareGet(restoredIndexName, docId).get().isExists(), equalTo(true));
216+
mockLogAppender.assertAllExpectationsMatched();
217+
} finally {
218+
Loggers.removeAppender(LogManager.getLogger(RestoreService.class), mockLogAppender);
219+
mockLogAppender.stop();
220+
}
221+
}
222+
161223
public void testRestoreIncreasesPrimaryTerms() {
162224
final String indexName = randomAlphaOfLengthBetween(5, 10).toLowerCase(Locale.ROOT);
163225
createIndex(indexName, indexSettingsNoReplicas(2).build());

server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/RestoreSnapshotRequest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
package org.elasticsearch.action.admin.cluster.snapshots.restore;
1010

11+
import org.elasticsearch.Version;
1112
import org.elasticsearch.action.ActionRequestValidationException;
1213
import org.elasticsearch.action.support.IndicesOptions;
1314
import org.elasticsearch.action.support.master.MasterNodeRequest;
@@ -48,6 +49,8 @@ public class RestoreSnapshotRequest extends MasterNodeRequest<RestoreSnapshotReq
4849
private boolean includeGlobalState = false;
4950
private boolean partial = false;
5051
private boolean includeAliases = true;
52+
public static Version VERSION_SUPPORTING_QUIET_PARAMETER = Version.V_8_4_0;
53+
private boolean quiet = false;
5154
private Settings indexSettings = Settings.EMPTY;
5255
private String[] ignoreIndexSettings = Strings.EMPTY_ARRAY;
5356

@@ -83,6 +86,11 @@ public RestoreSnapshotRequest(StreamInput in) throws IOException {
8386
includeGlobalState = in.readBoolean();
8487
partial = in.readBoolean();
8588
includeAliases = in.readBoolean();
89+
if (in.getVersion().onOrAfter(VERSION_SUPPORTING_QUIET_PARAMETER)) {
90+
quiet = in.readBoolean();
91+
} else {
92+
quiet = true;
93+
}
8694
indexSettings = readSettingsFromStream(in);
8795
ignoreIndexSettings = in.readStringArray();
8896
snapshotUuid = in.readOptionalString();
@@ -102,6 +110,9 @@ public void writeTo(StreamOutput out) throws IOException {
102110
out.writeBoolean(includeGlobalState);
103111
out.writeBoolean(partial);
104112
out.writeBoolean(includeAliases);
113+
if (out.getVersion().onOrAfter(VERSION_SUPPORTING_QUIET_PARAMETER)) {
114+
out.writeBoolean(quiet);
115+
}
105116
writeSettingsToStream(indexSettings, out);
106117
out.writeStringArray(ignoreIndexSettings);
107118
out.writeOptionalString(snapshotUuid);
@@ -383,6 +394,27 @@ public boolean includeAliases() {
383394
return includeAliases;
384395
}
385396

397+
/**
398+
* If {@code false}, report the start and completion of the restore at {@code INFO} log level.
399+
* If {@code true}, report the start and completion of the restore at {@code DEBUG} log level.
400+
*
401+
* @param quiet
402+
* @return this request
403+
*/
404+
public RestoreSnapshotRequest quiet(boolean quiet) {
405+
this.quiet = quiet;
406+
return this;
407+
}
408+
409+
/**
410+
*
411+
* @return {@code true} if logging of the start and completion of the restore should happen at {@code DEBUG} log level, else it
412+
* happens at {@code INFO} log level.
413+
*/
414+
public boolean quiet() {
415+
return quiet;
416+
}
417+
386418
/**
387419
* Sets settings that should be added/changed in all restored indices
388420
*/
@@ -601,6 +633,7 @@ public boolean equals(Object o) {
601633
&& includeGlobalState == that.includeGlobalState
602634
&& partial == that.partial
603635
&& includeAliases == that.includeAliases
636+
&& quiet == that.quiet
604637
&& Objects.equals(snapshot, that.snapshot)
605638
&& Objects.equals(repository, that.repository)
606639
&& Arrays.equals(indices, that.indices)
@@ -626,6 +659,7 @@ public int hashCode() {
626659
includeGlobalState,
627660
partial,
628661
includeAliases,
662+
quiet,
629663
indexSettings,
630664
snapshotUuid,
631665
skipOperatorOnlyState

server/src/main/java/org/elasticsearch/cluster/RestoreInProgress.java

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
package org.elasticsearch.cluster;
1010

1111
import org.elasticsearch.Version;
12+
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest;
1213
import org.elasticsearch.cluster.ClusterState.Custom;
1314
import org.elasticsearch.common.io.stream.StreamInput;
1415
import org.elasticsearch.common.io.stream.StreamOutput;
@@ -104,19 +105,36 @@ public RestoreInProgress build() {
104105
/**
105106
* Restore metadata
106107
*/
107-
public record Entry(String uuid, Snapshot snapshot, State state, List<String> indices, Map<ShardId, ShardRestoreStatus> shards) {
108+
public record Entry(
109+
String uuid,
110+
Snapshot snapshot,
111+
State state,
112+
boolean quiet,
113+
List<String> indices,
114+
Map<ShardId, ShardRestoreStatus> shards
115+
) {
108116
/**
109117
* Creates new restore metadata
110118
*
111119
* @param uuid uuid of the restore
112120
* @param snapshot snapshot
113121
* @param state current state of the restore process
122+
* @param quiet {@code true} if logging of the start and completion of the snapshot restore should be at {@code DEBUG} log
123+
* level, else it should be at {@code INFO} log level
114124
* @param indices list of indices being restored
115125
* @param shards map of shards being restored to their current restore status
116126
*/
117-
public Entry(String uuid, Snapshot snapshot, State state, List<String> indices, Map<ShardId, ShardRestoreStatus> shards) {
127+
public Entry(
128+
String uuid,
129+
Snapshot snapshot,
130+
State state,
131+
boolean quiet,
132+
List<String> indices,
133+
Map<ShardId, ShardRestoreStatus> shards
134+
) {
118135
this.snapshot = Objects.requireNonNull(snapshot);
119136
this.state = Objects.requireNonNull(state);
137+
this.quiet = Objects.requireNonNull(quiet);
120138
this.indices = Objects.requireNonNull(indices);
121139
if (shards == null) {
122140
this.shards = Map.of();
@@ -342,10 +360,24 @@ public RestoreInProgress(StreamInput in) throws IOException {
342360
uuid = in.readString();
343361
Snapshot snapshot = new Snapshot(in);
344362
State state = State.fromValue(in.readByte());
363+
boolean quiet;
364+
if (in.getVersion().onOrAfter(RestoreSnapshotRequest.VERSION_SUPPORTING_QUIET_PARAMETER)) {
365+
quiet = in.readBoolean();
366+
} else {
367+
// Backwards compatibility: previously there was no logging of the start or completion of a snapshot restore
368+
quiet = true;
369+
}
345370
List<String> indices = in.readImmutableList(StreamInput::readString);
346371
entriesBuilder.put(
347372
uuid,
348-
new Entry(uuid, snapshot, state, indices, in.readImmutableMap(ShardId::new, ShardRestoreStatus::readShardRestoreStatus))
373+
new Entry(
374+
uuid,
375+
snapshot,
376+
state,
377+
quiet,
378+
indices,
379+
in.readImmutableMap(ShardId::new, ShardRestoreStatus::readShardRestoreStatus)
380+
)
349381
);
350382
}
351383
this.entries = Collections.unmodifiableMap(entriesBuilder);
@@ -357,6 +389,9 @@ public void writeTo(StreamOutput out) throws IOException {
357389
o.writeString(entry.uuid);
358390
entry.snapshot().writeTo(o);
359391
o.writeByte(entry.state().value());
392+
if (out.getVersion().onOrAfter(RestoreSnapshotRequest.VERSION_SUPPORTING_QUIET_PARAMETER)) {
393+
o.writeBoolean(entry.quiet());
394+
}
360395
o.writeStringCollection(entry.indices);
361396
o.writeMap(entry.shards);
362397
});

server/src/main/java/org/elasticsearch/snapshots/RestoreService.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,6 @@ public void restoreSnapshot(
238238
final BiConsumer<ClusterState, Metadata.Builder> updater
239239
) {
240240
try {
241-
242241
// Try and fill in any missing repository UUIDs in case they're needed during the restore
243242
final StepListener<Void> repositoryUuidRefreshListener = new StepListener<>();
244243
refreshRepositoryUuids(refreshRepositoryUuidOnRestore, repositoriesService, repositoryUuidRefreshListener);
@@ -737,6 +736,7 @@ public static RestoreInProgress updateRestoreStateWithDeletedIndices(RestoreInPr
737736
entry.uuid(),
738737
entry.snapshot(),
739738
overallState(RestoreInProgress.State.STARTED, shards),
739+
entry.quiet(),
740740
entry.indices(),
741741
shards
742742
)
@@ -873,7 +873,9 @@ public RestoreInProgress applyChanges(final RestoreInProgress oldRestore) {
873873

874874
Map<ShardId, ShardRestoreStatus> shards = Map.copyOf(shardsBuilder);
875875
RestoreInProgress.State newState = overallState(RestoreInProgress.State.STARTED, shards);
876-
builder.add(new RestoreInProgress.Entry(entry.uuid(), entry.snapshot(), newState, entry.indices(), shards));
876+
builder.add(
877+
new RestoreInProgress.Entry(entry.uuid(), entry.snapshot(), newState, entry.quiet(), entry.indices(), shards)
878+
);
877879
} else {
878880
builder.add(entry);
879881
}
@@ -1051,6 +1053,7 @@ public ClusterState execute(ClusterState currentState) {
10511053
boolean changed = false;
10521054
for (RestoreInProgress.Entry entry : currentState.custom(RestoreInProgress.TYPE, RestoreInProgress.EMPTY)) {
10531055
if (entry.state().completed()) {
1056+
logger.log(entry.quiet() ? Level.DEBUG : Level.INFO, "completed restore of snapshot [{}]", entry.snapshot());
10541057
changed = true;
10551058
} else {
10561059
restoreInProgressBuilder.add(entry);
@@ -1373,6 +1376,7 @@ && isSystemIndex(snapshotIndexMetadata) == false) {
13731376
restoreUUID,
13741377
snapshot,
13751378
overallState(RestoreInProgress.State.INIT, shards),
1379+
request.quiet(),
13761380
List.copyOf(indicesToRestore.keySet()),
13771381
Map.copyOf(shards)
13781382
)
@@ -1569,6 +1573,12 @@ public void onFailure(Exception e) {
15691573

15701574
@Override
15711575
public void clusterStateProcessed(ClusterState oldState, ClusterState newState) {
1576+
logger.log(
1577+
request.quiet() ? Level.DEBUG : Level.INFO,
1578+
"started restore of snapshot [{}] for indices {}",
1579+
snapshot,
1580+
snapshotInfo.indices()
1581+
);
15721582
listener.onResponse(new RestoreCompletionResponse(restoreUUID, snapshot, restoreInfo));
15731583
}
15741584
}

server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/restore/RestoreSnapshotRequestTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ private RestoreSnapshotRequest randomState(RestoreSnapshotRequest instance) {
6464
}
6565
instance.partial(randomBoolean());
6666
instance.includeAliases(randomBoolean());
67+
instance.quiet(randomBoolean());
6768

6869
if (randomBoolean()) {
6970
Map<String, Object> indexSettings = new HashMap<>();
@@ -127,6 +128,7 @@ protected RestoreSnapshotRequest mutateInstance(RestoreSnapshotRequest instance)
127128
public void testSource() throws IOException {
128129
RestoreSnapshotRequest original = createTestInstance();
129130
original.snapshotUuid(null); // cannot be set via the REST API
131+
original.quiet(false); // cannot be set via the REST API
130132
XContentBuilder builder = original.toXContent(XContentFactory.jsonBuilder(), new ToXContent.MapParams(Collections.emptyMap()));
131133
XContentParser parser = XContentType.JSON.xContent()
132134
.createParser(NamedXContentRegistry.EMPTY, null, BytesReference.bytes(builder).streamInput());

server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexStateServiceTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ private static ClusterState addRestoredIndex(final String index, final int numSh
343343
"_uuid",
344344
snapshot,
345345
RestoreInProgress.State.INIT,
346+
false,
346347
Collections.singletonList(index),
347348
shardsBuilder
348349
);

server/src/test/java/org/elasticsearch/cluster/routing/allocation/ThrottlingAllocationTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ private ClusterState createRecoveryStateAndInitializeAllocations(
413413
restoreUUID,
414414
snapshot,
415415
RestoreInProgress.State.INIT,
416+
false,
416417
new ArrayList<>(snapshotIndices),
417418
restoreShards
418419
);

server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDeciderTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ public void testDiskThresholdWithSnapshotShardSizes() {
12121212
Map<ShardId, RestoreInProgress.ShardRestoreStatus> shards = Map.of(shardId, new RestoreInProgress.ShardRestoreStatus("node1"));
12131213

12141214
final RestoreInProgress.Builder restores = new RestoreInProgress.Builder().add(
1215-
new RestoreInProgress.Entry("_restore_uuid", snapshot, RestoreInProgress.State.INIT, List.of("test"), shards)
1215+
new RestoreInProgress.Entry("_restore_uuid", snapshot, RestoreInProgress.State.INIT, false, List.of("test"), shards)
12161216
);
12171217

12181218
ClusterState clusterState = ClusterState.builder(new ClusterName(getTestName()))

0 commit comments

Comments
 (0)