From 923f4542cffece28dbb797f8cf309f5a44a2789c Mon Sep 17 00:00:00 2001 From: Omri Zeneva Date: Wed, 11 May 2022 09:39:49 -0400 Subject: [PATCH] rgw: add functionality of SetAttribute and AddEvent method in postRequest context opentelemetry supports mainly string, int64, double and boolean for values of trace's Attributes, so we should validate those types and static cast to the proper type, which is different than Lua types SetAttribute Closure will be returned to lua only if the request's trace is real and not noop span or even null like what happens in preRequest Context AddEvent method comes to give us the ability to record an event. the event can be a single string that represents the event, or event name and key-value pairs. Signed-off-by: Omri Zeneva --- src/common/tracer.h | 9 ++++- src/rgw/rgw_lua_request.cc | 80 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/src/common/tracer.h b/src/common/tracer.h index 5d77a0dcf159c..9d13c78aafcee 100644 --- a/src/common/tracer.h +++ b/src/common/tracer.h @@ -11,6 +11,7 @@ using jspan = opentelemetry::nostd::shared_ptr; using jspan_context = opentelemetry::trace::SpanContext; +using jspan_attribute = opentelemetry::common::AttributeValue; namespace tracing { @@ -54,12 +55,13 @@ void decode(jspan_context& span_ctx, ceph::buffer::list::const_iterator& bl); #include - class Value { public: template Value(T val) {} }; +using jspan_attribute = Value; + struct jspan_context { jspan_context() {} jspan_context(bool sampled_flag, bool is_remote) {} @@ -69,9 +71,12 @@ struct span_stub { jspan_context _ctx; template void SetAttribute(std::string_view key, const T& value) const noexcept {} - void AddEvent(std::string_view, std::initializer_list> fields) {} + void AddEvent(std::string_view) {} + void AddEvent(std::string_view, std::initializer_list> fields) {} + template void AddEvent(std::string_view name, const T& fields = {}) {} const jspan_context& GetContext() { return _ctx; } void UpdateName(std::string_view) {} + bool IsRecording() { return false; } }; class jspan { diff --git a/src/rgw/rgw_lua_request.cc b/src/rgw/rgw_lua_request.cc index 58baa48b70e79..242ed9fa98b90 100644 --- a/src/rgw/rgw_lua_request.cc +++ b/src/rgw/rgw_lua_request.cc @@ -41,6 +41,80 @@ int RequestLog(lua_State* L) return ONE_RETURNVAL; } +int SetAttribute(lua_State* L) { + auto s = reinterpret_cast(lua_touserdata(L, lua_upvalueindex(1))); + + if (!s->trace || !s->trace->IsRecording()) { + return 0; + } + + auto key = luaL_checkstring(L, 1); + int value_type = lua_type(L, 2); + + switch (value_type) { + case LUA_TSTRING: + s->trace->SetAttribute(key, lua_tostring(L, 2)); + break; + + case LUA_TNUMBER: + if (lua_isinteger(L, 2)) { + s->trace->SetAttribute(key, static_cast(lua_tointeger(L, 2))); + } else { + s->trace->SetAttribute(key, static_cast(lua_tonumber(L, 2))); + } + break; + + default: + luaL_error(L, "unsupported value type for SetAttribute"); + } + return 0; +} + +int AddEvent(lua_State* L) { + auto s = reinterpret_cast(lua_touserdata(L, lua_upvalueindex(1))); + + if (!s->trace || !s->trace->IsRecording()) { + return 0; + } + + int args = lua_gettop(L); + if (args == 1) { + auto log = luaL_checkstring(L, 1); + s->trace->AddEvent(log); + } else if(args == 2) { + auto event_name = luaL_checkstring(L, 1); + std::unordered_map event_values; + lua_pushnil(L); + while (lua_next(L, 2) != 0) { + if (lua_type(L, -2) != LUA_TSTRING) { + // skip pair if key is not a string + lua_pop(L, 1); + continue; + } + + auto key = luaL_checkstring(L, -2); + int value_type = lua_type(L, -1); + switch (value_type) { + case LUA_TSTRING: + event_values.emplace(key, lua_tostring(L, -1)); + break; + + case LUA_TNUMBER: + if (lua_isinteger(L, -1)) { + event_values.emplace(key, static_cast(lua_tointeger(L, -1))); + } else { + event_values.emplace(key, static_cast(lua_tonumber(L, -1))); + } + break; + } + lua_pop(L, 1); + } + lua_pop(L, 1); + s->trace->AddEvent(event_name, event_values); + } + return 0; +} + struct ResponseMetaTable : public EmptyMetaTable { static std::string TableName() {return "Response";} static std::string Name() {return TableName() + "Meta";} @@ -159,6 +233,12 @@ struct TraceMetaTable : public EmptyMetaTable { if (strcasecmp(index, "Enable") == 0) { lua_pushboolean(L, s->trace_enabled); + } else if(strcasecmp(index, "SetAttribute") == 0) { + lua_pushlightuserdata(L, s); + lua_pushcclosure(L, SetAttribute, ONE_UPVAL); + } else if(strcasecmp(index, "AddEvent") == 0) { + lua_pushlightuserdata(L, s); + lua_pushcclosure(L, AddEvent, ONE_UPVAL); } else { return error_unknown_field(L, index, TableName()); } -- 2.39.5