Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DTRACE points to measure request timings. #11245

Merged
merged 18 commits into from
Mar 20, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
devel
-----

* Add DTRACE points to track a request through the infrastructure.

* Fixed issue #11275: indexes backward compatibility broken in 3.5+.

* Updated snowball dependency to the latest version.
Expand Down
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,12 @@ if (STATIC_EXECUTABLES)
endif ()
endif()

# enable dtrace
option(USE_DTRACE "enable dtrace probes" OFF)
if (USE_DTRACE)
add_definitions("-DUSE_DTRACE=1")
endif ()

# enable enterprise features
set(ENTERPRISE_INCLUDE_DIR "enterprise")
option(USE_ENTERPRISE "enable enterprise build" OFF)
Expand Down
7 changes: 6 additions & 1 deletion arangod/GeneralServer/CommTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "Basics/HybridLogicalClock.h"
#include "Basics/StaticStrings.h"
#include "Basics/compile-time-strlen.h"
#include "Basics/dtrace-wrapper.h"
#include "Cluster/ServerState.h"
#include "GeneralServer/AsyncJobManager.h"
#include "GeneralServer/AuthenticationFeature.h"
Expand Down Expand Up @@ -150,6 +151,8 @@ bool resolveRequestContext(GeneralRequest& req) {

CommTask::Flow CommTask::prepareExecution(auth::TokenCache::Entry const& authToken,
GeneralRequest& req) {
DTRACE_PROBE1(arangod, CommTaskPrepareExecution, this);

// Step 1: In the shutdown phase we simply return 503:
if (_server.server().isStopping()) {
addErrorResponse(ResponseCode::SERVICE_UNAVAILABLE, req.contentTypeResponse(),
Expand Down Expand Up @@ -324,7 +327,8 @@ void CommTask::finishExecution(GeneralResponse& res, std::string const& origin)

void CommTask::executeRequest(std::unique_ptr<GeneralRequest> request,
std::unique_ptr<GeneralResponse> response) {

DTRACE_PROBE1(arangod, CommTaskExecuteRequest, this);

response->setContentTypeRequested(request->contentTypeResponse());
response->setGenerateBody(request->requestType() != RequestType::HEAD);

Expand Down Expand Up @@ -516,6 +520,7 @@ void CommTask::addErrorResponse(rest::ResponseCode code,
// and scheduled later when the number of used threads decreases

bool CommTask::handleRequestSync(std::shared_ptr<RestHandler> handler) {
DTRACE_PROBE2(arangod, CommTaskHandleRequestSync, this, handler.get());
RequestStatistics::SET_QUEUE_START(handler->statistics(), SchedulerFeature::SCHEDULER->queueStatistics()._queued);

RequestLane lane = handler->getRequestLane();
Expand Down
43 changes: 42 additions & 1 deletion arangod/GeneralServer/H2CommTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "Basics/Exceptions.h"
#include "Basics/ScopeGuard.h"
#include "Basics/asio_ns.h"
#include "Basics/dtrace-wrapper.h"
#include "Cluster/ServerState.h"
#include "GeneralServer/GeneralServer.h"
#include "GeneralServer/GeneralServerFeature.h"
Expand Down Expand Up @@ -389,8 +390,20 @@ bool H2CommTask<T>::readCallback(asio_ns::error_code ec) {
return true; // continue read lopp
}

#ifdef USE_DTRACE
// Moved out to avoid duplication by templates.
static void __attribute__ ((noinline)) DTraceH2CommTaskProcessStream(size_t th) {
DTRACE_PROBE1(arangod, H2CommTaskProcessStream, th);
}
#else
static void DTraceH2CommTaskProcessStream(size_t) {}
#endif

template <SocketType T>
void H2CommTask<T>::processStream(H2CommTask<T>::Stream* stream) {

DTraceH2CommTaskProcessStream((size_t) this);

TRI_ASSERT(stream);

std::unique_ptr<HttpRequest> req = std::move(stream->request);
Expand Down Expand Up @@ -463,10 +476,21 @@ bool expectResponseBody(int status_code) {
}
} // namespace

#ifdef USE_DTRACE
// Moved out to avoid duplication by templates.
static void __attribute__ ((noinline)) DTraceH2CommTaskSendResponse(size_t th) {
DTRACE_PROBE1(arangod, H2CommTaskSendResponse, th);
}
#else
static void DTraceH2CommTaskSendResponse(size_t) {}
#endif

template <SocketType T>
void H2CommTask<T>::sendResponse(std::unique_ptr<GeneralResponse> res,
RequestStatistics* stat) {


DTraceH2CommTaskSendResponse((size_t) this);

// TODO the statistics are total bogus here
double const totalTime = RequestStatistics::ELAPSED_SINCE_READ_START(stat);
if (stat) {
Expand Down Expand Up @@ -630,6 +654,19 @@ void H2CommTask<T>::queueHttp2Responses() {
}
}

#ifdef USE_DTRACE
// Moved out to avoid duplication by templates.
static void __attribute__ ((noinline)) DTraceH2CommTaskBeforeAsyncWrite(size_t th) {
DTRACE_PROBE1(arangod, H2CommTaskBeforeAsyncWrite, th);
}
static void __attribute__ ((noinline)) DTraceH2CommTaskAfterAsyncWrite(size_t th) {
DTRACE_PROBE1(arangod, H2CommTaskAfterAsyncWrite, th);
}
#else
static void DTraceH2CommTaskBeforeAsyncWrite(size_t) {}
static void DTraceH2CommTaskAfterAsyncWrite(size_t) {}
#endif

// called on IO context thread
template <SocketType T>
void H2CommTask<T>::doWrite() {
Expand Down Expand Up @@ -685,6 +722,8 @@ void H2CommTask<T>::doWrite() {
return;
}

DTraceH2CommTaskBeforeAsyncWrite((size_t) this);

asio_ns::async_write(this->_protocol->socket, outBuffers,
[self = this->shared_from_this()](const asio_ns::error_code& ec,
std::size_t nwrite) {
Expand All @@ -695,6 +734,8 @@ void H2CommTask<T>::doWrite() {
return;
}

DTraceH2CommTaskAfterAsyncWrite((size_t) self.get());

me.doWrite();
});
}
Expand Down
44 changes: 44 additions & 0 deletions arangod/GeneralServer/HttpCommTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include "Basics/ScopeGuard.h"
#include "Basics/asio_ns.h"
#include "Basics/dtrace-wrapper.h"
#include "Cluster/ServerState.h"
#include "GeneralServer/GeneralServer.h"
#include "GeneralServer/GeneralServerFeature.h"
Expand Down Expand Up @@ -336,8 +337,20 @@ void HttpCommTask<T>::checkVSTPrefix() {
asio_ns::transfer_at_least(11), std::move(cb));
}

#ifdef USE_DTRACE
// Moved here to prevent multiplicity by template
static void __attribute__ ((noinline)) DTraceHttpCommTaskProcessRequest(size_t th) {
DTRACE_PROBE1(arangod, HttpCommTaskProcessRequest, th);
}
#else
static void DTraceHttpCommTaskProcessRequest(size_t) {}
#endif

template <SocketType T>
void HttpCommTask<T>::processRequest() {

DTraceHttpCommTaskProcessRequest((size_t) this);

TRI_ASSERT(_request);
this->_protocol->timer.cancel();

Expand Down Expand Up @@ -414,9 +427,21 @@ void HttpCommTask<T>::processRequest() {
this->executeRequest(std::move(_request), std::move(resp));
}

#ifdef USE_DTRACE
// Moved here to prevent multiplicity by template
static void __attribute__ ((noinline)) DTraceHttpCommTaskSendResponse(size_t th) {
DTRACE_PROBE1(arangod, HttpCommTaskSendResponse, th);
}
#else
static void DTraceHttpCommTaskSendResponse(size_t) {}
#endif

template <SocketType T>
void HttpCommTask<T>::sendResponse(std::unique_ptr<GeneralResponse> baseRes,
RequestStatistics* stat) {

DTraceHttpCommTaskSendResponse((size_t) this);

if (this->_stopped.load(std::memory_order_acquire)) {
return;
}
Expand Down Expand Up @@ -534,9 +559,25 @@ void HttpCommTask<T>::sendResponse(std::unique_ptr<GeneralResponse> baseRes,
});
}

#ifdef USE_DTRACE
// Moved here to prevent multiplicity by template
static void __attribute__ ((noinline)) DTraceHttpCommTaskWriteResponse(size_t th) {
DTRACE_PROBE1(arangod, HttpCommTaskWriteResponse, th);
}
static void __attribute__ ((noinline)) DTraceHttpCommTaskResponseWritten(size_t th) {
DTRACE_PROBE1(arangod, HttpCommTaskResponseWritten, th);
}
#else
static void DTraceHttpCommTaskWriteResponse(size_t) {}
static void DTraceHttpCommTaskResponseWritten(size_t) {}
#endif

// called on IO context thread
template <SocketType T>
void HttpCommTask<T>::writeResponse(RequestStatistics* stat) {

DTraceHttpCommTaskWriteResponse((size_t) this);

TRI_ASSERT(!_header.empty());

RequestStatistics::SET_WRITE_START(stat);
Expand All @@ -551,6 +592,9 @@ void HttpCommTask<T>::writeResponse(RequestStatistics* stat) {
asio_ns::async_write(this->_protocol->socket, buffers,
[self = this->shared_from_this(),
stat](asio_ns::error_code ec, size_t nwrite) {

DTraceHttpCommTaskResponseWritten((size_t) self.get());

auto* thisPtr = static_cast<HttpCommTask<T>*>(self.get());
RequestStatistics::SET_WRITE_END(stat);
RequestStatistics::ADD_SENT_BYTES(stat, nwrite);
Expand Down
2 changes: 2 additions & 0 deletions arangod/GeneralServer/RestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "ApplicationFeatures/ApplicationServer.h"
#include "Basics/RecursiveLocker.h"
#include "Basics/StringUtils.h"
#include "Basics/dtrace-wrapper.h"
#include "Cluster/ClusterFeature.h"
#include "Cluster/ClusterInfo.h"
#include "Cluster/ClusterMethods.h"
Expand Down Expand Up @@ -398,6 +399,7 @@ bool RestHandler::wakeupHandler() {
}

void RestHandler::executeEngine(bool isContinue) {
DTRACE_PROBE1(arangod, RestHandlerExecuteEngine, this);
ExecContext* exec = static_cast<ExecContext*>(_request->requestContext());
ExecContextScope scope(exec);

Expand Down
39 changes: 35 additions & 4 deletions arangod/GeneralServer/SslServerFeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ SslServerFeature::SslServerFeature(application_features::ApplicationServer& serv
_sslProtocol(TLS_GENERIC),
_sslOptions(asio_ns::ssl::context::default_workarounds |
asio_ns::ssl::context::single_dh_use),
_ecdhCurve("prime256v1") {
_ecdhCurve("prime256v1"),
_preferHttp11InAlpn(false) {
setOptional(true);
startsAfter<application_features::AqlFeaturePhase>();
}
Expand Down Expand Up @@ -116,6 +117,10 @@ void SslServerFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
"--ssl.ecdh-curve",
"SSL ECDH Curve, see the output of \"openssl ecparam -list_curves\"",
new StringParameter(&_ecdhCurve));

options->addOption("--ssl.prefer-http1-in-alpn",
"Allows to let the server prefer HTTP/1.1 over HTTP/2 in ALPN protocol negotiations",
new BooleanParameter(&_preferHttp11InAlpn));
}

void SslServerFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
Expand Down Expand Up @@ -201,12 +206,38 @@ class BIOGuard {
};
} // namespace

static inline bool searchForProtocol(const unsigned char** out, unsigned char* outlen,
const unsigned char* in, unsigned int inlen,
const char* proto) {
size_t len = strlen(proto);
size_t i = 0;
while (i + len <= inlen) {
if (memcmp(in + i, proto, len) == 0) {
*out = (const unsigned char *)(in + i + 1);
*outlen = proto[0];
return true;
}
i += in[i] + 1;
}
return false;
}

static int alpn_select_proto_cb(SSL* ssl, const unsigned char** out,
unsigned char* outlen, const unsigned char* in,
unsigned int inlen, void* arg) {
int rv = nghttp2_select_next_protocol((unsigned char**)out, outlen, in, inlen);
int rv = 0;
bool const* preferHttp11InAlpn = (bool*) arg;
if (*preferHttp11InAlpn) {
if (!searchForProtocol(out, outlen, in, inlen, "\x8http/1.1")) {
if (!searchForProtocol(out, outlen, in, inlen, "\x2h2")) {
rv = -1;
}
}
} else {
rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, inlen);
}

if (rv != 1) {
if (rv < 0) {
return SSL_TLSEXT_ERR_NOACK;
}

Expand Down Expand Up @@ -344,7 +375,7 @@ asio_ns::ssl::context SslServerFeature::createSslContextInternal(std::string key

sslContext.set_verify_mode(SSL_VERIFY_NONE);

SSL_CTX_set_alpn_select_cb(sslContext.native_handle(), alpn_select_proto_cb, NULL);
SSL_CTX_set_alpn_select_cb(sslContext.native_handle(), alpn_select_proto_cb, (void*) (&_preferHttp11InAlpn));

return sslContext;
} catch (std::exception const& ex) {
Expand Down
1 change: 1 addition & 0 deletions arangod/GeneralServer/SslServerFeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class SslServerFeature : public application_features::ApplicationFeature {
uint64_t _sslProtocol;
uint64_t _sslOptions;
std::string _ecdhCurve;
bool _preferHttp11InAlpn;

private:
asio_ns::ssl::context createSslContextInternal(std::string keyfileName,
Expand Down
Loading