-export(
[ of_beam_stats/1
, of_beam_stats/2
- , to_bin/1
- , path_to_bin/1
+ , to_iolist/1
+ , path_to_iolist/1
, node_id_to_bin/1
]).
+-define(SCHEMA_VERSION, <<"beam_stats_v0">>).
-define(T, #?MODULE).
-type t() ::
++ of_processes(Processes, NodeID, Ts),
lists:map(fun path_prefix_schema_version/1, Msgs).
--spec to_bin(t()) ->
- binary().
-to_bin(
+-spec to_iolist(t()) ->
+ iolist().
+to_iolist(
?T
{ path = Path
, value = Value
, timestamp = Timestamp
}
) ->
- PathBin = path_to_bin(Path),
+ PathIOList = path_to_iolist(Path),
ValueBin = integer_to_binary(Value),
TimestampInt = timestamp_to_integer(Timestamp),
TimestampBin = integer_to_binary(TimestampInt),
- <<PathBin/binary, " ", ValueBin/binary, " ", TimestampBin/binary>>.
+ [PathIOList, <<" ">>, ValueBin, <<" ">>, TimestampBin].
--spec path_to_bin([binary()]) ->
- binary().
-path_to_bin(Path) ->
- bin_join(Path, <<".">>).
+-spec path_to_iolist([binary()]) ->
+ iolist().
+path_to_iolist(Path) ->
+ list_interleave(Path, <<".">>).
-spec node_id_to_bin(node()) ->
binary().
-spec path_prefix_schema_version(t()) ->
t().
path_prefix_schema_version(?T{}=T) ->
- path_prefix(T, schema_version()).
+ path_prefix(T, ?SCHEMA_VERSION).
-spec path_prefix(t(), binary()) ->
t().
path_prefix(?T{path=Path}=T, <<Prefix/binary>>) ->
T?T{path = [Prefix | Path]}.
--spec schema_version() ->
- binary().
-schema_version() ->
- <<"beam_stats_v0">>.
-
--spec bin_join([binary()], binary()) ->
- binary().
-bin_join([] , <<_/binary>> ) -> <<>>;
-bin_join([<<B/binary>> | []] , <<_/binary>> ) -> B;
-bin_join([<<B/binary>> | [_|_]=Bins], <<Sep/binary>>) ->
- BinsBin = bin_join(Bins, Sep),
- <<B/binary, Sep/binary, BinsBin/binary>>.
+-spec list_interleave([A], A) ->
+ [A].
+list_interleave([], _) ->
+ [];
+list_interleave([X], _) ->
+ [X];
+list_interleave([X|Xs], Sep) ->
+ [X, Sep | list_interleave(Xs, Sep)].
-spec timestamp_to_integer(erlang:timestamp()) ->
non_neg_integer().
[t()].
of_ets(PerTableStats, <<NodeID/binary>>, Timestamp) ->
OfEtsTable = fun (Table) -> of_ets_table(Table, NodeID, Timestamp) end,
- NestedMsgs = lists:map(OfEtsTable, PerTableStats),
- lists:append(NestedMsgs).
+ MsgsNested = lists:map(OfEtsTable, PerTableStats),
+ MsgsFlattened = lists:append(MsgsNested),
+ aggregate_by_path(MsgsFlattened, Timestamp).
-spec of_ets_table(beam_stats_ets_table:t(), binary(), erlang:timestamp()) ->
[t()].
<<NodeID/binary>>,
Timestamp
) ->
- IDBin = beam_stats_ets_table:id_to_bin(ID),
+ IDType =
+ case ID =:= Name
+ of true -> <<"NAMED">>
+ ; false -> <<"TID">>
+ end,
NameBin = atom_to_binary(Name, latin1),
- NameAndID = [NameBin, IDBin],
+ NameAndID = [NameBin, IDType],
[ cons([NodeID, <<"ets_table">>, <<"size">> | NameAndID], Size , Timestamp)
, cons([NodeID, <<"ets_table">>, <<"memory">> | NameAndID], Memory, Timestamp)
].
, total_heap_size = TotalHeapSize
, stack_size = StackSize
, message_queue_len = MsgQueueLen
+ , reductions = Reductions
}=Process,
<<NodeID/binary>>,
Timestamp
, cons([N, <<"process_total_heap_size">> , OriginBin], TotalHeapSize , Ts)
, cons([N, <<"process_stack_size">> , OriginBin], StackSize , Ts)
, cons([N, <<"process_message_queue_len">> , OriginBin], MsgQueueLen , Ts)
+ , cons([N, <<"process_reductions">> , OriginBin], Reductions , Ts)
].
-spec aggregate_by_path([t()], erlang:timestamp()) ->