%% ------------------------------------------------------------------- %% %% 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 Accessor function for exometer data structures %% %% This module uses the exprecs transform (see exprecs) %% to generate accessor functions for exometer data structures. %% %% Note that the `value' attribute in `exometer_entry{}' records may not %% represent the true value of the metric, since exometer entries often %% have structured values, or are represented as CRDTs for update efficiency. %% %% @end -module(exometer_info). -export([status/1, pp/1, pp_lookup/1, pp_find/1, pp_select/1]). -include("exometer.hrl"). -include_lib("parse_trans/include/exprecs.hrl"). -export_type([pp/0]). -export_records([exometer_entry]). -type pp() :: {atom(), [{atom(), any()}]}. -spec status(exometer:entry()) -> enabled | disabled. %% @doc Return the operational status of the given exometer entry. %% %% The `status' attribute is overloaded in the `#exometer_entry{}' record. %% This function extracts the correct status (`enabled | disabled'). %% @end status(#exometer_entry{status = St}) -> exometer_util:get_status(St). -spec pp(tuple() | list()) -> pp() | [pp() | any()]. %% @doc Pretty-print a record, or list containing records. %% %% This function pretty-prints a record as `{RecordName, [{Attr,Value}]}', %% or, if the input is a list, recognizes records and pretty-prints them, %% leaving other data structures unchanged. %% @end pp(L) when is_list(L) -> [pp(X) || X <- L]; pp(X) -> case '#is_record-'(X) of true -> RecName = element(1,X), {RecName, lists:zip( '#info-'(RecName,fields), pp(tl(tuple_to_list(X))))}; false -> if is_tuple(X) -> list_to_tuple(pp(tuple_to_list(X))); true -> X end end. -spec pp_lookup(exometer:name()) -> pp() | undefined. %% @doc Performs a lookup by name of entry and pretty-prints the result. %% %% This function returns `undefined' if the entry cannot be found. %% @end pp_lookup(Name) -> case exometer:info(Name, entry) of undefined -> undefined; Entry -> pp(Entry) end. -spec pp_find(list()) -> [pp()]. %% @doc Performs `exometer:find_entries(Path) & returns pretty-printed result. %% %% This function calls `exometer:find_entries(Path)', retrieves the entry %% for each matching metric, and calls `pp(Entry)' for each entry. %% @end pp_find(Path) -> pp([exometer:info(M, entry) || {M,_,_} <- exometer:find_entries(Path)]). -spec pp_select(ets:match_spec()) -> [pp()]. %% @doc Performs `exometer:select(Pattern) & returns pretty-printed result. %% %% This function calls `exometer:select(Pattern)', retrieves the entry %% for each matching metric, and calls `pp(Entry)' for each entry. %% %% Note that the match body of the select pattern must produce the full %% `{Name, Type, Status}' object, e.g. by specifying ['$_']. %% @end pp_select(Pat) -> pp([exometer:info(M, entry) || {M,_,_} <- exometer:select(Pat)]).