/** Test that if all 'marks' are timeouts that it will trip the circuit. */
  @Test
  public void testTripCircuitOnTimeouts() {
    String key = "cmd-D";
    try {
      HystrixCommand<Boolean> cmd1 = new TimeoutCommand(key);
      HystrixCircuitBreaker cb = cmd1.circuitBreaker;

      // this should start as allowing requests
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());

      // success with high latency
      cmd1.execute();
      HystrixCommand<Boolean> cmd2 = new TimeoutCommand(key);
      cmd2.execute();
      HystrixCommand<Boolean> cmd3 = new TimeoutCommand(key);
      cmd3.execute();
      HystrixCommand<Boolean> cmd4 = new TimeoutCommand(key);
      cmd4.execute();

      // everything has been a timeout so we should not allow any requests
      Thread.sleep(100);
      assertFalse(cb.allowRequest());
      assertTrue(cb.isOpen());
    } catch (Exception e) {
      e.printStackTrace();
      fail("Error occurred: " + e.getMessage());
    }
  }
  /**
   * When volume of reporting during a statistical window is lower than a defined threshold the
   * circuit will not trip regardless of whatever statistics are calculated.
   */
  @Test
  public void testLowVolumeDoesNotTripCircuit() {
    String key = "cmd-I";
    try {
      int sleepWindow = 200;
      int lowVolume = 5;

      HystrixCommand<Boolean> cmd1 = new FailureCommand(key, 60, sleepWindow, lowVolume);
      HystrixCircuitBreaker cb = cmd1.circuitBreaker;

      // this should start as allowing requests
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());

      cmd1.execute();
      HystrixCommand<Boolean> cmd2 = new FailureCommand(key, 1, sleepWindow, lowVolume);
      cmd2.execute();
      HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1, sleepWindow, lowVolume);
      cmd3.execute();
      HystrixCommand<Boolean> cmd4 = new FailureCommand(key, 1, sleepWindow, lowVolume);
      cmd4.execute();

      // even though it has all failed we won't trip the circuit because the volume is low
      Thread.sleep(100);
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());

    } catch (Exception e) {
      e.printStackTrace();
      fail("Error occurred: " + e.getMessage());
    }
  }
  /**
   * Test that an open circuit is closed after 1 success. This also ensures that the rolling window
   * (containing failures) is cleared after the sleep window Otherwise, the next bucket roll would
   * produce another signal to fail unless it is explicitly cleared (via {@link
   * HystrixCommandMetrics#resetStream()}.
   */
  @Test
  public void testCircuitClosedAfterSuccess() {
    String key = "cmd-G";
    try {
      int sleepWindow = 20;
      HystrixCommand<Boolean> cmd1 = new FailureCommand(key, 1, sleepWindow);
      HystrixCircuitBreaker cb = cmd1.circuitBreaker;

      // this should start as allowing requests
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());

      cmd1.execute();
      HystrixCommand<Boolean> cmd2 = new FailureCommand(key, 1, sleepWindow);
      cmd2.execute();
      HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1, sleepWindow);
      cmd3.execute();
      HystrixCommand<Boolean> cmd4 = new TimeoutCommand(key, sleepWindow);
      cmd4.execute();

      // everything has failed in the test window so we should return false now
      Thread.sleep(100);
      System.out.println(
          "ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
      System.out.println("CircuitBreaker state 1 : " + cmd1.getMetrics().getHealthCounts());
      assertFalse(cb.allowRequest());
      assertTrue(cb.isOpen());

      // wait for sleepWindow to pass
      Thread.sleep(sleepWindow + 50);

      // but the circuit should still be open
      assertTrue(cb.isOpen());

      // we should now allow 1 request, and upon success, should cause the circuit to be closed
      HystrixCommand<Boolean> cmd5 = new SuccessCommand(key, 60, sleepWindow);
      Observable<Boolean> asyncResult = cmd5.observe();

      // and further requests are still blocked while the singleTest command is in flight
      assertFalse(cb.allowRequest());

      asyncResult.toBlocking().single();

      // all requests should be open again
      System.out.println("CircuitBreaker state 2 : " + cmd1.getMetrics().getHealthCounts());
      assertTrue(cb.allowRequest());
      assertTrue(cb.allowRequest());
      assertTrue(cb.allowRequest());
      // and the circuit should be closed again
      assertFalse(cb.isOpen());

    } catch (Exception e) {
      e.printStackTrace();
      fail("Error occurred: " + e.getMessage());
    }
  }
  /** Test that if the % of failures is higher than the threshold that the circuit trips. */
  @Test
  public void testCircuitDoesNotTripOnFailuresBelowThreshold() {
    String key = "cmd-C";
    try {
      HystrixCommand<Boolean> cmd1 = new SuccessCommand(key, 60);
      HystrixCircuitBreaker cb = cmd1.circuitBreaker;

      // this should start as allowing requests
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());

      // success with high latency
      cmd1.execute();
      HystrixCommand<Boolean> cmd2 = new SuccessCommand(key, 1);
      cmd2.execute();
      HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1);
      cmd3.execute();
      HystrixCommand<Boolean> cmd4 = new SuccessCommand(key, 1);
      cmd4.execute();
      HystrixCommand<Boolean> cmd5 = new SuccessCommand(key, 1);
      cmd5.execute();
      HystrixCommand<Boolean> cmd6 = new FailureCommand(key, 1);
      cmd6.execute();
      HystrixCommand<Boolean> cmd7 = new SuccessCommand(key, 1);
      cmd7.execute();
      HystrixCommand<Boolean> cmd8 = new FailureCommand(key, 1);
      cmd8.execute();

      // this should remain closed as the failure threshold is below the percentage limit
      Thread.sleep(100);
      System.out.println(
          "ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
      System.out.println("Current CircuitBreaker Status : " + cmd1.getMetrics().getHealthCounts());
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());
    } catch (Exception e) {
      e.printStackTrace();
      fail("Error occurred: " + e.getMessage());
    }
  }
  /**
   * Test that if all 'marks' are successes during the test window that it does NOT trip the
   * circuit. Test that if all 'marks' are failures during the test window that it trips the
   * circuit.
   */
  @Test
  public void testTripCircuit() {
    String key = "cmd-A";
    try {
      HystrixCommand<Boolean> cmd1 = new SuccessCommand(key, 1);
      HystrixCommand<Boolean> cmd2 = new SuccessCommand(key, 1);
      HystrixCommand<Boolean> cmd3 = new SuccessCommand(key, 1);
      HystrixCommand<Boolean> cmd4 = new SuccessCommand(key, 1);

      HystrixCircuitBreaker cb = cmd1.circuitBreaker;

      cmd1.execute();
      cmd2.execute();
      cmd3.execute();
      cmd4.execute();

      // this should still allow requests as everything has been successful
      Thread.sleep(100);
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());

      // fail
      HystrixCommand<Boolean> cmd5 = new FailureCommand(key, 1);
      HystrixCommand<Boolean> cmd6 = new FailureCommand(key, 1);
      HystrixCommand<Boolean> cmd7 = new FailureCommand(key, 1);
      HystrixCommand<Boolean> cmd8 = new FailureCommand(key, 1);
      cmd5.execute();
      cmd6.execute();
      cmd7.execute();
      cmd8.execute();

      // everything has failed in the test window so we should return false now
      Thread.sleep(100);
      assertFalse(cb.allowRequest());
      assertTrue(cb.isOpen());
    } catch (Exception e) {
      e.printStackTrace();
      fail("Error occurred: " + e.getMessage());
    }
  }
  /** Test that if the % of timeouts is higher than the threshold that the circuit trips. */
  @Test
  public void testTripCircuitOnTimeoutsAboveThreshold() {
    String key = "cmd-E";
    try {
      HystrixCommand<Boolean> cmd1 = new SuccessCommand(key, 60);
      HystrixCircuitBreaker cb = cmd1.circuitBreaker;

      // this should start as allowing requests
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());

      // success with high latency
      cmd1.execute();
      HystrixCommand<Boolean> cmd2 = new SuccessCommand(key, 1);
      cmd2.execute();
      HystrixCommand<Boolean> cmd3 = new TimeoutCommand(key);
      cmd3.execute();
      HystrixCommand<Boolean> cmd4 = new SuccessCommand(key, 1);
      cmd4.execute();
      HystrixCommand<Boolean> cmd5 = new TimeoutCommand(key);
      cmd5.execute();
      HystrixCommand<Boolean> cmd6 = new TimeoutCommand(key);
      cmd6.execute();
      HystrixCommand<Boolean> cmd7 = new SuccessCommand(key, 1);
      cmd7.execute();
      HystrixCommand<Boolean> cmd8 = new TimeoutCommand(key);
      cmd8.execute();
      HystrixCommand<Boolean> cmd9 = new TimeoutCommand(key);
      cmd9.execute();

      // this should trip the circuit as the error percentage is above the threshold
      Thread.sleep(100);
      assertFalse(cb.allowRequest());
      assertTrue(cb.isOpen());
    } catch (Exception e) {
      e.printStackTrace();
      fail("Error occurred: " + e.getMessage());
    }
  }
  /**
   * Test that on an open circuit that a single attempt will be allowed after a window of time to
   * see if issues are resolved.
   */
  @Test
  public void testSingleTestOnOpenCircuitAfterTimeWindow() {
    String key = "cmd-F";
    try {
      int sleepWindow = 200;
      HystrixCommand<Boolean> cmd1 = new FailureCommand(key, 60);
      HystrixCircuitBreaker cb = cmd1.circuitBreaker;

      // this should start as allowing requests
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());

      cmd1.execute();
      HystrixCommand<Boolean> cmd2 = new FailureCommand(key, 1);
      cmd2.execute();
      HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1);
      cmd3.execute();
      HystrixCommand<Boolean> cmd4 = new FailureCommand(key, 1);
      cmd4.execute();

      // everything has failed in the test window so we should return false now
      Thread.sleep(100);
      assertFalse(cb.allowRequest());
      assertTrue(cb.isOpen());

      // wait for sleepWindow to pass
      Thread.sleep(sleepWindow + 50);

      // we should now allow 1 request
      assertTrue(cb.allowRequest());
      // but the circuit should still be open
      assertTrue(cb.isOpen());
      // and further requests are still blocked
      assertFalse(cb.allowRequest());

    } catch (Exception e) {
      e.printStackTrace();
      fail("Error occurred: " + e.getMessage());
    }
  }
  /**
   * Over a period of several 'windows' a single attempt will be made and fail and then finally
   * succeed and close the circuit.
   *
   * <p>Ensure the circuit is kept open through the entire testing period and that only the single
   * attempt in each window is made.
   */
  @Test
  public void testMultipleTimeWindowRetriesBeforeClosingCircuit() {
    String key = "cmd-H";
    try {
      int sleepWindow = 200;
      HystrixCommand<Boolean> cmd1 = new FailureCommand(key, 60);
      HystrixCircuitBreaker cb = cmd1.circuitBreaker;

      // this should start as allowing requests
      assertTrue(cb.allowRequest());
      assertFalse(cb.isOpen());

      cmd1.execute();
      HystrixCommand<Boolean> cmd2 = new FailureCommand(key, 1);
      cmd2.execute();
      HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1);
      cmd3.execute();
      HystrixCommand<Boolean> cmd4 = new TimeoutCommand(key);
      cmd4.execute();

      // everything has failed in the test window so we should return false now
      System.out.println("!!!! 1 4 failures, circuit will open on recalc");
      Thread.sleep(100);

      assertFalse(cb.allowRequest());
      assertTrue(cb.isOpen());

      // wait for sleepWindow to pass
      System.out.println("!!!! 2 Sleep window starting where all commands fail-fast");
      Thread.sleep(sleepWindow + 50);
      System.out.println("!!!! 3 Sleep window over, should allow singleTest()");

      // but the circuit should still be open
      assertTrue(cb.isOpen());

      // we should now allow 1 request, and upon failure, should not affect the circuit breaker,
      // which should remain open
      HystrixCommand<Boolean> cmd5 = new FailureCommand(key, 60);
      Observable<Boolean> asyncResult5 = cmd5.observe();
      System.out.println("!!!! Kicked off the single-test");

      // and further requests are still blocked while the singleTest command is in flight
      assertFalse(cb.allowRequest());
      System.out.println("!!!! Confirmed that no other requests go out during single-test");

      asyncResult5.toBlocking().single();
      System.out.println("!!!! SingleTest just completed");

      // all requests should still be blocked, because the singleTest failed
      assertFalse(cb.allowRequest());
      assertFalse(cb.allowRequest());
      assertFalse(cb.allowRequest());

      // wait for sleepWindow to pass
      System.out.println("!!!! 2nd sleep window START");
      Thread.sleep(sleepWindow + 50);
      System.out.println("!!!! 2nd sleep window over");

      // we should now allow 1 request, and upon failure, should not affect the circuit breaker,
      // which should remain open
      HystrixCommand<Boolean> cmd6 = new FailureCommand(key, 60);
      Observable<Boolean> asyncResult6 = cmd6.observe();
      System.out.println("2nd singleTest just kicked off");

      // and further requests are still blocked while the singleTest command is in flight
      assertFalse(cb.allowRequest());
      System.out.println("confirmed that 2nd singletest only happened once");

      asyncResult6.toBlocking().single();
      System.out.println("2nd singleTest now over");

      // all requests should still be blocked, because the singleTest failed
      assertFalse(cb.allowRequest());
      assertFalse(cb.allowRequest());
      assertFalse(cb.allowRequest());

      // wait for sleepWindow to pass
      Thread.sleep(sleepWindow + 50);

      // but the circuit should still be open
      assertTrue(cb.isOpen());

      // we should now allow 1 request, and upon success, should cause the circuit to be closed
      HystrixCommand<Boolean> cmd7 = new SuccessCommand(key, 60);
      Observable<Boolean> asyncResult7 = cmd7.observe();

      // and further requests are still blocked while the singleTest command is in flight
      assertFalse(cb.allowRequest());

      asyncResult7.toBlocking().single();

      // all requests should be open again
      assertTrue(cb.allowRequest());
      assertTrue(cb.allowRequest());
      assertTrue(cb.allowRequest());
      // and the circuit should be closed again
      assertFalse(cb.isOpen());

      // and the circuit should be closed again
      assertFalse(cb.isOpen());
    } catch (Exception e) {
      e.printStackTrace();
      fail("Error occurred: " + e.getMessage());
    }
  }
Beispiel #9
0
  @Override
  public void run() {

    try {
      // command metrics
      for (HystrixCommandMetrics commandMetrics : HystrixCommandMetrics.getInstances()) {
        HystrixCommandKey key = commandMetrics.getCommandKey();
        HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key);
        StringWriter jsonString = new StringWriter();
        JsonGenerator json = jsonFactory.createJsonGenerator(jsonString);

        // Informational and Status
        json.writeStartObject();
        json.writeStringField(type.value, HystrixCommand.value);
        json.writeStringField(name.value, key.name());
        json.writeStringField(group.value, commandMetrics.getCommandGroup().name());
        json.writeNumberField(currentTime.value, (int) (System.currentTimeMillis() / 1000));

        // circuit breaker
        json.writeBooleanField(isCircuitBreakerOpen.value, circuitBreaker.isOpen());
        HystrixCommandMetrics.HealthCounts healthCounts = commandMetrics.getHealthCounts();
        json.writeNumberField(errorPercentage.value, healthCounts.getErrorPercentage());
        json.writeNumberField(errorCount.value, healthCounts.getErrorCount());
        json.writeNumberField(requestCount.value, healthCounts.getTotalRequests());

        // rolling counters  Gauge
        json.writeNumberField(
            rollingCountCollapsedRequests.value,
            commandMetrics.getRollingCount(HystrixRollingNumberEvent.COLLAPSED));
        json.writeNumberField(
            rollingCountExceptionsThrown.value,
            commandMetrics.getRollingCount(HystrixRollingNumberEvent.EXCEPTION_THROWN));
        json.writeNumberField(
            rollingCountFailure.value,
            commandMetrics.getRollingCount(HystrixRollingNumberEvent.FAILURE));
        json.writeNumberField(
            rollingCountFallbackFailure.value,
            commandMetrics.getRollingCount(HystrixRollingNumberEvent.FALLBACK_FAILURE));
        json.writeNumberField(
            rollingCountFallbackRejection.value,
            commandMetrics.getRollingCount(HystrixRollingNumberEvent.FALLBACK_REJECTION));
        json.writeNumberField(
            rollingCountFallbackSuccess.value,
            commandMetrics.getRollingCount(HystrixRollingNumberEvent.FALLBACK_SUCCESS));
        json.writeNumberField(
            rollingCountResponsesFromCache.value,
            commandMetrics.getRollingCount(HystrixRollingNumberEvent.RESPONSE_FROM_CACHE));
        json.writeNumberField(
            rollingCountSemaphoreRejected.value,
            commandMetrics.getRollingCount(HystrixRollingNumberEvent.SEMAPHORE_REJECTED));
        json.writeNumberField(
            rollingCountShortCircuited.value,
            commandMetrics.getRollingCount(HystrixRollingNumberEvent.SHORT_CIRCUITED));
        json.writeNumberField(
            rollingCountSuccess.value,
            commandMetrics.getRollingCount(HystrixRollingNumberEvent.SUCCESS));
        json.writeNumberField(
            rollingCountThreadPoolRejected.value,
            commandMetrics.getRollingCount(HystrixRollingNumberEvent.THREAD_POOL_REJECTED));
        json.writeNumberField(
            rollingCountTimeout.value,
            commandMetrics.getRollingCount(HystrixRollingNumberEvent.TIMEOUT));

        json.writeNumberField(
            currentConcurrentExecutionCount.value,
            commandMetrics.getCurrentConcurrentExecutionCount());

        // latency percentiles
        json.writeNumberField(latencyExecute_mean.value, commandMetrics.getExecutionTimeMean());
        json.writeObjectFieldStart(latencyExecute.value);
        json.writeNumberField("0", commandMetrics.getExecutionTimePercentile(0));
        json.writeNumberField("25", commandMetrics.getExecutionTimePercentile(25));
        json.writeNumberField("50", commandMetrics.getExecutionTimePercentile(50));
        json.writeNumberField("75", commandMetrics.getExecutionTimePercentile(75));
        json.writeNumberField("90", commandMetrics.getExecutionTimePercentile(90));
        json.writeNumberField("95", commandMetrics.getExecutionTimePercentile(95));
        json.writeNumberField("99", commandMetrics.getExecutionTimePercentile(99));
        json.writeNumberField("99.5", commandMetrics.getExecutionTimePercentile(99.5));
        json.writeNumberField("100", commandMetrics.getExecutionTimePercentile(100));
        json.writeEndObject();
        //
        json.writeNumberField(latencyTotal_mean.value, commandMetrics.getTotalTimeMean());
        json.writeObjectFieldStart(latencyTotal.value);
        json.writeNumberField("0", commandMetrics.getTotalTimePercentile(0));
        json.writeNumberField("25", commandMetrics.getTotalTimePercentile(25));
        json.writeNumberField("50", commandMetrics.getTotalTimePercentile(50));
        json.writeNumberField("75", commandMetrics.getTotalTimePercentile(75));
        json.writeNumberField("90", commandMetrics.getTotalTimePercentile(90));
        json.writeNumberField("95", commandMetrics.getTotalTimePercentile(95));
        json.writeNumberField("99", commandMetrics.getTotalTimePercentile(99));
        json.writeNumberField("99.5", commandMetrics.getTotalTimePercentile(99.5));
        json.writeNumberField("100", commandMetrics.getTotalTimePercentile(100));
        json.writeEndObject();

        // property values for reporting what is actually seen by the command rather than what was
        // set somewhere
        HystrixCommandProperties commandProperties = commandMetrics.getProperties();

        json.writeNumberField(
            propertyValue_circuitBreakerRequestVolumeThreshold.value,
            commandProperties.circuitBreakerRequestVolumeThreshold().get());
        json.writeNumberField(
            propertyValue_circuitBreakerSleepWindowInMilliseconds.value,
            commandProperties.circuitBreakerSleepWindowInMilliseconds().get());
        json.writeNumberField(
            propertyValue_circuitBreakerErrorThresholdPercentage.value,
            commandProperties.circuitBreakerErrorThresholdPercentage().get());
        json.writeBooleanField(
            propertyValue_circuitBreakerForceOpen.value,
            commandProperties.circuitBreakerForceOpen().get());
        json.writeBooleanField(
            propertyValue_circuitBreakerForceClosed.value,
            commandProperties.circuitBreakerForceClosed().get());
        json.writeBooleanField(
            propertyValue_circuitBreakerEnabled.value,
            commandProperties.circuitBreakerEnabled().get());

        json.writeStringField(
            propertyValue_executionIsolationStrategy.value,
            commandProperties.executionIsolationStrategy().get().name());
        json.writeNumberField(
            propertyValue_executionIsolationThreadTimeoutInMilliseconds.value,
            commandProperties.executionIsolationThreadTimeoutInMilliseconds().get());
        json.writeBooleanField(
            propertyValue_executionIsolationThreadInterruptOnTimeout.value,
            commandProperties.executionIsolationThreadInterruptOnTimeout().get());
        json.writeStringField(
            propertyValue_executionIsolationThreadPoolKeyOverride.value,
            commandProperties.executionIsolationThreadPoolKeyOverride().get());
        json.writeNumberField(
            propertyValue_executionIsolationSemaphoreMaxConcurrentRequests.value,
            commandProperties.executionIsolationSemaphoreMaxConcurrentRequests().get());
        json.writeNumberField(
            propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests.value,
            commandProperties.fallbackIsolationSemaphoreMaxConcurrentRequests().get());

        /*
         * The following are commented out as these rarely change and are verbose for streaming for something people don't change.
         * We could perhaps allow a property or request argument to include these.
         */

        //                    json.put("propertyValue_metricsRollingPercentileEnabled",
        // commandProperties.metricsRollingPercentileEnabled().get());
        //                    json.put("propertyValue_metricsRollingPercentileBucketSize",
        // commandProperties.metricsRollingPercentileBucketSize().get());
        //                    json.put("propertyValue_metricsRollingPercentileWindow",
        // commandProperties.metricsRollingPercentileWindowInMilliseconds().get());
        //                    json.put("propertyValue_metricsRollingPercentileWindowBuckets",
        // commandProperties.metricsRollingPercentileWindowBuckets().get());
        //                    json.put("propertyValue_metricsRollingStatisticalWindowBuckets",
        // commandProperties.metricsRollingStatisticalWindowBuckets().get());
        json.writeNumberField(
            propertyValue_metricsRollingStatisticalWindowInMilliseconds.value,
            commandProperties.metricsRollingStatisticalWindowInMilliseconds().get());
        json.writeBooleanField(
            propertyValue_requestCacheEnabled.value, commandProperties.requestCacheEnabled().get());
        json.writeBooleanField(
            propertyValue_requestLogEnabled.value, commandProperties.requestLogEnabled().get());
        json.writeNumberField(reportingHosts.value, 1);

        json.writeStringField(Key.ip.value, app_ip);

        json.writeEndObject();
        json.close();
        //                System.out.println(ip + ":" + port + "||" +
        // jsonString.getBuffer().toString());
        UDPClient.send(
            socketIp, socketPort, jsonString.getBuffer().toString().getBytes(), new byte[] {});
      }

      // thread pool metrics
      for (HystrixThreadPoolMetrics threadPoolMetrics : HystrixThreadPoolMetrics.getInstances()) {
        HystrixThreadPoolKey key = threadPoolMetrics.getThreadPoolKey();

        StringWriter jsonString = new StringWriter();
        JsonGenerator json = jsonFactory.createJsonGenerator(jsonString);
        json.writeStartObject();

        json.writeStringField(type.value, HystrixThreadPool.value);
        json.writeStringField(name.value, key.name());
        json.writeNumberField(currentTime.value, System.currentTimeMillis());

        // 101.3 80 154

        json.writeNumberField(
            currentActiveCount.value, threadPoolMetrics.getCurrentActiveCount().intValue());
        json.writeNumberField(
            currentCompletedTaskCount.value,
            threadPoolMetrics.getCurrentCompletedTaskCount().longValue());
        json.writeNumberField(
            currentCorePoolSize.value, threadPoolMetrics.getCurrentCorePoolSize().intValue());
        json.writeNumberField(
            currentLargestPoolSize.value, threadPoolMetrics.getCurrentLargestPoolSize().intValue());
        json.writeNumberField(
            currentMaximumPoolSize.value, threadPoolMetrics.getCurrentMaximumPoolSize().intValue());
        json.writeNumberField(
            currentPoolSize.value, threadPoolMetrics.getCurrentPoolSize().intValue());
        json.writeNumberField(
            currentQueueSize.value, threadPoolMetrics.getCurrentQueueSize().intValue());
        json.writeNumberField(
            currentTaskCount.value, threadPoolMetrics.getCurrentTaskCount().longValue());
        json.writeNumberField(
            rollingCountThreadsExecuted.value, threadPoolMetrics.getRollingCountThreadsExecuted());
        json.writeNumberField(
            rollingMaxActiveThreads.value, threadPoolMetrics.getRollingMaxActiveThreads());

        json.writeNumberField(
            propertyValue_queueSizeRejectionThreshold.value,
            threadPoolMetrics.getProperties().queueSizeRejectionThreshold().get());
        json.writeNumberField(
            propertyValue_metricsRollingStatisticalWindowInMilliseconds.value,
            threadPoolMetrics
                .getProperties()
                .metricsRollingStatisticalWindowInMilliseconds()
                .get());

        json.writeNumberField(
            reportingHosts.value, 1); // this will get summed across all instances in a cluster
        json.writeStringField(Key.ip.value, app_ip);
        json.writeEndObject();
        json.close();

        String str = jsonString.getBuffer().toString();
        byte[] ret = str.getBytes();
        UDPClient.send(socketIp, socketPort, ret, new byte[] {});
      }
    } catch (Exception e) {
      System.err.println("Failed to output metrics as JSON");
      e.printStackTrace();
    }
  }