Current section
Files
Jump to
Current section
Files
src/otter_span.erl
%%%-------------------------------------------------------------------
%%% 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.
%%%
%%% @doc This module supports both the functional and p-dict style
%%% APIs. This is for internal use. Use the API in the `otter' module
%%% primarily, or if you want to use the process dictionary API, use
%%% the `otter_span_pdict_api' module
%%% @end
%%% -------------------------------------------------------------------
-module(otter_span).
-export([
fstart/1, fstart/2, fstart/3,
fend/1,
fget_ids/1,
flog/2, flog/3,
ftag/3, ftag/4,
pstart/1, pstart/2, pstart/3,
pend/0,
pget_span/0,
pget_ids/0,
plog/1, plog/2,
ptag/2, ptag/3
]).
-include("otter.hrl").
fstart(Name) ->
fstart(Name, otter_lib:id()).
fstart(Name, TraceId) ->
fstart(Name, TraceId, undefined).
fstart(Name, TraceId, ParentId) ->
#span{
timestamp = otter_lib:timestamp(),
trace_id = TraceId,
id = otter_lib:id(),
parent_id = ParentId,
name = Name
}.
ftag(Span, Key, Value) ->
Tags = Span#span.tags,
Span#span{
tags = lists:keystore(Key, 1, Tags, {Key, Value})
}.
ftag(Span, Key, Value, Service) ->
Tags = Span#span.tags,
Span#span{
tags = lists:keystore(Key, 1, Tags, {Key, Value, Service})
}.
flog(Span, Text) ->
Logs = Span#span.logs,
Span#span{
logs = [{otter_lib:timestamp(), Text} | Logs]
}.
flog(Span, Text, Service) ->
Logs = Span#span.logs,
Span#span{
logs = [{otter_lib:timestamp(), Text, Service} | Logs]
}.
fend(Span) ->
Start = Span#span.timestamp,
Logs = Span#span.logs,
otter_filter:span(Span#span{
duration = otter_lib:timestamp() - Start,
logs = lists:reverse(Logs)
}),
ok.
fget_ids(Span) ->
#span{trace_id = TraceId, id = Id} = Span,
{TraceId, Id}.
%% ==================== SPAN process API ======================
%% This API uses the process dictionary to collect span information
%% and can be used when all span tags an events happen in the same
%% request handling process.
pstart(Name) ->
pstart(Name, otter_lib:id()).
pstart(Name, TraceId) ->
pstart(Name, TraceId, undefined).
pstart(Name, TraceId, ParentId) ->
Span = fstart(Name, TraceId, ParentId),
put(otter_span_information, Span),
Span.
ptag(Key, Value) ->
Span = ftag(get(otter_span_information), Key, Value),
put(otter_span_information, Span),
Span.
ptag(Key, Value, Service) ->
Span = ftag(get(otter_span_information), Key, Value, Service),
put(otter_span_information, Span),
Span.
plog(Text) ->
Span = flog(get(otter_span_information), Text),
put(otter_span_information, Span),
Span.
plog(Text, Service) ->
Span = flog(get(otter_span_information), Text, Service),
put(otter_span_information, Span),
Span.
pend() ->
Span = get(otter_span_information),
fend(Span).
%% This call can be used to retrieve the IDs from the calling process
%% e.g. when you have a gen_server and you get an API function call
%% (which is in the context of the calling process) then calling pget_id()
%% returns a {TraceId, SpanId} that is stored with the process API calls
%% above for the calling process, so they can be used in the handling of
%% the call
pget_ids() ->
#span{trace_id = TraceId, id = Id} = get(otter_span_information),
{TraceId, Id}.
pget_span() ->
get(otter_span_information).