add_link/2 |
+add_handler/1 | Equivalent to add_handler(Handler, []). | add_handler/2 |
+Add new handler Module and pass Args as the configuration to
+Module:init/1 callback. | add_link/2 |
Add a Link to the list of Links in the span. | add_time_event/2 |
Add an Annotation or MessageEvent to the list of TimeEvents in a span. | add_time_event/3 | | annotation/2 |
Create an Annotation. | current_span_ctx/1 |
-Return the current span context in a Ctx or undefined . | finish_span/1 |
+Return the current span context in a Ctx or undefined . | delete_handler/1 |
+Delete handler marked by the Handler . | finish_span/1 |
Finish a span, setting the end_time. | from_ctx/1 |
Return the span context, if it exists, from Ctx. | is_enabled/1 |
Returns true if trace is enabled. | link/4 |
@@ -56,6 +59,34 @@ Set the current span context in a context to SpanCtx . |
+
+### add_handler/1 ###
+
+
+add_handler(Handler) -> ok | term()
+
+
+Handler = Module | {Module, Id} Module = module() Id = term()
+
+Equivalent to [`add_handler(Handler, [])`](#add_handler-2).
+
+
+
+### add_handler/2 ###
+
+
+add_handler(Handler, Args::term()) -> ok | term()
+
+
+Handler = Module | {Module, Id} Module = module() Id = term()
+
+Add new handler `Module` and pass `Args` as the configuration to
+`Module:init/1` callback.
+
+You can create multiple instances of the same `Module` handler by
+differentiating them with `Id` value.
+
### add_link/2 ###
@@ -111,12 +142,24 @@ current_span_ctx(Ctx::ctx:t()) ->
+
+### delete_handler/1 ###
+
+
+delete_handler(Handler) -> ok | term()
+
+
+Handler = Module | {Module, Id} Module = module() Id = term()
+
+Delete handler marked by the `Handler`.
+
### finish_span/1 ###
-finish_span(Span_ctx::maybe(opencensus:span_ctx())) -> boolean()
+finish_span(Span_ctx::maybe(opencensus:span_ctx())) -> ok | {error, invalid_span} | {error, no_report_buffer}
diff --git a/doc/oc_trace_pb.md b/doc/oc_trace_pb.md
deleted file mode 100644
index c7cd222..0000000
--- a/doc/oc_trace_pb.md
+++ /dev/null
@@ -1,510 +0,0 @@
-
-
-# Module oc_trace_pb #
-* [Data Types](#types)
-* [Function Index](#index)
-* [Function Details](#functions)
-
-
-
-## Data Types ##
-
-
-
-
-### 'opencensus.proto.trace.Span.Link.Type'() ###
-
-
-
-'opencensus.proto.trace.Span.Link.Type'() = TYPE_UNSPECIFIED | CHILD_LINKED_SPAN | PARENT_LINKED_SPAN
-
-
-
-
-
-### 'opencensus.proto.trace.Span.SpanKind'() ###
-
-
-
-'opencensus.proto.trace.Span.SpanKind'() = SPAN_KIND_UNSPECIFIED | SERVER | CLIENT
-
-
-
-
-
-### 'opencensus.proto.trace.Span.TimeEvent.MessageEvent.Type'() ###
-
-
-
-'opencensus.proto.trace.Span.TimeEvent.MessageEvent.Type'() = TYPE_UNSPECIFIED | SENT | RECEIVED
-
-
-
-
-
-### annotation_pb() ###
-
-
-
-annotation_pb() = #annotation_pb{}
-
-
-
-
-
-### attribute_value_pb() ###
-
-
-
-attribute_value_pb() = #attribute_value_pb{}
-
-
-
-
-
-### attributes_pb() ###
-
-
-
-attributes_pb() = #attributes_pb{}
-
-
-
-
-
-### bool_value_pb() ###
-
-
-
-bool_value_pb() = #bool_value_pb{}
-
-
-
-
-
-### bytes_value_pb() ###
-
-
-
-bytes_value_pb() = #bytes_value_pb{}
-
-
-
-
-
-### double_value_pb() ###
-
-
-
-double_value_pb() = #double_value_pb{}
-
-
-
-
-
-### float_value_pb() ###
-
-
-
-float_value_pb() = #float_value_pb{}
-
-
-
-
-
-### int_32_value_pb() ###
-
-
-
-int_32_value_pb() = #int_32_value_pb{}
-
-
-
-
-
-### int_64_value_pb() ###
-
-
-
-int_64_value_pb() = #int_64_value_pb{}
-
-
-
-
-
-### link_pb() ###
-
-
-
-link_pb() = #link_pb{}
-
-
-
-
-
-### links_pb() ###
-
-
-
-links_pb() = #links_pb{}
-
-
-
-
-
-### message_event_pb() ###
-
-
-
-message_event_pb() = #message_event_pb{}
-
-
-
-
-
-### module_pb() ###
-
-
-
-module_pb() = #module_pb{}
-
-
-
-
-
-### span_pb() ###
-
-
-
-span_pb() = #span_pb{}
-
-
-
-
-
-### stack_frame_pb() ###
-
-
-
-stack_frame_pb() = #stack_frame_pb{}
-
-
-
-
-
-### stack_frames_pb() ###
-
-
-
-stack_frames_pb() = #stack_frames_pb{}
-
-
-
-
-
-### stack_trace_pb() ###
-
-
-
-stack_trace_pb() = #stack_trace_pb{}
-
-
-
-
-
-### status_pb() ###
-
-
-
-status_pb() = #status_pb{}
-
-
-
-
-
-### string_value_pb() ###
-
-
-
-string_value_pb() = #string_value_pb{}
-
-
-
-
-
-### time_event_pb() ###
-
-
-
-time_event_pb() = #time_event_pb{}
-
-
-
-
-
-### time_events_pb() ###
-
-
-
-time_events_pb() = #time_events_pb{}
-
-
-
-
-
-### timestamp_pb() ###
-
-
-
-timestamp_pb() = #timestamp_pb{}
-
-
-
-
-
-### truncatable_string_pb() ###
-
-
-
-truncatable_string_pb() = #truncatable_string_pb{}
-
-
-
-
-
-### u_int_32_value_pb() ###
-
-
-
-u_int_32_value_pb() = #u_int_32_value_pb{}
-
-
-
-
-
-### u_int_64_value_pb() ###
-
-
-
-u_int_64_value_pb() = #u_int_64_value_pb{}
-
-
-
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### 'enum_symbol_by_value_opencensus.proto.trace.Span.Link.Type'/1 ###
-
-`enum_symbol_by_value_opencensus.proto.trace.Span.Link.Type(X1) -> any()`
-
-
-
-### 'enum_symbol_by_value_opencensus.proto.trace.Span.SpanKind'/1 ###
-
-`enum_symbol_by_value_opencensus.proto.trace.Span.SpanKind(X1) -> any()`
-
-
-
-### 'enum_symbol_by_value_opencensus.proto.trace.Span.TimeEvent.MessageEvent.Type'/1 ###
-
-`enum_symbol_by_value_opencensus.proto.trace.Span.TimeEvent.MessageEvent.Type(X1) -> any()`
-
-
-
-### 'enum_value_by_symbol_opencensus.proto.trace.Span.Link.Type'/1 ###
-
-`enum_value_by_symbol_opencensus.proto.trace.Span.Link.Type(X1) -> any()`
-
-
-
-### 'enum_value_by_symbol_opencensus.proto.trace.Span.SpanKind'/1 ###
-
-`enum_value_by_symbol_opencensus.proto.trace.Span.SpanKind(X1) -> any()`
-
-
-
-### 'enum_value_by_symbol_opencensus.proto.trace.Span.TimeEvent.MessageEvent.Type'/1 ###
-
-`enum_value_by_symbol_opencensus.proto.trace.Span.TimeEvent.MessageEvent.Type(X1) -> any()`
-
-
-
-### decode_msg/2 ###
-
-`decode_msg(Bin, MsgName) -> any()`
-
-
-
-### decode_msg/3 ###
-
-`decode_msg(Bin, MsgName, Opts) -> any()`
-
-
-
-### encode_msg/1 ###
-
-
-encode_msg(Msg::#bool_value_pb{} | #message_event_pb{} | #truncatable_string_pb{} | #module_pb{} | #attribute_value_pb{} | #attributes_pb{} | #annotation_pb{} | #timestamp_pb{} | #time_event_pb{} | #float_value_pb{} | #int_32_value_pb{} | #bytes_value_pb{} | #string_value_pb{} | #int_64_value_pb{} | #stack_frame_pb{} | #stack_frames_pb{} | #status_pb{} | #u_int_32_value_pb{} | #link_pb{} | #stack_trace_pb{} | #double_value_pb{} | #links_pb{} | #u_int_64_value_pb{} | #time_events_pb{} | #span_pb{}) -> binary()
-
-
-
-
-
-### encode_msg/2 ###
-
-
-encode_msg(Msg::#bool_value_pb{} | #message_event_pb{} | #truncatable_string_pb{} | #module_pb{} | #attribute_value_pb{} | #attributes_pb{} | #annotation_pb{} | #timestamp_pb{} | #time_event_pb{} | #float_value_pb{} | #int_32_value_pb{} | #bytes_value_pb{} | #string_value_pb{} | #int_64_value_pb{} | #stack_frame_pb{} | #stack_frames_pb{} | #status_pb{} | #u_int_32_value_pb{} | #link_pb{} | #stack_trace_pb{} | #double_value_pb{} | #links_pb{} | #u_int_64_value_pb{} | #time_events_pb{} | #span_pb{}, Opts::list()) -> binary()
-
-
-
-
-
-### enum_symbol_by_value/2 ###
-
-`enum_symbol_by_value(X1, Value) -> any()`
-
-
-
-### enum_value_by_symbol/2 ###
-
-`enum_value_by_symbol(X1, Sym) -> any()`
-
-
-
-### fetch_enum_def/1 ###
-
-`fetch_enum_def(EnumName) -> any()`
-
-
-
-### fetch_msg_def/1 ###
-
-`fetch_msg_def(MsgName) -> any()`
-
-
-
-### fetch_rpc_def/2 ###
-
-
-fetch_rpc_def(ServiceName::term(), RpcName::term()) -> no_return()
-
-
-
-
-
-### find_enum_def/1 ###
-
-`find_enum_def(X1) -> any()`
-
-
-
-### find_msg_def/1 ###
-
-`find_msg_def(X1) -> any()`
-
-
-
-### find_rpc_def/2 ###
-
-`find_rpc_def(X1, X2) -> any()`
-
-
-
-### get_enum_names/0 ###
-
-`get_enum_names() -> any()`
-
-
-
-### get_group_names/0 ###
-
-`get_group_names() -> any()`
-
-
-
-### get_msg_defs/0 ###
-
-`get_msg_defs() -> any()`
-
-
-
-### get_msg_names/0 ###
-
-`get_msg_names() -> any()`
-
-
-
-### get_msg_or_group_names/0 ###
-
-`get_msg_or_group_names() -> any()`
-
-
-
-### get_package_name/0 ###
-
-`get_package_name() -> any()`
-
-
-
-### get_rpc_names/1 ###
-
-`get_rpc_names(X1) -> any()`
-
-
-
-### get_service_def/1 ###
-
-`get_service_def(X1) -> any()`
-
-
-
-### get_service_names/0 ###
-
-`get_service_names() -> any()`
-
-
-
-### gpb_version_as_list/0 ###
-
-`gpb_version_as_list() -> any()`
-
-
-
-### gpb_version_as_string/0 ###
-
-`gpb_version_as_string() -> any()`
-
-
-
-### merge_msgs/2 ###
-
-`merge_msgs(Prev, New) -> any()`
-
-
-
-### merge_msgs/3 ###
-
-`merge_msgs(Prev, New, Opts) -> any()`
-
-
-
-### verify_msg/1 ###
-
-`verify_msg(Msg) -> any()`
-
-
-
-### verify_msg/2 ###
-
-`verify_msg(Msg, Opts) -> any()`
-
diff --git a/doc/oc_trace_reporter.md b/doc/oc_trace_reporter.md
new file mode 100644
index 0000000..6ad6ed1
--- /dev/null
+++ b/doc/oc_trace_reporter.md
@@ -0,0 +1,45 @@
+
+
+# Module oc_trace_reporter #
+* [Description](#description)
+* [Function Index](#index)
+* [Function Details](#functions)
+
+This module has the behaviour that each reporter must implement
+and creates the buffer of trace spans to be reported.
+
+__Behaviours:__ [`oc_internal_timer`](oc_internal_timer.md).
+
+
+
+## Function Index ##
+
+
+
+
+
+
+
+## Function Details ##
+
+
+
+### ping/0 ###
+
+`ping() -> any()`
+
+
+
+### start_link/1 ###
+
+`start_link(Handlers) -> any()`
+
+
+
+### store_span/1 ###
+
+
+store_span(Span::opencensus:span()) -> ok | {error, invalid_span} | {error, no_report_buffer}
+
+
+
diff --git a/doc/oc_trace_stdout_handler.md b/doc/oc_trace_stdout_handler.md
new file mode 100644
index 0000000..8825322
--- /dev/null
+++ b/doc/oc_trace_stdout_handler.md
@@ -0,0 +1,38 @@
+
+
+# Module oc_trace_stdout_handler #
+* [Function Index](#index)
+* [Function Details](#functions)
+
+__Behaviours:__ [`gen_event`](gen_event.md).
+
+
+
+## Function Index ##
+
+
+
+
+
+
+
+## Function Details ##
+
+
+
+### handle_call/2 ###
+
+`handle_call(Msg, State) -> any()`
+
+
+
+### handle_event/2 ###
+
+`handle_event(X1, State) -> any()`
+
+
+
+### init/1 ###
+
+`init(Opts) -> any()`
+
diff --git a/doc/oc_transform.md b/doc/oc_transform.md
deleted file mode 100644
index a8bda0b..0000000
--- a/doc/oc_transform.md
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-# Module oc_transform #
-* [Description](#description)
-* [Function Index](#index)
-* [Function Details](#functions)
-
-oc_transform provides a parse transform for wrapping a function in
-a start and a finish of a span.
-
-
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### format_error/1 ###
-
-`format_error(X1) -> any()`
-
-
-
-### parse_transform/2 ###
-
-`parse_transform(Ast, Options) -> any()`
-
diff --git a/doc/ocp.md b/doc/ocp.md
index 39244e7..be99033 100644
--- a/doc/ocp.md
+++ b/doc/ocp.md
@@ -139,7 +139,7 @@ current_tags() -> opencensus:tags()
### finish_span/0 ###
-finish_span() -> boolean()
+finish_span() -> ok | {error, invalid_span} | {error, no_report_buffer}
diff --git a/doc/opencensus_sup.md b/doc/opencensus_sup.md
deleted file mode 100644
index 42bfd02..0000000
--- a/doc/opencensus_sup.md
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-# Module opencensus_sup #
-* [Description](#description)
-* [Function Index](#index)
-* [Function Details](#functions)
-
-opencensus top level supervisor.
-
-__Behaviours:__ [`supervisor`](supervisor.md).
-
-
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### init/1 ###
-
-`init(X1) -> any()`
-
-
-
-### start_link/0 ###
-
-`start_link() -> any()`
-
diff --git a/doc/tpl.html b/doc/tpl.html
index 7558a64..25a372d 100644
--- a/doc/tpl.html
+++ b/doc/tpl.html
@@ -18,15 +18,10 @@
Modules
- oc_reporter
- oc_reporter_noop
- oc_reporter_sequential
- oc_reporter_zipkin
oc_sampler
oc_sampler_always
oc_sampler_never
oc_sampler_probability
- oc_server
oc_span
oc_span_ctx_binary
oc_span_ctx_header
@@ -36,18 +31,12 @@ Modules
oc_stat_aggregation_distribution
oc_stat_aggregation_latest
oc_stat_aggregation_sum
- oc_stat_config
- oc_stat_exporter
- oc_stat_exporter_prometheus
oc_stat_measure
oc_stat_view
- oc_std_encoder
oc_tag_ctx_binary
oc_tag_ctx_header
oc_tags
oc_trace
- oc_trace_pb
- oc_transform
ocp
opencensus
opencensus_app
diff --git a/elvis.config b/elvis.config
index 80862bf..12bd362 100644
--- a/elvis.config
+++ b/elvis.config
@@ -7,8 +7,8 @@
filter => "*.erl",
ignore => ["src/oc_trace_pb.erl", "src/oc_trace_config_pb.erl"],
rules => [{elvis_style, god_modules, #{ignore => [ocp]}},
- {elvis_style, no_debug_call, #{ignore => [oc_reporter_stdout,
- oc_stat_exporter_stdout]}},
+ {elvis_style, no_debug_call, #{ignore => [oc_trace_stdout_handler,
+ oc_stat_stdout_handler]}},
{elvis_style, dont_repeat_yourself, #{min_complexity => 20}},
{elvis_style, line_length, #{limit => 120}},
{elvis_style, state_record_and_type, disable},
diff --git a/src/oc_internal_timer.erl b/src/oc_internal_timer.erl
new file mode 100644
index 0000000..dfc4443
--- /dev/null
+++ b/src/oc_internal_timer.erl
@@ -0,0 +1,51 @@
+%%%------------------------------------------------------------------------
+%% Copyright 2017, OpenCensus Authors
+%% Licensed 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.
+%%%------------------------------------------------------------------------
+
+-module(oc_internal_timer).
+
+-callback ping() -> ok.
+
+-export([start_link/2,
+ init/1,
+ handle_call/3,
+ handle_cast/2,
+ handle_info/2]).
+
+-record(state, {timer :: reference(),
+ interval :: pos_integer(),
+ module :: module()}).
+
+start_link(Interval, Module) ->
+ gen_server:start_link(?MODULE, {Interval, Module}, []).
+
+init({Interval, Module}) ->
+ Ref = erlang:send_after(Interval, self(), ping),
+
+ {ok, #state{timer = Ref,
+ interval = Interval,
+ module = Module}}.
+
+handle_call(_Msg, _From, State) -> {reply, ok, State}.
+
+handle_cast(_Msg, State) -> {noreply, State}.
+
+handle_info(ping, #state{timer = Ref, interval = Interval, module = Mod}) ->
+ _ = erlang:cancel_timer(Ref),
+ NewRef = erlang:send_after(Interval, self(), ping),
+ ok = Mod:ping(),
+
+ {noreply, #state{timer = NewRef,
+ interval = Interval,
+ module = Mod}}.
diff --git a/src/oc_reporter.erl b/src/oc_reporter.erl
deleted file mode 100644
index cb49bf8..0000000
--- a/src/oc_reporter.erl
+++ /dev/null
@@ -1,166 +0,0 @@
-%%%------------------------------------------------------------------------
-%% Copyright 2017, OpenCensus Authors
-%% Licensed 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.
-%%
-%% @doc This module has the behaviour that each reporter must implement
-%% and creates the buffer of trace spans to be reported.
-%% @end
-%%%-----------------------------------------------------------------------
--module(oc_reporter).
-
--behaviour(gen_server).
-
--compile({no_auto_import, [register/2]}).
-
--export([start_link/0,
- store_span/1,
- register/1,
- register/2]).
-
--export([init/1,
- handle_call/3,
- handle_cast/2,
- handle_info/2,
- code_change/3,
- terminate/2]).
-
--include("opencensus.hrl").
--include("oc_logger.hrl").
-
-%% behaviour for reporters to implement
--type opts() :: term().
-
-%% Do any initialization of the reporter here and return configuration
-%% that will be passed along with a list of spans to the `report' function.
--callback init(term()) -> opts().
-
-%% This function is called when the configured interval expires with any
-%% spans that have been collected so far and the configuration returned in `init'.
-%% Do whatever needs to be done to report each span here, the caller will block
-%% until it returns.
--callback report(nonempty_list(opencensus:span()), opts()) -> ok.
-
--record(state, {reporters :: [{module(), term()}],
- send_interval_ms :: integer(),
- timer_ref :: reference()}).
-
--define(BUFFER_1, oc_report_buffer1).
--define(BUFFER_2, oc_report_buffer2).
--define(BUFFER_STATUS, oc_report_status).
-
-start_link() ->
- maybe_init_ets(),
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-
-%% @doc
-%% @equiv register(Reporter, []).
-%% @end
-register(Reporter) -> register(Reporter, []).
-
-%% @doc
-%% Register new traces reporter `Reporter' with `Config'.
-%% @end
--spec register(module(), term()) -> ok.
-register(Reporter, Options) ->
- gen_server:call(?MODULE, {register, init_reporter({Reporter, Options})}).
-
--spec store_span(opencensus:span()) -> true | {error, invalid_span} | {error, no_report_buffer}.
-store_span(Span=#span{}) ->
- try
- [{_, Buffer}] = ets:lookup(?BUFFER_STATUS, current_buffer),
- ets:insert(Buffer, Span)
- catch
- error:badarg ->
- {error, no_report_buffer}
- end;
-store_span(_) ->
- {error, invalid_span}.
-
-init(_Args) ->
- SendInterval = application:get_env(opencensus, send_interval_ms, 500),
- Reporters = [init_reporter(Config) || Config <- application:get_env(opencensus, reporters, [])],
- Ref = erlang:send_after(SendInterval, self(), report_spans),
- {ok, #state{reporters=Reporters,
- send_interval_ms=SendInterval,
- timer_ref=Ref}}.
-
-handle_call({register, Reporter}, _From, #state{reporters=Reporters} = State) ->
- {reply, ok, State#state{reporters=[Reporter | Reporters]}};
-handle_call(_, _From, State) ->
- {noreply, State}.
-
-handle_cast(_, State) ->
- {noreply, State}.
-
-handle_info(report_spans, State=#state{reporters=Reporters,
- send_interval_ms=SendInterval,
- timer_ref=Ref}) ->
- erlang:cancel_timer(Ref),
- Ref1 = erlang:send_after(SendInterval, self(), report_spans),
- send_spans(Reporters),
- {noreply, State#state{timer_ref=Ref1}}.
-
-code_change(_, State, _) ->
- {ok, State}.
-
-terminate(_, #state{timer_ref=Ref}) ->
- erlang:cancel_timer(Ref),
- ok.
-
-init_reporter({Reporter, Config}) ->
- {Reporter, Reporter:init(Config)};
-init_reporter(Reporter) when is_atom(Reporter) ->
- {Reporter, Reporter:init([])}.
-
-maybe_init_ets() ->
- case ets:info(?BUFFER_STATUS, name) of
- undefined ->
- [ets:new(Tab, [named_table, public | TableProps ]) ||
- {Tab, TableProps} <- [{?BUFFER_1, [{write_concurrency, true}, {keypos, #span.span_id}]},
- {?BUFFER_2, [{write_concurrency, true}, {keypos, #span.span_id}]},
- {?BUFFER_STATUS, [{read_concurrency, true}]}]],
- ets:insert(?BUFFER_STATUS, {current_buffer, ?BUFFER_1});
- _ ->
- ok
- end.
-
-send_spans(Reporters) ->
- [{_, Buffer}] = ets:lookup(?BUFFER_STATUS, current_buffer),
- NewBuffer = case Buffer of
- ?BUFFER_1 ->
- ?BUFFER_2;
- ?BUFFER_2 ->
- ?BUFFER_1
- end,
- ets:insert(?BUFFER_STATUS, {current_buffer, NewBuffer}),
- case ets:tab2list(Buffer) of
- [] ->
- ok;
- Spans ->
- ets:delete_all_objects(Buffer),
- [report(Reporter, Spans, Config)
- || {Reporter, Config} <- Reporters],
- ok
- end.
-
-report(undefined, _, _) ->
- ok;
-report(Reporter, Spans, Config) ->
- %% don't let a reporter exception crash us
- try
- Reporter:report(Spans, Config)
- catch
- ?WITH_STACKTRACE(Class, Exception, StackTrace)
- ?LOG_INFO("reporter threw exception: reporter=~p ~p:~p stacktrace=~p",
- [Reporter, Class, Exception, StackTrace])
- end.
diff --git a/src/oc_reporter_pid.erl b/src/oc_reporter_pid.erl
index 9b94c3c..cdb9480 100644
--- a/src/oc_reporter_pid.erl
+++ b/src/oc_reporter_pid.erl
@@ -17,13 +17,16 @@
%%%-----------------------------------------------------------------------
-module(oc_reporter_pid).
--behaviour(oc_reporter).
+-behaviour(gen_event).
-export([init/1,
- report/2]).
+ handle_call/2,
+ handle_event/2]).
-init(Pid) -> Pid.
+init(Pid) -> {ok, Pid}.
-report(Spans, Pid) ->
+handle_call(_Msg, State) -> {ok, ok, State}.
+
+handle_event({spans, Spans}, Pid) ->
[Pid ! {span, Span} || Span <- Spans],
- ok.
+ {ok, Pid}.
diff --git a/src/oc_reporter_stdout.erl b/src/oc_reporter_stdout.erl
deleted file mode 100644
index 583568e..0000000
--- a/src/oc_reporter_stdout.erl
+++ /dev/null
@@ -1,10 +0,0 @@
--module(oc_reporter_stdout).
-
--export([init/1,
- report/2]).
-
-init(_) ->
- ok.
-
-report(Spans, _) ->
- [io:format("~p~n", [Span]) || Span <- Spans].
diff --git a/src/oc_span.erl b/src/oc_span.erl
index f2b2142..f17e21f 100644
--- a/src/oc_span.erl
+++ b/src/oc_span.erl
@@ -41,15 +41,15 @@
%% Finish a span, setting the end_time and sending to the reporter.
%% @end
%%--------------------------------------------------------------------
--spec finish_span(opencensus:span_ctx(), maybe(opencensus:span())) -> true.
+-spec finish_span(opencensus:span_ctx(), maybe(opencensus:span())) -> ok | {error, term()}.
finish_span(#span_ctx{tracestate=Tracestate}, Span=#span{}) ->
EndTime = wts:timestamp(),
%% update tracestate to what the context has when finished
Span1 = Span#span{end_time=EndTime,
tracestate=Tracestate},
- oc_reporter:store_span(Span1);
+ oc_trace_reporter:store_span(Span1);
finish_span(_, _) ->
- true.
+ ok.
%%--------------------------------------------------------------------
%% @doc
diff --git a/src/oc_stat.erl b/src/oc_stat.erl
index 8e8d9f5..c237dc2 100644
--- a/src/oc_stat.erl
+++ b/src/oc_stat.erl
@@ -17,10 +17,16 @@
%%%-----------------------------------------------------------------------
-module(oc_stat).
+-behaviour(gen_server).
+
-export([record/2,
record/3,
export/0]).
+-export([add_handler/1,
+ add_handler/2,
+ delete_handler/1]).
+
-export([start_link/0,
init/1,
handle_call/3,
@@ -75,6 +81,29 @@ record(Ctx, Measures) ->
export() ->
[oc_stat_view:export(View) || View <- oc_stat_view:all_subscribed_()].
+%%--------------------------------------------------------------------
+%% @doc
+%% @equiv add_handler(Handler, [])
+%% @end
+%%--------------------------------------------------------------------
+add_handler(Handler) -> add_handler(Handler, []).
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Add new handler
+%% @end
+%%--------------------------------------------------------------------
+add_handler(Handler, Args) ->
+ gen_event:add_handler(oc_stat_reporter, Handler, Args).
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Delete handler
+%% @end
+%%--------------------------------------------------------------------
+delete_handler(Handler) ->
+ gen_event:delete_handler(oc_stat_reporter, Handler, []).
+
%% gen_server implementation
%% @private
diff --git a/src/oc_stat_exporter.erl b/src/oc_stat_exporter.erl
deleted file mode 100644
index 95b6bbb..0000000
--- a/src/oc_stat_exporter.erl
+++ /dev/null
@@ -1,160 +0,0 @@
-%% 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.
-%%
-%% @doc
-%% Exporter exports the collected records as view data.
-%% @end
--module(oc_stat_exporter).
-
--export([start_link/0,
- batch_register/1,
- register/1,
- register/2,
- deregister/1,
- registered/1]).
-
--export([init/1,
- handle_call/3,
- handle_cast/2,
- handle_info/2,
- code_change/3,
- terminate/2]).
-
--export_type([exporter/0]).
-
--compile({no_auto_import, [register/2]}).
-
--type exporter() :: module().
-
--include("opencensus.hrl").
--include("oc_logger.hrl").
-
--callback export(ViewData, Config) -> ok when
- ViewData :: oc_stat_view:view_data(),
- Config :: any().
-
--record(state, {exporters :: #{module() => any},
- export_interval_ms :: integer(),
- timer_ref :: reference()}).
-
-start_link() ->
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-
-%% @doc
-%% Register many `Exporters' at once.
-%% @end
--spec batch_register(Exporters) -> ok when
- Exporters :: [exporter()].
-batch_register(Exporters) when is_list(Exporters) ->
- gen_server:call(?MODULE, {batch_register, Exporters}, infinity),
- ok.
-
-%% @doc
-%% @equiv register(Exporter, [])
-%% @end
--spec register(Exporter) -> ok when
- Exporter :: exporter().
-register(Exporter) ->
- register(Exporter, []),
- ok.
-
-%% @doc
-%% Registers an `Exporter' with `Config'.
-%% Collected data will be reported via all the
-%% registered exporters. Once you no longer
-%% want data to be exported, invoke {@link deregister/1}
-%% with the previously registered exporter.
-%% @end
--spec register(Exporter, Config) -> ok when
- Exporter :: exporter(),
- Config :: any().
-register(Exporter, Config) ->
- gen_server:call(?MODULE, {register, Exporter, Config}, infinity),
- ok.
-
-%% @doc
-%% Deregisters an `Exporter'.
-%% @end
--spec deregister(Exporter) -> ok when
- Exporter :: exporter().
-deregister(Exporter) ->
- gen_server:call(?MODULE, {deregister, Exporter}, infinity),
- ok.
-
-%% @doc
-%% Checks whether `Exporter' is registered.
-%% @end
--spec registered(Exporter) -> boolean() when
- Exporter :: exporter().
-registered(Exporter) ->
- gen_server:call(?MODULE, {registered, Exporter}, infinity).
-
-%% @doc
-%% @private
-%% Called by opencensus
-%% @end
-export(Exporters) ->
- Measurements = oc_stat:export(),
-
- [try
- Exporter:export(Measurements, Config)
- catch
- ?WITH_STACKTRACE(Class, Exception, Stacktrace)
- ?LOG_INFO("stat exporter ~p threw ~p:~p, stacktrace=~p",
- [Exporter, Class, Exception, Stacktrace])
- end
- || {Exporter, Config} <- Exporters],
- ok.
-
-init(_Args) ->
- ExportInterval = oc_stat_config:export_interval(),
- %% TODO: validate
- Exporters = oc_stat_config:exporters(),
- %% TODO: should we init exporters here, before exporting?
- Ref = erlang:send_after(ExportInterval, self(), export_stats),
- {ok, #state{exporters=to_map(Exporters),
- export_interval_ms=ExportInterval,
- timer_ref=Ref}}.
-
-handle_call({batch_register, NewExporters}, _From, State=#state{exporters=Exporters}) ->
- {reply, ok, State#state{exporters=maps:merge(Exporters, maps:from_list(NewExporters))}};
-handle_call({register, Exporter, Config}, _From, State=#state{exporters=Exporters}) ->
- {reply, ok, State#state{exporters=maps:put(Exporter, Config, Exporters)}};
-handle_call({deregister, Exporter}, _From, State=#state{exporters=Exporters}) ->
- {reply, ok, State#state{exporters=maps:remove(Exporter, Exporters)}};
-handle_call({registered, Exporter}, _From, State=#state{exporters=Exporters}) ->
- {reply, maps:is_key(Exporter, Exporters), State};
-handle_call(_, _From, State) ->
- {noreply, State}.
-
-handle_cast(_, State) ->
- {noreply, State}.
-
-handle_info(export_stats, State=#state{exporters=Exporters,
- export_interval_ms=ExportInterval,
- timer_ref=Ref}) ->
- erlang:cancel_timer(Ref),
- Ref1 = erlang:send_after(ExportInterval, self(), export_stats),
- spawn(fun () ->
- export(maps:to_list(Exporters))
- end),
- {noreply, State#state{timer_ref=Ref1}}.
-
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-terminate(_, #state{timer_ref=Ref}) ->
- erlang:cancel_timer(Ref),
- ok.
-
-to_map(Map) when is_map(Map) ->
- Map;
-to_map(List) when is_list(List) ->
- maps:from_list(List);
-to_map(Thing) ->
- erlang:error({invalid_exporters, Thing}).
diff --git a/src/oc_stat_exporter_stdout.erl b/src/oc_stat_exporter_stdout.erl
deleted file mode 100644
index 2c3c726..0000000
--- a/src/oc_stat_exporter_stdout.erl
+++ /dev/null
@@ -1,7 +0,0 @@
--module(oc_stat_exporter_stdout).
-
--export([export/2]).
-
-export(ViewData, _) ->
- [io:format("~s: ~p~n", [Name, Data]) || #{name := Name,
- data := Data} <- ViewData].
diff --git a/src/oc_server.erl b/src/oc_stat_reporter.erl
similarity index 51%
rename from src/oc_server.erl
rename to src/oc_stat_reporter.erl
index 7ed7704..ac88350 100644
--- a/src/oc_server.erl
+++ b/src/oc_stat_reporter.erl
@@ -1,5 +1,5 @@
%%%------------------------------------------------------------------------
-%% Copyright 2018, OpenCensus Authors
+%% Copyright 2017, OpenCensus Authors
%% Licensed 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
@@ -11,39 +11,34 @@
%% 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.
-%%
-%% @doc Server with no logic, simply owns the span ets table.
+%%%------------------------------------------------------------------------
+
+%% @doc
+%% Exporter exports the collected records as view data.
%% @end
-%%%-------------------------------------------------------------------------
--module(oc_server).
+-module(oc_stat_reporter).
--export([start_link/0]).
+-behaviour(oc_internal_timer).
--export([init/1,
- handle_call/3,
- handle_cast/2]).
+-export([start_link/1,
+ ping/0]).
-include("opencensus.hrl").
+-include("oc_logger.hrl").
--record(state, {}).
-
-start_link() ->
- maybe_init_ets(),
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
+start_link(Handlers) ->
+ case gen_event:start_link({local, ?MODULE}, []) of
+ {ok, Pid} ->
+ [gen_event:add_handler(Pid, Handler, Opts)
+ || {Handler, Opts} <- Handlers],
-init([]) ->
- {ok, #state{}}.
-
-handle_call(_, _From, State) ->
- {noreply, State}.
+ {ok, Pid};
+ Other -> Other
+ end.
-handle_cast(_, State) ->
- {noreply, State}.
+%% @private
+ping() ->
+ Measurements = oc_stat:export(),
+ gen_event:sync_notify(?MODULE, {stats, Measurements}),
-maybe_init_ets() ->
- case ets:info(?SPAN_TAB, name) of
- undefined ->
- ets:new(?SPAN_TAB, [named_table, public, {write_concurrency, true}, {keypos, #span.span_id}]);
- _ ->
- ok
- end.
+ ok.
diff --git a/src/oc_stat_stdout_handler.erl b/src/oc_stat_stdout_handler.erl
new file mode 100644
index 0000000..bc7ea6e
--- /dev/null
+++ b/src/oc_stat_stdout_handler.erl
@@ -0,0 +1,16 @@
+-module(oc_stat_stdout_handler).
+
+-behaviour(gen_event).
+
+-export([init/1,
+ handle_call/2,
+ handle_event/2]).
+
+init(Opts) -> {ok, Opts}.
+
+handle_call(_Msg, State) -> {ok, ok, State}.
+
+handle_event({stats, ViewData}, State) ->
+ [io:format("~s: ~p~n", [Name, Data]) || #{name := Name,
+ data := Data} <- ViewData],
+ {ok, State}.
diff --git a/src/oc_stat_sup.erl b/src/oc_stat_sup.erl
new file mode 100644
index 0000000..f31085c
--- /dev/null
+++ b/src/oc_stat_sup.erl
@@ -0,0 +1,37 @@
+%%%------------------------------------------------------------------------
+%% Copyright 2017, OpenCensus Authors
+%% Licensed 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.
+%%%------------------------------------------------------------------------
+
+%% @private
+
+-module(oc_stat_sup).
+
+-export([start_link/1, init/1]).
+
+start_link(Opts) ->
+ supervisor:start_link(?MODULE, Opts).
+
+init(Opts) ->
+ Interval = proplists:get_value(interval, Opts, 5000),
+ Handlers = proplists:get_value(handlers, Opts, []),
+
+ Reporter = #{id => reporter,
+ start => {oc_stat_reporter, start_link, [Handlers]}},
+ ViewServer = #{id => view_server,
+ start => {oc_stat, start_link, []}},
+ Timer = #{id => timer,
+ start => {oc_internal_timer, start_link, [Interval,
+ oc_stat_reporter]}},
+
+ {ok, {#{strategy => one_for_one}, [Reporter, Timer, ViewServer]}}.
diff --git a/src/oc_trace.erl b/src/oc_trace.erl
index cd190a3..a3c5c40 100644
--- a/src/oc_trace.erl
+++ b/src/oc_trace.erl
@@ -49,7 +49,11 @@
message_event/4,
- set_status/3]).
+ set_status/3,
+
+ add_handler/1,
+ add_handler/2,
+ delete_handler/1]).
-dialyzer({nowarn_function, update_trace_options/2}).
@@ -199,17 +203,17 @@ update_trace_options(should_sample, #span_ctx{trace_id=TraceId,
%% Finish a span, setting the end_time.
%% @end
%%--------------------------------------------------------------------
--spec finish_span(maybe(opencensus:span_ctx())) -> boolean().
+-spec finish_span(maybe(opencensus:span_ctx())) -> ok | {error, invalid_span} | {error, no_report_buffer}.
finish_span(SpanCtx=#span_ctx{span_id=SpanId,
trace_options=TraceOptions}) when ?IS_ENABLED(TraceOptions) ->
case ets:take(?SPAN_TAB, SpanId) of
[SpanData] ->
oc_span:finish_span(SpanCtx, SpanData);
_ ->
- false
+ {error, invalid_span}
end;
finish_span(_) ->
- true.
+ {error, invalid_span}.
%%--------------------------------------------------------------------
%% @doc
@@ -328,6 +332,45 @@ link(LinkType, TraceId, SpanId, Attributes) ->
span_id=SpanId,
attributes=Attributes}.
+%%--------------------------------------------------------------------
+%% @doc
+%% @equiv add_handler(Handler, [])
+%% @end
+%%--------------------------------------------------------------------
+-spec add_handler(Handler) -> ok | term() when
+ Handler :: Module | {Module, Id},
+ Module :: module(),
+ Id :: term().
+add_handler(Handler) -> add_handler(Handler, []).
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Add new handler `Module' and pass `Args' as the configuration to
+%% `Module:init/1' callback.
+%%
+%% You can create multiple instances of the same `Module' handler by
+%% differentiating them with `Id' value.
+%% @end
+%%--------------------------------------------------------------------
+-spec add_handler(Handler, Args::term()) -> ok | term() when
+ Handler :: Module | {Module, Id},
+ Module :: module(),
+ Id :: term().
+add_handler(Handler, Args) ->
+ gen_event:add_handler(oc_trace_reporter, Handler, Args).
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Delete handler marked by the `Handler'.
+%% @end
+%%--------------------------------------------------------------------
+-spec delete_handler(Handler) -> ok | term() when
+ Handler :: Module | {Module, Id},
+ Module :: module(),
+ Id :: term().
+delete_handler(Handler) ->
+ gen_event:delete_handler(oc_trace_reporter, Handler, []).
+
%% Internal functions
lookup_and_replace(#span_ctx{span_id=SpanId,
diff --git a/src/oc_trace_reporter.erl b/src/oc_trace_reporter.erl
new file mode 100644
index 0000000..5001ea2
--- /dev/null
+++ b/src/oc_trace_reporter.erl
@@ -0,0 +1,89 @@
+%%%------------------------------------------------------------------------
+%% Copyright 2017, OpenCensus Authors
+%% Licensed 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.
+%%
+%% @doc This module has the behaviour that each reporter must implement
+%% and creates the buffer of trace spans to be reported.
+%% @end
+%%%-----------------------------------------------------------------------
+-module(oc_trace_reporter).
+
+-behaviour(oc_internal_timer).
+
+-export([start_link/1,
+ store_span/1]).
+
+-export([ping/0]).
+
+-include("opencensus.hrl").
+-include("oc_logger.hrl").
+
+-define(BUFFER_1, oc_report_buffer1).
+-define(BUFFER_2, oc_report_buffer2).
+-define(BUFFER_STATUS, oc_report_status).
+
+start_link(Handlers) ->
+ maybe_init_ets(),
+ case gen_event:start_link({local, ?MODULE}, []) of
+ {ok, Pid} ->
+ [gen_event:add_handler(Pid, Handler, Opts)
+ || {Handler, Opts} <- Handlers],
+
+ {ok, Pid};
+ Other -> Other
+ end.
+
+-spec store_span(opencensus:span()) -> ok | {error, invalid_span} | {error, no_report_buffer}.
+store_span(Span=#span{}) ->
+ try
+ [{_, Buffer}] = ets:lookup(?BUFFER_STATUS, current_buffer),
+ true = ets:insert(Buffer, Span),
+ ok
+ catch
+ error:badarg ->
+ {error, no_report_buffer}
+ end;
+store_span(_) ->
+ {error, invalid_span}.
+
+ping() ->
+ [{_, Buffer}] = ets:lookup(?BUFFER_STATUS, current_buffer),
+ NewBuffer = case Buffer of
+ ?BUFFER_1 ->
+ ?BUFFER_2;
+ ?BUFFER_2 ->
+ ?BUFFER_1
+ end,
+ ets:insert(?BUFFER_STATUS, {current_buffer, NewBuffer}),
+ case ets:tab2list(Buffer) of
+ [] ->
+ ok;
+ Spans ->
+ ets:delete_all_objects(Buffer),
+ gen_event:sync_notify(?MODULE, {spans, Spans}),
+ ok
+ end.
+
+maybe_init_ets() ->
+ case ets:info(?BUFFER_STATUS, name) of
+ undefined ->
+ [ets:new(Tab, [named_table, public | TableProps]) ||
+ {Tab, TableProps} <- [{?BUFFER_1, [{write_concurrency, true}, {keypos, #span.span_id}]},
+ {?BUFFER_2, [{write_concurrency, true}, {keypos, #span.span_id}]},
+ {?BUFFER_STATUS, [{read_concurrency, true}]}]],
+ ets:insert(?BUFFER_STATUS, {current_buffer, ?BUFFER_1}),
+
+ ok;
+ _ ->
+ ok
+ end.
diff --git a/src/oc_stat_config.erl b/src/oc_trace_stdout_handler.erl
similarity index 57%
rename from src/oc_stat_config.erl
rename to src/oc_trace_stdout_handler.erl
index f332bd8..bca1281 100644
--- a/src/oc_stat_config.erl
+++ b/src/oc_trace_stdout_handler.erl
@@ -11,29 +11,21 @@
%% 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.
-%%
-%% @doc stats configuration
-%% @end
%%%------------------------------------------------------------------------
--module(oc_stat_config).
+-module(oc_trace_stdout_handler).
--export([views/0,
- export_interval/0,
- exporters/0]).
+-behaviour(gen_event).
--define(DEFAULT_VIEWS, []).
--define(DEFAULT_EXPORTERS, []).
--define(DEFAULT_EXPORT_INTERVAL, 5000).
+-export([init/1,
+ handle_call/2,
+ handle_event/2]).
-views() ->
- proplists:get_value(views, stat_conf(), ?DEFAULT_VIEWS).
+init(Opts) -> {ok, Opts}.
-export_interval() ->
- proplists:get_value(export_interval, stat_conf(), ?DEFAULT_EXPORT_INTERVAL).
+handle_call(_Msg, State) -> {ok, ok, State}.
-exporters() ->
- proplists:get_value(exporters, stat_conf(), ?DEFAULT_EXPORTERS).
+handle_event({spans, Spans}, State) ->
+ [io:format("~p~n", [Span]) || Span <- Spans],
-stat_conf() ->
- application:get_env(opencensus, stat, []).
+ {ok, State}.
diff --git a/src/oc_trace_sup.erl b/src/oc_trace_sup.erl
new file mode 100644
index 0000000..8d843a2
--- /dev/null
+++ b/src/oc_trace_sup.erl
@@ -0,0 +1,56 @@
+%%%------------------------------------------------------------------------
+%% Copyright 2017, OpenCensus Authors
+%% Licensed 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.
+%%%------------------------------------------------------------------------
+
+%% @private
+
+-module(oc_trace_sup).
+
+-behaviour(supervisor).
+
+-export([start_link/1, init/1]).
+
+-include("opencensus.hrl").
+-include("oc_logger.hrl").
+
+start_link(Opts) ->
+ supervisor:start_link(?MODULE, Opts).
+
+init(Opts) ->
+ Interval = proplists:get_value(interval, Opts, 500),
+ Handlers = proplists:get_value(handlers, Opts, []),
+
+ Exporter = #{id => exporter,
+ start => {oc_trace_reporter, start_link, [Handlers]}},
+ % TODO: Rename oc_span_sweeper to oc_trace_sweeper
+ Sweeper = #{id => sweeper,
+ start => {oc_span_sweeper, start_link, []}},
+ Timer = #{id => timer,
+ start => {oc_internal_timer, start_link, [Interval,
+ oc_trace_reporter]}},
+
+ ok = maybe_init_span_tab(),
+
+ {ok, {#{strategy => one_for_one}, [Exporter, Timer, Sweeper]}}.
+
+maybe_init_span_tab() ->
+ case ets:info(?SPAN_TAB, name) of
+ undefined ->
+ ets:new(?SPAN_TAB, [named_table, public,
+ {write_concurrency, true},
+ {keypos, #span.span_id}]),
+ ok;
+ _ ->
+ ok
+ end.
diff --git a/src/ocp.erl b/src/ocp.erl
index 723149d..ab0f6ff 100644
--- a/src/ocp.erl
+++ b/src/ocp.erl
@@ -171,7 +171,7 @@ current_tags() ->
%% Finishes the span in the current pdict context.
%% @end
%%--------------------------------------------------------------------
--spec finish_span() -> boolean().
+-spec finish_span() -> ok | {error, invalid_span} | {error, no_report_buffer}.
finish_span() ->
CurrentCtx = current_span_ctx(),
ParentCtx = oc_trace:parent_span_ctx(CurrentCtx),
diff --git a/src/opencensus_sup.erl b/src/opencensus_sup.erl
index d68b06a..73eff28 100644
--- a/src/opencensus_sup.erl
+++ b/src/opencensus_sup.erl
@@ -12,9 +12,11 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
+%%%------------------------------------------------------------------------
+
%% @doc opencensus top level supervisor.
+%% @private
%% @end
-%%%------------------------------------------------------------------------
-module(opencensus_sup).
@@ -24,49 +26,20 @@
-export([init/1]).
--define(SERVER, ?MODULE).
-
start_link() ->
- supervisor:start_link({local, ?SERVER}, ?MODULE, []).
+ supervisor:start_link(?MODULE, []).
init([]) ->
ok = oc_sampler:init(application:get_env(opencensus, sampler, {oc_sampler_always, []})),
- Reporter = #{id => oc_reporter,
- start => {oc_reporter, start_link, []},
- restart => permanent,
- shutdown => 1000,
- type => worker,
- modules => [oc_reporter]},
-
- Exporter = #{id => oc_stat_exporter,
- start => {oc_stat_exporter, start_link, []},
- restart => permanent,
- shutdown => 1000,
- type => worker,
- modules => [oc_stat_exporter]},
-
- ViewServer = #{id => oc_stat,
- start => {oc_stat, start_link, []},
- restart => permanent,
- shutdown => 1000,
- type => worker,
- modules => [oc_stat]},
-
- TraceServer = #{id => oc_server,
- start => {oc_server, start_link, []},
- restart => permanent,
- shutdown => 1000,
- type => worker,
- modules => [oc_server]},
+ StatOpts = application:get_env(opencensus, stat, []),
+ StatSup = #{id => stat,
+ start => {oc_stat_sup, start_link, [StatOpts]},
+ type => supervisor},
- Sweeper = #{id => oc_span_sweeper,
- start => {oc_span_sweeper, start_link, []},
- restart => permanent,
- shutdown => 1000,
- type => worker,
- modules => [oc_span_sweeper]},
+ TraceOpts = application:get_env(opencensus, trace, []),
+ TraceSup = #{id => traces,
+ start => {oc_trace_sup, start_link, [TraceOpts]},
+ type => supervisor},
- {ok, {#{strategy => one_for_one,
- intensity => 1,
- period => 5}, [Reporter, Exporter, ViewServer, TraceServer, Sweeper]}}.
+ {ok, {#{strategy => one_for_one}, [TraceSup, StatSup]}}.
diff --git a/test/oc_span_SUITE.erl b/test/oc_span_SUITE.erl
index 01272ce..e6acac9 100644
--- a/test/oc_span_SUITE.erl
+++ b/test/oc_span_SUITE.erl
@@ -56,7 +56,7 @@ modifications(_Config) ->
?assertEqual({error, no_report_buffer}, oc_span:finish_span(#span_ctx{}, Span6)),
{ok, _} = application:ensure_all_started(opencensus),
- ?assertEqual(true, oc_span:finish_span(#span_ctx{}, Span6)),
- ?assertEqual(true, oc_span:finish_span(#span_ctx{}, undefined)),
+ ?assertEqual(ok, oc_span:finish_span(#span_ctx{}, Span6)),
+ ?assertEqual(ok, oc_span:finish_span(#span_ctx{}, undefined)),
application:stop(opencensus).
diff --git a/test/oc_stat_SUITE.erl b/test/oc_stat_SUITE.erl
index 5192178..a2ce632 100644
--- a/test/oc_stat_SUITE.erl
+++ b/test/oc_stat_SUITE.erl
@@ -65,7 +65,7 @@ end_per_suite(_Config) ->
init_per_testcase(full, Config) ->
Exporters = [{oc_stat_exporter_pid, self()}],
- application:set_env(opencensus, stat, [{exporters, Exporters}]),
+ application:set_env(opencensus, stat, [{handlers, Exporters}]),
{ok, _} = application:ensure_all_started(opencensus),
Config;
init_per_testcase(_Name, Config) ->
@@ -241,7 +241,7 @@ full(_Config) ->
?assertMatch(?VD,
lists:sort(oc_stat:export())),
- ?assertMatch(true, oc_stat_exporter:registered(oc_stat_exporter_pid)),
+ % ?assertMatch(true, oc_stat_exporter:registered(oc_stat_exporter_pid)),
receive
{view_data, Thing} ->
diff --git a/test/oc_stat_exporter_pid.erl b/test/oc_stat_exporter_pid.erl
index 8e743bc..a15bc1f 100644
--- a/test/oc_stat_exporter_pid.erl
+++ b/test/oc_stat_exporter_pid.erl
@@ -1,6 +1,14 @@
-module(oc_stat_exporter_pid).
--export([export/2]).
+-behaviour(gen_event).
-export(ViewData, Pid) ->
+-export([init/1,
+ handle_call/2,
+ handle_event/2]).
+
+init(Pid) -> {ok, Pid}.
+
+handle_call(_Msg, State) -> {ok, ok, State}.
+
+handle_event({stats, ViewData}, Pid) ->
Pid ! {view_data, ViewData}.
diff --git a/test/oc_sweeper_SUITE.erl b/test/oc_sweeper_SUITE.erl
index 0d04e73..6913774 100644
--- a/test/oc_sweeper_SUITE.erl
+++ b/test/oc_sweeper_SUITE.erl
@@ -33,8 +33,9 @@ init_per_testcase(storage_size, Config) ->
span_ttl => 500,
storage_size => 100}),
- application:set_env(opencensus, send_interval_ms, 1),
- application:set_env(opencensus, reporters, [{oc_reporter_pid, self()}]),
+ Reporters = [{oc_reporter_pid, self()}],
+ application:set_env(opencensus, trace, [{interval, 1},
+ {handlers, Reporters}]),
{ok, _} = application:ensure_all_started(opencensus),
Config;
init_per_testcase(Type, Config) ->
@@ -42,8 +43,9 @@ init_per_testcase(Type, Config) ->
strategy => Type,
span_ttl => 500}),
- application:set_env(opencensus, send_interval_ms, 1),
- application:set_env(opencensus, reporters, [{oc_reporter_pid, self()}]),
+ Reporters = [{oc_reporter_pid, self()}],
+ application:set_env(opencensus, trace, [{interval, 1},
+ {handlers, Reporters}]),
{ok, _} = application:ensure_all_started(opencensus),
Config.
diff --git a/test/oc_tab_reporter.erl b/test/oc_tab_reporter.erl
index 5bd3bae..5ed64fb 100644
--- a/test/oc_tab_reporter.erl
+++ b/test/oc_tab_reporter.erl
@@ -17,15 +17,17 @@
%%%-----------------------------------------------------------------------
-module(oc_tab_reporter).
--behaviour(oc_reporter).
+-behaviour(gen_event).
-export([init/1,
- report/2]).
+ handle_call/2,
+ handle_event/2]).
-init(_) ->
- application:get_env(opencensus, tab_reporter, #{}).
+init(Tab) -> {ok, Tab}.
-report(Spans, Opts) ->
- Tid = maps:get(tid, Opts),
- ets:insert(Tid, Spans),
- ok.
+handle_call(_Msg, State) -> {ok, ok, State}.
+
+handle_event({spans, Spans}, Tab) ->
+ true = ets:insert(Tab, Spans),
+
+ {ok, Tab}.
diff --git a/test/oc_reporters_SUITE.erl b/test/oc_trace_reporter_SUITE.erl
similarity index 87%
rename from test/oc_reporters_SUITE.erl
rename to test/oc_trace_reporter_SUITE.erl
index 0921914..e0cf32e 100644
--- a/test/oc_reporters_SUITE.erl
+++ b/test/oc_trace_reporter_SUITE.erl
@@ -2,7 +2,7 @@
%%% @doc
%%% @end
%%% ---------------------------------------------------------------------------
--module(oc_reporters_SUITE).
+-module(oc_trace_reporter_SUITE).
-compile(export_all).
@@ -25,17 +25,20 @@ end_per_suite(_Config) ->
ok.
init_per_testcase(pid_reporter, Config) ->
- application:set_env(opencensus, send_interval_ms, 1),
- application:set_env(opencensus, reporters, [{oc_reporter_pid, self()}]),
+ Reporters = [{oc_reporter_pid, self()}],
+ application:set_env(opencensus, trace, [{interval, 1},
+ {handlers, Reporters}]),
{ok, _} = application:ensure_all_started(opencensus),
Config;
init_per_testcase(dynamically_register_reporter, Config) ->
- application:set_env(opencensus, send_interval_ms, 1),
+ application:set_env(opencensus, trace, [{interval, 1}]),
{ok, _} = application:ensure_all_started(opencensus),
Config;
init_per_testcase(sequential_reporter, Config) ->
- application:set_env(opencensus, send_interval_ms, 1),
- application:set_env(opencensus, reporters, [{oc_reporter_pid, self()}, {oc_reporter_pid, self()}]),
+ Reporters = [{{oc_reporter_pid, 1}, self()},
+ {{oc_reporter_pid, 2}, self()}],
+ application:set_env(opencensus, trace, [{interval, 1},
+ {handlers, Reporters}]),
{ok, _} = application:ensure_all_started(opencensus),
Config.
@@ -54,8 +57,8 @@ pid_reporter(_Config) ->
?assertEqual(ChildSpanName1, ChildSpanData#span.name),
?assertEqual(SpanCtx#span_ctx.span_id, ChildSpanData#span.parent_span_id),
- oc_trace:finish_span(ChildSpanCtx),
- oc_trace:finish_span(SpanCtx),
+ ok = oc_trace:finish_span(ChildSpanCtx),
+ ok = oc_trace:finish_span(SpanCtx),
%% Order the spans are reported is undefined, so use a selective receive to make
%% sure we get them all
@@ -73,7 +76,7 @@ pid_reporter(_Config) ->
end, [SpanName1, ChildSpanName1]).
dynamically_register_reporter(_Config) ->
- oc_reporter:register(oc_reporter_pid, self()),
+ oc_trace:add_handler(oc_reporter_pid, self()),
SpanName1 = <<"span-1">>,
SpanCtx = oc_trace:start_span(SpanName1, undefined),
@@ -119,7 +122,7 @@ sequential_reporter(_Config) ->
receive
{span, #span{name = Name}} ->
Name
- after 5000 ->
+ after 1000 ->
undefined
end
end, SortedNames), %% receive order is undefined though
diff --git a/test/oc_transform_SUITE.erl b/test/oc_transform_SUITE.erl
index 06e4748..2d16a8e 100644
--- a/test/oc_transform_SUITE.erl
+++ b/test/oc_transform_SUITE.erl
@@ -25,9 +25,9 @@ end_per_suite(_Config) ->
ok.
init_per_testcase(_, Config) ->
- application:set_env(opencensus, reporters, [{oc_reporter_pid, self()}]),
- application:set_env(opencensus, pid_reporter, #{pid => self()}),
-
+ Reporters = [{oc_reporter_pid, self()}],
+ application:set_env(opencensus, trace, [{interval, 1},
+ {handlers, Reporters}]),
{ok, _} = application:ensure_all_started(opencensus),
Config.
diff --git a/test/ocp_SUITE.erl b/test/ocp_SUITE.erl
index fdbc5a7..e413876 100644
--- a/test/ocp_SUITE.erl
+++ b/test/ocp_SUITE.erl
@@ -28,9 +28,9 @@ end_per_suite(_Config) ->
init_per_testcase(_, Config) ->
Tab = ets:new(reporter_tab, [public, {keypos, #span.span_id}]),
- application:set_env(opencensus, send_interval_ms, 1),
- application:set_env(opencensus, reporters, [{oc_tab_reporter, []}]),
- application:set_env(opencensus, tab_reporter, #{tid => Tab}),
+ Reporters = [{oc_tab_reporter, Tab}],
+ application:set_env(opencensus, trace, [{interval, 1},
+ {handlers, Reporters}]),
{ok, _} = application:ensure_all_started(opencensus),
[{tid, Tab} | Config].
diff --git a/test/opencensus_SUITE.erl b/test/opencensus_SUITE.erl
index 486c755..fb0dd3b 100644
--- a/test/opencensus_SUITE.erl
+++ b/test/opencensus_SUITE.erl
@@ -26,9 +26,9 @@ end_per_suite(_Config) ->
init_per_testcase(_, Config) ->
Tab = ets:new(reporter_tab, [public, {keypos, #span.span_id}]),
- application:set_env(opencensus, send_interval_ms, 1),
- application:set_env(opencensus, reporters, [{oc_tab_reporter, []}]),
- application:set_env(opencensus, tab_reporter, #{tid => Tab}),
+ Reporters = [{oc_tab_reporter, Tab}],
+ application:set_env(opencensus, trace, [{interval, 1},
+ {handlers, Reporters}]),
application:set_env(opencensus, sampler, {oc_sampler_always, []}),
{ok, _} = application:ensure_all_started(opencensus),
[{tid, Tab} | Config].
@@ -52,7 +52,7 @@ start_finish(Config) ->
?assertEqual(false, oc_trace:put_attribute(<<"attr-1">>, <<"value-1">>, SpanCtx)),
%% finish already finished span
- ?assertEqual(false, oc_trace:finish_span(SpanCtx)).
+ ?assertEqual({error, invalid_span}, oc_trace:finish_span(SpanCtx)).
child_spans(Config) ->
Tab = ?config(tid, Config),
|