michaelbahr
michaelbahr

Reputation: 4973

HystrixObservableCommand executions don't show up in dashboard/hystrix.stream

Problem

The Hystrix dashboard shows executions of HystrixCommands, but not of the HystrixObservableCommand. We need the HystrixObservableCommand, as we're wrapping an async HTTP call. The code below shows an example which we tracked in the dashboard. Integration tests show that the call is properly executed, the stream mentions the AsyncHttpCommand, but never tracks any hits.

hystrix dashboard

void aMethod(A requestHeaders, B asyncContext, C message) {
    // this is tracked
    new DummyCommand().execute();

    // this not
    Observable<Response> observable = new AsyncHttpCommand(builder.setHeaders(requestHeaders), message).construct();
    observable.subscribe(createObserver(asyncContext, message));
}

// we added and removed some properties without any change on the tracking
private final HystrixCommandProperties.Setter defaultProperties = HystrixCommandProperties.Setter()
                  .withExecutionIsolationSemaphoreMaxConcurrentRequests(400)
                  .withFallbackIsolationSemaphoreMaxConcurrentRequests(400)
                  .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
                  .withExecutionTimeoutInMilliseconds(10000)
                  .withExecutionTimeoutEnabled(true)
                  .withFallbackEnabled(true)
                  .withCircuitBreakerEnabled(true)
                  .withCircuitBreakerErrorThresholdPercentage(50)
                  .withCircuitBreakerRequestVolumeThreshold(20)
                  .withCircuitBreakerSleepWindowInMilliseconds(5000)
                  .withCircuitBreakerForceOpen(false)
                  .withCircuitBreakerForceClosed(false);

private class DummyCommand extends HystrixCommand<String> {

    protected DummyCommand() {
        super(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("default"))
                                                 .andCommandPropertiesDefaults(defaultProperties));
    }

    @Override
    protected String run() throws Exception {
        return "test";
    }
}

private class AsyncHttpCommand extends HystrixObservableCommand<Response> {

    private BoundRequestBuilder builder;

    protected AsyncHttpCommand(final BoundRequestBuilder builder) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("default2"))
             .andCommandPropertiesDefaults(defaultProperties));
        this.builder = builder;
    }

    @Override
    protected Observable<Response> construct() {
        return Observable.from(builder.execute()).subscribeOn(Schedulers.io());
    }
}

private Observer<? super Response> createObserver(final AsyncContext asyncContext, final SentRequestMessage message) {
    return new Observer<Response>() {
        @Override
        public void onCompleted() {
            // was never reached
        }

        @Override
        public void onError(final Throwable throwable) {
            // should not be reached, as fallback kicks in
        }

        @Override
        public void onNext(final Response response) {
            // omitted result handling ...
        }
    };
}

Hystrix.stream

web.xml

<servlet>
    <description></description>
    <display-name>HystrixMetricsStreamServlet</display-name>
    <servlet-name>HystrixMetricsStreamServlet</servlet-name>
    <servlet-class>com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>HystrixMetricsStreamServlet</servlet-name>
    <url-pattern>/hystrix.stream</url-pattern>
</servlet-mapping>

pom.xml

<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-core</artifactId>
    <version>RELEASE</version>
</dependency>
<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-metrics-event-stream</artifactId>
    <version>1.4.10</version>
</dependency>

Question

Am I doing anything wrong with the AsyncHttpCommand? What needs to be changed/added, so that the hystrix stream will also show hits of that command.

Upvotes: 0

Views: 307

Answers (1)

michaelbahr
michaelbahr

Reputation: 4973

The commands were correct, but we have to use observe() instead of construct().

Observable<Response> observable = new AsyncHttpCommand(builder.setHeaders(requestHeaders), message)
                                         .observe();
observable.subscribe(createObserver(asyncContext, message));

Upvotes: 1

Related Questions