Improve the emqx_vm module and update test cases
This commit is contained in:
parent
d3107facf9
commit
17332b0465
216
src/emqx_vm.erl
216
src/emqx_vm.erl
|
@ -19,6 +19,7 @@
|
||||||
-export([ schedulers/0
|
-export([ schedulers/0
|
||||||
, scheduler_usage/1
|
, scheduler_usage/1
|
||||||
, microsecs/0
|
, microsecs/0
|
||||||
|
, system_info_keys/0
|
||||||
, get_system_info/0
|
, get_system_info/0
|
||||||
, get_system_info/1
|
, get_system_info/1
|
||||||
, get_memory/0
|
, get_memory/0
|
||||||
|
@ -26,11 +27,12 @@
|
||||||
, loads/0
|
, loads/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([ get_process_list/0
|
-export([ process_info_keys/0
|
||||||
, get_process_info/0
|
, get_process_info/0
|
||||||
, get_process_info/1
|
, get_process_info/1
|
||||||
, get_process_gc/0
|
, process_gc_info_keys/0
|
||||||
, get_process_gc/1
|
, get_process_gc_info/0
|
||||||
|
, get_process_gc_info/1
|
||||||
, get_process_group_leader_info/1
|
, get_process_group_leader_info/1
|
||||||
, get_process_limit/0
|
, get_process_limit/0
|
||||||
]).
|
]).
|
||||||
|
@ -62,86 +64,83 @@
|
||||||
sl_alloc,
|
sl_alloc,
|
||||||
ll_alloc,
|
ll_alloc,
|
||||||
fix_alloc,
|
fix_alloc,
|
||||||
std_alloc]).
|
std_alloc
|
||||||
|
]).
|
||||||
|
|
||||||
-define(PROCESS_LIST, [initial_call,
|
-define(PROCESS_INFO_KEYS, [initial_call,
|
||||||
reductions,
|
current_function,
|
||||||
memory,
|
registered_name,
|
||||||
message_queue_len,
|
status,
|
||||||
current_function]).
|
message_queue_len,
|
||||||
|
group_leader,
|
||||||
|
priority,
|
||||||
|
trap_exit,
|
||||||
|
reductions,
|
||||||
|
%%binary,
|
||||||
|
last_calls,
|
||||||
|
catchlevel,
|
||||||
|
trace,
|
||||||
|
suspending,
|
||||||
|
sequential_trace_token,
|
||||||
|
error_handler
|
||||||
|
]).
|
||||||
|
|
||||||
-define(PROCESS_INFO, [initial_call,
|
-define(PROCESS_GC_KEYS, [memory,
|
||||||
current_function,
|
total_heap_size,
|
||||||
registered_name,
|
heap_size,
|
||||||
status,
|
stack_size,
|
||||||
message_queue_len,
|
min_heap_size
|
||||||
group_leader,
|
]).
|
||||||
priority,
|
|
||||||
trap_exit,
|
|
||||||
reductions,
|
|
||||||
%%binary,
|
|
||||||
last_calls,
|
|
||||||
catchlevel,
|
|
||||||
trace,
|
|
||||||
suspending,
|
|
||||||
sequential_trace_token,
|
|
||||||
error_handler]).
|
|
||||||
|
|
||||||
-define(PROCESS_GC, [memory,
|
-define(SYSTEM_INFO_KEYS, [allocated_areas,
|
||||||
total_heap_size,
|
allocator,
|
||||||
heap_size,
|
alloc_util_allocators,
|
||||||
stack_size,
|
build_type,
|
||||||
min_heap_size]).
|
check_io,
|
||||||
%fullsweep_after]).
|
compat_rel,
|
||||||
|
creation,
|
||||||
-define(SYSTEM_INFO, [allocated_areas,
|
debug_compiled,
|
||||||
allocator,
|
dist,
|
||||||
alloc_util_allocators,
|
dist_ctrl,
|
||||||
build_type,
|
driver_version,
|
||||||
check_io,
|
elib_malloc,
|
||||||
compat_rel,
|
dist_buf_busy_limit,
|
||||||
creation,
|
%fullsweep_after, % included in garbage_collection
|
||||||
debug_compiled,
|
garbage_collection,
|
||||||
dist,
|
%global_heaps_size, % deprecated
|
||||||
dist_ctrl,
|
heap_sizes,
|
||||||
driver_version,
|
heap_type,
|
||||||
elib_malloc,
|
info,
|
||||||
dist_buf_busy_limit,
|
kernel_poll,
|
||||||
%fullsweep_after, % included in garbage_collection
|
loaded,
|
||||||
garbage_collection,
|
logical_processors,
|
||||||
%global_heaps_size, % deprecated
|
logical_processors_available,
|
||||||
heap_sizes,
|
logical_processors_online,
|
||||||
heap_type,
|
machine,
|
||||||
info,
|
%min_heap_size, % included in garbage_collection
|
||||||
kernel_poll,
|
%min_bin_vheap_size, % included in garbage_collection
|
||||||
loaded,
|
modified_timing_level,
|
||||||
logical_processors,
|
multi_scheduling,
|
||||||
logical_processors_available,
|
multi_scheduling_blockers,
|
||||||
logical_processors_online,
|
otp_release,
|
||||||
machine,
|
port_count,
|
||||||
%min_heap_size, % included in garbage_collection
|
process_count,
|
||||||
%min_bin_vheap_size, % included in garbage_collection
|
process_limit,
|
||||||
modified_timing_level,
|
scheduler_bind_type,
|
||||||
multi_scheduling,
|
scheduler_bindings,
|
||||||
multi_scheduling_blockers,
|
scheduler_id,
|
||||||
otp_release,
|
schedulers,
|
||||||
port_count,
|
schedulers_online,
|
||||||
process_count,
|
smp_support,
|
||||||
process_limit,
|
system_version,
|
||||||
scheduler_bind_type,
|
system_architecture,
|
||||||
scheduler_bindings,
|
threads,
|
||||||
scheduler_id,
|
thread_pool_size,
|
||||||
schedulers,
|
trace_control_word,
|
||||||
schedulers_online,
|
update_cpu_info,
|
||||||
smp_support,
|
version,
|
||||||
system_version,
|
wordsize
|
||||||
system_architecture,
|
]).
|
||||||
threads,
|
|
||||||
thread_pool_size,
|
|
||||||
trace_control_word,
|
|
||||||
update_cpu_info,
|
|
||||||
version,
|
|
||||||
wordsize]).
|
|
||||||
|
|
||||||
-define(SOCKET_OPTS, [active,
|
-define(SOCKET_OPTS, [active,
|
||||||
broadcast,
|
broadcast,
|
||||||
|
@ -166,7 +165,8 @@
|
||||||
send_timeout,
|
send_timeout,
|
||||||
send_timeout_close,
|
send_timeout_close,
|
||||||
sndbuf,
|
sndbuf,
|
||||||
tos]).
|
tos
|
||||||
|
]).
|
||||||
|
|
||||||
schedulers() ->
|
schedulers() ->
|
||||||
erlang:system_info(schedulers).
|
erlang:system_info(schedulers).
|
||||||
|
@ -178,16 +178,16 @@ microsecs() ->
|
||||||
loads() ->
|
loads() ->
|
||||||
[{load1, ftos(avg1()/256)},
|
[{load1, ftos(avg1()/256)},
|
||||||
{load5, ftos(avg5()/256)},
|
{load5, ftos(avg5()/256)},
|
||||||
{load15, ftos(avg15()/256)}].
|
{load15, ftos(avg15()/256)}
|
||||||
|
].
|
||||||
|
|
||||||
|
system_info_keys() -> ?SYSTEM_INFO_KEYS.
|
||||||
|
|
||||||
get_system_info() ->
|
get_system_info() ->
|
||||||
[{Key, format_system_info(Key, get_system_info(Key))} || Key <- ?SYSTEM_INFO].
|
[{Key, format_system_info(Key, get_system_info(Key))} || Key <- ?SYSTEM_INFO_KEYS].
|
||||||
|
|
||||||
get_system_info(Key) ->
|
get_system_info(Key) ->
|
||||||
try erlang:system_info(Key) catch
|
try erlang:system_info(Key) catch error:badarg-> undefined end.
|
||||||
error:badarg->undefined
|
|
||||||
end.
|
|
||||||
%% conversion functions for erlang:system_info(Key)
|
|
||||||
|
|
||||||
format_system_info(allocated_areas, List) ->
|
format_system_info(allocated_areas, List) ->
|
||||||
[convert_allocated_areas(Value) || Value <- List];
|
[convert_allocated_areas(Value) || Value <- List];
|
||||||
|
@ -221,8 +221,9 @@ convert_allocated_areas({Key, Value}) ->
|
||||||
|
|
||||||
mem_info() ->
|
mem_info() ->
|
||||||
Dataset = memsup:get_system_memory_data(),
|
Dataset = memsup:get_system_memory_data(),
|
||||||
[{total_memory, proplists:get_value(total_memory, Dataset)},
|
Total = proplists:get_value(total_memory, Dataset),
|
||||||
{used_memory, proplists:get_value(total_memory, Dataset) - proplists:get_value(free_memory, Dataset)}].
|
Free = proplists:get_value(free_memory, Dataset),
|
||||||
|
[{total_memory, Total}, {used_memory, Total - Free}].
|
||||||
|
|
||||||
ftos(F) ->
|
ftos(F) ->
|
||||||
S = io_lib:format("~.2f", [F]), S.
|
S = io_lib:format("~.2f", [F]), S.
|
||||||
|
@ -300,24 +301,24 @@ container_value(Props, Pos, Type, Container) ->
|
||||||
TypeProps = proplists:get_value(Type, Props),
|
TypeProps = proplists:get_value(Type, Props),
|
||||||
element(Pos, lists:keyfind(Container, 1, TypeProps)).
|
element(Pos, lists:keyfind(Container, 1, TypeProps)).
|
||||||
|
|
||||||
get_process_list()->
|
process_info_keys() ->
|
||||||
[get_process_list(Pid) || Pid <- processes()].
|
?PROCESS_INFO_KEYS.
|
||||||
|
|
||||||
get_process_list(Pid) when is_pid(Pid) ->
|
|
||||||
[{pid, Pid} | [process_info(Pid, Key) || Key <- ?PROCESS_LIST]].
|
|
||||||
|
|
||||||
get_process_info() ->
|
get_process_info() ->
|
||||||
[get_process_info(Pid) || Pid <- processes()].
|
get_process_info(self()).
|
||||||
get_process_info(Pid) when is_pid(Pid) ->
|
get_process_info(Pid) when is_pid(Pid) ->
|
||||||
process_info(Pid, ?PROCESS_INFO).
|
process_info(Pid, ?PROCESS_INFO_KEYS).
|
||||||
|
|
||||||
get_process_gc() ->
|
process_gc_info_keys() ->
|
||||||
[get_process_gc(Pid) || Pid <- processes()].
|
?PROCESS_GC_KEYS.
|
||||||
get_process_gc(Pid) when is_pid(Pid) ->
|
|
||||||
process_info(Pid, ?PROCESS_GC).
|
get_process_gc_info() ->
|
||||||
|
get_process_gc_info(self()).
|
||||||
|
get_process_gc_info(Pid) when is_pid(Pid) ->
|
||||||
|
process_info(Pid, ?PROCESS_GC_KEYS).
|
||||||
|
|
||||||
get_process_group_leader_info(LeaderPid) when is_pid(LeaderPid) ->
|
get_process_group_leader_info(LeaderPid) when is_pid(LeaderPid) ->
|
||||||
[{Key, Value}|| {Key, Value} <- process_info(LeaderPid), lists:member(Key, ?PROCESS_INFO)].
|
[{Key, Value}|| {Key, Value} <- process_info(LeaderPid), lists:member(Key, ?PROCESS_INFO_KEYS)].
|
||||||
|
|
||||||
get_process_limit() ->
|
get_process_limit() ->
|
||||||
erlang:system_info(process_limit).
|
erlang:system_info(process_limit).
|
||||||
|
@ -446,8 +447,7 @@ ports_type_count(Types) ->
|
||||||
|
|
||||||
mapping(Entries) ->
|
mapping(Entries) ->
|
||||||
mapping(Entries, []).
|
mapping(Entries, []).
|
||||||
mapping([], Acc) ->
|
mapping([], Acc) -> Acc;
|
||||||
Acc;
|
|
||||||
mapping([{owner, V}|Entries], Acc) when is_pid(V) ->
|
mapping([{owner, V}|Entries], Acc) when is_pid(V) ->
|
||||||
OwnerInfo = process_info(V),
|
OwnerInfo = process_info(V),
|
||||||
Owner = proplists:get_value(registered_name, OwnerInfo, undefined),
|
Owner = proplists:get_value(registered_name, OwnerInfo, undefined),
|
||||||
|
@ -470,10 +470,10 @@ cpu_util() ->
|
||||||
compat_windows(Fun) ->
|
compat_windows(Fun) ->
|
||||||
case os:type() of
|
case os:type() of
|
||||||
{win32, nt} -> 0;
|
{win32, nt} -> 0;
|
||||||
_Other -> handle_error(Fun())
|
_Type ->
|
||||||
|
case catch Fun() of
|
||||||
|
Val when is_number(Val) -> Val;
|
||||||
|
_Error -> 0
|
||||||
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
handle_error(Value) when is_number(Value) ->
|
|
||||||
Value;
|
|
||||||
handle_error({error, _Reason}) ->
|
|
||||||
0.
|
|
||||||
|
|
|
@ -21,115 +21,29 @@
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
-define(SYSTEM_INFO, [allocated_areas,
|
|
||||||
allocator,
|
|
||||||
alloc_util_allocators,
|
|
||||||
build_type,
|
|
||||||
check_io,
|
|
||||||
compat_rel,
|
|
||||||
creation,
|
|
||||||
debug_compiled,
|
|
||||||
dist,
|
|
||||||
dist_ctrl,
|
|
||||||
driver_version,
|
|
||||||
elib_malloc,
|
|
||||||
dist_buf_busy_limit,
|
|
||||||
%fullsweep_after, % included in garbage_collection
|
|
||||||
garbage_collection,
|
|
||||||
%global_heaps_size, % deprecated
|
|
||||||
heap_sizes,
|
|
||||||
heap_type,
|
|
||||||
info,
|
|
||||||
kernel_poll,
|
|
||||||
loaded,
|
|
||||||
logical_processors,
|
|
||||||
logical_processors_available,
|
|
||||||
logical_processors_online,
|
|
||||||
machine,
|
|
||||||
%min_heap_size, % included in garbage_collection
|
|
||||||
%min_bin_vheap_size, % included in garbage_collection
|
|
||||||
modified_timing_level,
|
|
||||||
multi_scheduling,
|
|
||||||
multi_scheduling_blockers,
|
|
||||||
otp_release,
|
|
||||||
port_count,
|
|
||||||
process_count,
|
|
||||||
process_limit,
|
|
||||||
scheduler_bind_type,
|
|
||||||
scheduler_bindings,
|
|
||||||
scheduler_id,
|
|
||||||
schedulers,
|
|
||||||
schedulers_online,
|
|
||||||
smp_support,
|
|
||||||
system_version,
|
|
||||||
system_architecture,
|
|
||||||
threads,
|
|
||||||
thread_pool_size,
|
|
||||||
trace_control_word,
|
|
||||||
update_cpu_info,
|
|
||||||
version,
|
|
||||||
wordsize]).
|
|
||||||
|
|
||||||
-define(PROCESS_INFO, [initial_call,
|
|
||||||
current_function,
|
|
||||||
registered_name,
|
|
||||||
status,
|
|
||||||
message_queue_len,
|
|
||||||
group_leader,
|
|
||||||
priority,
|
|
||||||
trap_exit,
|
|
||||||
reductions,
|
|
||||||
%%binary,
|
|
||||||
last_calls,
|
|
||||||
catchlevel,
|
|
||||||
trace,
|
|
||||||
suspending,
|
|
||||||
sequential_trace_token,
|
|
||||||
error_handler]).
|
|
||||||
|
|
||||||
-define(PROCESS_GC, [memory,
|
|
||||||
total_heap_size,
|
|
||||||
heap_size,
|
|
||||||
stack_size,
|
|
||||||
min_heap_size]).
|
|
||||||
%fullsweep_after]).
|
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
||||||
t_load(_Config) ->
|
t_load(_Config) ->
|
||||||
?assertMatch([{load1, _},
|
?assertMatch([{load1, _}, {load5, _}, {load15, _}], emqx_vm:loads()).
|
||||||
{load5, _},
|
|
||||||
{load15, _}
|
|
||||||
], emqx_vm:loads()).
|
|
||||||
|
|
||||||
t_systeminfo(_Config) ->
|
t_systeminfo(_Config) ->
|
||||||
Keys = [Key || {Key, _} <- emqx_vm:get_system_info()],
|
?assertEqual(emqx_vm:system_info_keys(),
|
||||||
?SYSTEM_INFO = Keys,
|
[Key || {Key, _} <- emqx_vm:get_system_info()]),
|
||||||
?assertEqual(undefined, emqx_vm:get_system_info(undefined)).
|
?assertEqual(undefined, emqx_vm:get_system_info(undefined)).
|
||||||
|
|
||||||
t_mem_info(_Config) ->
|
t_mem_info(_Config) ->
|
||||||
application:ensure_all_started(os_mon),
|
application:ensure_all_started(os_mon),
|
||||||
MemInfo = emqx_vm:mem_info(),
|
MemInfo = emqx_vm:mem_info(),
|
||||||
[{total_memory, _},
|
[{total_memory, _}, {used_memory, _}]= MemInfo,
|
||||||
{used_memory, _}]= MemInfo,
|
|
||||||
application:stop(os_mon).
|
application:stop(os_mon).
|
||||||
|
|
||||||
t_process_list(_Config) ->
|
|
||||||
Pid = self(),
|
|
||||||
ProcessInfo = emqx_vm:get_process_list(),
|
|
||||||
true = lists:member({pid, Pid}, lists:concat(ProcessInfo)).
|
|
||||||
|
|
||||||
t_process_info(_Config) ->
|
t_process_info(_Config) ->
|
||||||
ProcessInfos = emqx_vm:get_process_info(),
|
ProcessInfo = emqx_vm:get_process_info(),
|
||||||
ProcessInfo = lists:last(ProcessInfos),
|
?assertEqual(emqx_vm:process_info_keys(), [K || {K, _V}<- ProcessInfo]).
|
||||||
Keys = [K || {K, _V}<- ProcessInfo],
|
|
||||||
?PROCESS_INFO = Keys.
|
|
||||||
|
|
||||||
t_process_gc(_Config) ->
|
t_process_gc(_Config) ->
|
||||||
ProcessGcs = emqx_vm:get_process_gc(),
|
GcInfo = emqx_vm:get_process_gc_info(),
|
||||||
ProcessGc = lists:last(ProcessGcs),
|
?assertEqual(emqx_vm:process_gc_info_keys(), [K || {K, _V}<- GcInfo]).
|
||||||
Keys = [K || {K, _V}<- ProcessGc],
|
|
||||||
?PROCESS_GC = Keys.
|
|
||||||
|
|
||||||
t_get_ets_list(_Config) ->
|
t_get_ets_list(_Config) ->
|
||||||
ets:new(test, [named_table]),
|
ets:new(test, [named_table]),
|
||||||
|
|
Loading…
Reference in New Issue