Skip to content

Commit 96f2246

Browse files
author
Garth Kidd
committed
WIP: configurable span tracking behaviour
1 parent 3af2473 commit 96f2246

File tree

4 files changed

+130
-4
lines changed

4 files changed

+130
-4
lines changed

config/config.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ if Mix.env() == :test do
88
report_dir: "reports/exunit"
99

1010
config :opencensus,
11+
process_context: Opencensus.ProcessContext.DefaultImplementation,
1112
reporters: [{Opencensus.TestSupport.SpanCaptureReporter, []}],
1213
send_interval_ms: 100
1314
end

lib/opencensus/process_context.ex

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
defmodule Opencensus.ProcessContext do
2+
@moduledoc """
3+
Experimental behaviour to control how the span context is tracked.
4+
5+
Use the matching methods in `Opencensus.ProcessContext.ConfiguredImplementation`.
6+
"""
7+
8+
@doc """
9+
Put the current context.
10+
11+
Returns the previous value.
12+
"""
13+
@callback put_span_ctx(span_ctx :: :opencensus.span_ctx() | :undefined) ::
14+
:opencensus.span_ctx() | :undefined
15+
16+
@doc """
17+
Get the current span context.
18+
19+
Implementations [SHOULD NOT] attempt recovery if the span context isn't where `c:put_span_ctx/1`
20+
should have put it. Callers [MAY] rely on this behaviour, using `c:put_span_ctx/1` to "put back"
21+
any value they got from `c:get_span_ctx/0`.
22+
23+
[SHOULD NOT]: https://tools.ietf.org/html/rfc2119#section-4
24+
[MAY]: https://tools.ietf.org/html/rfc2119#section-5
25+
"""
26+
@callback get_span_ctx() :: :opencensus.span_ctx() | :undefined
27+
28+
@doc """
29+
Recover the current span context by less reliable means.
30+
31+
Implementations [SHOULD] check `c:get_span_ctx/0` and return its value if not `:undefined`.
32+
33+
Callers [SHOULD] check `c:get_span_ctx/0` and avoid calling `c:recover_span_ctx/0` if possible.
34+
Callers [MUST NOT] pass a value obtained via `c:recover_span_ctx/0` to `c:put_span_ctx/1`.
35+
36+
[SHOULD]: https://tools.ietf.org/html/rfc2119#section-3
37+
[MUST NOT]: https://tools.ietf.org/html/rfc2119#section-2
38+
"""
39+
@callback recover_span_ctx() :: :opencensus.span_ctx() | :undefined
40+
end
41+
42+
defmodule Opencensus.ProcessContext.DefaultImplementation do
43+
@moduledoc "Process context behaviour matching the default implementation."
44+
45+
@behaviour Opencensus.ProcessContext
46+
47+
@impl true
48+
def put_span_ctx(span_ctx) do
49+
previous_span_ctx = get_span_ctx()
50+
Process.put(:oc_span_ctx_key, span_ctx)
51+
previous_span_ctx
52+
end
53+
54+
@impl true
55+
def get_span_ctx do
56+
Process.get(:oc_span_ctx_key, :undefined)
57+
end
58+
59+
@impl true
60+
def recover_span_ctx do
61+
get_span_ctx()
62+
end
63+
end

lib/opencensus/trace.ex

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ defmodule Opencensus.Trace do
4545
end
4646
```
4747
"""
48+
49+
@behaviour Opencensus.ProcessContext
50+
4851
defmacro with_child_span(label, attributes \\ quote(do: %{}), do: block) do
4952
line = __CALLER__.line
5053
module = __CALLER__.module
@@ -60,21 +63,22 @@ defmodule Opencensus.Trace do
6063
})
6164

6265
quote do
63-
parent_span_ctx = :ocp.current_span_ctx()
66+
previous_span_ctx = Opencensus.Trace.get_span_ctx()
67+
parent_span_ctx = Opencensus.Trace.effective_span_ctx()
6468

6569
new_span_ctx =
6670
:oc_trace.start_span(unquote(label), parent_span_ctx, %{
6771
:attributes => unquote(computed_attributes)
6872
})
6973

70-
_ = :ocp.with_span_ctx(new_span_ctx)
74+
_ = Opencensus.Trace.put_span_ctx(new_span_ctx)
7175
Opencensus.Logger.set_logger_metadata()
7276

7377
try do
7478
unquote(block)
7579
after
7680
_ = :oc_trace.finish_span(new_span_ctx)
77-
_ = :ocp.with_span_ctx(parent_span_ctx)
81+
_ = Opencensus.Trace.put_span_ctx(previous_span_ctx)
7882
Opencensus.Logger.set_logger_metadata()
7983
end
8084
end
@@ -166,4 +170,62 @@ defmodule Opencensus.Trace do
166170
"""
167171
@spec await(Task.t(), :infinity | pos_integer()) :: term()
168172
defdelegate await(task, timeout \\ 5000), to: Task
173+
174+
@doc """
175+
Put the current span context.
176+
177+
Replaces `:ocp.with_span_ctx/1`.
178+
179+
Callers [MAY] pass values from `get_span_ctx/0` to `put_span_ctx/1`.
180+
181+
Callers [MUST NOT] pass a value obtained via `recover_span_ctx/0` to `put_span_ctx/1`.
182+
183+
Uses the configured `process_context`. See also: `Opencensus.ProcessContext`.
184+
185+
[MAY]: https://tools.ietf.org/html/rfc2119#section-5
186+
"""
187+
@impl Opencensus.ProcessContext
188+
def put_span_ctx(span_ctx), do: process_context() |> apply(:put_span_ctx, [span_ctx])
189+
190+
@doc """
191+
Get the current span context.
192+
193+
Replaces `:ocp.current_span_ctx/0`, along with `recover_span_ctx/0`.
194+
195+
Callers [MAY] pass values from `get_span_ctx/0` to `put_span_ctx/1`.
196+
197+
Uses the configured `process_context`. See also: `Opencensus.ProcessContext`.
198+
199+
[MAY]: https://tools.ietf.org/html/rfc2119#section-5
200+
"""
201+
@impl Opencensus.ProcessContext
202+
def get_span_ctx, do: process_context() |> apply(:get_span_ctx, [])
203+
204+
@doc """
205+
Recover the current span context by less reliable means.
206+
207+
Replaces `:ocp.current_span_ctx/0`, along with `get_span_ctx/0`.
208+
209+
Callers [MUST NOT] pass a value obtained via `recover_span_ctx/0` to `put_span_ctx/1`.
210+
211+
Uses the configured `process_context`. See also: `Opencensus.ProcessContext`.
212+
"""
213+
@impl Opencensus.ProcessContext
214+
def recover_span_ctx, do: process_context() |> apply(:recover_span_ctx, [])
215+
216+
@doc false
217+
def effective_span_ctx do
218+
case get_span_ctx() do
219+
:undefined -> recover_span_ctx()
220+
span_ctx -> span_ctx
221+
end
222+
end
223+
224+
defp process_context do
225+
Application.get_env(
226+
:opencensus,
227+
:process_context,
228+
Opencensus.ProcessContext.DefaultImplementation
229+
)
230+
end
169231
end

test/opencensus_trace_async_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ defmodule Opencensus.AsyncTest do
4242
{inner, outer} =
4343
Trace.with_child_span "outside" do
4444
outer = :ocp.current_span_ctx() |> Span.load()
45-
Trace.async(M, :f, [outer]) |> Trace.await(10)
45+
M |> Trace.async(:f, [outer]) |> Trace.await(10)
4646
end
4747

4848
assert inner.trace_id == outer.trace_id

0 commit comments

Comments
 (0)