View Source exometer_function (exometer_core v1.7.1)

Summary

Types

-type arg() :: '$dp' | {'$call', atom(), atom(), arg_spec()} | any().
-type arg_spec() :: [arg()].
-type binding() :: {atom(), any()}.
-type datapoints() :: [atom()].
-type expr() :: expr_descr() | expr_action() | expr_match() | expr_erl().
-type expr_action() :: expr_op() | expr_call() | expr_fold() | expr_case().
-type expr_atom() :: atom() | {a, atom()} | {atom, atom()}.
-type expr_binary_op() :: {op, expr_operator(), expr(), expr()}.
-type expr_call() :: {call, atom(), [expr()]} | {call, {atom(), atom()}, [expr()]}.
-type expr_case() :: {'case', [expr()], [expr_clause()]}.
-type expr_clause() :: {expr_pattern(), [expr_guard()], [expr()]}.
-type expr_descr() :: expr_int() | expr_atom() | expr_list() | expr_tuple() | expr_string().
-type expr_erl() :: {erl, [erl_parse:abstract_expr()]}.
-type expr_fold() ::
    {fold,
     _IterVal :: atom(),
     _AccVar :: atom(),
     _IterExpr :: [expr()],
     _Acc0Expr :: expr(),
     _ListExpr :: expr()}.
-type expr_guard() :: [expr()].
Must all return 'true'.
-type expr_int() :: integer() | {i, integer()} | {integer, integer()}.
-type expr_list() :: {cons, expr(), expr()} | nil | {l, [expr()]}.
-type expr_match() :: {match, expr_pattern(), expr()} | {m, expr_pattern(), expr()}.
-type expr_op() :: expr_unary_op() | expr_binary_op().
-type expr_operator() ::
    '+' | '-' | '*' | '/' | 'div' | 'rem' | 'band' | 'and' | 'bor' | 'bxor' | 'bsl' | 'bsr' |
    'or' | 'xor' | '++' | '--' | '==' | '/=' | '>=' | '=<' | '<' | '>' | '=:=' | '=/='.
-type expr_pattern() :: '_' | expr_descr().
-type expr_string() :: {string, string()} | {s, string()}.
-type expr_tuple() :: {tuple, [expr()]} | {t, [expr()]}.
-type expr_unary_op() :: {op, '-' | 'not', expr()}.
-type extended_fun() :: {function, mod_name(), fun_name(), arg_spec(), res_type(), datapoints()}.
-type fun_name() :: atom().
-type fun_rep() ::
    {mod_name(), fun_name()} |
    {mod_name(), fun_name(), each | once, arg_spec(), res_type(), datapoints()} |
    {mod_name(), fun_name(), each | once, arg_spec(), match, any()} |
    {eval, [expr()], datapoints()}.
-type fun_spec() :: simple_fun() | extended_fun().
-type mod_name() :: atom().
-type res_type() :: value | proplist | tagged.
-type simple_fun() :: {function, mod_name(), fun_name()}.

Functions

-spec behaviour() -> exometer:behaviour().
-spec eval_exprs([expr()], [binding()]) -> {value, any(), [binding()]}.

Evaluate a list of abstract expressions.

This function is reminiscent of erl_eval:exprs/2, but with a slightly different expression grammar. Most prominently, forms have no line numbers, and a few aliases for more compact representation. Otherwise, the forms can be seen as mostly a subset of the Erlang abstract forms.

The list of bindings correspods exactly to the bindings in erl_eval.

* Integers: {integer, I}, {i, I}, or simply just the integer * Atoms: {atom, A}, {a, A}, or simply just the atom (note that some atoms are special). * Lists: {cons, H, T}, nil, or {l, [...]} * Tuples: {tuple, [Elem]}, or {t, [Elem]} * Variables: {var, V}, or {v, V} * Matches: {match, Pattern, Expr}, or {m, Pattern, Expr} * Function calls: {call, {M, F}, Args}, or {call, F, Args} * Folds: {fold, IterVar, AccVar, [IterExpr], Acc0Expr, ListExpr} * Operators: {op, Op, ExprA, ExprB} * Unary operators: {op, '-' | 'not', Expr} * Case exprs: {'case', [Expr], [{Pat, Gs, Body}]} * Generic Erlang: {erl, [ErlAbstractExpr]}

The currently supported "built-in functions" are length/1, size/1, byte_size/1 and bit_size/1.

The operators supported are all the Erlang binary operators (as in: '+', '-', '==', '=/=', etc.)

When evaluating guards in a case clause, any expression is legal. The guard must return true to succeed. Note that the abstract form of a guard sequence is [ [G11,...], [G21,...], ...], where each sublist represents an 'and' sequence, i.e. all guards in the sublist must succeed. The relationship between sublists is 'or'. This is the same as in Erlang.
Link to this function

get_datapoints(Name, Type, T)

View Source
Link to this function

get_value(_, _, _, DataPoints0)

View Source
-spec new(exometer:name(), function, exometer:options()) -> {ok, fun_rep()}.

Callback for creating an exometer function entry.

Function entries are created as
  exometer:new(Name,{function,...},Opts)
  
which is syntactic sugar for
  exometer:new(Name,function,[{arg,{function,...}}|Opts])
  

{function,...} can be {function, Mod, Fun}, in which case where get_value(Name, DataPoints) will result in a call to Mod:Fun(DataPoints). Invoking get_value(Name) (with no datapoints), will call Mod:Fun(default), which must return a default list of data point values. `{function,...} can also be setup as {function, Mod,Fun,ArgSpec,Type,DataPoints} in order to invoke a limited interpreter. The ArgSpec is evaluated as follows:

  • [] means to call with no arguments, i.e. M:F()
  • A list of patterns will be used as arguments, substituting the following patterns:
    • '$dp' is replaced by the current data point
    • '$datapoints' is replaced by the requested list of data points. Note that '$dp' and '$datapoints' are mutually exclusive
    • {'$call', M, F, Args0} will be replaced by the result of calling apply(M, F, Args) where Args is the list of arguments after performing substitution on Args0.
    • {'$value', Term} uses Term without substitution.
The return value of the above call will be processed according to Type:
  • If Type==value, the return value is returned as-is
  • If Type==histogram, the return value is a list of integers, which will be compiled into a histogram (see exometer_histogram).
  • If Type==proplist, the current data point or list of data points will be picked out of the returned proplist.
  • If Type==tagged, the return value is assumed to be either {ok, Value} or {DataPointName, Value}.
  • If Type==match, DataPoints is used as a pattern to match against, where the names of data points are used where the values are expected to be, and '_' is used for values to ignore. The pattern can be any combination of tuples and lists of datapoints or '_'.
  • If Type==eval, DataPoints is expected to be {Exprs, DPs}, and eval_exprs/2 will be used to evaluate Exprs. The return value from the function call will be bound to Value, and the list of data points will be bound to DPs. The evaluation must return a list of {DataPointName, Value} tuples.

An alternative version of arg is {arg, {eval, Exprs, Datapoints}}, which doesn't in fact call a function, but simply evaluates Exprs using eval_exprs/2, with the pre-bound variables Value = undefined and DPs = Datapoints.

Examples:

An entry that returns a subset of erlang:memory():

  exometer:new([mem], {function,erlang,memory,[],proplist,[total,processes]}).
  

An entry that reports the heap size and message queue length of the code server:

  exometer:new(
      [code_server, pinfo],
      {function,erlang,process_info,[{'$call',erlang,whereis,[code_server]}],
       proplist, [heap_size, message_queue_len]}).
  

An entry that reports the heap size of the code server.

  exometer:new(
    [code_server, heap_size],
    {function,erlang,process_info,
     [{'$call',erlang,whereis,[code_server]}, '$dp'], tagged, [heap_size]}).
  

An entry that does pattern-matching on the return value (erlang:statistics(garbage_collection) returns {GCs, Reclaimed, 0}).

  exometer:new(
     [gc],
     { function,erlang,statistics,[garbage_collection],
       match, {gcs,reclaimed,'_'} }, []).
  

An entry that calls erlang:processes() and evaluates a list of expressions that calculate the length of the returned list.

  exometer:new(
      [ps],
      {function,erlang,processes,[],
       eval, {[{l,[{t,[value,{call,length,[{v,'Value'}]}]}]}],[value]}}, []).
  

An entry that simply builds a list of datapoints, using the abstract syntax.

  exometer:new([stub],
      {function,{eval,[{l,[{t,[{a,1}]},{t,[{b,2}]}]}], [a,b]}}, []).
  
Link to this function

preprocess_setopts(Name, Opts, Type, Ref, OldOpts)

View Source
Link to this function

test_mem_info(DataPoints)

View Source