Skip to content
This repository was archived by the owner on Jul 31, 2023. It is now read-only.

Latest commit

 

History

History
222 lines (152 loc) · 10.3 KB

File metadata and controls

222 lines (152 loc) · 10.3 KB

OpenCensus Erlang library

Version: 0.2.0

Erlang stats collection and distributed tracing framework

CircleCI Coverage Status Hex.pm Hex.pm

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"}}}]}.

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 a ctx record.

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).

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.

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.

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.

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),

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_events. 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 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).

oc_sampler_never: Never enable a new trace, but keeps a trace enabled if its propagated context is enabled.

oc_sampler_always: Enable every new trace for sampling.

oc_sampler_probability: Takes a probability, default 0.5, that any new trace will be sampled.

Google Cloud Trace: Support for v1 in master, v2 and grpc coming soon;

Prometheus: Exports spans as Prometheus metrics.

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

Modules

oc_producer
oc_producer_registry
oc_propagation_binary
oc_propagation_http_b3
oc_propagation_http_tracecontext
oc_reporter
oc_reporter_pid
oc_reporter_stdout
oc_sampler
oc_sampler_always
oc_sampler_impl
oc_sampler_never
oc_sampler_period_or_count
oc_sampler_probability
oc_self_producer
oc_server
oc_span
oc_span_sweeper
oc_span_transform
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_stdout
oc_stat_measure
oc_stat_transform
oc_stat_unit
oc_stat_view
oc_tag_ctx_binary
oc_tag_ctx_header
oc_tags
oc_trace
oc_tracestate
ocp
opencensus
opencensus_app
opencensus_sup