before lua script is being executed, we keep the tracer runtime configuration value, and then decides whether to trace or not the request based on the value that maybe changed during lua exeuction, so we can disable/enable tracing for request even if the tracer is in the opposite state at the same time
Signed-off-by: Omri Zeneva <ozeneva@redhat.com>
+----------------------------------------------------+----------+--------------------------------------------------------------+----------+-----------+----------+
| ``Request.User.Id`` | string | triggering user id | no | no | no |
+----------------------------------------------------+----------+--------------------------------------------------------------+----------+-----------+----------+
+| ``Request.Trace`` | table | info on trace | no | no | no |
++----------------------------------------------------+----------+--------------------------------------------------------------+----------+-----------+----------+
+| ``Request.Trace.Enable`` | boolean | tracing is enabled | no | yes | no |
++----------------------------------------------------+----------+--------------------------------------------------------------+----------+-----------+----------+
Request Functions
--------------------
assert(s:close())
end
+
+- Trace only requests of specific bucket
+
+Tracing is disabled by default, so we should enable tracing for this specific bucket
+
+.. code-block:: lua
+
+ if Request.Bucket.Name == "my-bucket" then
+ Request.Trace.Enable = true
+ end
+
+
+If `tracing is enabled <https://docs.ceph.com/en/latest/jaegertracing/#how-to-enable-tracing-in-ceph/>`_ on the RGW, the value of Request.Trace.Enable is true, so we should disable tracing for all other requests that do not match the bucket name.
+In the `preRequest` context:
+
+.. code-block:: lua
+
+ if Request.Bucket.Name ~= "my-bucket" then
+ Request.Trace.Enable = false
+ end
+
+Note that changing `Request.Trace.Enable` does not change the tracer's state, but disables or enables the tracing for the request only.
+
return noop_tracer->StartSpan(trace_name);
}
+jspan Tracer::start_trace(opentelemetry::nostd::string_view trace_name, bool trace_is_enabled) {
+ if (trace_is_enabled) {
+ return tracer->StartSpan(trace_name);
+ }
+ return noop_tracer->StartSpan(trace_name);
+}
+
jspan Tracer::add_span(opentelemetry::nostd::string_view span_name, const jspan& parent_span) {
- if (is_enabled() && parent_span) {
+ if (is_enabled() && parent_span->IsRecording()) {
const auto parent_ctx = parent_span->GetContext();
return add_span(span_name, parent_ctx);
}
// creates and returns a new span with `trace_name`
// this span represents a trace, since it has no parent.
jspan start_trace(opentelemetry::nostd::string_view trace_name);
+
+ // creates and returns a new span with `trace_name`
+ // if false is given to `trace_is_enabled` param, noop span will be returned
+ jspan start_trace(opentelemetry::nostd::string_view trace_name, bool trace_is_enabled);
+
// creates and returns a new span with `span_name` which parent span is `parent_span'
jspan add_span(opentelemetry::nostd::string_view span_name, const jspan& parent_span);
// creates and return a new span with `span_name`
struct Tracer {
bool is_enabled() const { return false; }
- jspan start_trace(std::string_view) { return {}; }
+ jspan start_trace(std::string_view, bool enabled = true) { return {}; }
jspan add_span(std::string_view, const jspan&) { return {}; }
jspan add_span(std::string_view span_name, const jspan_context& parent_ctx) { return {}; }
void init(std::string_view service_name) {}
std::vector<rgw::IAM::Policy> session_policies;
jspan trace;
+ bool trace_enabled = false;
//Principal tags that come in as part of AssumeRoleWithWebIdentity
std::vector<std::pair<std::string, std::string>> principal_tags;
}
};
+struct TraceMetaTable : public EmptyMetaTable {
+ static std::string TableName() {return "Trace";}
+ static std::string Name() {return TableName() + "Meta";}
+
+ static int IndexClosure(lua_State* L) {
+ const auto s = reinterpret_cast<req_state*>(lua_touserdata(L, lua_upvalueindex(1)));
+
+ const char* index = luaL_checkstring(L, 2);
+
+ if (strcasecmp(index, "Enable") == 0) {
+ lua_pushboolean(L, s->trace_enabled);
+ } else {
+ return error_unknown_field(L, index, TableName());
+ }
+ return ONE_RETURNVAL;
+ }
+
+ static int NewIndexClosure(lua_State* L) {
+ const auto s = reinterpret_cast<req_state*>(lua_touserdata(L, lua_upvalueindex(1)));
+
+ const char* index = luaL_checkstring(L, 2);
+
+ if (strcasecmp(index, "Enable") == 0) {
+ s->trace_enabled = lua_toboolean(L, 3);
+ } else {
+ return error_unknown_field(L, index, TableName());
+ }
+ return NO_RETURNVAL;
+ }
+};
+
struct OwnerMetaTable : public EmptyMetaTable {
static std::string TableName() {return "Owner";}
static std::string Name() {return TableName() + "Meta";}
} else {
create_metatable<UserMetaTable>(L, false, const_cast<rgw_user*>(&(s->user->get_id())));
}
+ } else if (strcasecmp(index, "Trace") == 0) {
+ create_metatable<TraceMetaTable>(L, false, s);
} else {
return error_unknown_field(L, index, TableName());
}
void RGWInitMultipart::execute(optional_yield y)
{
+ multipart_trace = tracing::rgw::tracer.start_trace(tracing::rgw::MULTIPART, s->trace_enabled);
bufferlist aclbl, tracebl;
rgw::sal::Attrs attrs;
RGWInitMultipart() {}
void init(rgw::sal::Store* store, struct req_state *s, RGWHandler *h) override {
- multipart_trace = tracing::rgw::tracer.start_trace(tracing::rgw::MULTIPART);
RGWOp::init(store, s, h);
policy.set_ctx(s->cct);
}
goto done;
}
{
+ s->trace_enabled = tracing::rgw::tracer.is_enabled();
std::string script;
auto rc = rgw::lua::read_script(s, store, s->bucket_tenant, s->yield, rgw::lua::context::preRequest, script);
if (rc == -ENOENT) {
goto done;
}
+
const auto trace_name = std::string(op->name()) + " " + s->trans_id;
- s->trace = tracing::rgw::tracer.start_trace(trace_name);
+ s->trace = tracing::rgw::tracer.start_trace(trace_name, s->trace_enabled);
s->trace->SetAttribute(tracing::rgw::OP, op->name());
s->trace->SetAttribute(tracing::rgw::TYPE, tracing::rgw::REQUEST);