void Filter::onUpstreamComplete(UpstreamRequest& upstream_request) {
  if (!downstream_end_stream_) {
    upstream_request.resetStream();
  }
  callbacks_->streamInfo().setUpstreamTiming(final_upstream_request_->upstream_timing_);

  if (config_.emit_dynamic_stats_ && !callbacks_->streamInfo().healthCheck() &&
      DateUtil::timePointValid(downstream_request_complete_time_)) {
    Event::Dispatcher& dispatcher = callbacks_->dispatcher();
    std::chrono::milliseconds response_time = std::chrono::duration_cast<std::chrono::milliseconds>(
        dispatcher.timeSource().monotonicTime() - downstream_request_complete_time_);

    upstream_request.upstream_host_->outlierDetector().putResponseTime(response_time);

    const Http::HeaderEntry* internal_request_header = downstream_headers_->EnvoyInternalRequest();
    const bool internal_request =
        internal_request_header && internal_request_header->value() == "true";

    Http::CodeStats& code_stats = httpContext().codeStats();
    Http::CodeStats::ResponseTimingInfo info{config_.scope_,
                                             cluster_->statsScope(),
                                             config_.empty_stat_name_,
                                             response_time,
                                             upstream_request.upstream_canary_,
                                             internal_request,
                                             route_entry_->virtualHost().statName(),
                                             request_vcluster_ ? request_vcluster_->statName()
                                                               : config_.empty_stat_name_,
                                             config_.zone_name_,
                                             upstreamZone(upstream_request.upstream_host_)};

    code_stats.chargeResponseTiming(info);

    if (alt_stat_prefix_ != nullptr) {
      Http::CodeStats::ResponseTimingInfo info{config_.scope_,
                                               cluster_->statsScope(),
                                               alt_stat_prefix_->statName(),
                                               response_time,
                                               upstream_request.upstream_canary_,
                                               internal_request,
                                               config_.empty_stat_name_,
                                               config_.empty_stat_name_,
                                               config_.zone_name_,
                                               upstreamZone(upstream_request.upstream_host_)};

      code_stats.chargeResponseTiming(info);
    }
  }

  upstream_request.removeFromList(upstream_requests_);
  cleanup();
}
void Filter::onUpstreamComplete(UpstreamRequest& upstream_request) {
  if (!downstream_end_stream_) {
    upstream_request.resetStream();
  }
  callbacks_->streamInfo().setUpstreamTiming(final_upstream_request_->upstream_timing_);

  if (config_.emit_dynamic_stats_ && !callbacks_->streamInfo().healthCheck() &&
      DateUtil::timePointValid(downstream_request_complete_time_)) {
    Event::Dispatcher& dispatcher = callbacks_->dispatcher();
    std::chrono::milliseconds response_time = std::chrono::duration_cast<std::chrono::milliseconds>(
        dispatcher.timeSource().monotonicTime() - downstream_request_complete_time_);

    upstream_request.upstream_host_->outlierDetector().putResponseTime(response_time);

    const Http::HeaderEntry* internal_request_header = downstream_headers_->EnvoyInternalRequest();
    const bool internal_request =
        internal_request_header && internal_request_header->value() == "true";

    Http::CodeStats& code_stats = httpContext().codeStats();
    Http::CodeStats::ResponseTimingInfo info{config_.scope_,
                                             cluster_->statsScope(),
                                             config_.empty_stat_name_,
                                             response_time,
                                             upstream_request.upstream_canary_,
                                             internal_request,
                                             route_entry_->virtualHost().statName(),
                                             request_vcluster_ ? request_vcluster_->statName()
                                                               : config_.empty_stat_name_,
                                             config_.zone_name_,
                                             upstreamZone(upstream_request.upstream_host_)};

    code_stats.chargeResponseTiming(info);

    if (alt_stat_prefix_ != nullptr) {
      Http::CodeStats::ResponseTimingInfo info{config_.scope_,
                                               cluster_->statsScope(),
                                               alt_stat_prefix_->statName(),
                                               response_time,
                                               upstream_request.upstream_canary_,
                                               internal_request,
                                               config_.empty_stat_name_,
                                               config_.empty_stat_name_,
                                               config_.zone_name_,
                                               upstreamZone(upstream_request.upstream_host_)};

      code_stats.chargeResponseTiming(info);
    }
  }

  upstream_request.removeFromList(upstream_requests_);
  cleanup();
}