private boolean applySlow(ClientRequestContext ctx, @Nullable Throwable cause, RequestLog log) {
        if (cause != null && exceptionFilter != null &&
            exceptionFilter.test(ctx, Exceptions.peel(cause))) {
            return true;
        }

        if (responseHeadersFilter != null && log.isAvailable(RequestLogProperty.RESPONSE_HEADERS)) {
            final ResponseHeaders responseHeaders = log.responseHeaders();
            if (responseHeadersFilter.test(ctx, responseHeaders)) {
                return true;
            }
        }

        if (responseTrailersFilter != null && log.isAvailable(RequestLogProperty.RESPONSE_TRAILERS)) {
            final HttpHeaders responseTrailers = log.responseTrailers();
            if (responseTrailersFilter.test(ctx, responseTrailers)) {
                return true;
            }
        }

        if (grpcTrailersFilter != null && log.isAvailable(RequestLogProperty.RESPONSE_TRAILERS)) {
            // Check HTTP trailers first, because most gRPC responses have non-empty payload + trailers.
            HttpHeaders maybeGrpcTrailers = log.responseTrailers();
            if (!maybeGrpcTrailers.contains("grpc-status")) {
                // Check HTTP headers secondly.
                maybeGrpcTrailers = log.responseHeaders();
                if (!maybeGrpcTrailers.contains("grpc-status")) {
                    // Check gRPC Web trailers lastly, because gRPC Web is the least used protocol
                    // in reality.
                    maybeGrpcTrailers = InternalGrpcWebTrailers.get(ctx);
                }
            }

            // Suppressing the inspection rule because we don't want to return false too early.
            if (maybeGrpcTrailers != null && grpcTrailersFilter.test(ctx, maybeGrpcTrailers)) {
                // Found the matching gRPC trailers.
                return true;
            }
        }

        if (totalDurationFilter != null && log.isAvailable(RequestLogProperty.RESPONSE_END_TIME)) {
            final long totalDurationNanos = log.totalDurationNanos();
            if (totalDurationFilter.test(ctx, Duration.ofNanos(totalDurationNanos))) {
                return true;
            }
        }

        return false;
    }
Merges the filters of {@link AbstractRuleBuilder} that returns {@code true}
if all rules in the {@link AbstractRuleBuilder} match
a given {@link ClientRequestContext} and {@link Throwable}.
core/src/main/java/com/linecorp/armeria/internal/client/RuleFilter.java