Add used memory amount to CircuitBreakingException message (#22521)

This commit is contained in:
Alex Bumbu 2017-01-19 15:38:18 +00:00
parent e042c77301
commit 41abf6e81d
5 changed files with 45 additions and 26 deletions

View File

@ -90,12 +90,12 @@ public class ChildMemoryCircuitBreaker implements CircuitBreaker {
@Override @Override
public void circuitBreak(String fieldName, long bytesNeeded) { public void circuitBreak(String fieldName, long bytesNeeded) {
this.trippedCount.incrementAndGet(); this.trippedCount.incrementAndGet();
final String message = "[" + this.name + "] Data too large, data for [" + final String message = "[" + this.name + "] Data too large, data for [" + fieldName + "]" +
fieldName + "] would be larger than limit of [" + " would be [" + bytesNeeded + "/" + new ByteSizeValue(bytesNeeded) + "]" +
", which is larger than the limit of [" +
memoryBytesLimit + "/" + new ByteSizeValue(memoryBytesLimit) + "]"; memoryBytesLimit + "/" + new ByteSizeValue(memoryBytesLimit) + "]";
logger.debug("{}", message); logger.debug("{}", message);
throw new CircuitBreakingException(message, throw new CircuitBreakingException(message, bytesNeeded, memoryBytesLimit);
bytesNeeded, this.memoryBytesLimit);
} }
/** /**

View File

@ -79,7 +79,9 @@ public class MemoryCircuitBreaker implements CircuitBreaker {
@Override @Override
public void circuitBreak(String fieldName, long bytesNeeded) throws CircuitBreakingException { public void circuitBreak(String fieldName, long bytesNeeded) throws CircuitBreakingException {
this.trippedCount.incrementAndGet(); this.trippedCount.incrementAndGet();
final String message = "Data too large, data for field [" + fieldName + "] would be larger than limit of [" + final String message = "[" + getName() + "] Data too large, data for field [" + fieldName + "]" +
" would be [" + bytesNeeded + "/" + new ByteSizeValue(bytesNeeded) + "]" +
", which is larger than the limit of [" +
memoryBytesLimit + "/" + new ByteSizeValue(memoryBytesLimit) + "]"; memoryBytesLimit + "/" + new ByteSizeValue(memoryBytesLimit) + "]";
logger.debug("{}", message); logger.debug("{}", message);
throw new CircuitBreakingException(message, bytesNeeded, memoryBytesLimit); throw new CircuitBreakingException(message, bytesNeeded, memoryBytesLimit);

View File

@ -208,10 +208,11 @@ public class HierarchyCircuitBreakerService extends CircuitBreakerService {
long parentLimit = this.parentSettings.getLimit(); long parentLimit = this.parentSettings.getLimit();
if (totalUsed > parentLimit) { if (totalUsed > parentLimit) {
this.parentTripCount.incrementAndGet(); this.parentTripCount.incrementAndGet();
throw new CircuitBreakingException("[parent] Data too large, data for [" + final String message = "[parent] Data too large, data for [" + label + "]" +
label + "] would be larger than limit of [" + " would be [" + totalUsed + "/" + new ByteSizeValue(totalUsed) + "]" +
parentLimit + "/" + new ByteSizeValue(parentLimit) + "]", ", which is larger than the limit of [" +
totalUsed, parentLimit); parentLimit + "/" + new ByteSizeValue(parentLimit) + "]";
throw new CircuitBreakingException(message, totalUsed, parentLimit);
} }
} }

View File

@ -235,6 +235,9 @@ public class MemoryCircuitBreakerTests extends ESTestCase {
fail("should never reach this"); fail("should never reach this");
} catch (CircuitBreakingException cbe) { } catch (CircuitBreakingException cbe) {
assertThat("breaker was tripped exactly twice", breaker.getTrippedCount(), equalTo(2L)); assertThat("breaker was tripped exactly twice", breaker.getTrippedCount(), equalTo(2L));
long newUsed = (long)(breaker.getUsed() * breaker.getOverhead());
assertThat(cbe.getMessage().contains("would be [" + newUsed + "/"), equalTo(true));
assertThat(cbe.getMessage().contains("field [" + field + "]"), equalTo(true)); assertThat(cbe.getMessage().contains("field [" + field + "]"), equalTo(true));
} }
} }

View File

@ -153,8 +153,11 @@ public class CircuitBreakerServiceIT extends ESIntegTestCase {
// execute a search that loads field data (sorting on the "test" field) // execute a search that loads field data (sorting on the "test" field)
// again, this time it should trip the breaker // again, this time it should trip the breaker
SearchRequestBuilder searchRequest = client.prepareSearch("cb-test").setQuery(matchAllQuery()).addSort("test", SortOrder.DESC); SearchRequestBuilder searchRequest = client.prepareSearch("cb-test").setQuery(matchAllQuery()).addSort("test", SortOrder.DESC);
assertFailures(searchRequest, RestStatus.INTERNAL_SERVER_ERROR,
containsString("Data too large, data for [test] would be larger than limit of [100/100b]")); String errMsg = "Data too large, data for [test] would be";
assertFailures(searchRequest, RestStatus.INTERNAL_SERVER_ERROR, containsString(errMsg));
errMsg = "which is larger than the limit of [100/100b]";
assertFailures(searchRequest, RestStatus.INTERNAL_SERVER_ERROR, containsString(errMsg));
NodesStatsResponse stats = client.admin().cluster().prepareNodesStats().setBreaker(true).get(); NodesStatsResponse stats = client.admin().cluster().prepareNodesStats().setBreaker(true).get();
int breaks = 0; int breaks = 0;
@ -201,9 +204,12 @@ public class CircuitBreakerServiceIT extends ESIntegTestCase {
// execute a search that loads field data (sorting on the "test" field) // execute a search that loads field data (sorting on the "test" field)
// again, this time it should trip the breaker // again, this time it should trip the breaker
assertFailures(client.prepareSearch("ramtest").setQuery(matchAllQuery()).addSort("test", SortOrder.DESC), SearchRequestBuilder searchRequest = client.prepareSearch("ramtest").setQuery(matchAllQuery()).addSort("test", SortOrder.DESC);
RestStatus.INTERNAL_SERVER_ERROR,
containsString("Data too large, data for [test] would be larger than limit of [100/100b]")); String errMsg = "Data too large, data for [test] would be";
assertFailures(searchRequest, RestStatus.INTERNAL_SERVER_ERROR, containsString(errMsg));
errMsg = "which is larger than the limit of [100/100b]";
assertFailures(searchRequest, RestStatus.INTERNAL_SERVER_ERROR, containsString(errMsg));
NodesStatsResponse stats = client.admin().cluster().prepareNodesStats().setBreaker(true).get(); NodesStatsResponse stats = client.admin().cluster().prepareNodesStats().setBreaker(true).get();
int breaks = 0; int breaks = 0;
@ -247,14 +253,20 @@ public class CircuitBreakerServiceIT extends ESIntegTestCase {
client.prepareSearch("cb-test").setQuery(matchAllQuery()).addSort("test", SortOrder.DESC).get(); client.prepareSearch("cb-test").setQuery(matchAllQuery()).addSort("test", SortOrder.DESC).get();
fail("should have thrown an exception"); fail("should have thrown an exception");
} catch (Exception e) { } catch (Exception e) {
String errMsg = "[fielddata] Data too large, data for [test] would be larger than limit of [10/10b]"; String errMsg = "CircuitBreakingException[[fielddata] Data too large, data for [test] would be";
assertThat("Exception: [" + e.toString() + "] should contain a CircuitBreakingException", assertThat("Exception: [" + e.toString() + "] should contain a CircuitBreakingException", e.toString(), containsString(errMsg));
e.toString(), containsString(errMsg)); errMsg = "which is larger than the limit of [10/10b]]";
assertThat("Exception: [" + e.toString() + "] should contain a CircuitBreakingException", e.toString(), containsString(errMsg));
} }
assertFailures(client.prepareSearch("cb-test").setQuery(matchAllQuery()).addSort("test", SortOrder.DESC), // execute a search that loads field data (sorting on the "test" field)
RestStatus.INTERNAL_SERVER_ERROR, // again, this time it should trip the breaker
containsString("Data too large, data for [test] would be larger than limit of [10/10b]")); SearchRequestBuilder searchRequest = client.prepareSearch("cb-test").setQuery(matchAllQuery()).addSort("test", SortOrder.DESC);
String errMsg = "Data too large, data for [test] would be";
assertFailures(searchRequest, RestStatus.INTERNAL_SERVER_ERROR, containsString(errMsg));
errMsg = "which is larger than the limit of [10/10b]";
assertFailures(searchRequest, RestStatus.INTERNAL_SERVER_ERROR, containsString(errMsg));
reset(); reset();
@ -318,9 +330,8 @@ public class CircuitBreakerServiceIT extends ESIntegTestCase {
fail("aggregation should have tripped the breaker"); fail("aggregation should have tripped the breaker");
} catch (Exception e) { } catch (Exception e) {
String errMsg = "CircuitBreakingException[[request] Data too large"; String errMsg = "CircuitBreakingException[[request] Data too large";
assertThat("Exception: [" + e.toString() + "] should contain a CircuitBreakingException", assertThat("Exception: [" + e.toString() + "] should contain a CircuitBreakingException", e.toString(), containsString(errMsg));
e.toString(), containsString(errMsg)); errMsg = "which is larger than the limit of [10/10b]]";
errMsg = "would be larger than limit of [10/10b]]";
assertThat("Exception: [" + e.toString() + "] should contain a CircuitBreakingException", e.toString(), containsString(errMsg)); assertThat("Exception: [" + e.toString() + "] should contain a CircuitBreakingException", e.toString(), containsString(errMsg));
} }
} }
@ -356,9 +367,11 @@ public class CircuitBreakerServiceIT extends ESIntegTestCase {
assertTrue("there should be shard failures", resp.getFailedShards() > 0); assertTrue("there should be shard failures", resp.getFailedShards() > 0);
fail("aggregation should have tripped the breaker"); fail("aggregation should have tripped the breaker");
} catch (Exception e) { } catch (Exception e) {
String errMsg = "CircuitBreakingException[[request] " + String errMsg = "CircuitBreakingException[[request] Data too large, data for [<agg [my_terms]>] would be";
"Data too large, data for [<agg [my_terms]>] would be larger than limit of [100/100b]]"; assertThat("Exception: [" + e.toString() + "] should contain a CircuitBreakingException",
assertThat("Exception: " + e.toString() + " should contain a CircuitBreakingException", e.toString(), containsString(errMsg));
errMsg = "which is larger than the limit of [100/100b]]";
assertThat("Exception: [" + e.toString() + "] should contain a CircuitBreakingException",
e.toString(), containsString(errMsg)); e.toString(), containsString(errMsg));
} }
} }