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 oc_stat oc_stat_aggregation oc_stat_aggregation_count oc_stat_aggregation_distribution oc_stat_aggregation_latest oc_stat_aggregation_sum oc_stat_config oc_stat_exporter oc_stat_exporter_prometheus oc_stat_view oc_std_encoder oc_tag_ctx_binary oc_tags oc_trace oc_trace_pb oc_transform ocp opencensus opencensus_app opencensus_sup

@title OpenCensus Erlang library @version 0.2.0

@doc

Erlang stats collection and distributed tracing framework

CircleCI Coverage Status Hex.pm Hex.pm

=== Using with Rebar3 project ===

Add as dependency to `rebar.config':

{deps, [opencensus]}.
      '''
      
      Or to use the latest from git master branch:
      
      

{deps, [{opencensus, {git, "https://github.com/census-instrumentation/opencensus-erlang.git", {branch, "master"}}}]}. '''

=== Creating Spans ===

Span data is stored and manipulated in an ETS table. Span context must be tracked in order to create child span's, propagate span context across process or node boundaries and for the library to which span data to manipulate in the context it is called.

opencensus' provides two methods for tracking this context, the process dictionary and a variable holding actx' record.

==== Process Dictionary as Context ====

With ocp the span context is tracked in the current process's process dictionary.

some_fun() ->
        ocp:with_child_span(<<"some_fun/0">>,
                            fun() ->
                                ... body ..
                            end).
      
      '''
      
      ==== Parse Transform ====
      
      The parse transform provides an attribute to decorate functions with that will start a span, wrap the contents in a `try' and finish the span in an `after' clause. Add the parse transform to the compile opts in `rebar.config':
      
      

{erl_opts, [{parse_transform, oc_transform}]}. '''

And use:

-span([]).
      function_to_trace() ->
        ...
        SpanCtx = ocp:current_span(), %% ocp works in a decorated function too
        ...
      '''
      
      Since the tranformed functions use the process dictionary to store the context you can interact with the current span the same way as you do with `ocp', covered in the previous section.
      
      ==== Manual Context Tracking ====
      
      `ctx' is a generic context library for Erlang. OpenCensus provides the option to use it in place of the process dictionary for tracking the span context.
      
      In this example a function is passed a `ctx' variable `Ctx' that some instrumented library could have set the span context based on the incoming metadata of a request, like HTTP headers. The `oc_trace:new_span' function will check `Ctx' for a span context and create a child span of that span context if it exists, otherwise a root span will be created. We can pass the span context to another function, we could also createa a new `ctx' to pass (`oc_trace:with_span(Ctx, SpanCtx)'), to be further updated or have new children created:
      
      

handler(Ctx, NextHandler) -> SpanCtx = oc_trace:with_child_span(Ctx, <<"span-name">>), try oc_trace:put_attribute(<<"key">>, <<"value">>, SpanCtx), {Code, Message} = NextHandler(SpanCtx), oc_trace:set_status(Code, Message, SpanCtx) after oc_trace:finish_span(SpanCtx) end. '''

==== Manual Span Data Handling ====

The module `oc_span' has the functional span data manipulation functions, meaning ETS is not involved. Most users will not need this, but for potential alternative span data stores or context trackers they are necessary.

=== Working with Spans ===

==== Attributes ====

A span has a map of attributes providing details about the span. The key is a binary string and the value of the attribute can be a binary string, integer, or boolean.

Span1 = oc_trace:put_attribute(<<"/instance_id">>, <<"my-instance">>, SpanCtx),
      '''
      
      ==== Time Events ====
      
      A time event is a timestamped annotation with user-supplied key-value pairs or a message event to represent a message (not specificly an Erlang message) sent to or received from another span.
      
      The `message_event' consists of a type, identifier and size of the message. `Id' is an identifier for the event's message that can be used to match `SENT' and `RECEIVED' `message_event's. For example, this field could represent a sequence ID for a streaming RPC. It is recommended to be unique within a Span. If `CompressedSize' is `0' it is assumed to be the same as `UncompressedSize'.
      
      

Event = opencensus:message_event(?MESSAGE_EVENT_TYPE_SENT, Id, UncompressedSize, CompressedSize) oc_trace:add_time_event(Event, SpanCtx), '''

==== Links ====

Links are useful in cases like a job queue. A job is created with a span context and when run wants to report a new span. The job isn't a direct child of the span that inserted it into the queue, but it is related. The job creates a link to the span that created it.

SpanCtx = oc_trace:with_child_span(Ctx, <<"running job">>),
      Link = oc_trace:link(?LINK_TYPE_PARENT_LINKED_SPAN, TraceId, ParentSpanId, #{}),
      oc_trace:add_link(Link, SpanCtx),
      ... run job ...
      oc_trace:finish_span(SpanCtx).
      '''
      
      === Propagating Span Context ===
      
      === Samplers ===
      
      {@link oc_sampler_never. <b>oc_sampler_never:</b>} Never enable a new trace, but keeps a trace enabled if its propagated context is enabled.
      
      {@link oc_sampler_always. <b>oc_sampler_always:</b>} Enable every new trace for sampling.
      
      {@link oc_sampler_probability. <b>oc_sampler_probability:</b>} Takes a probability, default 0.5, that any new trace will be sampled.
      
      === Reporters ===
      
      <a href="https://github.com/tsloughter/oc_google_reporter">Google Cloud Trace</a>: Support for v1 in master, v2 and grpc coming soon;
      
      <a href="https://github.com/deadtrickster/opencensus-erlang-prometheus">Prometheus</a>: Exports spans as Prometheus metrics.
      
      === Tags ===
      
      

Ctx1 = oc_tags:new_ctx(Ctx, #{"method" => "GET"}) '''

Tags = oc_tags:from_ctx(Ctx)
      '''
      
      ### Development
      
      

$ rebar3 compile '''

Running tests:

$ rebar3 ct
      '''
      
      #### Updating OpenCensus standard protobuf encoder and decoder
      
      Language independent interface types for Census are found in the `opencensus-proto' repo. The opencensus Erlang app provides functionality for converting from the apps internal representation to the standard protobuf interface. Below are the steps to update the Erlang module and header for encoding and decoding the protobufs:
      
      

$ git clone https://github.com/census-instrumentation/opencensus-proto priv/opencensus-proto $ rebar3 protobuf compile '''