services:
- rgw
with_legacy: true
+- name: rgw_jaeger_enable
+ type: bool
+ level: advanced
+ desc: should RGW use jaeger tracing system
+ default: false
+ services:
+ - rgw
+ with_legacy: true
- name: rgw_s3_auth_use_keystone
type: bool
level: advanced
rgw_lua_utils.cc
rgw_lua.cc
rgw_lua_request.cc
- rgw_bucket_encryption.cc)
+ rgw_bucket_encryption.cc
+ rgw_tracer.cc)
if(WITH_RADOSGW_AMQP_ENDPOINT)
list(APPEND librgw_common_srcs rgw_amqp.cc)
endif()
if(WITH_JAEGER)
- add_dependencies(rgw_common jaegertracing::libjaegertracing)
+ add_dependencies(rgw_common jaeger-base)
endif()
if(WITH_RADOSGW_DBSTORE)
#include "cls/rgw/cls_rgw_types.h"
#include "include/rados/librados.hpp"
#include "rgw_public_access.h"
+#include "rgw_tracer.h"
namespace ceph {
class Formatter;
std::vector<rgw::IAM::Policy> session_policies;
+ jspan trace;
+
req_state(CephContext* _cct, RGWEnv* e, uint64_t id);
~req_state();
#include "rgw_notify_event_type.h"
#include "rgw_sal.h"
#include "rgw_sal_rados.h"
+#include "rgw_tracer.h"
#include "services/svc_zone.h"
#include "services/svc_quota.h"
rgw_placement_rule *pdest_placement = &s->dest_placement;
if (multipart) {
+ s->trace->SetTag(tracing::UPLOAD_ID, multipart_upload_id);
std::unique_ptr<rgw::sal::MultipartUpload> upload;
upload = store->get_multipart_upload(s->bucket.get(), s->object->get_name(),
multipart_upload_id);
if (op_ret == 0) {
upload_id = upload->get_upload_id();
}
+ s->trace->SetTag(tracing::UPLOAD_ID, upload_id);
}
upload = store->get_multipart_upload(s->bucket.get(), s->object->get_name(), upload_id);
+ s->trace->SetTag(tracing::UPLOAD_ID, upload_id);
RGWCompressionInfo cs_info;
bool compressed = false;
}
ldpp_dout(op, 2) << "verifying op permissions" << dendl;
- ret = op->verify_permission(y);
+ {
+ auto span = rgw_tracer.start_span("verify_permission", s->trace);
+ std::swap(span, s->trace);
+ ret = op->verify_permission(y);
+ std::swap(span, s->trace);
+ }
if (ret < 0) {
if (s->system_request) {
dout(2) << "overriding permissions due to system operation" << dendl;
op->pre_exec();
ldpp_dout(op, 2) << "executing" << dendl;
- op->execute(y);
+ {
+ auto span = rgw_tracer.start_span("execute", s->trace);
+ std::swap(span, s->trace);
+ op->execute(y);
+ std::swap(span, s->trace);
+ }
ldpp_dout(op, 2) << "completing" << dendl;
op->complete();
goto done;
}
+ const auto trace_name = std::string(op->name()) + " " + s->trans_id;
+ s->trace = rgw_tracer.start_trace(trace_name);
+ s->trace->SetTag(tracing::OP, op->name());
+ s->trace->SetTag(tracing::TYPE, tracing::REQUEST);
+
ret = rgw_process_authenticated(handler, op, req, s, yield);
if (ret < 0) {
abort_early(s, op, ret, handler, yield);
done:
if (op) {
+ s->trace->SetTag(tracing::RETURN, op->get_ret());
+ if (s->user) {
+ s->trace->SetTag(tracing::USER_ID, s->user->get_id().id);
+ }
+ if (s->bucket) {
+ s->trace->SetTag(tracing::BUCKET_NAME, s->bucket->get_name());
+ }
+ if (s->object) {
+ s->trace->SetTag(tracing::OBJECT_NAME, s->object->get_name());
+ }
std::string script;
auto rc = rgw::lua::read_script(s, store, s->bucket_tenant, s->yield, rgw::lua::context::postRequest, script);
if (rc == -ENOENT) {
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+#include "common/ceph_context.h"
+#include "global/global_context.h"
+#include "rgw_tracer.h"
+
+#ifdef HAVE_JAEGER
+
+thread_local tracing::Tracer rgw_tracer(jaeger_configuration::jaeger_default_config);
+
+namespace tracing {
+
+const std::shared_ptr<opentracing::Tracer> Tracer::noop_tracer = opentracing::MakeNoopTracer();
+
+Tracer::Tracer(jaegertracing::Config& conf):open_tracer(jaegertracing::Tracer::make(conf)) {}
+
+std::unique_ptr<opentracing::Span> Tracer::start_trace(opentracing::string_view trace_name) {
+ if(is_enabled()) {
+ return open_tracer->StartSpan(trace_name);
+ }
+ return noop_tracer->StartSpan(trace_name);
+}
+
+std::unique_ptr<opentracing::Span> Tracer::start_span(opentracing::string_view span_name, std::unique_ptr<opentracing::Span>& parent_span) {
+ if(is_enabled()) {
+ return open_tracer->StartSpan(span_name, { opentracing::ChildOf(&parent_span->context()) });
+ }
+ return noop_tracer->StartSpan(span_name);
+}
+
+bool Tracer::is_enabled() const {
+ return g_ceph_context->_conf->rgw_jaeger_enable;
+}
+} // namespace tracing
+
+namespace jaeger_configuration {
+
+jaegertracing::samplers::Config const_sampler("const", 1, "", 0, jaegertracing::samplers::Config::defaultSamplingRefreshInterval());
+
+jaegertracing::reporters::Config reporter_default_config(jaegertracing::reporters::Config::kDefaultQueueSize, jaegertracing::reporters::Config::defaultBufferFlushInterval(), true, jaegertracing::reporters::Config::kDefaultLocalAgentHostPort, "");
+
+jaegertracing::propagation::HeadersConfig headers_config("","","","");
+
+jaegertracing::baggage::RestrictionsConfig baggage_config(false, "", std::chrono::steady_clock::duration());
+
+jaegertracing::Config jaeger_default_config(false, const_sampler, reporter_default_config, headers_config, baggage_config, "rgw", std::vector<jaegertracing::Tag>());
+
+}
+
+#else // !HAVE_JAEGER
+
+tracing::Tracer rgw_tracer;
+
+#endif
+
\ No newline at end of file
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+#ifndef RGW_TRACER_H
+#define RGW_TRACER_H
+
+#ifdef HAVE_JAEGER
+
+#define SIGNED_RIGHT_SHIFT_IS 1
+#define ARITHMETIC_RIGHT_SHIFT 1
+#include <jaegertracing/Tracer.h>
+
+typedef std::unique_ptr<opentracing::Span> jspan;
+
+#else // !HAVE_JAEGER
+
+struct span_stub {
+ template <typename T>
+ void SetTag(std::string_view key, const T& value) const noexcept {}
+ void Log(std::initializer_list<std::pair<std::string_view, std::string_view>> fields) {}
+};
+
+class jspan {
+ span_stub span;
+ public:
+ span_stub& operator*() { return span; }
+ const span_stub& operator*() const { return span; }
+
+ span_stub* operator->() { return &span; }
+ const span_stub* operator->() const { return &span; }
+};
+
+#endif // !HAVE_JAEGER
+
+namespace tracing {
+
+const auto OP = "op";
+const auto BUCKET_NAME = "bucket_name";
+const auto USER_ID = "user_id";
+const auto OBJECT_NAME = "object_name";
+const auto RETURN = "return";
+const auto UPLOAD_ID = "upload_id";
+const auto TYPE = "type";
+const auto REQUEST = "request";
+
+#ifdef HAVE_JAEGER
+
+class Tracer {
+private:
+ const static std::shared_ptr<opentracing::Tracer> noop_tracer;
+ std::shared_ptr<opentracing::Tracer> open_tracer;
+
+public:
+ Tracer(jaegertracing::Config& conf);
+ bool is_enabled() const;
+ // creates and returns a new span with `trace_name`
+ // this span represents a trace, since it has no parent.
+ jspan start_trace(opentracing::string_view trace_name);
+ // creates and returns a new span with `trace_name` which parent span is `parent_span'
+ jspan start_span(opentracing::string_view span_name, jspan& parent_span);
+};
+
+#else // !HAVE_JAEGER
+
+struct Tracer {
+ bool is_enabled() const { return false; }
+ jspan start_trace(std::string_view) { return {}; }
+ jspan start_span(std::string_view, const jspan&) { return {}; }
+};
+
+#endif
+
+} // namespace tracing
+
+
+#ifdef HAVE_JAEGER
+
+extern thread_local tracing::Tracer rgw_tracer;
+
+namespace jaeger_configuration {
+
+extern jaegertracing::Config jaeger_default_config;
+
+}
+
+#else // !HAVE_JAEGER
+
+extern tracing::Tracer rgw_tracer;
+
+#endif
+
+#endif // RGW_TRACER_H
+
\ No newline at end of file