Finish the basic structure of nginx.conf
diff --git a/examples/nginx.conf b/examples/nginx.conf
index 8540267..84feefc 100644
--- a/examples/nginx.conf
+++ b/examples/nginx.conf
@@ -33,6 +33,9 @@
server {
listen 8080;
+ # This is for local dev only, please do not add this in any production env.
+ lua_code_cache off;
+
location /ingress {
default_type text/html;
rewrite_by_lua_block {
@@ -50,19 +53,46 @@
end
local contextCarrier = {}
- local exitSpan = tracingContext:createExitSpan("exit_op", nil, "127.0.0.1", contextCarrier)
+ contextCarrier["sw6"] = ngx.req.get_headers()["sw6"]
+ local entrySpan = tracingContext:createEntrySpan(ngx.var.uri, nil, contextCarrier)
+ entrySpan:start(ngx.now())
+
+ contextCarrier = {}
+ -- Use the same URI to represent incoming and forwarding requests
+ -- Change it if you need.
+ local upstreamUri = ngx.var.uri
+ -- This variable represents the upstream logic address
+ -- Please set them as service logic name or DNS name
+ local upstreamServerName = "upstream_ip:port"
+ local exitSpan = tracingContext:createExitSpan(upstreamUri, entrySpan, upstreamServerName, contextCarrier)
+ entrySpan:start(ngx.now())
+
for name, value in pairs(contextCarrier) do
ngx.req.set_header(name, value)
end
-- Push the data in the context
+ ngx.ctx.tracingContext = tracingContext
+ ngx.ctx.entrySpan = entrySpan
ngx.ctx.exitSpan = exitSpan
}
proxy_pass http://127.0.0.1:8080/backend;
body_filter_by_lua_block {
- ngx.log(ngx.ERR, 'span exist? ' .. ngx.ctx.exitSpan.span_id)
+ -- Finish the exit span when received the first response package from upstream
+ if ngx.ctx.exitSpan ~= nil then
+ ngx.ctx.exitSpan:finish()
+ ngx.ctx.exitSpan = nil
+ end
+ }
+
+ log_by_lua_block {
+ if ngx.ctx.entrySpan ~= nil then
+ ngx.ctx.entrySpan:finish()
+ local status, segment = ngx.ctx.tracingContext:drainAfterFinished()
+ ngx.log(ngx.ERR, 'span exist? ' .. segment.spans[1].start_time)
+ end
}
}
diff --git a/lib/skywalking/segment.lua b/lib/skywalking/segment.lua
new file mode 100644
index 0000000..3b64229
--- /dev/null
+++ b/lib/skywalking/segment.lua
@@ -0,0 +1,36 @@
+--
+-- 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.
+--
+
+-- Segment represents a finished tracing context
+-- Including all information to send to the SkyWalking OAP server.
+
+local Segment = {
+ trace_id,
+ segment_id,
+ service_inst_id,
+ spans,
+}
+
+function Segment:new()
+ local o = {}
+ setmetatable(o, self)
+ self.__index = self
+
+ return o
+end
+
+return Segment
\ No newline at end of file
diff --git a/lib/skywalking/span.lua b/lib/skywalking/span.lua
index 9f66ec2..deffd50 100644
--- a/lib/skywalking/span.lua
+++ b/lib/skywalking/span.lua
@@ -163,12 +163,39 @@
end
---- All belowing are instance methods
-function Span:finish()
+
+-- Set start time explicitly
+function Span:start(startTime)
if self.is_noop then
return self
end
- self.end_time = Util.timestamp()
+ self.start_time = startTime
+
+ return self
+end
+
+function Span:finishWithDuration(duration)
+ if self.is_noop then
+ return self
+ end
+
+ self:finish(self.start_time + duration)
+
+ return self
+end
+
+-- @param endTime, optional.
+function Span:finish(endTime)
+ if self.is_noop then
+ return self
+ end
+
+ if endTime == nil then
+ self.end_time = Util.timestamp()
+ else
+ self.end_time = endTime
+ end
self.owner.internal:finishSpan(self)
return self
diff --git a/lib/skywalking/span_test.lua b/lib/skywalking/span_test.lua
index fea35a1..d005d44 100644
--- a/lib/skywalking/span_test.lua
+++ b/lib/skywalking/span_test.lua
@@ -104,6 +104,18 @@
lu.assertEquals(span1.parent_span_id, -1)
lu.assertEquals(span1.span_id, 0)
end
+
+ function TestSpan:testProperties()
+ local context = TC:new(1)
+
+ local span1 = Span:new("operation_name", context, nil)
+ span1:start(1234567)
+ lu.assertEquals(span1.start_time, 1234567)
+ span1:finish(2222222)
+ lu.assertEquals(span1.end_time, 2222222)
+ span1:finishWithDuration(123)
+ lu.assertEquals(span1.end_time, 1234690)
+ end
-- end TestSpan
diff --git a/lib/skywalking/tracing_context.lua b/lib/skywalking/tracing_context.lua
index c4dcc3d..52ff9b8 100644
--- a/lib/skywalking/tracing_context.lua
+++ b/lib/skywalking/tracing_context.lua
@@ -17,6 +17,7 @@
local Util = require('util')
local Span = require('span')
+local Segment = require('segment')
local TracingContext = {
trace_id,
@@ -97,14 +98,23 @@
-- 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, list SpanList).
--- SpanList has value only when the isSegmentFinished is true
+-- 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
- return true, self.internal.finished_spans
+ local segment = Segment:new()
+ segment.trace_id = self.trace_id
+ segment.segment_id = self.segment_id
+ segment.service_inst_id = self.service_inst_id
+ segment.spans = self.internal.finished_spans
+ return true, segment
end
end
@@ -158,7 +168,7 @@
-- 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
- table.insert(self.finished_spans, span)
+ self.finished_spans[#self.finished_spans + 1] = span
return self.owner
end
diff --git a/lib/skywalking/tracing_context_test.lua b/lib/skywalking/tracing_context_test.lua
index d665850..50f127f 100644
--- a/lib/skywalking/tracing_context_test.lua
+++ b/lib/skywalking/tracing_context_test.lua
@@ -66,9 +66,9 @@
lu.assertEquals(#(activeSpans), 0)
lu.assertEquals(#(finishedSpans), 2)
- local isSegmentFinished, spanList = context:drainAfterFinished()
- lu.assertEquals(span2, spanList[1])
- lu.assertEquals(span1, spanList[2])
+ local isSegmentFinished, segment = context:drainAfterFinished()
+ lu.assertEquals(span2, segment.spans[1])
+ lu.assertEquals(span1, segment.spans[2])
end
function TestTracingContext:testNewNoOP()