Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions docs/configuration/http_conn_man/http_conn_man.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ HTTP connection manager
"route_config": "{...}",
"filters": [],
"add_user_agent": "...",
"tracing_enabled": "...",
"tracing": "{...}",
"http_codec_options": "...",
"server_name": "...",
"idle_timeout_s": "...",
Expand Down Expand Up @@ -71,11 +71,34 @@ add_user_agent
:ref:`config_http_conn_man_headers_downstream-service-cluster` headers. See the linked
documentation for more information. Defaults to false.

.. _config_http_conn_man_tracing_enabled:

tracing_enabled
*(optional, boolean)* Whether the connection manager emits :ref:`tracing <arch_overview_tracing>`
data to the :ref:`configured tracing provider <config_tracing>`. Defaults to false.
.. _config_http_conn_man_tracing:

tracing

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally a sub-level json object gets its own section (see other docs). Can you make a new section on this page, put the nested json docs there, and link to it from here (again see other docs)

*(optional, object)* Presence of the object defines whether the connection manager
emits :ref:`tracing <arch_overview_tracing>` data to the :ref:`configured tracing provider <config_tracing>`.
Tracing object is in the following format:

.. code-block:: json

{
"tracing": {
"operation_name": "...",
"type": "..."
}
}

operation_name
*(required, string)* Span name that will be emitted on completed request.

type
*(optional, string)* Allows to filter requests so that only some of them are traced. Default value is *all*.
Possible values are:

all
Trace all requests.

upstream_failure
Trace only requests for which upstream failure reason is defined.

.. _config_http_conn_man_http_codec_options:

Expand Down
4 changes: 2 additions & 2 deletions docs/intro/arch_overview/tracing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ sources of latency. Envoy supports three features related to system wide tracing

How to initiate a trace
-----------------------
The HTTP connection manager that handles the request must have the :ref:`tracing_enabled
<config_http_conn_man_tracing_enabled>` option set. There are several ways tracing can be
The HTTP connection manager that handles the request must have the :ref:`tracing
<config_http_conn_man_tracing>` object set. There are several ways tracing can be
initiated:

* By an external client via the :ref:`config_http_conn_man_headers_x-client-trace-id`
Expand Down
13 changes: 11 additions & 2 deletions include/envoy/tracing/http_tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

namespace Tracing {

class TracingContext {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

public:
virtual ~TracingContext() {}

virtual const std::string& operationName() const PURE;
};

/**
* Http sink for traces. Sink is responsible for delivering trace to the collector.
*/
Expand All @@ -15,7 +22,8 @@ class HttpSink {

virtual void flushTrace(const Http::HeaderMap& request_headers,
const Http::HeaderMap& response_headers,
const Http::AccessLog::RequestInfo& request_info) PURE;
const Http::AccessLog::RequestInfo& request_info,
const TracingContext& tracing_context) PURE;
};

typedef std::unique_ptr<HttpSink> HttpSinkPtr;
Expand All @@ -30,7 +38,8 @@ class HttpTracer {
virtual void addSink(HttpSinkPtr&& sink) PURE;
virtual void trace(const Http::HeaderMap* request_headers,
const Http::HeaderMap* response_headers,
const Http::AccessLog::RequestInfo& request_info) PURE;
const Http::AccessLog::RequestInfo& request_info,
const TracingContext& tracing_context) PURE;
};

typedef std::unique_ptr<HttpTracer> HttpTracerPtr;
Expand Down
9 changes: 7 additions & 2 deletions source/common/http/conn_manager_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,10 @@ ConnectionManagerImpl::ActiveStream::~ActiveStream() {
access_log->log(request_headers_.get(), response_headers_.get(), request_info_);
}

if (connection_manager_.config_.isTracing()) {
if (ConnectionManagerUtility::shouldTraceRequest(request_info_,
connection_manager_.config_.tracingConfig())) {
connection_manager_.tracer_.trace(request_headers_.get(), response_headers_.get(),
request_info_);
request_info_, *this);
}
}

Expand Down Expand Up @@ -644,6 +645,10 @@ void ConnectionManagerImpl::ActiveStream::onResetStream(StreamResetReason) {
removeFromList(connection_manager_.streams_));
}

const std::string& ConnectionManagerImpl::ActiveStream::operationName() const {
return connection_manager_.config_.tracingConfig().value().operation_name_;
}

void ConnectionManagerImpl::ActiveStreamFilterBase::addResetStreamCallback(
std::function<void()> callback) {
parent_.reset_callbacks_.push_back(callback);
Expand Down
27 changes: 24 additions & 3 deletions source/common/http/conn_manager_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@ struct ConnectionManagerStats {
Stats::Store& store_;
};

enum class TracingType {
// Trace all traceable requests.
All,
// Trace only when there is an upstream failure reason.
UpstreamFailureReason

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call this UpstreamFailure

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

};

/**
* Configuration for tracing which is set on the connection manager level.
* Http Tracing can be enabled/disabled on a per connection manager basis.
* Here we specify some specific for connection manager settings.
*/
struct TracingConnectionManagerConfig {
std::string operation_name_;
TracingType tracing_type_;
};

/**
* Abstract configuration for the connection manager.
*/
Expand Down Expand Up @@ -159,9 +176,9 @@ class ConnectionManagerConfig {
virtual const Optional<std::string>& userAgent() PURE;

/**
* @return true if tracing is enabled otherwise it returns false;
* @return tracing config.
*/
virtual bool isTracing() PURE;
virtual const Optional<TracingConnectionManagerConfig>& tracingConfig() PURE;
};

/**
Expand Down Expand Up @@ -319,7 +336,8 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>,
public Event::DeferredDeletable,
public StreamCallbacks,
public StreamDecoder,
public FilterChainFactoryCallbacks {
public FilterChainFactoryCallbacks,
public Tracing::TracingContext {
ActiveStream(ConnectionManagerImpl& connection_manager);
~ActiveStream();

Expand Down Expand Up @@ -349,6 +367,9 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>,
void addStreamEncoderFilter(StreamEncoderFilterPtr filter) override;
void addStreamFilter(StreamFilterPtr filter) override;

// Tracing::TracingContext
virtual const std::string& operationName() const override;

static DateFormatter date_formatter_;

// All state for the stream. Put here for readability. We could move this to a bit field
Expand Down
20 changes: 19 additions & 1 deletion source/common/http/conn_manager_utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ void ConnectionManagerUtility::mutateRequestHeaders(Http::HeaderMap& request_hea
}
}

if (config.isTracing()) {
if (config.tracingConfig().valid()) {
Tracing::HttpTracerUtility::mutateHeaders(request_headers, runtime);
}
}
Expand All @@ -131,4 +131,22 @@ void ConnectionManagerUtility::mutateResponseHeaders(Http::HeaderMap& response_h
}
}

bool ConnectionManagerUtility::shouldTraceRequest(
const Http::AccessLog::RequestInfo& request_info,
const Optional<TracingConnectionManagerConfig>& config) {
if (!config.valid()) {
return false;
}

switch (config.value().tracing_type_) {
case Http::TracingType::All:
return true;
case Http::TracingType::UpstreamFailureReason:
return request_info.failureReason() != Http::AccessLog::FailureReason::None;
}

// This should not happen as switch above covers all cases, this is just to make compiler happy.
throw EnvoyException("unknown tracing type");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the tracing_type value to the exception?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use NOT_IMPLEMENTED or something clear that it should not happen

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'll switch to NOT_IMPLEMENTED here and refine the comment to emphasize that compiler also enforces all types covered by switch above.

}

} // Http
3 changes: 3 additions & 0 deletions source/common/http/conn_manager_utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ class ConnectionManagerUtility {
static void mutateResponseHeaders(Http::HeaderMap& response_headers,
const Http::HeaderMap& request_headers,
ConnectionManagerConfig& config);

static bool shouldTraceRequest(const Http::AccessLog::RequestInfo& request_info,
const Optional<TracingConnectionManagerConfig>& config);
};

} // Http
10 changes: 6 additions & 4 deletions source/common/tracing/http_tracer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ void HttpTracerImpl::addSink(HttpSinkPtr&& sink) { sinks_.push_back(std::move(si

void HttpTracerImpl::trace(const Http::HeaderMap* request_headers,
const Http::HeaderMap* response_headers,
const Http::AccessLog::RequestInfo& request_info) {
const Http::AccessLog::RequestInfo& request_info,
const TracingContext& tracing_context) {
static const Http::HeaderMapImpl empty_headers;
if (!request_headers) {
request_headers = &empty_headers;
Expand All @@ -90,7 +91,7 @@ void HttpTracerImpl::trace(const Http::HeaderMap* request_headers,
stats_.doing_tracing_.inc();

for (HttpSinkPtr& sink : sinks_) {
sink->flushTrace(*request_headers, *response_headers, request_info);
sink->flushTrace(*request_headers, *response_headers, request_info, tracing_context);
}
}
}
Expand Down Expand Up @@ -226,9 +227,10 @@ std::string LightStepSink::buildResponseCode(const Http::AccessLog::RequestInfo&
}

void LightStepSink::flushTrace(const Http::HeaderMap& request_headers, const Http::HeaderMap&,
const Http::AccessLog::RequestInfo& request_info) {
const Http::AccessLog::RequestInfo& request_info,
const TracingContext& tracing_context) {
lightstep::Span span = tls_.getTyped<TlsLightStepTracer>(tls_slot_).tracer_.StartSpan(
"full request",
tracing_context.operationName(),
{
lightstep::StartTimestamp(request_info.startTime()),
lightstep::SetTag("join:x-request-id", request_headers.get(Http::Headers::get().RequestId)),
Expand Down
10 changes: 6 additions & 4 deletions source/common/tracing/http_tracer_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class HttpNullTracer : public HttpTracer {
public:
// Tracing::HttpTracer
void addSink(HttpSinkPtr&&) override {}
void trace(const Http::HeaderMap*, const Http::HeaderMap*,
const Http::AccessLog::RequestInfo&) override {}
void trace(const Http::HeaderMap*, const Http::HeaderMap*, const Http::AccessLog::RequestInfo&,
const TracingContext&) override {}
};

enum class Reason {
Expand Down Expand Up @@ -81,7 +81,8 @@ class HttpTracerImpl : public HttpTracer {
// Tracing::HttpTracer
void addSink(HttpSinkPtr&& sink) override;
void trace(const Http::HeaderMap* request_headers, const Http::HeaderMap* response_headers,
const Http::AccessLog::RequestInfo& request_info) override;
const Http::AccessLog::RequestInfo& request_info,
const TracingContext& tracing_context) override;

private:
void populateStats(const Decision& decision);
Expand All @@ -105,7 +106,8 @@ class LightStepSink : public HttpSink {

// Tracer::HttpSink
void flushTrace(const Http::HeaderMap& request_headers, const Http::HeaderMap& response_headers,
const Http::AccessLog::RequestInfo& request_info) override;
const Http::AccessLog::RequestInfo& request_info,
const TracingContext& tracing_context) override;

Upstream::ClusterManager& clusterManager() { return cm_; }
const std::string& collectorCluster() { return collector_cluster_; }
Expand Down
16 changes: 15 additions & 1 deletion source/server/config/network/http_connection_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,21 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig(const Json::Object& con
user_agent_.value(server.options().serviceClusterName());
}

is_tracing_ = config.getBoolean("tracing_enabled", false);
if (config.hasObject("tracing")) {
const std::string operation_name = config.getObject("tracing").getString("operation_name");

std::string tracing_type = config.getObject("tracing").getString("type", "all");
Http::TracingType type;
if (tracing_type == "all") {
type = Http::TracingType::All;
} else if (tracing_type == "upstream_failure") {
type = Http::TracingType::UpstreamFailureReason;
} else {
throw EnvoyException(fmt::format("unsupported tracing type '{}'", tracing_type));
}

tracing_config_.value({operation_name, type});
}

if (config.hasObject("idle_timeout_s")) {
idle_timeout_.value(std::chrono::seconds(config.getInteger("idle_timeout_s")));
Expand Down
6 changes: 4 additions & 2 deletions source/server/config/network/http_connection_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ class HttpConnectionManagerConfig : Logger::Loggable<Logger::Id::config>,
const std::string& serverName() override { return server_name_; }
Http::ConnectionManagerStats& stats() override { return stats_; }
bool useRemoteAddress() override { return use_remote_address_; }
bool isTracing() override { return is_tracing_; }
const Optional<Http::TracingConnectionManagerConfig>& tracingConfig() override {
return tracing_config_;
}
const std::string& localAddress() override;
const Optional<std::string>& userAgent() override { return user_agent_; }

Expand Down Expand Up @@ -99,7 +101,7 @@ class HttpConnectionManagerConfig : Logger::Loggable<Logger::Id::config>,
CodecType codec_type_;
const uint64_t codec_options_;
std::string server_name_;
bool is_tracing_;
Optional<Http::TracingConnectionManagerConfig> tracing_config_;
Optional<std::string> user_agent_;
Optional<std::chrono::milliseconds> idle_timeout_;
Router::ConfigPtr route_config_;
Expand Down
4 changes: 2 additions & 2 deletions source/server/configuration_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ void MainImpl::initializeTracers(const Json::Object& tracing_configuration_) {
server_.options().serviceNodeName(), server_.threadLocal(), server_.runtime(),
std::move(opts))});
} else {
throw EnvoyException(fmt::format("Unsupported sink type: '{}'", type));
throw EnvoyException(fmt::format("unsupported sink type: '{}'", type));
}
}
}
} else {
throw EnvoyException("Incorrect tracing configuration");
throw EnvoyException("incorrect tracing configuration");
}
}

Expand Down
5 changes: 4 additions & 1 deletion source/server/http/admin.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ class AdminImpl : public Admin,
bool useRemoteAddress() override { return true; }
const std::string& localAddress() override;
const Optional<std::string>& userAgent() override { return user_agent_; }
bool isTracing() override { return false; }
const Optional<Http::TracingConnectionManagerConfig>& tracingConfig() override {
return tracing_config_;
}

private:
/**
Expand Down Expand Up @@ -99,6 +101,7 @@ class AdminImpl : public Admin,
std::list<UrlHandler> handlers_;
Optional<std::chrono::milliseconds> idle_timeout_;
Optional<std::string> user_agent_;
Optional<Http::TracingConnectionManagerConfig> tracing_config_;
};

/**
Expand Down
Loading