mirror of https://gitee.com/bigwinds/arangodb
added "bindVars" to attributes of currently running and slow queries
This commit is contained in:
parent
965a9547cc
commit
644ef08ce0
|
@ -1,6 +1,8 @@
|
||||||
devel
|
devel
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
* added "bindVars" to attributes of currently running and slow queries
|
||||||
|
|
||||||
* added input file type `auto` for arangoimp so it can automatically detect the
|
* added input file type `auto` for arangoimp so it can automatically detect the
|
||||||
type of the input file from the filename extension
|
type of the input file from the filename extension
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,15 @@ database. Each query is a JSON object with the following attributes:
|
||||||
|
|
||||||
- *query*: the query string (potentially truncated)
|
- *query*: the query string (potentially truncated)
|
||||||
|
|
||||||
|
- *bindVars*: the bind parameter values used by the query
|
||||||
|
|
||||||
- *started*: the date and time when the query was started
|
- *started*: the date and time when the query was started
|
||||||
|
|
||||||
- *runTime*: the query's run time up to the point the list of queries was
|
- *runTime*: the query's run time up to the point the list of queries was
|
||||||
queried
|
queried
|
||||||
|
|
||||||
|
- *state*: the query's current execution state (as a string)
|
||||||
|
|
||||||
@RESTRETURNCODES
|
@RESTRETURNCODES
|
||||||
|
|
||||||
@RESTRETURNCODE{200}
|
@RESTRETURNCODE{200}
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
@RESTHEADER{GET /_api/query/slow, Returns the list of slow AQL queries}
|
@RESTHEADER{GET /_api/query/slow, Returns the list of slow AQL queries}
|
||||||
|
|
||||||
@RESTDESCRIPTION
|
@RESTDESCRIPTION
|
||||||
Returns an array containing the last AQL queries that exceeded the slow
|
Returns an array containing the last AQL queries that are finished and
|
||||||
query threshold in the selected database.
|
have exceeded the slow query threshold in the selected database.
|
||||||
The maximum amount of queries in the list can be controlled by setting
|
The maximum amount of queries in the list can be controlled by setting
|
||||||
the query tracking property `maxSlowQueries`. The threshold for treating
|
the query tracking property `maxSlowQueries`. The threshold for treating
|
||||||
a query as *slow* can be adjusted by setting the query tracking property
|
a query as *slow* can be adjusted by setting the query tracking property
|
||||||
|
@ -18,10 +18,14 @@ Each query is a JSON object with the following attributes:
|
||||||
|
|
||||||
- *query*: the query string (potentially truncated)
|
- *query*: the query string (potentially truncated)
|
||||||
|
|
||||||
|
- *bindVars*: the bind parameter values used by the query
|
||||||
|
|
||||||
- *started*: the date and time when the query was started
|
- *started*: the date and time when the query was started
|
||||||
|
|
||||||
- *runTime*: the query's run time up to the point the list of queries was
|
- *runTime*: the query's total run time
|
||||||
queried
|
|
||||||
|
- *state*: the query's current execution state (will always be "finished"
|
||||||
|
for the list of slow queries)
|
||||||
|
|
||||||
@RESTRETURNCODES
|
@RESTRETURNCODES
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ describe ArangoDB do
|
||||||
@fastQueryBody = JSON.dump({query: @fastQuery})
|
@fastQueryBody = JSON.dump({query: @fastQuery})
|
||||||
@longQuery = "FOR x IN 1..1 LET y = SLEEP(0.2) LET a = y LET b = a LET c = b LET d = c LET e = d LET f = e RETURN x"
|
@longQuery = "FOR x IN 1..1 LET y = SLEEP(0.2) LET a = y LET b = a LET c = b LET d = c LET e = d LET f = e RETURN x"
|
||||||
@longQueryBody = JSON.dump({query: @longQuery})
|
@longQueryBody = JSON.dump({query: @longQuery})
|
||||||
|
@queryWithBind = "FOR x IN 1..5 LET y = SLEEP(@value) RETURN x"
|
||||||
|
@queryWithBindBody = JSON.dump({query: @queryWithBind, bindVars: {value: 2}})
|
||||||
@queryEndpoint ="/_api/cursor"
|
@queryEndpoint ="/_api/cursor"
|
||||||
@queryPrefix = "api-cursor"
|
@queryPrefix = "api-cursor"
|
||||||
end
|
end
|
||||||
|
@ -33,20 +35,24 @@ describe ArangoDB do
|
||||||
ArangoDB.log_post(@queryPrefix, @queryEndpoint, :body => @fastQueryBody, :headers => {"X-Arango-Async" => async })
|
ArangoDB.log_post(@queryPrefix, @queryEndpoint, :body => @fastQueryBody, :headers => {"X-Arango-Async" => async })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def send_queries_with_bind (count = 1, async = "true")
|
||||||
|
count.times do
|
||||||
|
ArangoDB.log_post(@queryPrefix, @queryEndpoint, :body => @queryWithBindBody, :headers => {"X-Arango-Async" => async })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def contains_query (body, testq = @query)
|
def contains_query (body, testq = @query)
|
||||||
found = false
|
|
||||||
res = JSON.parse body
|
res = JSON.parse body
|
||||||
res.each do |q|
|
res.each do |q|
|
||||||
if q["query"] === testq
|
if q["query"] === testq
|
||||||
found = true
|
return q
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return found
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should activate Tracking" do
|
it "should activate tracking" do
|
||||||
doc = ArangoDB.log_put("#{@prefix}-properties", @properties, :body => JSON.dump({enable: true}))
|
doc = ArangoDB.log_put("#{@prefix}-properties", @properties, :body => JSON.dump({enable: true}))
|
||||||
doc.code.should eq(200)
|
doc.code.should eq(200)
|
||||||
end
|
end
|
||||||
|
@ -79,7 +85,35 @@ describe ArangoDB do
|
||||||
doc = ArangoDB.log_get("#{@prefix}-current", @current)
|
doc = ArangoDB.log_get("#{@prefix}-current", @current)
|
||||||
doc.code.should eq(200)
|
doc.code.should eq(200)
|
||||||
found = contains_query doc.body, @query
|
found = contains_query doc.body, @query
|
||||||
found.should eq(true)
|
found.should_not eq(false)
|
||||||
|
found.should have_key("id")
|
||||||
|
found["id"].should match(/^\d+$/)
|
||||||
|
found.should have_key("query")
|
||||||
|
found["query"].should eq(@query)
|
||||||
|
found.should have_key("bindVars")
|
||||||
|
found["bindVars"].should eq({})
|
||||||
|
found.should have_key("runTime")
|
||||||
|
found["runTime"].should be_kind_of(Numeric)
|
||||||
|
found.should have_key("started")
|
||||||
|
found["state"].should eq("executing");
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should track running queries, with bind parameters" do
|
||||||
|
send_queries_with_bind
|
||||||
|
doc = ArangoDB.log_get("#{@prefix}-current-bind", @current)
|
||||||
|
doc.code.should eq(200)
|
||||||
|
found = contains_query doc.body, @queryWithBind
|
||||||
|
found.should_not eq(false)
|
||||||
|
found.should have_key("id")
|
||||||
|
found["id"].should match(/^\d+$/)
|
||||||
|
found.should have_key("query")
|
||||||
|
found["query"].should eq(@queryWithBind)
|
||||||
|
found.should have_key("bindVars")
|
||||||
|
found["bindVars"].should eq({"value" => 2})
|
||||||
|
found.should have_key("runTime")
|
||||||
|
found["runTime"].should be_kind_of(Numeric)
|
||||||
|
found.should have_key("started")
|
||||||
|
found["state"].should eq("executing")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should track slow queries by threshold" do
|
it "should track slow queries by threshold" do
|
||||||
|
@ -99,7 +133,14 @@ describe ArangoDB do
|
||||||
doc = ArangoDB.log_get("#{@prefix}-slow", @slow)
|
doc = ArangoDB.log_get("#{@prefix}-slow", @slow)
|
||||||
doc.code.should eq(200)
|
doc.code.should eq(200)
|
||||||
found = contains_query doc.body, @fastQuery
|
found = contains_query doc.body, @fastQuery
|
||||||
found.should eq(true)
|
found.should_not eq(false)
|
||||||
|
found.should have_key("query")
|
||||||
|
found["query"].should eq(@fastQuery)
|
||||||
|
found["bindVars"].should eq({})
|
||||||
|
found.should have_key("runTime")
|
||||||
|
found["runTime"].should be_kind_of(Numeric)
|
||||||
|
found.should have_key("started")
|
||||||
|
found["state"].should eq("finished")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should track at most n slow queries" do
|
it "should track at most n slow queries" do
|
||||||
|
@ -143,9 +184,12 @@ describe ArangoDB do
|
||||||
res = JSON.parse doc.body
|
res = JSON.parse doc.body
|
||||||
res.length.should eq(1)
|
res.length.should eq(1)
|
||||||
# This string is exactly 64 bytes long
|
# This string is exactly 64 bytes long
|
||||||
shortend = "FOR x IN 1..1 LET y = SLEEP(0.2) LET a = y LET b = a LET c = b L"
|
shortened = "FOR x IN 1..1 LET y = SLEEP(0.2) LET a = y LET b = a LET c = b L"
|
||||||
found = contains_query doc.body, shortend + "..."
|
found = contains_query doc.body, shortened + "..."
|
||||||
found.should eq(true)
|
found.should_not eq(false)
|
||||||
|
found.should have_key("query")
|
||||||
|
found["query"].should eq(shortened + "...")
|
||||||
|
found["bindVars"].should eq({})
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should properly truncate UTF8 symbols" do
|
it "should properly truncate UTF8 symbols" do
|
||||||
|
@ -156,9 +200,12 @@ describe ArangoDB do
|
||||||
res = JSON.parse doc.body
|
res = JSON.parse doc.body
|
||||||
res.length.should eq(1)
|
res.length.should eq(1)
|
||||||
# This string is exactly 64 bytes long
|
# This string is exactly 64 bytes long
|
||||||
shortend = "FOR x IN 1..1 LET y = SLEEP(0.2) LET a= y LET b= a LET c= \"öö"
|
shortened = "FOR x IN 1..1 LET y = SLEEP(0.2) LET a= y LET b= a LET c= \"öö"
|
||||||
found = contains_query doc.body, shortend + "..."
|
found = contains_query doc.body, shortened + "..."
|
||||||
found.should eq(true)
|
found.should_not eq(false)
|
||||||
|
found.should have_key("query")
|
||||||
|
found["query"].should eq(shortened + "...")
|
||||||
|
found["bindVars"].should eq({})
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should be able to kill a running query" do
|
it "should be able to kill a running query" do
|
||||||
|
|
|
@ -57,6 +57,9 @@ class BindParameters {
|
||||||
return _parameters;
|
return _parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief return the bind parameters as passed by the user
|
||||||
|
std::shared_ptr<arangodb::velocypack::Builder> builder() const { return _builder; }
|
||||||
|
|
||||||
/// @brief create a hash value for the bind parameters
|
/// @brief create a hash value for the bind parameters
|
||||||
uint64_t hash() const;
|
uint64_t hash() const;
|
||||||
|
|
||||||
|
|
|
@ -298,6 +298,11 @@ class Query {
|
||||||
/// @brief look up a graph in the _graphs collection
|
/// @brief look up a graph in the _graphs collection
|
||||||
Graph const* lookupGraphByName(std::string const& name);
|
Graph const* lookupGraphByName(std::string const& name);
|
||||||
|
|
||||||
|
/// @brief return the bind parameters as passed by the user
|
||||||
|
std::shared_ptr<arangodb::velocypack::Builder> bindParameters() const {
|
||||||
|
return _bindParameters.builder();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// @brief initializes the query
|
/// @brief initializes the query
|
||||||
void init();
|
void init();
|
||||||
|
|
|
@ -33,10 +33,12 @@
|
||||||
using namespace arangodb::aql;
|
using namespace arangodb::aql;
|
||||||
|
|
||||||
QueryEntryCopy::QueryEntryCopy(TRI_voc_tick_t id,
|
QueryEntryCopy::QueryEntryCopy(TRI_voc_tick_t id,
|
||||||
std::string&& queryString, double started,
|
std::string&& queryString,
|
||||||
|
std::shared_ptr<arangodb::velocypack::Builder> bindParameters,
|
||||||
|
double started,
|
||||||
double runTime, QueryExecutionState::ValueType state)
|
double runTime, QueryExecutionState::ValueType state)
|
||||||
: id(id), queryString(std::move(queryString)), started(started), runTime(runTime),
|
: id(id), queryString(std::move(queryString)), bindParameters(bindParameters),
|
||||||
state(state) {}
|
started(started), runTime(runTime), state(state) {}
|
||||||
|
|
||||||
double const QueryList::DefaultSlowQueryThreshold = 10.0;
|
double const QueryList::DefaultSlowQueryThreshold = 10.0;
|
||||||
size_t const QueryList::DefaultMaxSlowQueries = 64;
|
size_t const QueryList::DefaultMaxSlowQueries = 64;
|
||||||
|
@ -56,14 +58,6 @@ QueryList::QueryList(TRI_vocbase_t*)
|
||||||
_current.reserve(64);
|
_current.reserve(64);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief destroy a query list
|
|
||||||
QueryList::~QueryList() {
|
|
||||||
WRITE_LOCKER(writeLocker, _lock);
|
|
||||||
|
|
||||||
_current.clear();
|
|
||||||
_slow.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief insert a query
|
/// @brief insert a query
|
||||||
bool QueryList::insert(Query const* query) {
|
bool QueryList::insert(Query const* query) {
|
||||||
// not enable or no query string
|
// not enable or no query string
|
||||||
|
@ -132,6 +126,7 @@ void QueryList::remove(Query const* query) {
|
||||||
_slow.emplace_back(QueryEntryCopy(
|
_slow.emplace_back(QueryEntryCopy(
|
||||||
query->id(),
|
query->id(),
|
||||||
std::move(q),
|
std::move(q),
|
||||||
|
query->bindParameters(),
|
||||||
started, now - started,
|
started, now - started,
|
||||||
QueryExecutionState::ValueType::FINISHED));
|
QueryExecutionState::ValueType::FINISHED));
|
||||||
|
|
||||||
|
@ -212,6 +207,7 @@ std::vector<QueryEntryCopy> QueryList::listCurrent() {
|
||||||
result.emplace_back(
|
result.emplace_back(
|
||||||
QueryEntryCopy(query->id(),
|
QueryEntryCopy(query->id(),
|
||||||
extractQueryString(query, maxLength),
|
extractQueryString(query, maxLength),
|
||||||
|
query->bindParameters(),
|
||||||
started, now - started,
|
started, now - started,
|
||||||
query->state()));
|
query->state()));
|
||||||
}
|
}
|
||||||
|
@ -227,7 +223,9 @@ std::vector<QueryEntryCopy> QueryList::listSlow() {
|
||||||
{
|
{
|
||||||
READ_LOCKER(readLocker, _lock);
|
READ_LOCKER(readLocker, _lock);
|
||||||
result.reserve(_slow.size());
|
result.reserve(_slow.size());
|
||||||
result.assign(_slow.begin(), _slow.end());
|
for (auto const& it : _slow) {
|
||||||
|
result.emplace_back(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -34,26 +34,28 @@
|
||||||
struct TRI_vocbase_t;
|
struct TRI_vocbase_t;
|
||||||
|
|
||||||
namespace arangodb {
|
namespace arangodb {
|
||||||
|
namespace velocypack {
|
||||||
|
class Builder;
|
||||||
|
}
|
||||||
|
|
||||||
namespace aql {
|
namespace aql {
|
||||||
|
|
||||||
class Query;
|
class Query;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- struct QueryEntry
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
struct QueryEntryCopy {
|
struct QueryEntryCopy {
|
||||||
QueryEntryCopy (TRI_voc_tick_t id,
|
QueryEntryCopy (TRI_voc_tick_t id,
|
||||||
std::string&& queryString,
|
std::string&& queryString,
|
||||||
|
std::shared_ptr<arangodb::velocypack::Builder> bindParameters,
|
||||||
double started,
|
double started,
|
||||||
double runTime,
|
double runTime,
|
||||||
QueryExecutionState::ValueType state);
|
QueryExecutionState::ValueType state);
|
||||||
|
|
||||||
TRI_voc_tick_t id;
|
TRI_voc_tick_t const id;
|
||||||
std::string queryString;
|
std::string const queryString;
|
||||||
double started;
|
std::shared_ptr<arangodb::velocypack::Builder> const bindParameters;
|
||||||
double runTime;
|
double const started;
|
||||||
QueryExecutionState::ValueType state;
|
double const runTime;
|
||||||
|
QueryExecutionState::ValueType const state;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QueryList {
|
class QueryList {
|
||||||
|
@ -62,7 +64,7 @@ class QueryList {
|
||||||
explicit QueryList(TRI_vocbase_t*);
|
explicit QueryList(TRI_vocbase_t*);
|
||||||
|
|
||||||
/// @brief destroy a query list
|
/// @brief destroy a query list
|
||||||
~QueryList();
|
~QueryList() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// @brief whether or not queries are tracked
|
/// @brief whether or not queries are tracked
|
||||||
|
|
|
@ -111,6 +111,11 @@ bool RestQueryHandler::readQuery(bool slow) {
|
||||||
result.add(VPackValue(VPackValueType::Object));
|
result.add(VPackValue(VPackValueType::Object));
|
||||||
result.add("id", VPackValue(StringUtils::itoa(q.id)));
|
result.add("id", VPackValue(StringUtils::itoa(q.id)));
|
||||||
result.add("query", VPackValue(q.queryString));
|
result.add("query", VPackValue(q.queryString));
|
||||||
|
if (q.bindParameters != nullptr) {
|
||||||
|
result.add("bindVars", q.bindParameters->slice());
|
||||||
|
} else {
|
||||||
|
result.add("bindVars", arangodb::basics::VelocyPackHelper::EmptyObjectValue());
|
||||||
|
}
|
||||||
result.add("started", VPackValue(timeString));
|
result.add("started", VPackValue(timeString));
|
||||||
result.add("runTime", VPackValue(q.runTime));
|
result.add("runTime", VPackValue(q.runTime));
|
||||||
result.add("state", VPackValue(QueryExecutionState::toString(q.state)));
|
result.add("state", VPackValue(QueryExecutionState::toString(q.state)));
|
||||||
|
|
|
@ -1099,12 +1099,12 @@ static void JS_ExplainAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
|
|
||||||
if (args.Length() < 1 || args.Length() > 3) {
|
if (args.Length() < 1 || args.Length() > 3) {
|
||||||
TRI_V8_THROW_EXCEPTION_USAGE(
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
||||||
"AQL_EXPLAIN(<querystring>, <bindvalues>, <options>)");
|
"AQL_EXPLAIN(<queryString>, <bindVars>, <options>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the query string
|
// get the query string
|
||||||
if (!args[0]->IsString()) {
|
if (!args[0]->IsString()) {
|
||||||
TRI_V8_THROW_TYPE_ERROR("expecting string for <querystring>");
|
TRI_V8_THROW_TYPE_ERROR("expecting string for <queryString>");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const queryString(TRI_ObjectToString(args[0]));
|
std::string const queryString(TRI_ObjectToString(args[0]));
|
||||||
|
@ -1114,7 +1114,7 @@ static void JS_ExplainAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
|
|
||||||
if (args.Length() > 1) {
|
if (args.Length() > 1) {
|
||||||
if (!args[1]->IsUndefined() && !args[1]->IsNull() && !args[1]->IsObject()) {
|
if (!args[1]->IsUndefined() && !args[1]->IsNull() && !args[1]->IsObject()) {
|
||||||
TRI_V8_THROW_TYPE_ERROR("expecting object for <bindvalues>");
|
TRI_V8_THROW_TYPE_ERROR("expecting object for <bindVars>");
|
||||||
}
|
}
|
||||||
if (args[1]->IsObject()) {
|
if (args[1]->IsObject()) {
|
||||||
bindVars.reset(new VPackBuilder);
|
bindVars.reset(new VPackBuilder);
|
||||||
|
@ -1285,12 +1285,12 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
|
|
||||||
if (args.Length() < 1 || args.Length() > 3) {
|
if (args.Length() < 1 || args.Length() > 3) {
|
||||||
TRI_V8_THROW_EXCEPTION_USAGE(
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
||||||
"AQL_EXECUTE(<querystring>, <bindvalues>, <options>)");
|
"AQL_EXECUTE(<queryString>, <bindVars>, <options>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the query string
|
// get the query string
|
||||||
if (!args[0]->IsString()) {
|
if (!args[0]->IsString()) {
|
||||||
TRI_V8_THROW_TYPE_ERROR("expecting string for <querystring>");
|
TRI_V8_THROW_TYPE_ERROR("expecting string for <queryString>");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const queryString(TRI_ObjectToString(args[0]));
|
std::string const queryString(TRI_ObjectToString(args[0]));
|
||||||
|
@ -1303,7 +1303,7 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
|
|
||||||
if (args.Length() > 1) {
|
if (args.Length() > 1) {
|
||||||
if (!args[1]->IsUndefined() && !args[1]->IsNull() && !args[1]->IsObject()) {
|
if (!args[1]->IsUndefined() && !args[1]->IsNull() && !args[1]->IsObject()) {
|
||||||
TRI_V8_THROW_TYPE_ERROR("expecting object for <bindvalues>");
|
TRI_V8_THROW_TYPE_ERROR("expecting object for <bindVars>");
|
||||||
}
|
}
|
||||||
if (args[1]->IsObject()) {
|
if (args[1]->IsObject()) {
|
||||||
bindVars.reset(new VPackBuilder);
|
bindVars.reset(new VPackBuilder);
|
||||||
|
@ -1481,6 +1481,11 @@ static void JS_QueriesCurrentAql(
|
||||||
v8::Handle<v8::Object> obj = v8::Object::New(isolate);
|
v8::Handle<v8::Object> obj = v8::Object::New(isolate);
|
||||||
obj->Set(TRI_V8_ASCII_STRING("id"), V8TickId(isolate, q.id));
|
obj->Set(TRI_V8_ASCII_STRING("id"), V8TickId(isolate, q.id));
|
||||||
obj->Set(TRI_V8_ASCII_STRING("query"), TRI_V8_STD_STRING(q.queryString));
|
obj->Set(TRI_V8_ASCII_STRING("query"), TRI_V8_STD_STRING(q.queryString));
|
||||||
|
if (q.bindParameters != nullptr) {
|
||||||
|
obj->Set(TRI_V8_ASCII_STRING("bindVars"), TRI_VPackToV8(isolate, q.bindParameters->slice()));
|
||||||
|
} else {
|
||||||
|
obj->Set(TRI_V8_ASCII_STRING("started"), v8::Object::New(isolate));
|
||||||
|
}
|
||||||
obj->Set(TRI_V8_ASCII_STRING("started"), TRI_V8_STD_STRING(timeString));
|
obj->Set(TRI_V8_ASCII_STRING("started"), TRI_V8_STD_STRING(timeString));
|
||||||
obj->Set(TRI_V8_ASCII_STRING("runTime"),
|
obj->Set(TRI_V8_ASCII_STRING("runTime"),
|
||||||
v8::Number::New(isolate, q.runTime));
|
v8::Number::New(isolate, q.runTime));
|
||||||
|
@ -1533,6 +1538,7 @@ static void JS_QueriesSlowAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
v8::Handle<v8::Object> obj = v8::Object::New(isolate);
|
v8::Handle<v8::Object> obj = v8::Object::New(isolate);
|
||||||
obj->Set(TRI_V8_ASCII_STRING("id"), V8TickId(isolate, q.id));
|
obj->Set(TRI_V8_ASCII_STRING("id"), V8TickId(isolate, q.id));
|
||||||
obj->Set(TRI_V8_ASCII_STRING("query"), TRI_V8_STD_STRING(q.queryString));
|
obj->Set(TRI_V8_ASCII_STRING("query"), TRI_V8_STD_STRING(q.queryString));
|
||||||
|
obj->Set(TRI_V8_ASCII_STRING("bindVars"), TRI_VPackToV8(isolate, q.bindParameters->slice()));
|
||||||
obj->Set(TRI_V8_ASCII_STRING("started"), TRI_V8_STD_STRING(timeString));
|
obj->Set(TRI_V8_ASCII_STRING("started"), TRI_V8_STD_STRING(timeString));
|
||||||
obj->Set(TRI_V8_ASCII_STRING("runTime"),
|
obj->Set(TRI_V8_ASCII_STRING("runTime"),
|
||||||
v8::Number::New(isolate, q.runTime));
|
v8::Number::New(isolate, q.runTime));
|
||||||
|
|
|
@ -125,6 +125,19 @@ describe('AQL query analyzer', function () {
|
||||||
sendQuery(1, true);
|
sendQuery(1, true);
|
||||||
expect(testee.current().filter(filterQueries).length).to.equal(1);
|
expect(testee.current().filter(filterQueries).length).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should have proper running query descriptions', function () {
|
||||||
|
sendQuery(1, true);
|
||||||
|
let queries = testee.current().filter(filterQueries);
|
||||||
|
expect(queries.length).to.equal(1);
|
||||||
|
expect(queries[0]).to.have.property('id');
|
||||||
|
expect(queries[0]).to.have.property('query', query);
|
||||||
|
expect(queries[0]).to.have.property('bindVars');
|
||||||
|
expect(queries[0].bindVars).to.eql({});
|
||||||
|
expect(queries[0]).to.have.property('started');
|
||||||
|
expect(queries[0]).to.have.property('runTime');
|
||||||
|
expect(queries[0]).to.have.property('state', 'executing');
|
||||||
|
});
|
||||||
|
|
||||||
it('should not track queries if turned off', function () {
|
it('should not track queries if turned off', function () {
|
||||||
testee.properties({
|
testee.properties({
|
||||||
|
@ -165,7 +178,15 @@ describe('AQL query analyzer', function () {
|
||||||
|
|
||||||
sendQuery(1, false);
|
sendQuery(1, false);
|
||||||
expect(testee.current().filter(filterQueries).length).to.equal(0);
|
expect(testee.current().filter(filterQueries).length).to.equal(0);
|
||||||
expect(testee.slow().filter(filterQueries).length).to.equal(1);
|
let queries = testee.slow().filter(filterQueries);
|
||||||
|
expect(queries.length).to.equal(1);
|
||||||
|
expect(queries[0]).to.have.property('id');
|
||||||
|
expect(queries[0]).to.have.property('query', query);
|
||||||
|
expect(queries[0]).to.have.property('bindVars');
|
||||||
|
expect(queries[0].bindVars).to.eql({});
|
||||||
|
expect(queries[0]).to.have.property('started');
|
||||||
|
expect(queries[0]).to.have.property('runTime');
|
||||||
|
expect(queries[0]).to.have.property('state', 'finished');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to clear the list of slow queries', function () {
|
it('should be able to clear the list of slow queries', function () {
|
||||||
|
|
Loading…
Reference in New Issue