本模块用于Trace相关能力接口的lua层隔离,以实现Lua层、封装层、开源引入层,Lua层与封装层、开源引入层隔离,Lua层与封装层之间通过弱引用隔离,在无法require到封装库时,Lua层提供空对象空接口保护业务不受影响
tracer创建
tracer是Trace能力构建中最初一环,业务需要持有tracer用于创建span,利用span的记录存储上报能力构建跨服务跟踪链路,目前组件初始化过程中自动以组件名作为tracer name创建tracer并存储,组件后续调用get_tracer()将直接返回tracer,组件也可以通过传入参数name新建tracer。
-- 方法原型
local tracer = trace.get_tracer(name, version, url)
-- 使用示例
local trace = require 'telemetry.trace'
local name = ...
local trace_custom = trace.get_tracer(name, '1.0.0')
local trace_default = tracer.get_tracer()req:
name: 必选参数,string类型,tracer名称,一般使用库名称. e.g."hwdiscovery"。version: 可选参数,string类型,库版本. e.g."1.0.0"。url: 可选参数,string类型,指向语义约定文档,用于属性命名规范. e.g."https://xxx/"。
rsp:
tracer:userdata类型,由业务持有并调用start_span进行span创建,然后进行后续操作;msg:string类型,错误信息,由业务选择是否接收,会返回失败的具体信息,若成功则不返回。
span创建
span是跟踪链路中的最小功能单元,生命周期一般为单个函数或代码块,业务在需要跟踪的位置创建span,并通过span提供的能力进行数据跟踪,在生命周期结束后进行上报,后台根据上报span间的关联将不同服务上报的span整合为一条完整的跟踪链路。
-- 方法原型
local child_span = tracer:start_span(name, attribute, options)
local child_span_opt = trace.start_span(name, attribute, options)
-- 使用示例
function get_object()
local root_span = tracer:start_span("get_object", {"level": "notice", "opcode": 1})
local parent_span_context = root_span:get_context()
local child_span = tracer:start_span("get_object", {"level": "notice", "opcode": 1}, {parent = parent_span_context})
-- 支持不通过tracer直接创建span,trace会自动获取当前组件名与组件版本创建tracer
local child_span_opt = trace.start_span("get_object", {"level": "notice", "opcode": 1}, {parent = parent_span_context})
endreq:
name: 必选参数,string类型,span的名称,无需唯一性,span创建时回分配span_id作为唯一性标识,业务不感知. e.g. "get_object";attribute: 必选参数,字典类型,键必须为string,值只支持string、bool、int、double类型,span的属性,由用户根据需要使用,后续跟随span数据导出,可用于链路标记、数据筛选等. e.g.{"level": "notice", "opcode": 1};options: 可选参数,字典类型,代表span创建时的可选配置项。可选项有:parent: table类型,只能使用由span:get_context()导出的spancontext数据,传入时创建为child span,继承上级的trace_id, 不传入时创建为root span,作为整条跟踪链路的起始。force_sample: bool类型,作为组件自定义采样标记,在业务需要强制跟踪采样时传入true
rsp:
- span:
userdata类型,由业务持有并调用相关方法完成跟踪链路的构建,Lua层未引用到封装层或创建失败会返回一个noop span,进行的任何操作都不会生效,数据也不会上报; - msg:
string类型,错误信息,由业务选择是否接收,会返回失败的具体信息,若成功则不返回。
span操作
set_attribute 设置span属性
span属性后续跟随span数据导出,可用于链路标记,数据筛选等
-- 方法原型
span:set_attribute(key, value)
-- 使用示例
function get_object()
local span = trace.start_span(name, attribute)
span:set_attribute("level", "notice")
local err_msg = span:set_attribute(key, value)
local err_msg then
log:error("%s", err_msg)
end
endreq:
key: 必选参数,string类型,属性名称,若已存在该属性名,则该操作会修改原属性. e.g."level";value: 必选参数,支持string、bool、int、double类型,对应属性名的属性值。
rsp:
msg: string类型,错误信息,由业务选择是否接收,会返回失败的具体信息,若成功则不返回。
add_link 添加关联span
在span之间建立非父子关系的关联,一般为异步场景使用
-- 方法原型
span:add_link(span_context, attribute)
-- 使用示例
function get_object()
local span = trace.start_span(name, attribute)
span:add_link(span_context, {"level": "notice", "opcode": 1})
local err_msg = span:add_link(span_context, attribute)
local err_msg then
log:error("%s", err_msg)
end
endreq:
span_context: 必选参数,字典类型,只能使用由span:get_context()导出的spancontext数据;attribute: 可选参数,字典类型,键必须为string,值只支持string、bool、int、double类型,span的属性,添加links时的补充属性,由用户根据需要使用,后续跟随span数据作为links字段的额外字段导出. e.g.{"level": "notice", "opcode": 1}。
rsp:
msg:string类型,错误信息,由业务选择是否接收,会返回失败的具体信息,若成功则不返回。
add_event 添加span事件
在span中记录事件,类似日志记录操作,是用于可视化的主要部分。
-- 方法原型
span:add_event(name, attribute)
-- 使用示例
function get_object()
local span = trace.start_span(name, attribute)
span:add_event(string.format("get object failed: %s", ret), {"level": "notice", "opcode": 1})
local err_msg = span:add_event(name, attribute)
local err_msg then
log:error("%s", err_msg)
end
endreq:
name: 必选参数,string类型,事件描述信息,即日志记录内容. e.g."get object failed";attribute: 可选参数,字典类型,键必须为string,值只支持string、bool、int、double类型,添加event时的补充属性,添加event时的补充属性,由用户根据需要使用,后续跟随span数据作为event字段的额外字段导出. e.g.{"level": "notice", "opcode": 1}。
rsp:
msg:string类型,错误信息,由业务选择是否接收,会返回失败的具体信息,若成功则不返回。
set_status 设置当前span状态
设置当前span状态,默认状态为unset,支持unset、ok、error三种状态设置,span状态可用于尾部采样、可视化筛选等。
-- 方法原型
span:set_status(status, description)
-- 使用示例
function get_object()
local span = trace.start_span(name, attribute)
span:set_status("ok", "get object successed")
local err_msg = span:set_status(status, description)
local err_msg then
log:error("%s", err_msg)
end
endreq\
status: 必选参数,string类型,span状态,仅可设置description. e.g."ok";description: 可选参数,string类型,状态补充描述. e.g."get object successed"。
rsp\
msg:string类型,错误信息,由业务选择是否接收,会返回失败的具体信息,若成功则不返回。
get_context 获取当前span的上下文信息
获取当前span的上下文信息,用于后续span进行link或child span创建。
-- 方法原型
local context = span:get_context()
-- 使用示例
function get_object()
local span = trace.start_span(name, attribute)
local context = span:get_context()
local context, err_msg = span:get_context()
local err_msg then
log:error("%s", err_msg)
end
endrsp:
context:span的上下文信息,字典类型,组成字段为trace_id,span_id,trace_state,is_remoting,trace_flags, 业务不感知具体信息,仅用来传递,禁止修改context内容,否则会导致下级span链接失败;msg:string类型,错误信息,由业务选择是否接收,会返回失败的具体信息,若成功则不返回。
is_recording 检查当前span是否可操作
采样策略制定、发生错误等都会导致创建span失败而返回no operation span,当业务需要记录的内容需要通过耗时或资源占用等方式获取,可以通过该方法进行判断是否需要收集记录信息。
-- 方法原型
local is_recording = span:is_recording()
-- 使用示例
function get_object()
local span = trace.start_span(name, attribute)
if span:is_recording() then
span:add_event()
span:set_status()
end
endrsp:
is_recording:bool类型,反应当前span是否可操作,发生错误时则返回false
finish 结束当前span
结束当前span,自动触发存储或上报等操作。
-- 方法原型
span:finish()
-- 使用示例
function get_object()
local span = trace.start_span(name, attribute)
span:add_event()
span:set_status()
span:finish()
endpcall 执行方法并捕获执行状态并记录到span中进行上报
类似lua的pcall方法,保护调用之外,同时捕获函数内部的执行结果,刷新span状态为"ok"或"error"并上报, 并且会自动结束此次跟踪
-- 方法原型
span:pcall(cb, ...)
-- 使用示例
function get_object()
local span = trace.start_span(name, attribute)
local function record(time, msg)
if type(msg) ~= "string" then
error("msg must be string")
end
print(time, msg)
end
local ok, ret = span:pcall(record, time, msg)
endreq:
function: 必选参数,pcall进行保护调用的函数. e.g.function();param: 可选不定参数,保护调用函数的参数
rsp:
status:bool类型,表示函数是否成功执行(true表示成功,false表示失败)。result: 函数的返回值(如果成功)或错误信息(如果失败)