Skip to content

Commit

Permalink
Merge pull request yangxikun#25 from plantfansam/baggage
Browse files Browse the repository at this point in the history
Add Baggage and Propagator
  • Loading branch information
yangxikun authored Aug 16, 2022
2 parents d098645 + 1973ede commit 5bb51c9
Show file tree
Hide file tree
Showing 12 changed files with 1,150 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ openresty-unit-test:
$(CONTAINER_ORCHESTRATOR) exec $(CONTAINER_ORCHESTRATOR_EXEC_OPTIONS) -- openresty bash -c 'cd /opt/opentelemetry-lua && prove -r'

lua-unit-test:
$(CONTAINER_ORCHESTRATOR) run $(CONTAINER_ORCHESTRATOR_EXEC_OPTIONS) -- openresty-test bash -c 'cd /opt/opentelemetry-lua && ./busted-runner'
$(CONTAINER_ORCHESTRATOR) run $(CONTAINER_ORCHESTRATOR_EXEC_OPTIONS) -- openresty-test bash -c 'cd /opt/opentelemetry-lua && ./busted-runner'

openresty-build:
$(CONTAINER_ORCHESTRATOR) build
2 changes: 1 addition & 1 deletion busted-runner
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package.path = './lib/?.lua;./lib/?/?.lua;./lib/?/init.lua' .. package.path

_TEST = true
_RUN_SLOW_TESTS = os.getenv("RUN_SLOW_TESTS") or false
_RUN_SLOW_TESTS = true

-- Set up global tracer
Global = require("opentelemetry.global")
Expand Down
67 changes: 67 additions & 0 deletions lib/opentelemetry/baggage.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
local util = require("opentelemetry.util")

local _M = {
}

local mt = {
__index = _M
}

function _M.new(values)
return setmetatable({ values = values or {} }, mt)
end

--------------------------------------------------------------------------------
-- Set a value in a baggage instance. Does _not_ inject into context
--
-- @name name for which to set the value in baggage
-- @value value to set must be string
-- @metadata metadata to set in baggage (string)
-- @return baggage
--------------------------------------------------------------------------------
function _M.set_value(self, name, value, metadata)
local new_values = util.shallow_copy_table(self.values)
new_values[name] = { value = value, metadata = metadata }
return self.new(new_values)
end

--------------------------------------------------------------------------------
-- Get value stored at a specific name in a baggage instance
--
-- @name name for which to set the value in baggage
-- @return baggage
--------------------------------------------------------------------------------
function _M.get_value(self, name)
if self.values[name] then
return self.values[name].value
else
return nil
end
end

--------------------------------------------------------------------------------
-- Remove value stored at a specific name in a baggage instance.
--
-- @name name to remove from baggage
-- @return baggage
--------------------------------------------------------------------------------
function _M.remove_value(self, name)
local new_values = util.shallow_copy_table(self.values)
new_values[name] = nil
return self.new(new_values)
end

--------------------------------------------------------------------------------
-- Get all values in a baggage instance. This is supposed to return an immutable
-- collection, but we just return a copy of the table stored at values.
--
-- @context context from which to access the baggage (defaults to
-- current context)
-- @return table like { keyname = { value = "value",
-- metadata = "metadatastring"} }
--------------------------------------------------------------------------------
function _M.get_all_values(self)
return util.shallow_copy_table(self.values)
end

return _M
123 changes: 123 additions & 0 deletions lib/opentelemetry/baggage/propagation/text_map/baggage_propagator.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
--------------------------------------------------------------------------------
--
-- See https://w3c.github.io/baggage/ for details.
--
--------------------------------------------------------------------------------

local baggage = require("opentelemetry.baggage")
local text_map_getter = require("opentelemetry.trace.propagation.text_map.getter")
local text_map_setter = require("opentelemetry.trace.propagation.text_map.setter")
local util = require("opentelemetry.util")

local _M = {
}

local mt = {
__index = _M,
}

local baggage_header = "baggage"

function _M.new()
return setmetatable(
{
text_map_setter = text_map_setter.new(),
text_map_getter = text_map_getter.new()
}, mt)
end

-------------=------------------------------------------------------------------
-- Set baggage header on outbound HTTP request header.
--
-- @param context context storage
-- @param carrier nginx request
-- @param setter setter for interacting with carrier
-- @return nil
--------------------------------------------------------------------------------
function _M:inject(context, carrier, setter)
setter = setter or self.text_map_setter
local bgg = context:extract_baggage()
local header_string = ""
for k, v in pairs(bgg.values) do
local element = k .. "=" .. v.value
if v.metadata then
element = element .. ";" .. v.metadata
end
element = element .. ","
header_string = header_string .. element
end

-- trim trailing comma
header_string = header_string:sub(0, -2)

setter.set(
carrier,
baggage_header,
util.percent_encode_baggage_string(header_string)
)
end

--------------------------------------------------------------------------------
-- Extract baggage from HTTP request headers.
--
-- @context current context
-- @carrier ngx.req
-- @return new context with baggage associated
--------------------------------------------------------------------------------
function _M:extract(context, carrier, getter)
getter = getter or self.text_map_getter
local baggage_string = getter.get(carrier, baggage_header)
if not baggage_string then
return context.new(context.entries)
else
baggage_string = util.decode_percent_encoded_string(baggage_string)
end

local baggage_entries = {}
-- split apart string on comma and build up baggage entries
for list_member in string.gmatch(baggage_string, "([^,]+)") do
-- extract metadata from each list member
local kv, metadata = string.match(list_member, "([^;]+);(.*)")

-- If there's no semicolon in list member, then kv and metadata are nil
-- and we need to correct that
if not kv then
kv = list_member
metadata = ""
end

-- split apart k/v on equals sign
for k, v in string.gmatch(kv, "(.+)=(.+)") do
if self.validate_baggage(k, v) then
baggage_entries[k] = { value = v, metadata = metadata }
else
ngx.log(ngx.WARN, "invalid baggage entry: " .. k .. "=" .. v)
end
end
end

local extracted_baggage = baggage.new(baggage_entries)
return context:inject_baggage(extracted_baggage)
end

--------------------------------------------------------------------------------
-- Check to see if baggage has both key and value component
--
-- @key baggage key
-- @value baggage value
-- @return boolean
--------------------------------------------------------------------------------
function _M.validate_baggage(key, value)
return (key and value) ~= nil
end

--------------------------------------------------------------------------------
-- Fields that will be used by the propagator
--
-- @return table
--------------------------------------------------------------------------------
function _M.fields()
return { "baggage" }
end

return _M
22 changes: 21 additions & 1 deletion lib/opentelemetry/context.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local baggage = require("opentelemetry.baggage")
local otel_global = require("opentelemetry.global")
local non_recording_span_new = require("opentelemetry.trace.non_recording_span").new
local noop_span = require("opentelemetry.trace.noop_span")
Expand All @@ -11,7 +12,7 @@ local mt = {
}

local context_key = "__opentelemetry_context__"

local baggage_context_key = "__opentelemetry_baggage__"

--------------------------------------------------------------------------------
-- Create new context with set of entries
Expand Down Expand Up @@ -92,6 +93,25 @@ function _M.set(self, key, value)
return self.new(vals, self.sp)
end

--------------------------------------------------------------------------------
-- Inject baggage into current context
--
-- @baggage baggage instance to inject
-- @return context
--------------------------------------------------------------------------------
function _M.inject_baggage(self, baggage)
return self:set(baggage_context_key, baggage)
end

--------------------------------------------------------------------------------
-- Extract baggage from context
--
-- @return baggage
--------------------------------------------------------------------------------
function _M.extract_baggage(self)
return self:get(baggage_context_key) or baggage.new({})
end

function _M.with_span(self, span)
return self.new({}, span)
end
Expand Down
Loading

0 comments on commit 5bb51c9

Please sign in to comment.