Skip to content

Commit

Permalink
Expose index age in ILM explain output (#44457)
Browse files Browse the repository at this point in the history
* Expose index age in ILM explain output

This adds the index's age to the ILM explain output, for example:

```
{
  "indices" : {
    "ilm-000001" : {
      "index" : "ilm-000001",
      "managed" : true,
      "policy" : "full-lifecycle",
      "lifecycle_date" : "2019-07-16T19:48:22.294Z",
      "lifecycle_date_millis" : 1563306502294,
      "age" : "1.34m",
      "phase" : "hot",
      "phase_time" : "2019-07-16T19:48:22.487Z",
      ... etc ...
    }
  }
}
```

This age can be used to tell when ILM will transition the index to the
next phase, based on that phase's `min_age`.

Resolves #38988

* Expose age in getters and in HLRC
  • Loading branch information
dakrone committed Jul 18, 2019
1 parent af093a4 commit fe2ef66
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
Expand Down Expand Up @@ -52,6 +53,7 @@ public class IndexLifecycleExplainResponse implements ToXContentObject {
private static final ParseField STEP_TIME_FIELD = new ParseField("step_time");
private static final ParseField STEP_INFO_FIELD = new ParseField("step_info");
private static final ParseField PHASE_EXECUTION_INFO = new ParseField("phase_execution");
private static final ParseField AGE_FIELD = new ParseField("age");

public static final ConstructingObjectParser<IndexLifecycleExplainResponse, Void> PARSER = new ConstructingObjectParser<>(
"index_lifecycle_explain_response", true,
Expand Down Expand Up @@ -205,6 +207,14 @@ public PhaseExecutionInfo getPhaseExecutionInfo() {
return phaseExecutionInfo;
}

public TimeValue getAge() {
if (lifecycleDate == null) {
return TimeValue.MINUS_ONE;
} else {
return TimeValue.timeValueMillis(System.currentTimeMillis() - lifecycleDate);
}
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
Expand All @@ -214,6 +224,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.field(POLICY_NAME_FIELD.getPreferredName(), policyName);
if (lifecycleDate != null) {
builder.timeField(LIFECYCLE_DATE_MILLIS_FIELD.getPreferredName(), LIFECYCLE_DATE_FIELD.getPreferredName(), lifecycleDate);
builder.field(AGE_FIELD.getPreferredName(), getAge().toHumanReadableString(2));
}
if (phase != null) {
builder.field(PHASE_FIELD.getPreferredName(), phase);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ protected boolean supportsUnknownFields() {
return false;
}

@Override
protected boolean assertToXContentEquivalence() {
return false;
}

@Override
protected NamedXContentRegistry xContentRegistry() {
List<NamedXContentRegistry.Entry> entries = new ArrayList<>(ClusterModule.getNamedXWriteables());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ protected boolean supportsUnknownFields() {
return true;
}

@Override
protected boolean assertToXContentEquivalence() {
return false;
}

@Override
protected Predicate<String> getRandomFieldsExcludeFilter() {
return (field) ->
Expand Down
17 changes: 11 additions & 6 deletions docs/reference/ilm/apis/explain.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,13 @@ that the index is managed and in the `new` phase:
"managed": true, <1>
"policy": "my_policy", <2>
"lifecycle_date_millis": 1538475653281, <3>
"age": "15s", <4>
"phase": "new",
"phase_time_millis": 1538475653317, <4>
"phase_time_millis": 1538475653317, <5>
"action": "complete",
"action_time_millis": 1538475653317, <5>
"action_time_millis": 1538475653317, <6>
"step": "complete",
"step_time_millis": 1538475653317 <6>
"step_time_millis": 1538475653317 <7>
}
}
}
Expand All @@ -114,9 +115,10 @@ that the index is managed and in the `new` phase:
ILM the other fields will not be shown
<2> The name of the policy which ILM is using for this index
<3> The timestamp used for the `min_age`
<4> When the index entered the current phase
<5> When the index entered the current action
<6> When the index entered the current step
<4> The age of the index (used for calculating when to enter the next phase)
<5> When the index entered the current phase
<6> When the index entered the current action
<7> When the index entered the current step

Once the policy is running on the index, the response includes a
`phase_execution` object that shows the definition of the current phase.
Expand All @@ -133,6 +135,7 @@ phase completes.
"policy": "my_lifecycle3",
"lifecycle_date_millis": 1538475653281,
"lifecycle_date": "2018-10-15T13:45:21.981Z",
"age": "25.14s",
"phase": "hot",
"phase_time_millis": 1538475653317,
"phase_time": "2018-10-15T13:45:22.577Z",
Expand Down Expand Up @@ -181,6 +184,7 @@ information for the step that's being performed on the index.
"policy": "my_lifecycle3",
"lifecycle_date_millis": 1538475653281,
"lifecycle_date": "2018-10-15T13:45:21.981Z",
"age": "4.12m",
"phase": "warm",
"phase_time_millis": 1538475653317,
"phase_time": "2018-10-15T13:45:22.577Z",
Expand Down Expand Up @@ -241,6 +245,7 @@ the step that failed and the step info provides information about the error.
"policy": "my_lifecycle3",
"lifecycle_date_millis": 1538475653281,
"lifecycle_date": "2018-10-15T13:45:21.981Z",
"age": "50.1d",
"phase": "hot",
"phase_time_millis": 1538475653317,
"phase_time": "2018-10-15T13:45:22.577Z",
Expand Down
30 changes: 16 additions & 14 deletions docs/reference/ilm/error-handling.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,21 @@ Which returns the following information:
"managed" : true, <1>
"policy" : "shrink-the-index", <2>
"lifecycle_date_millis" : 1541717265865,
"phase" : "warm", <3>
"age": "5.1d", <3>
"phase" : "warm", <4>
"phase_time_millis" : 1541717272601,
"action" : "shrink", <4>
"action" : "shrink", <5>
"action_time_millis" : 1541717272601,
"step" : "ERROR", <5>
"step" : "ERROR", <6>
"step_time_millis" : 1541717272688,
"failed_step" : "shrink", <6>
"failed_step" : "shrink", <7>
"step_info" : {
"type" : "illegal_argument_exception", <7>
"reason" : "the number of target shards [4] must be less that the number of source shards [2]" <8>
"type" : "illegal_argument_exception", <8>
"reason" : "the number of target shards [4] must be less that the number of source shards [2]" <9>
},
"phase_execution" : {
"policy" : "shrink-the-index",
"phase_definition" : { <9>
"phase_definition" : { <10>
"min_age" : "5d",
"actions" : {
"shrink" : {
Expand All @@ -108,13 +109,14 @@ Which returns the following information:
// TESTRESPONSE[skip:no way to know if we will get this response immediately]
<1> this index is managed by ILM
<2> the policy in question, in this case, "shrink-the-index"
<3> what phase the index is currently in
<4> what action the index is currently on
<5> what step the index is currently on, in this case, because there is an error, the index is in the "ERROR" step
<6> the name of the step that failed to execute, in this case "shrink"
<7> the error class that occurred during this step
<8> the error message that occurred during the execution failure
<9> the definition of the phase (in this case, the "warm" phase) that the index is currently on
<3> the current age for the index
<4> what phase the index is currently in
<5> what action the index is currently on
<6> what step the index is currently on, in this case, because there is an error, the index is in the "ERROR" step
<7> the name of the step that failed to execute, in this case "shrink"
<8> the error class that occurred during this step
<9> the error message that occurred during the execution failure
<10> the definition of the phase (in this case, the "warm" phase) that the index is currently on

The index here has been moved to the error step because the shrink definition in
the policy is using an incorrect number of shards. So rectifying that in the
Expand Down
22 changes: 12 additions & 10 deletions docs/reference/ilm/getting-started-ilm.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -173,15 +173,16 @@ managed indices.
"managed": true, <1>
"policy": "datastream_policy", <2>
"lifecycle_date_millis": 1538475653281,
"phase": "hot", <3>
"age": "30s", <3>
"phase": "hot", <4>
"phase_time_millis": 1538475653317,
"action": "rollover", <4>
"action": "rollover", <5>
"action_time_millis": 1538475653317,
"step": "attempt-rollover", <5>
"step": "attempt-rollover", <6>
"step_time_millis": 1538475653317,
"phase_execution": {
"policy": "datastream_policy",
"phase_definition": { <6>
"phase_definition": { <7>
"min_age": "0ms",
"actions": {
"rollover": {
Expand All @@ -190,7 +191,7 @@ managed indices.
}
}
},
"version": 1, <7>
"version": 1, <8>
"modified_date_in_millis": 1539609701576
}
}
Expand All @@ -201,12 +202,13 @@ managed indices.
// TESTRESPONSE[skip:no way to know if we will get this response immediately]
<1> this index is managed by ILM
<2> the policy in question, in this case, "datastream_policy"
<3> what phase the index is currently in
<4> what action the index is currently on
<5> what step the index is currently on
<6> the definition of the phase
<3> the current age of the index
<4> what phase the index is currently in
<5> what action the index is currently on
<6> what step the index is currently on
<7> the definition of the phase
(in this case, the "hot" phase) that the index is currently on
<7> the version of the policy being used to execute the current phase
<8> the version of the policy being used to execute the current phase

You can read about the full details of this response in the
<<ilm-explain-lifecycle, explain API docs>>. For now, let's focus on how
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/ilm/update-lifecycle-policy.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ GET my_index/_ilm/explain
"managed": true,
"policy": "my_executing_policy",
"lifecycle_date_millis": 1538475653281,
"age": "30s",
"phase": "hot",
"phase_time_millis": 1538475653317,
"action": "rollover",
Expand Down Expand Up @@ -275,6 +276,7 @@ GET my_index/_ilm/explain
"managed": true,
"policy": "my_executing_policy",
"lifecycle_date_millis": 1538475653281,
"age": "30s",
"phase": "hot",
"phase_time_millis": 1538475653317,
"action": "rollover",
Expand Down Expand Up @@ -354,6 +356,7 @@ GET my_index/_ilm/explain
"managed": true,
"policy": "my_executing_policy",
"lifecycle_date_millis": 1538475653281,
"age": "30s",
"phase": "hot",
"phase_time_millis": 1538475653317,
"action": "rollover",
Expand Down Expand Up @@ -408,6 +411,7 @@ GET my_index/_ilm/explain
"managed": true,
"policy": "my_executing_policy",
"lifecycle_date_millis": 1538475653281,
"age": "30s",
"phase": "warm",
"phase_time_millis": 1538475653317,
"action": "forcemerge",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public final void testFromXContent() throws IOException {
.shuffleFieldsExceptions(getShuffleFieldsExceptions())
.randomFieldsExcludeFilter(getRandomFieldsExcludeFilter())
.assertEqualsConsumer(this::assertEqualInstances)
.assertToXContentEquivalence(true)
.assertToXContentEquivalence(assertToXContentEquivalence())
.test();
}

Expand Down Expand Up @@ -83,6 +83,16 @@ protected String[] getShuffleFieldsExceptions() {
return Strings.EMPTY_ARRAY;
}

/**
* Whether or not to assert equivalence of the {@link org.elasticsearch.common.xcontent.XContent} of the test instance and the instance
* parsed from the {@link org.elasticsearch.common.xcontent.XContent} of the test instance.
*
* @return true if equivalence should be asserted, otherwise false
*/
protected boolean assertToXContentEquivalence() {
return true;
}

/**
* Params that have to be provided when calling calling {@link ToXContent#toXContent(XContentBuilder, ToXContent.Params)}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
Expand Down Expand Up @@ -42,6 +43,7 @@ public class IndexLifecycleExplainResponse implements ToXContentObject, Writeabl
private static final ParseField STEP_TIME_FIELD = new ParseField("step_time");
private static final ParseField STEP_INFO_FIELD = new ParseField("step_info");
private static final ParseField PHASE_EXECUTION_INFO = new ParseField("phase_execution");
private static final ParseField AGE_FIELD = new ParseField("age");

public static final ConstructingObjectParser<IndexLifecycleExplainResponse, Void> PARSER = new ConstructingObjectParser<>(
"index_lifecycle_explain_response",
Expand All @@ -58,7 +60,9 @@ public class IndexLifecycleExplainResponse implements ToXContentObject, Writeabl
(Long) (a[9]),
(Long) (a[10]),
(BytesReference) a[11],
(PhaseExecutionInfo) a[12]));
(PhaseExecutionInfo) a[12]
// a[13] == "age"
));
static {
PARSER.declareString(ConstructingObjectParser.constructorArg(), INDEX_FIELD);
PARSER.declareBoolean(ConstructingObjectParser.constructorArg(), MANAGED_BY_ILM_FIELD);
Expand All @@ -78,6 +82,7 @@ public class IndexLifecycleExplainResponse implements ToXContentObject, Writeabl
}, STEP_INFO_FIELD);
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> PhaseExecutionInfo.parse(p, ""),
PHASE_EXECUTION_INFO);
PARSER.declareString(ConstructingObjectParser.optionalConstructorArg(), AGE_FIELD);
}

private final String index;
Expand Down Expand Up @@ -243,6 +248,14 @@ public PhaseExecutionInfo getPhaseExecutionInfo() {
return phaseExecutionInfo;
}

public TimeValue getAge() {
if (lifecycleDate == null) {
return TimeValue.MINUS_ONE;
} else {
return TimeValue.timeValueMillis(System.currentTimeMillis() - lifecycleDate);
}
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
Expand All @@ -252,6 +265,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.field(POLICY_NAME_FIELD.getPreferredName(), policyName);
if (lifecycleDate != null) {
builder.timeField(LIFECYCLE_DATE_MILLIS_FIELD.getPreferredName(), LIFECYCLE_DATE_FIELD.getPreferredName(), lifecycleDate);
builder.field(AGE_FIELD.getPreferredName(), getAge().toHumanReadableString(2));
}
if (phase != null) {
builder.field(PHASE_FIELD.getPreferredName(), phase);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ protected boolean supportsUnknownFields() {
return false;
}

@Override
protected boolean assertToXContentEquivalence() {
return false;
}

protected NamedWriteableRegistry getNamedWriteableRegistry() {
return new NamedWriteableRegistry(Arrays
.asList(new NamedWriteableRegistry.Entry(LifecycleAction.class, MockAction.NAME, MockAction::new)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ protected IndexLifecycleExplainResponse doParseInstance(XContentParser parser) t
return IndexLifecycleExplainResponse.PARSER.apply(parser, null);
}

@Override
protected boolean assertToXContentEquivalence() {
return false;
}

@Override
protected IndexLifecycleExplainResponse mutateInstance(IndexLifecycleExplainResponse instance) throws IOException {
String index = instance.getIndex();
Expand Down
Loading

0 comments on commit fe2ef66

Please sign in to comment.