%% ------------------------------------------------------------------- %% %% Copyright (c) 2014 Basho Technologies, Inc. All Rights Reserved. %% %% This Source Code Form is subject to the terms of the Mozilla Public %% License, v. 2.0. If a copy of the MPL was not distributed with this %% file, You can obtain one at http://mozilla.org/MPL/2.0/. %% %% ------------------------------------------------------------------- %% @doc %% == Creating custom exometer entries == %% %% An exometer_entry behavior implementation can be created when custom %% processing of various metrics is needed. %% %% A custom exometer entry is invoked by mapping a type to the module %% name of the custom exometer entry module. All metrics created with the %% given type will trigger the invocation of the new entry module. See %% {@section Configuring type - entry maps} for details on how to setup %% such maps. %% %% The life cycle of a an exometer entry consists of the following steps. %% %% + Metrics Creation %%
`new/3' is invoked by exometer to signal that a new metrics %% should be created. The name of the new metric will be provided as %% a list of atoms. %% %% + Update Data %%
Values will be sent to the entry through the `update/4' %% function. The custom entry should store this value for the given %% metric and break it down into data points that can be reported for %% the metric. %% %% + Retrieve Value %%
`get_value/4' will be invoked by exometer to retrieve specific %% data points from a given metric. %% %% See individual functions for details on the %% in the exometer_entry behavior. %% %% === behaviour/0 === %% %% The `behaviour()' function for an entry implementation should return %% the atom `entry'. This function will be involved by the %% exometer system in order to determine if a callback is %% an entry or a probe. %% %% === new/3 === %% %% The `new()' function is invoked as follows: %% %%
%%      new(Name, Type, Options)
%% %% The custom entry should create the necessary state for the new metric and store %% it for furure access through `update()' and `get_value()' calls. %% %% + `Name' %%
Specifies the name of the metric to be created as a list of atoms. %% %% + `Type' %%
Specifies the type provided to the `exometer:new()' call (before it %% was translated by the type - exometer entry map). It can be used if several %% different types are mapped to the same entry module. %% %% + `Options' %%
Specifies an option list that contains additional setup directives to %% the entry. The actual options to support are implementation dependent. %% %% The `new()' function should return `{ok, Ref}' where Ref is a %% tuple that will be provided as a reference argument to other calls %% made into the module. Any other return formats will cancel the %% creation of the new metric. %% %% === delete/3 === %% %% The `delete()' function is invoked as follows: %% %%
%%      delete(Name, Type, Ref)
%% %% The custom entry should free all resources associated with the given name. %% %% + `Name' %%
Specifies the name of the metric to be deleted as a list of atoms. %% %% + `Type' %%
Specifies the type provided to the `exometer:new()' call (before it %% was translated by the type - exometer entry map). %% %% + `Ref' %%
Will contain the same tuple returned as `Ref' by the module's `new()' function. %% %% The `delete()' function shall return `ok'. %% %% %% === get_value/4 === %% %% The `get_value()' function is invoked as follows: %% %%
%%      get_value(Name, Type, Ref, DataPoints)
%% %% The custom entry should retrieve the metric with the given name and %% return the values of the specified data points. Data points can be %% expected to be one or more of those returned by the entry's %% `get_datapoints()' function. %% %% + `Name' %%
Specifies the name of the metric to update with a value. %% %% + `Type' %%
Specifies the type provided to the `exometer:new()' call (before it %% was translated by the type - exometer entry map). %% %% + `Ref' %%
Will contain the same tuple returned as `Ref' by the module's `new()' function. %% %% + `DataPoints' %%
Will contain a list of data points, each picked from the list returned by %% the module's `get_datapoints()' function. %% %% The `get_value()' function should calculate the values of the given %% data points based on previous calls to `update()' and return them to the caller. %% %% The return format shall be: %% %%
%%      {ok, [ { DataPoint, Value }, ...]}
%% %% Each `{ DataPoint, Value }' tuple shall contain the name and value of %% one of the data points provided as arguments to `get_value()'. %% %% If a data point is not valid (i.e. not in the list returned by %% `get_datapoints()'), the returned tuple should be `{ DataPoint, %% undefined }'. %% %% %% === update/4 === %% %% The `update()' function is invoked as follows: %% %%
%%      update(Name, Value, Type, Ref)
%% %% + `Name' %%
Specifies the name of the metric to update. %% %% + `Value' %%
Specifies the new value to integrate into the given metric. %% %% + `Type' %%
Specifies the type provided to the `exometer:new()' call (before it %% was translated by the type - exometer entry map). %% %% + `Ref' %%
Will contain the same tuple returned as `Ref' by the module's `new()' function. %% %% The `update()' function should update the data points for the metric with the %% given name in preparation for future calls to `get_value()'. %% %% The return format shall be `ok'. %% %% %% === reset/3 === %% %% The `reset()' function is invoked as follows: %% %%
%%      reset(Name, Type, Ref)
%% %% + `Name' %%
Specifies the name of the metric to reset. %% %% + `Type' %%
Specifies the type provided to the `exometer:new()' call (before it %% was translated by the type - exometer entry map). %% %% + `Ref' %%
Will contain the same tuple returned as `Ref' by the module's `new()' function. %% %% The `reset()' function should revert the metric with the given name to %% its original state. A counter, for example, should be reset to 0 while %% histograms should be emptied. %% %% The return format shall be `ok'. %% %% === sample/3 === %% %% The `sample()' function is invoked as follows: %% %%
%%      sample(Name, Type, Ref)
%% %% + `Name' %%
Specifies the name of the metric to run the sample. %% %% + `Type' %%
Specifies the type provided to the `exometer:new()' call (before it %% was translated by the type - exometer entry map). %% %% + `Ref' %%
Will contain the same tuple returned as `Ref' by the module's %% `new()' function. %% %% This function is only used by probes, where it is periodically called %% to sample a local sub system such as /proc or netlink in order to %% update its data points. %% %% Any exometer entry-based implementation should do nothing and return %% `ok'. %% %% === get_datapoints/3 === %% %% The `get_datapoints()' function is invoked as follows: %% %%
%%      get_datapoints(Name, Type, Ref)
%% %% + `Name' %%
Specifies the name of the metric to return available datapoints for. %% %% + `Type' %%
Specifies the type provided to the `exometer:new()' call (before it %% was translated by the type - exometer entry map). %% %% + `Ref' %%
Will contain the same tuple returned as `Ref' by the module's %% `new()' function. %% %% This function should return a list of all data points supported by %% the exometer entry implementation. The returned data points shall %% be supported by the module's `get_value()' function. %% %% %% === setopts/3 === %% %% The `setopts()' function is invoked as follows: %% %%
%%      setopts(Entry, Options, Type, Ref)
%% %% + `Entry' %% The (opaque) exometer entry record. See {@link exometer_info} for %% information on how to inspect the data structure. %% %% + `Options' %%
Specifies an option list that contains additional setup directives to %% the entry. The actual options to support are implementation dependent. %% %% + `Type' %%
Specifies the type provided to the `exometer:new()' call (before it %% was translated by the type - exometer entry map). %% %% + `Ref' %%
Will contain the same tuple returned as `Ref' by the module's %% `new()' function. %% %% This function should modify the behavior of the given metric by the %% options provided in the `Options' property list. %% %% The function should return either `ok' or `{error, Reason}', where %% `Reason' contins a descriptive reason for a failure to set one or more %% options. %% %% @end -module(exometer_entry). -include("exometer.hrl"). -export_type([name/0, type/0, options/0, datapoint/0, datapoints/0, value/0, ref/0, error/0]). -type name() :: list(). -type type() :: atom(). -type options() :: [{atom(), any()}]. -type datapoints() :: [datapoint()]. -type datapoint() :: exometer:datapoint(). -type value() :: any(). -type ref() :: any(). -type error() :: {error, any()}. -callback behaviour() -> exometer:behaviour(). -callback new(name(), type(), options()) -> ok | {ok, ref()} | error(). -callback delete(name(), type(), ref()) -> ok | error(). -callback get_value(name(), type(), ref(), datapoints()) -> [{datapoint(), value()}]. -callback update(name(), value(), type(), ref()) -> ok | {ok, value()} | error(). -callback reset(name(), type(), ref()) -> ok | {ok, value()} | error(). -callback sample(name(), type(), ref()) -> ok | error(). -callback get_datapoints(name(), type(), ref()) -> datapoints(). -callback setopts(exometer:entry(), options(), exometer:status()) -> ok | error().