aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2013-11-14 15:34:55 +0100
committerDan Gudmundsson <[email protected]>2014-01-27 16:13:57 +0100
commitcf20035dc7a4fbab47ce17b99b674e4db5eb7a07 (patch)
tree2cb48cabb34977d3f465ad38def55df70bdfe509 /lib
parentbfae535d4ac51d2c3bef146e0f058e105bb5e956 (diff)
downloadotp-cf20035dc7a4fbab47ce17b99b674e4db5eb7a07.tar.gz
otp-cf20035dc7a4fbab47ce17b99b674e4db5eb7a07.tar.bz2
otp-cf20035dc7a4fbab47ce17b99b674e4db5eb7a07.zip
observer: Fix memory and scheduler info and handle missing fields
Fix app viewer crash
Diffstat (limited to 'lib')
-rw-r--r--lib/observer/src/observer_app_wx.erl15
-rw-r--r--lib/observer/src/observer_lib.erl31
-rw-r--r--lib/observer/src/observer_perf_wx.erl29
-rw-r--r--lib/observer/src/observer_sys_wx.erl9
-rw-r--r--lib/runtime_tools/src/observer_backend.erl15
5 files changed, 66 insertions, 33 deletions
diff --git a/lib/observer/src/observer_app_wx.erl b/lib/observer/src/observer_app_wx.erl
index 82395fbe08..a710bd0a69 100644
--- a/lib/observer/src/observer_app_wx.erl
+++ b/lib/observer/src/observer_app_wx.erl
@@ -178,11 +178,16 @@ handle_event(#wx{id=Id, event=_Sz=#wxSize{size=Size}},
{noreply, State};
handle_event(#wx{event=#wxMouse{type=Type, x=X0, y=Y0}},
- S0=#state{app=#app{ptree=Tree}, app_w=AppWin}) ->
- {X,Y} = wxScrolledWindow:calcUnscrolledPosition(AppWin, X0, Y0),
- Hit = locate_node(X,Y, [Tree]),
- State = handle_mouse_click(Hit, Type, S0),
- {noreply, State};
+ S0=#state{app=App, app_w=AppWin}) ->
+ case App of
+ #app{ptree=Tree} ->
+ {X,Y} = wxScrolledWindow:calcUnscrolledPosition(AppWin, X0, Y0),
+ Hit = locate_node(X,Y, [Tree]),
+ State = handle_mouse_click(Hit, Type, S0),
+ {noreply, State};
+ _ ->
+ {noreply, S0}
+ end;
handle_event(#wx{event=#wxCommand{type=command_menu_selected}},
State = #state{sel=undefined}) ->
diff --git a/lib/observer/src/observer_lib.erl b/lib/observer/src/observer_lib.erl
index f11ccfb752..6288dd3a45 100644
--- a/lib/observer/src/observer_lib.erl
+++ b/lib/observer/src/observer_lib.erl
@@ -144,29 +144,29 @@ fill_info([{dynamic, Key}|Rest], Data)
%% Special case used by crashdump_viewer when the value decides
%% which header to use
case get_value(Key, Data) of
- undefined -> fill_info(Rest, Data);
+ undefined -> [undefined | fill_info(Rest, Data)];
{Str,Value} -> [{Str, Value} | fill_info(Rest, Data)]
end;
fill_info([{Str, Key}|Rest], Data) when is_atom(Key); is_function(Key) ->
case get_value(Key, Data) of
- undefined -> fill_info(Rest, Data);
+ undefined -> [undefined | fill_info(Rest, Data)];
Value -> [{Str, Value} | fill_info(Rest, Data)]
end;
fill_info([{Str,Attrib,Key}|Rest], Data) when is_atom(Key); is_function(Key) ->
case get_value(Key, Data) of
- undefined -> fill_info(Rest, Data);
+ undefined -> [undefined | fill_info(Rest, Data)];
Value -> [{Str,Attrib,Value} | fill_info(Rest, Data)]
end;
fill_info([{Str, {Format, Key}}|Rest], Data)
when is_atom(Key); is_function(Key), is_atom(Format) ->
case get_value(Key, Data) of
- undefined -> fill_info(Rest, Data);
+ undefined -> [undefined | fill_info(Rest, Data)];
Value -> [{Str, {Format, Value}} | fill_info(Rest, Data)]
end;
fill_info([{Str, Attrib, {Format, Key}}|Rest], Data)
when is_atom(Key); is_function(Key), is_atom(Format) ->
case get_value(Key, Data) of
- undefined -> fill_info(Rest, Data);
+ undefined -> [undefined | fill_info(Rest, Data)];
Value -> [{Str, Attrib, {Format, Value}} | fill_info(Rest, Data)]
end;
fill_info([{Str,SubStructure}|Rest], Data) when is_list(SubStructure) ->
@@ -189,6 +189,8 @@ update_info([Fields|Fs], [{_Header, _Attrib, SubStructure}| Rest]) ->
update_info([], []) ->
ok.
+update_info2([undefined|Fs], [_|Rest]) ->
+ update_info2(Fs, Rest);
update_info2([Scroll = {_, _, _}|Fs], [{_, NewInfo}|Rest]) ->
update_scroll_boxes(Scroll, NewInfo),
update_info2(Fs, Rest);
@@ -198,6 +200,9 @@ update_info2([Field|Fs], [{_Str, {click, Value}}|Rest]) ->
update_info2([Field|Fs], [{_Str, Value}|Rest]) ->
wxTextCtrl:setValue(Field, to_str(Value)),
update_info2(Fs, Rest);
+update_info2([Field|Fs], [undefined|Rest]) ->
+ wxTextCtrl:setValue(Field, ""),
+ update_info2(Fs, Rest);
update_info2([], []) -> ok.
update_scroll_boxes({_, _, 0}, {_, []}) -> ok;
@@ -223,10 +228,10 @@ to_str({bytes, B}) ->
MB = KB div 1024,
GB = MB div 1024,
if
- GB > 10 -> integer_to_list(GB) ++ " gB";
- MB > 10 -> integer_to_list(MB) ++ " mB";
+ GB > 10 -> integer_to_list(GB) ++ " GB";
+ MB > 10 -> integer_to_list(MB) ++ " MB";
KB > 0 -> integer_to_list(KB) ++ " kB";
- true -> integer_to_list(B) ++ " B "
+ true -> integer_to_list(B) ++ " B"
end;
to_str({time_ms, MS}) ->
S = MS div 1000,
@@ -396,7 +401,9 @@ create_box(Panel, {scroll_boxes,Data}) ->
AddBox = fun({Title,Proportion,Format = {_,_}}) ->
add_box(Panel, OuterBox, Cursor, Title, Proportion, Format);
({Title, Format = {_,_}}) ->
- add_box(Panel, OuterBox, Cursor, Title, 1, Format)
+ add_box(Panel, OuterBox, Cursor, Title, 1, Format);
+ (undefined) ->
+ undefined
end,
Boxes = [AddBox(Entry) || Entry <- Data],
wxCursor:destroy(Cursor),
@@ -457,7 +464,9 @@ create_box(Panel, Data) ->
wxTextCtrl:setMinSize(Field,{0,H}),
wxSizer:add(Box, Line, [{proportion,0},{flag,?wxEXPAND}]),
- Field
+ Field;
+ (undefined) ->
+ undefined
end,
InfoFields = [AddRow(Entry) || Entry <- Info],
{Box, InfoFields}.
@@ -512,6 +521,8 @@ get_max_size(Txt,[{Desc,_}|Info],MaxX,MaxY) ->
true ->
get_max_size(Txt,Info,MaxX,MaxY)
end;
+get_max_size(Txt,[undefined|Info],MaxX,MaxY) ->
+ get_max_size(Txt,Info,MaxX,MaxY);
get_max_size(_,[],X,Y) ->
{X+2,Y}.
diff --git a/lib/observer/src/observer_perf_wx.erl b/lib/observer/src/observer_perf_wx.erl
index 54c98f3ba3..8173349ed7 100644
--- a/lib/observer/src/observer_perf_wx.erl
+++ b/lib/observer/src/observer_perf_wx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -283,7 +283,12 @@ mem_types() ->
lmax([]) -> 0;
lmax(List) ->
- lists:max([lists:max(tuple_to_list(T)) || T <- List]).
+ Max = [lists:max(tuple_to_list(T)) || T <- List,
+ tuple_size(T) > 0],
+ case Max of
+ [] -> 0;
+ _ -> lists:max(Max)
+ end.
calc_delta([{Id, WN, TN}|Ss], [{Id, WP, TP}|Ps]) ->
[100*(WN-WP) div (TN-TP)|calc_delta(Ss, Ps)];
@@ -301,25 +306,23 @@ draw(Offset, Id, DC, Panel, Paint=#paint{pens=Pens, small=Small}, Data, Active)
{X0,Y0,WS,HS} = draw_borders(Id, NoGraphs, DC, Size, Max, Paint),
Last = 60*WS+X0-1,
Start = max(61-Len, 0)*WS+X0 - Offset*WS,
- case Hs of
- [] -> ignore;
- [_] -> ignore;
- _ ->
+ Samples = length(Hs),
+ case Active andalso Samples > 1 andalso NoGraphs > 0 of
+ true ->
Draw = fun(N) ->
Lines = make_lines(Hs, Start, N, {X0,Max*HS,Last}, Y0, WS, HS),
setPen(DC, element(1+ ((N-1) rem tuple_size(Pens)), Pens)),
strokeLines(DC, Lines),
N+1
end,
- [Draw(I) || I <- lists:seq(NoGraphs, 1, -1)]
- end,
- case Active of
+ [Draw(I) || I <- lists:seq(NoGraphs, 1, -1)];
false ->
- NotActive = "Service not available",
+ Info = case Active andalso Samples =< 1 of
+ true -> "Waiting on data";
+ false -> "Information not available"
+ end,
setFont(DC, Small, {0,0,0}),
- drawText(DC, NotActive, X0 + 100, element(2,Size) div 2);
- true ->
- ignore
+ drawText(DC, Info, X0 + 100, element(2,Size) div 2)
end,
ok.
diff --git a/lib/observer/src/observer_sys_wx.erl b/lib/observer/src/observer_sys_wx.erl
index 31800cf12a..8321d6eefe 100644
--- a/lib/observer/src/observer_sys_wx.erl
+++ b/lib/observer/src/observer_sys_wx.erl
@@ -167,9 +167,12 @@ info_fields() ->
{"Async thread pool size", thread_pool_size}
]},
{"CPU's and Threads",
- [{"System Logical CPU's", logical_processors},
- {"Erlang Logical CPU's", logical_processors_online},
- {"Used Logical CPU's", logical_processors_available}
+ [{"Logical CPU's", logical_processors},
+ {"Online Logical CPU's", logical_processors_online},
+ {"Available Logical CPU's", logical_processors_available},
+ {"Schedulers", schedulers},
+ {"Online schedulers", schedulers_online},
+ {"Available schedulers", schedulers_available}
]}
],
Stat = [{"Memory Usage", right,
diff --git a/lib/runtime_tools/src/observer_backend.erl b/lib/runtime_tools/src/observer_backend.erl
index 202129c61a..68ef04f20c 100644
--- a/lib/runtime_tools/src/observer_backend.erl
+++ b/lib/runtime_tools/src/observer_backend.erl
@@ -53,6 +53,13 @@ sys_info() ->
Mem -> Mem
catch _:_ -> []
end,
+
+ SchedulersOnline = erlang:system_info(schedulers_online),
+ SchedulersAvailable = case erlang:system_info(multi_scheduling) of
+ enabled -> SchedulersOnline;
+ _ -> 1
+ end,
+
{{_,Input},{_,Output}} = erlang:statistics(io),
[{process_count, erlang:system_info(process_count)},
{process_limit, erlang:system_info(process_limit)},
@@ -60,9 +67,13 @@ sys_info() ->
{run_queue, erlang:statistics(run_queue)},
{io_input, Input},
{io_output, Output},
+
{logical_processors, erlang:system_info(logical_processors)},
- {logical_processors_available, erlang:system_info(logical_processors_available)},
{logical_processors_online, erlang:system_info(logical_processors_online)},
+ {logical_processors_available, erlang:system_info(logical_processors_available)},
+ {schedulers, erlang:system_info(schedulers)},
+ {schedulers_online, SchedulersOnline},
+ {schedulers_available, SchedulersAvailable},
{otp_release, erlang:system_info(otp_release)},
{version, erlang:system_info(version)},
@@ -221,7 +232,7 @@ fetch_stats_loop(Parent, Time) ->
_M = Parent ! {stats, 1,
erlang:statistics(scheduler_wall_time),
erlang:statistics(io),
- erlang:memory()},
+ try erlang:memory() catch _:_ -> [] end},
fetch_stats_loop(Parent, Time)
end.
%%