private void processErrorFromOrigin(Throwable ex, Channel origCh) {
        try {
            SessionContext zuulCtx = context;
            ErrorType err = requestAttemptFactory.mapNettyToOutboundErrorType(ex);

            // Be cautious about how much we log about errors from origins, as it can have perf implications at high
            // rps.
            if (zuulCtx.isInBrownoutMode()) {
                // Don't include the stacktrace or the channel info.
                logger.warn(
                        "{}, origin = {}: {}", err.getStatusCategory().name(), origin.getName(), String.valueOf(ex));
            } else {
                String origChInfo = (origCh != null) ? ChannelUtils.channelInfoForLogging(origCh) : "";
                if (logger.isInfoEnabled()) {
                    // Include the stacktrace.
                    logger.warn(
                            "{}, origin = {}, origin channel info = {}",
                            err.getStatusCategory().name(),
                            origin.getName(),
                            origChInfo,
                            ex);
                } else {
                    logger.warn(
                            "{}, origin = {}, {}, origin channel info = {}",
                            err.getStatusCategory().name(),
                            origin.getName(),
                            String.valueOf(ex),
                            origChInfo);
                }
            }

            // Update the NIWS stat.
            if (currentRequestStat != null) {
                currentRequestStat.failAndSetErrorCode(err);
            }

            // Update RequestAttempt info.
            if (currentRequestAttempt != null) {
                currentRequestAttempt.complete(-1, currentRequestStat.duration(), ex);
            }

            postErrorProcessing(ex, zuulCtx, err, chosenServer.get(), attemptNum);

            ClientException niwsEx = new ClientException(
                    ClientException.ErrorType.valueOf(err.getClientErrorType().name()));
            if (!Objects.equals(chosenServer.get(), DiscoveryResult.EMPTY)) {
                origin.onRequestExceptionWithServer(zuulRequest, chosenServer.get(), attemptNum, niwsEx);
            }

            boolean retryable = isRetryable(err);
            if (retryable) {
                origin.adjustRetryPolicyIfNeeded(zuulRequest);
            }

            if (retryable && isBelowRetryLimit()) {
                // retry request with different origin
                passport.add(PassportState.ORIGIN_RETRY_START);
                proxyRequestToOrigin();
            } else {
                // Record the exception in context. An error filter should later run which can translate this into an
                // app-specific error response if needed.
                zuulCtx.setError(ex);
                zuulCtx.setShouldSendErrorResponse(true);

                StatusCategoryUtils.storeStatusCategoryIfNotAlreadyFailure(zuulCtx, err.getStatusCategory());
                origin.recordFinalError(zuulRequest, ex);
                origin.onRequestExecutionFailed(zuulRequest, chosenServer.get(), attemptNum - 1, niwsEx);

                // Send error response to client
                handleError(ex);
            }
        } catch (Exception e) {
            // Use original origin returned exception
            handleError(ex);
        }
    }
Override to track your own request stats.
zuul-core/src/main/java/com/netflix/zuul/filters/endpoint/ProxyEndpoint.java