blob: 78976b79f10481093f10940e28cc006d6fa2eaba [file] [log] [blame]
--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
local Util = require('util')
local Span = require('span')
local Segment = require('segment')
local TracingContext = {
trace_id,
segment_id,
service_id,
service_inst_id,
is_noop = false,
internal,
}
-------------- Internal Object-------------
-- Internal Object hosts the methods for SkyWalking LUA internal APIs only.
local Internal = {
self_generated_trace_id,
-- span id starts from 0
span_id_seq,
-- Owner means the Context instance holding this Internal object.
owner,
-- The first created span.
first_span,
-- The first ref injected in this context
first_ref,
-- Created span and still active
active_spans,
active_count,
-- Finished spans
finished_spans,
}
function TracingContext:new(serviceId, serviceInstID)
local o = {}
setmetatable(o, self)
self.__index = self
if serviceInstID == nil then
return TracingContext:newNoOP()
end
o.trace_id = Util:newID()
o.segment_id = o.trace_id
o.service_id = serviceId
o.service_inst_id = serviceInstID
o.internal = Internal:new()
o.internal.owner = o
return o
end
function TracingContext:newNoOP()
local o = {}
setmetatable(o, self)
self.__index = self
o.is_noop = true
return o
end
-- Delegate to Span:createEntrySpan
-- @param contextCarrier could be nil if there is no downstream propagated context
function TracingContext:createEntrySpan(operationName, parent, contextCarrier)
if self.is_noop then
return Span:newNoOP()
end
return Span:createEntrySpan(operationName, self, parent, contextCarrier)
end
-- Delegate to Span:createExitSpan
-- @param contextCarrier could be nil if don't need to inject any context to propagate
function TracingContext:createExitSpan(operationName, parent, peer, contextCarrier)
if self.is_noop then
return Span:newNoOP()
end
return Span:createExitSpan(operationName, self, parent, peer, contextCarrier)
end
-- After all active spans finished, this segment will be treated as finished status.
-- Notice, it is different with Java agent, a finished context is still able to recreate new span, and be checked as finished again.
-- This gives the end user more flexibility. Unless it is a real reasonable case, don't call #drainAfterFinished multiple times.
--
-- Return (boolean isSegmentFinished, Segment segment).
-- Segment has value only when the isSegmentFinished is true
-- if isSegmentFinished == false, SpanList = nil
function TracingContext:drainAfterFinished()
if self.is_noop then
return true, Segment:new()
end
if self.internal.active_count ~= 0 then
return false, nil
else
local segment = Segment:new()
segment.trace_id = self.trace_id
segment.segment_id = self.segment_id
segment.service_id = self.service_id
segment.service_inst_id = self.service_inst_id
segment.spans = self.internal.finished_spans
return true, segment
end
end
-------------- Internal Object-------------
-- Internal Object hosts the methods for SkyWalking LUA internal APIs only.
-- Create an internal instance
function Internal:new()
local o = {}
setmetatable(o, self)
self.__index = self
o.self_generated_trace_id = true
o.span_id_seq = 0
o.active_spans = {}
o.active_count = 0
o.finished_spans = {}
return o
end
-- add the segment ref if this is the first ref of this context
function Internal:addRefIfFirst(ref)
if self.self_generated_trace_id == true then
self.self_generated_trace_id = false
self.owner.trace_id = ref.trace_id
self.first_ref = ref
end
end
function Internal:hasRef()
return first_ref ~= nil
end
function Internal:getFirstRef()
return first_ref
end
function Internal:addActive(span)
if self.first_span == nil then
self.first_span = span
end
-- span id starts at 0, to fit LUA, we need to plus one.
self.active_spans[span.span_id + 1] = span
self.active_count = self.active_count + 1
return self.owner
end
function Internal:finishSpan(span)
-- span id starts at 0, to fit LUA, we need to plus one.
self.active_spans[span.span_id + 1] = nil
self.active_count = self.active_count - 1
self.finished_spans[#self.finished_spans + 1] = span
return self.owner
end
-- Generate the next span ID.
function Internal:nextSpanID()
local nextSpanId = self.span_id_seq
self.span_id_seq = self.span_id_seq + 1;
return nextSpanId
end
---------------------------------------------
return TracingContext