diff options
Diffstat (limited to 'lib/observer')
64 files changed, 736 insertions, 547 deletions
diff --git a/lib/observer/Makefile b/lib/observer/Makefile index 865dddaf51..8483922f76 100644 --- a/lib/observer/Makefile +++ b/lib/observer/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/observer/doc/src/book.xml b/lib/observer/doc/src/book.xml index 5ef1fd794b..7cc60718b1 100644 --- a/lib/observer/doc/src/book.xml +++ b/lib/observer/doc/src/book.xml @@ -4,7 +4,7 @@ <book xmlns:xi="http://www.w3.org/2001/XInclude"> <header titlestyle="normal"> <copyright> - <year>2002</year><year>2013</year> + <year>2002</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/observer/doc/src/crashdump.xml b/lib/observer/doc/src/crashdump.xml index 27e88d07e5..48f944cbce 100644 --- a/lib/observer/doc/src/crashdump.xml +++ b/lib/observer/doc/src/crashdump.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2003</year> - <year>2013</year> + <year>2016</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> diff --git a/lib/observer/doc/src/etop.xml b/lib/observer/doc/src/etop.xml index 52f3b2a156..d70d9d1d23 100644 --- a/lib/observer/doc/src/etop.xml +++ b/lib/observer/doc/src/etop.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2002</year> - <year>2013</year> + <year>2016</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml index dd99f45b19..c3bd0d33b9 100644 --- a/lib/observer/doc/src/notes.xml +++ b/lib/observer/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2004</year><year>2013</year> + <year>2004</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/observer/doc/src/notes_history.xml b/lib/observer/doc/src/notes_history.xml index ec155b852f..ef20a6dfa4 100644 --- a/lib/observer/doc/src/notes_history.xml +++ b/lib/observer/doc/src/notes_history.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2006</year> - <year>2013</year> + <year>2016</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> diff --git a/lib/observer/doc/src/part.xml b/lib/observer/doc/src/part.xml index d8ec7664d9..165bd5864a 100644 --- a/lib/observer/doc/src/part.xml +++ b/lib/observer/doc/src/part.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2002</year><year>2013</year> + <year>2002</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/observer/doc/src/part_notes.xml b/lib/observer/doc/src/part_notes.xml index c187702f64..ba15c39cda 100644 --- a/lib/observer/doc/src/part_notes.xml +++ b/lib/observer/doc/src/part_notes.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2004</year><year>2013</year> + <year>2004</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/observer/doc/src/part_notes_history.xml b/lib/observer/doc/src/part_notes_history.xml index c0c7b10a7e..e60210924c 100644 --- a/lib/observer/doc/src/part_notes_history.xml +++ b/lib/observer/doc/src/part_notes_history.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2006</year> - <year>2013</year> + <year>2016</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> diff --git a/lib/observer/doc/src/ref_man.xml b/lib/observer/doc/src/ref_man.xml index 37e20b2643..73e7e0053a 100644 --- a/lib/observer/doc/src/ref_man.xml +++ b/lib/observer/doc/src/ref_man.xml @@ -4,7 +4,7 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2002</year><year>2013</year> + <year>2002</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/observer/include/etop.hrl b/lib/observer/include/etop.hrl index 0dac322a2b..002937e522 100644 --- a/lib/observer/include/etop.hrl +++ b/lib/observer/include/etop.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/Makefile b/lib/observer/src/Makefile index 2d42510b47..85dc5933c1 100644 --- a/lib/observer/src/Makefile +++ b/lib/observer/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2013. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_atom_cb.erl b/lib/observer/src/cdv_atom_cb.erl index 0f0c397479..a123354c8f 100644 --- a/lib/observer/src/cdv_atom_cb.erl +++ b/lib/observer/src/cdv_atom_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_bin_cb.erl b/lib/observer/src/cdv_bin_cb.erl index 7e17ef135e..0cea1fdcf0 100644 --- a/lib/observer/src/cdv_bin_cb.erl +++ b/lib/observer/src/cdv_bin_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2014. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_detail_wx.erl b/lib/observer/src/cdv_detail_wx.erl index d53b721141..44f121f359 100644 --- a/lib/observer/src/cdv_detail_wx.erl +++ b/lib/observer/src/cdv_detail_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_dist_cb.erl b/lib/observer/src/cdv_dist_cb.erl index 9c53ec86bc..2b4c9f56d1 100644 --- a/lib/observer/src/cdv_dist_cb.erl +++ b/lib/observer/src/cdv_dist_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2014. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_ets_cb.erl b/lib/observer/src/cdv_ets_cb.erl index bac8b56fc3..52a90b093b 100644 --- a/lib/observer/src/cdv_ets_cb.erl +++ b/lib/observer/src/cdv_ets_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_fun_cb.erl b/lib/observer/src/cdv_fun_cb.erl index 3a62eb3305..acebc94811 100644 --- a/lib/observer/src/cdv_fun_cb.erl +++ b/lib/observer/src/cdv_fun_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_gen_cb.erl b/lib/observer/src/cdv_gen_cb.erl index 69ecfbe80e..5fb43b5719 100644 --- a/lib/observer/src/cdv_gen_cb.erl +++ b/lib/observer/src/cdv_gen_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_html_wx.erl b/lib/observer/src/cdv_html_wx.erl index 70f0d02982..0ab0ba4315 100644 --- a/lib/observer/src/cdv_html_wx.erl +++ b/lib/observer/src/cdv_html_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2014. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_info_wx.erl b/lib/observer/src/cdv_info_wx.erl index 13c80942ac..01fe6b15f2 100644 --- a/lib/observer/src/cdv_info_wx.erl +++ b/lib/observer/src/cdv_info_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_int_tab_cb.erl b/lib/observer/src/cdv_int_tab_cb.erl index c48fbb6ee1..401ebf9664 100644 --- a/lib/observer/src/cdv_int_tab_cb.erl +++ b/lib/observer/src/cdv_int_tab_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_mem_cb.erl b/lib/observer/src/cdv_mem_cb.erl index bfe21bf309..ba972d6963 100644 --- a/lib/observer/src/cdv_mem_cb.erl +++ b/lib/observer/src/cdv_mem_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_mod_cb.erl b/lib/observer/src/cdv_mod_cb.erl index 2e41699c5a..2183e1aa3d 100644 --- a/lib/observer/src/cdv_mod_cb.erl +++ b/lib/observer/src/cdv_mod_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_multi_wx.erl b/lib/observer/src/cdv_multi_wx.erl index 13b980b5ea..b511503752 100644 --- a/lib/observer/src/cdv_multi_wx.erl +++ b/lib/observer/src/cdv_multi_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_port_cb.erl b/lib/observer/src/cdv_port_cb.erl index 7dbe6d7819..b5cbe8132d 100644 --- a/lib/observer/src/cdv_port_cb.erl +++ b/lib/observer/src/cdv_port_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_proc_cb.erl b/lib/observer/src/cdv_proc_cb.erl index 90f6715a06..592150146b 100644 --- a/lib/observer/src/cdv_proc_cb.erl +++ b/lib/observer/src/cdv_proc_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_sched_cb.erl b/lib/observer/src/cdv_sched_cb.erl index f236e6a159..192aaf31a7 100644 --- a/lib/observer/src/cdv_sched_cb.erl +++ b/lib/observer/src/cdv_sched_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2014. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_table_wx.erl b/lib/observer/src/cdv_table_wx.erl index 4e9c158ce3..df16230b70 100644 --- a/lib/observer/src/cdv_table_wx.erl +++ b/lib/observer/src/cdv_table_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_term_cb.erl b/lib/observer/src/cdv_term_cb.erl index 155cde2cd0..f0d90dde7c 100644 --- a/lib/observer/src/cdv_term_cb.erl +++ b/lib/observer/src/cdv_term_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2014. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_timer_cb.erl b/lib/observer/src/cdv_timer_cb.erl index 42285b0fc9..dcc794242c 100644 --- a/lib/observer/src/cdv_timer_cb.erl +++ b/lib/observer/src/cdv_timer_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_virtual_list_wx.erl b/lib/observer/src/cdv_virtual_list_wx.erl index 5b2775d61b..ebf58865e9 100644 --- a/lib/observer/src/cdv_virtual_list_wx.erl +++ b/lib/observer/src/cdv_virtual_list_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/cdv_wx.erl b/lib/observer/src/cdv_wx.erl index 82247cb93b..2587a6e64e 100644 --- a/lib/observer/src/cdv_wx.erl +++ b/lib/observer/src/cdv_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013. All Rights Reserved. +%% Copyright Ericsson AB 2013-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl index b66b4d59c9..de52e2a995 100644 --- a/lib/observer/src/crashdump_viewer.erl +++ b/lib/observer/src/crashdump_viewer.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2014. All Rights Reserved. +%% Copyright Ericsson AB 2003-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/crashdump_viewer.hrl b/lib/observer/src/crashdump_viewer.hrl index bd08d3e1e1..a08659efd6 100644 --- a/lib/observer/src/crashdump_viewer.hrl +++ b/lib/observer/src/crashdump_viewer.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2013. All Rights Reserved. +%% Copyright Ericsson AB 2003-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/etop.erl b/lib/observer/src/etop.erl index c97fcc481b..fcb900960b 100644 --- a/lib/observer/src/etop.erl +++ b/lib/observer/src/etop.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2013. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/etop_defs.hrl b/lib/observer/src/etop_defs.hrl index 39acda5758..7ad8417e2a 100644 --- a/lib/observer/src/etop_defs.hrl +++ b/lib/observer/src/etop_defs.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2013. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/etop_tr.erl b/lib/observer/src/etop_tr.erl index 38e048c307..8e43f8bb35 100644 --- a/lib/observer/src/etop_tr.erl +++ b/lib/observer/src/etop_tr.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/etop_txt.erl b/lib/observer/src/etop_txt.erl index b77fc3c55d..3b4c176478 100644 --- a/lib/observer/src/etop_txt.erl +++ b/lib/observer/src/etop_txt.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2013. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/multitrace.erl b/lib/observer/src/multitrace.erl index dbb6858646..a01eeec6ae 100644 --- a/lib/observer/src/multitrace.erl +++ b/lib/observer/src/multitrace.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/observer.app.src b/lib/observer/src/observer.app.src index 61c21a832e..5ddf65fa59 100644 --- a/lib/observer/src/observer.app.src +++ b/lib/observer/src/observer.app.src @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2013. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/observer.appup.src b/lib/observer/src/observer.appup.src index 9c7ae3a195..da3cd6a4aa 100644 --- a/lib/observer/src/observer.appup.src +++ b/lib/observer/src/observer.appup.src @@ -1,7 +1,7 @@ %% -*- erlang -*- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2014. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/observer.erl b/lib/observer/src/observer.erl index bb1dedb7e6..79ba7fd614 100644 --- a/lib/observer/src/observer.erl +++ b/lib/observer/src/observer.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2014. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/observer_alloc_wx.erl b/lib/observer/src/observer_alloc_wx.erl index 8d5c8a9037..77609b11ce 100644 --- a/lib/observer/src/observer_alloc_wx.erl +++ b/lib/observer/src/observer_alloc_wx.erl @@ -30,55 +30,75 @@ -record(state, { - offset = 0.0, + time = #ti{}, active = false, parent, - windows, - data = {0, queue:new()}, + wins, + mem, + samples, panel, paint, appmon, async }). --define(ALLOC_W, 1). --define(UTIL_W, 2). +-define(ID_REFRESH_INTERVAL, 102). + +-import(observer_perf_wx, + [make_win/4, setup_graph_drawing/1, refresh_panel/4, interval_dialog/2, + add_data/5, precalc/4]). start_link(Notebook, Parent) -> wx_object:start_link(?MODULE, [Notebook, Parent], []). init([Notebook, Parent]) -> try - Panel = wxPanel:new(Notebook), + TopP = wxPanel:new(Notebook), Main = wxBoxSizer:new(?wxVERTICAL), - Style = ?wxFULL_REPAINT_ON_RESIZE bor ?wxCLIP_CHILDREN, - Carrier = wxPanel:new(Panel, [{winid, ?ALLOC_W}, {style,Style}]), - Utilz = wxPanel:new(Panel, [{winid, ?UTIL_W}, {style,Style}]), + Panel = wxPanel:new(TopP), + GSzr = wxBoxSizer:new(?wxVERTICAL), BorderFlags = ?wxLEFT bor ?wxRIGHT, - wxSizer:add(Main, Carrier, [{flag, ?wxEXPAND bor BorderFlags bor ?wxTOP}, - {proportion, 1}, {border, 5}]), - - wxSizer:add(Main, Utilz, [{flag, ?wxEXPAND bor BorderFlags}, - {proportion, 1}, {border, 5}]), - - MemWin = {MemPanel,_} = create_mem_info(Panel), - wxSizer:add(Main, MemPanel, [{flag, ?wxEXPAND bor BorderFlags bor ?wxBOTTOM}, - {proportion, 1}, {border, 5}]), - wxWindow:setSizer(Panel, Main), - - PaintInfo = observer_perf_wx:setup_graph_drawing([Carrier, Utilz]), - {Panel, #state{parent=Parent, - panel =Panel, - windows = {Carrier, Utilz, MemWin}, - paint=PaintInfo} + Carrier = make_win(alloc, Panel, GSzr, BorderFlags bor ?wxTOP), + Utilz = make_win(utilz, Panel, GSzr, BorderFlags), + wxWindow:setSizer(Panel, GSzr), + wxSizer:add(Main, Panel, [{flag, ?wxEXPAND},{proportion,2}]), + + MemWin = create_mem_info(TopP), + wxSizer:add(Main, MemWin, [{flag, ?wxEXPAND bor BorderFlags bor ?wxBOTTOM}, + {proportion, 1}, {border, 5}]), + wxWindow:setSizer(TopP, Main), + Windows = [Carrier, Utilz], + PaintInfo = setup_graph_drawing(Windows), + {TopP, #state{parent= Parent, + panel = Panel, + wins = Windows, + mem = MemWin, + paint = PaintInfo, + time = setup_time() + } } catch _:Err -> io:format("~p crashed ~p: ~p~n",[?MODULE, Err, erlang:get_stacktrace()]), {stop, Err} end. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +setup_time() -> + Freq = 1, + #ti{fetch=Freq, disp=?DISP_FREQ/Freq}. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +handle_event(#wx{id=?ID_REFRESH_INTERVAL, event=#wxCommand{type=command_menu_selected}}, + #state{active=Active, panel=Panel, appmon=Old, wins=Wins0, time=#ti{fetch=F0} = Ti0} = State) -> + case interval_dialog(Panel, Ti0) of + Ti0 -> {noreply, State}; + #ti{fetch=F0} = Ti -> %% Same fetch interval force refresh + Wins = [W#win{max=undefined} || W <- Wins0], + {noreply, precalc(State#state{time=Ti, wins=Wins})}; + Ti when not Active -> + {noreply, State#state{time=Ti}}; + Ti -> %% Changed fetch interval, drop all data + {noreply, restart_fetcher(Old, State#state{time=Ti})} + end; handle_event(#wx{event=#wxCommand{type=command_menu_selected}}, State = #state{}) -> {noreply, State}; @@ -88,13 +108,11 @@ handle_event(Event, _State) -> %%%%%%%%%% handle_sync_event(#wx{obj=Panel, event = #wxPaint{}},_, - #state{active=Active, offset=Offset, paint=Paint, - windows=Windows, data=Data}) -> + #state{active=Active, time=Ti, paint=Paint, + wins = Windows}) -> %% Sigh workaround bug on MacOSX (Id in paint event is always 0) - Id = if Panel =:= element(?ALLOC_W, Windows) -> alloc; - Panel =:= element(?UTIL_W, Windows) -> utilz - end, - observer_perf_wx:refresh_panel(Panel, Id, Offset, Data, Active, Paint), + Win = lists:keyfind(Panel, #win.panel, Windows), + refresh_panel(Active, Win, Ti, Paint), ok. %%%%%%%%%% handle_call(Event, From, _State) -> @@ -107,24 +125,36 @@ handle_cast(Event, _State) -> handle_info({Key, {promise_reply, {badrpc, _}}}, #state{async=Key} = State) -> {noreply, State#state{active=false, appmon=undefined}}; -handle_info({Key, {promise_reply, SysInfo}}, #state{async=Key, data=Data} = State) -> +handle_info({Key, {promise_reply, SysInfo}}, + #state{async=Key, panel=_Panel, samples=Data, active=Active, wins=Wins0, + time=#ti{tick=Tick, disp=Disp0}=Ti} = S0) -> + Disp = trunc(Disp0), + Next = max(Tick - Disp, 0), + erlang:send_after(1000 div ?DISP_FREQ, self(), {refresh, Next}), Info = alloc_info(SysInfo), - update_alloc(State, Info), - {noreply, State#state{offset=0.0, data = add_data(Info, Data), async=undefined}}; + {Wins, Samples} = add_data(Info, Data, Wins0, Ti, Active), + S1 = S0#state{time=Ti#ti{tick=Next}, wins=Wins, samples=Samples, async=undefined}, + if Active -> + update_alloc(S0, Info), + State = precalc(S1), + {noreply, State}; + true -> + {noreply, S1} + end; -handle_info({refresh, Seq, Freq, Node}, #state{panel=Panel, appmon=Node, async=Key} = State) -> - wxWindow:refresh(Panel), +handle_info({refresh, Seq}, + State = #state{panel=Panel, appmon=Node, time=#ti{tick=Seq, disp=DispF}=Ti}) + when (Seq+1) < (DispF*1.5) -> Next = Seq+1, - if - Next > Freq, Key =:= undefined -> - erlang:send_after(trunc(1000 / Freq), self(), {refresh, 1, Freq, Node}), + State#state.active andalso (catch wxWindow:refresh(Panel)), + erlang:send_after(1000 div ?DISP_FREQ, self(), {refresh, Next}), + if Seq =:= (trunc(DispF)-1) -> Req = rpc:async_call(Node, observer_backend, sys_info, []), - {noreply, State#state{offset=Seq/Freq, async=Req}}; + {noreply, State#state{time=Ti#ti{tick=Next}, async=Req}}; true -> - erlang:send_after(trunc(1000 / Freq), self(), {refresh, Next, Freq, Node}), - {noreply, State#state{offset=Seq/Freq}} + {noreply, State#state{time=Ti#ti{tick=Next}}} end; -handle_info({refresh, _Seq, _Freq, _Node}, State) -> +handle_info({refresh, _S}, #state{}=State) -> {noreply, State}; handle_info({active, Node}, State = #state{parent=Parent, panel=Panel, appmon=Old}) -> @@ -132,15 +162,9 @@ handle_info({active, Node}, State = #state{parent=Parent, panel=Panel, appmon=Ol try Node = Old, wxWindow:refresh(Panel), - {noreply, State#state{active=true}} + {noreply, precalc(State#state{active=true})} catch _:_ -> - SysInfo = observer_wx:try_rpc(Node, observer_backend, sys_info, []), - Info = alloc_info(SysInfo), - Freq = 6, - erlang:send_after(trunc(1000 / Freq), self(), {refresh, 1, Freq, Node}), - wxWindow:refresh(Panel), - {noreply, State#state{active=true, appmon=Node, offset=0.0, - data = add_data(Info, {0, queue:new()})}} + {noreply, restart_fetcher(Node, State)} end; handle_info(not_active, State = #state{appmon=_Pid}) -> @@ -160,12 +184,22 @@ code_change(_, _, State) -> %%%%%%%%%% -add_data(Stats, {N, Q}) when N > 60 -> - {N, queue:drop(queue:in(Stats, Q))}; -add_data(Stats, {N, Q}) -> - {N+1, queue:in(Stats, Q)}. +restart_fetcher(Node, #state{panel=Panel, wins=Wins0, time=Ti} = State) -> + SysInfo = observer_wx:try_rpc(Node, observer_backend, sys_info, []), + Info = alloc_info(SysInfo), + {Wins, Samples} = add_data(Info, {0, queue:new()}, Wins0, Ti, true), + erlang:send_after(1000 div ?DISP_FREQ, self(), {refresh, 0}), + wxWindow:refresh(Panel), + precalc(State#state{active=true, appmon=Node, time=Ti#ti{tick=0}, + wins=Wins, samples=Samples}). + +precalc(#state{samples=Data0, paint=Paint, time=Ti, wins=Wins0}=State) -> + Wins = [precalc(Ti, Data0, Paint, Win) || Win <- Wins0], + State#state{wins=Wins}. -update_alloc(#state{windows={_, _, {_, Grid}}}, Fields) -> + +update_alloc(#state{mem=Grid}, Fields) -> + wxWindow:freeze(Grid), Max = wxListCtrl:getItemCount(Grid), Update = fun({Name, BS, CS}, Row) -> (Row >= Max) andalso wxListCtrl:insertItem(Grid, Row, ""), @@ -174,7 +208,8 @@ update_alloc(#state{windows={_, _, {_, Grid}}}, Fields) -> wxListCtrl:setItem(Grid, Row, 2, observer_lib:to_str(CS div 1024)), Row + 1 end, - lists:foldl(Update, 0, Fields), + wx:foldl(Update, 0, Fields), + wxWindow:thaw(Grid), Fields. alloc_info(SysInfo) -> @@ -221,10 +256,9 @@ sum_alloc_one_instance([],BS,CS,TotalBS,TotalCS) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% create_mem_info(Parent) -> - Panel = wxPanel:new(Parent), - wxWindow:setBackgroundColour(Panel, {255,255,255}), Style = ?wxLC_REPORT bor ?wxLC_SINGLE_SEL bor ?wxLC_HRULES bor ?wxLC_VRULES, - Grid = wxListCtrl:new(Panel, [{style, Style}]), + Grid = wxListCtrl:new(Parent, [{style, Style}]), + Li = wxListItem:new(), AddListEntry = fun({Name, Align, DefSize}, Col) -> wxListItem:setText(Li, Name), @@ -239,19 +273,10 @@ create_mem_info(Parent) -> lists:foldl(AddListEntry, 0, ListItems), wxListItem:destroy(Li), - Sizer = wxBoxSizer:new(?wxVERTICAL), - wxSizer:add(Sizer, Grid, [{flag, ?wxEXPAND bor ?wxLEFT bor ?wxRIGHT}, - {border, 5}, {proportion, 1}]), - wxWindow:setSizerAndFit(Panel, Sizer), - {Panel, Grid}. - + Grid. create_menus(Parent, _) -> - MenuEntries = - [{"File", - [ - ]} - ], - observer_wx:create_menus(Parent, MenuEntries). + View = {"View", [#create_menu{id = ?ID_REFRESH_INTERVAL, text = "Graph Settings"}]}, + observer_wx:create_menus(Parent, [{"File", []}, View]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/lib/observer/src/observer_app_wx.erl b/lib/observer/src/observer_app_wx.erl index a2b7c21993..cef83037d0 100644 --- a/lib/observer/src/observer_app_wx.erl +++ b/lib/observer/src/observer_app_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ -include("observer_defs.hrl"). %% Import drawing wrappers --import(observer_perf_wx, [haveGC/0, +-import(observer_perf_wx, [haveGC/0, make_gc/2, destroy_gc/1, setPen/2, setFont/3, setBrush/2, strokeLine/5, strokeLines/2, drawRoundedRectangle/6, drawText/4, getTextExtent/2]). @@ -244,28 +244,18 @@ handle_event(Event, _State) -> %%%%%%%%%% handle_sync_event(#wx{event = #wxPaint{}},_, #state{app_w=DA, app=App, sel=Sel, paint=Paint, usegc=UseGC}) -> - %% PaintDC must be created in a callback to work on windows. - IsWindows = element(1, os:type()) =:= win32, - %% Avoid Windows flickering hack - DC = if IsWindows -> wx:typeCast(wxBufferedPaintDC:new(DA), wxPaintDC); - true -> wxPaintDC:new(DA) - end, - IsWindows andalso wxDC:clear(DC), - GC = case UseGC of - true -> - GC0 = ?wxGC:create(DC), - %% Argh must handle scrolling when using ?wxGC - {Sx,Sy} = wxScrolledWindow:calcScrolledPosition(DA, {0,0}), - ?wxGC:translate(GC0, Sx,Sy), - GC0; - false -> - wxScrolledWindow:doPrepareDC(DA,DC), - DC - end, + GC = {GC0, DC} = make_gc(DA, UseGC), + case UseGC of + false -> + wxScrolledWindow:doPrepareDC(DA,DC); + true -> + %% Argh must handle scrolling when using ?wxGC + {Sx,Sy} = wxScrolledWindow:calcScrolledPosition(DA, {0,0}), + ?wxGC:translate(GC0, Sx,Sy) + end, %% Nothing is drawn until wxPaintDC is destroyed. - draw({UseGC, GC}, App, Sel, Paint), - UseGC andalso ?wxGC:destroy(GC), - wxPaintDC:destroy(DC), + draw(GC, App, Sel, Paint), + destroy_gc(GC), ok. %%%%%%%%%% handle_call(Event, From, _State) -> @@ -312,15 +302,12 @@ handle_info({delivery, _Pid, app, _Curr, {[], [], [], []}}, handle_info({delivery, Pid, app, Curr, AppData}, State = #state{panel=Panel, appmon=Pid, current=Curr, usegc=UseGC, app_w=AppWin, paint=#paint{font=Font}}) -> - GC = if UseGC -> ?wxGC:create(AppWin); - true -> wxWindowDC:new(AppWin) + GC = if UseGC -> {?wxGC:create(AppWin), false}; + true -> {false, wxWindowDC:new(AppWin)} end, - FontW = {UseGC, GC}, - setFont(FontW, Font, {0,0,0}), - App = build_tree(AppData, FontW), - if UseGC -> ?wxGC:destroy(GC); - true -> wxWindowDC:destroy(GC) - end, + setFont(GC, Font, {0,0,0}), + App = build_tree(AppData, GC), + destroy_gc(GC), setup_scrollbar(AppWin, App), wxWindow:refresh(Panel), wxWindow:layout(Panel), diff --git a/lib/observer/src/observer_defs.hrl b/lib/observer/src/observer_defs.hrl index 1c2fe520b7..504d0877d9 100644 --- a/lib/observer/src/observer_defs.hrl +++ b/lib/observer/src/observer_defs.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -49,3 +49,14 @@ -define(LCTRL_WDECR, 4). %% Remove some pixels in column width to avoid creating unnecessary scrollbar -define(SASH_STYLE, ?wxSP_LIVE_UPDATE bor ?wxSP_NOBORDER bor ?wxSP_3DSASH). + +-define(DISP_FREQ, 10). %% per second +-define(FETCH_DATA, 2). %% per second +-define(DISP_SECONDS, 60). + +-record(ti, {tick=0, disp=?DISP_FREQ/?FETCH_DATA, fetch=?FETCH_DATA, secs=?DISP_SECONDS}). + +-record(win, {name, panel, size, geom, + graphs=[], no_samples=0, + max, state, + info=[]}). diff --git a/lib/observer/src/observer_html_lib.erl b/lib/observer/src/observer_html_lib.erl index f646f8ed3e..1f1306c370 100644 --- a/lib/observer/src/observer_html_lib.erl +++ b/lib/observer/src/observer_html_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2014. All Rights Reserved. +%% Copyright Ericsson AB 2003-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/observer_lib.erl b/lib/observer/src/observer_lib.erl index 71a2b71a72..c6a1c73c83 100644 --- a/lib/observer/src/observer_lib.erl +++ b/lib/observer/src/observer_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2014. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -122,7 +122,7 @@ display_yes_no_dialog(Str) -> %% display_info(Parent, [{Title, [{Label, Info}]}]) -> {Panel, Sizer, InfoFieldsToUpdate} display_info(Frame, Info) -> Panel = wxPanel:new(Frame), - wxWindow:setBackgroundColour(Panel, {255,255,255}), + wxWindow:setBackgroundStyle(Panel, ?wxBG_STYLE_SYSTEM), Sizer = wxBoxSizer:new(?wxVERTICAL), wxSizer:addSpacer(Sizer, 5), Add = fun(BoxInfo) -> @@ -201,22 +201,21 @@ update_info2([Scroll = {_, _, _}|Fs], [{_, NewInfo}|Rest]) -> update_scroll_boxes(Scroll, NewInfo), update_info2(Fs, Rest); update_info2([Field|Fs], [{_Str, {click, Value}}|Rest]) -> - wxTextCtrl:setValue(Field, to_str(Value)), + wxStaticText:setLabel(Field, to_str(Value)), update_info2(Fs, Rest); update_info2([Field|Fs], [{_Str, Value}|Rest]) -> - wxTextCtrl:setValue(Field, to_str(Value)), + wxStaticText:setLabel(Field, to_str(Value)), update_info2(Fs, Rest); update_info2([Field|Fs], [undefined|Rest]) -> - wxTextCtrl:setValue(Field, ""), + wxStaticText:setLabel(Field, ""), update_info2(Fs, Rest); update_info2([], []) -> ok. update_scroll_boxes({_, _, 0}, {_, []}) -> ok; update_scroll_boxes({Win, Sizer, _}, {Type, List}) -> [wxSizerItem:deleteWindows(Child) || Child <- wxSizer:getChildren(Sizer)], - BC = wxWindow:getBackgroundColour(Win), Cursor = wxCursor:new(?wxCURSOR_HAND), - add_entries(Type, List, Win, Sizer, BC, Cursor), + add_entries(Type, List, Win, Sizer, Cursor), wxCursor:destroy(Cursor), wxSizer:recalcSizes(Sizer), wxWindow:refresh(Win), @@ -379,25 +378,22 @@ add_box(Panel, OuterBox, Cursor, Title, Proportion, {Format, List}) -> wxScrolledWindow:setScrollbars(Scroll,1,1,0,0), ScrollSizer = wxBoxSizer:new(?wxVERTICAL), wxScrolledWindow:setSizer(Scroll, ScrollSizer), - BC = wxWindow:getBackgroundColour(Panel), - wxWindow:setBackgroundColour(Scroll,BC), - add_entries(Format, List, Scroll, ScrollSizer, BC, Cursor), + wxWindow:setBackgroundStyle(Scroll, ?wxBG_STYLE_SYSTEM), + add_entries(Format, List, Scroll, ScrollSizer, Cursor), wxSizer:add(Box,Scroll,[{proportion,1},{flag,?wxEXPAND}]), wxSizer:add(OuterBox,Box,[{proportion,Proportion},{flag,?wxEXPAND}]), {Scroll,ScrollSizer,length(List)}. -add_entries(click, List, Scroll, ScrollSizer, BC, Cursor) -> +add_entries(click, List, Scroll, ScrollSizer, Cursor) -> Add = fun(Link) -> TC = link_entry(Scroll, Link, Cursor), - wxWindow:setBackgroundColour(TC,BC), - wxSizer:add(ScrollSizer,TC,[{flag,?wxEXPAND}]) + wxWindow:setBackgroundStyle(TC, ?wxBG_STYLE_SYSTEM), + wxSizer:add(ScrollSizer,TC, [{flag,?wxEXPAND}]) end, [Add(Link) || Link <- List]; -add_entries(plain, List, Scroll, ScrollSizer, _, _) -> +add_entries(plain, List, Scroll, ScrollSizer, _) -> Add = fun(String) -> - TC = wxTextCtrl:new(Scroll, ?wxID_ANY, - [{style,?SINGLE_LINE_STYLE}, - {value,String}]), + TC = wxStaticText:new(Scroll, ?wxID_ANY, String), wxSizer:add(ScrollSizer,TC,[{flag,?wxEXPAND}]) end, [Add(String) || String <- List]. @@ -435,51 +431,44 @@ create_box(Panel, {scroll_boxes,Data}) -> wxSizer:layout(OuterBox), {OuterBox, Boxes}; -create_box(Panel, Data) -> - {Title, Align, Info} = get_box_info(Data), - Box = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, Title}]), - LeftSize = get_max_size(Panel,Info), - LeftProportion = [{proportion,0}], - RightProportion = [{proportion,1}, {flag, Align bor ?wxEXPAND}], +create_box(Parent, Data) -> + {Title, _Align, Info} = get_box_info(Data), + Top = wxStaticBoxSizer:new(?wxVERTICAL, Parent, [{label, Title}]), + Panel = wxPanel:new(Parent), + Box = wxBoxSizer:new(?wxVERTICAL), + LeftSize = 30 + get_max_width(Panel,Info), + RightProportion = [{flag, ?wxEXPAND}], AddRow = fun({Desc0, Value0}) -> Desc = Desc0++":", Line = wxBoxSizer:new(?wxHORIZONTAL), - wxSizer:add(Line, - wxTextCtrl:new(Panel, ?wxID_ANY, - [{style,?SINGLE_LINE_STYLE}, - {size,LeftSize}, - {value,Desc}]), - LeftProportion), + Label = wxStaticText:new(Panel, ?wxID_ANY, Desc), + wxSizer:add(Line, 5, 0), + wxSizer:add(Line, Label), + wxSizer:setItemMinSize(Line, Label, LeftSize, -1), Field = case Value0 of {click,"unknown"} -> - wxTextCtrl:new(Panel, ?wxID_ANY, - [{style,?SINGLE_LINE_STYLE}, - {value,"unknown"}]); + wxStaticText:new(Panel, ?wxID_ANY,"unknown"); {click,Value} -> link_entry(Panel,Value); _ -> Value = to_str(Value0), - TCtrl = wxTextCtrl:new(Panel, ?wxID_ANY, - [{style,?SINGLE_LINE_STYLE}, - {value,Value}]), + TCtrl = wxStaticText:new(Panel, ?wxID_ANY,Value), length(Value) > 50 andalso wxWindow:setToolTip(TCtrl,wxToolTip:new(Value)), TCtrl end, wxSizer:add(Line, 10, 0), % space of size 10 horisontally wxSizer:add(Line, Field, RightProportion), - - {_,H,_,_} = wxTextCtrl:getTextExtent(Field,"Wj"), - wxTextCtrl:setMinSize(Field,{0,H}), - - wxSizer:add(Box, Line, [{proportion,0},{flag,?wxEXPAND}]), + wxSizer:add(Box, Line, [{proportion,1},{flag,?wxEXPAND}]), Field; (undefined) -> undefined end, InfoFields = [AddRow(Entry) || Entry <- Info], - {Box, InfoFields}. + wxWindow:setSizer(Panel, Box), + wxSizer:add(Top, Panel, [{proportion,1},{flag,?wxEXPAND}]), + {Top, InfoFields}. link_entry(Panel, Link) -> Cursor = wxCursor:new(?wxCURSOR_HAND), @@ -490,13 +479,12 @@ link_entry(Panel, Link, Cursor) -> link_entry2(Panel, to_link(Link), Cursor). link_entry2(Panel,{Target,Str},Cursor) -> - TC = wxTextCtrl:new(Panel, ?wxID_ANY, [{style, ?SINGLE_LINE_STYLE}]), - wxTextCtrl:setForegroundColour(TC,?wxBLUE), - wxTextCtrl:appendText(TC, Str), + TC = wxStaticText:new(Panel, ?wxID_ANY, Str), + wxWindow:setForegroundColour(TC,?wxBLUE), wxWindow:setCursor(TC, Cursor), - wxTextCtrl:connect(TC, left_down, [{userData,Target}]), - wxTextCtrl:connect(TC, enter_window), - wxTextCtrl:connect(TC, leave_window), + wxWindow:connect(TC, left_down, [{userData,Target}]), + wxWindow:connect(TC, enter_window), + wxWindow:connect(TC, leave_window), ToolTip = wxToolTip:new("Click to see properties for " ++ Str), wxWindow:setToolTip(TC, ToolTip), TC. @@ -521,23 +509,12 @@ html_window(Panel, Html) -> wxHtmlWindow:setPage(Win, Html), Win. -get_max_size(Panel,Info) -> - Txt = wxTextCtrl:new(Panel, ?wxID_ANY, []), - Size = get_max_size(Txt,Info,0,0), - wxTextCtrl:destroy(Txt), - Size. - -get_max_size(Txt,[{Desc,_}|Info],MaxX,MaxY) -> - {X,Y,_,_} = wxTextCtrl:getTextExtent(Txt,Desc++":"), - if X>MaxX -> - get_max_size(Txt,Info,X,Y); - 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,-1}. +get_max_width(Parent,Info) -> + lists:foldl(fun({Desc,_}, Max) -> + {W, _, _, _} = wxWindow:getTextExtent(Parent, Desc), + max(W,Max); + (_, Max) -> Max + end, 0, Info). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% set_listctrl_col_size(LCtrl, Total) -> diff --git a/lib/observer/src/observer_perf_wx.erl b/lib/observer/src/observer_perf_wx.erl index ace0b62c1d..1010a6af4c 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-2013. All Rights Reserved. +%% Copyright Ericsson AB 2012-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -25,8 +25,9 @@ handle_event/2, handle_sync_event/3, handle_cast/2]). %% Drawing wrappers for DC and GC areas --export([setup_graph_drawing/1, refresh_panel/6, - haveGC/0, +-export([make_win/4, setup_graph_drawing/1, + refresh_panel/4, precalc/4, add_data/5, interval_dialog/2, + haveGC/0, make_gc/2, destroy_gc/1, setPen/2, setFont/3, setBrush/2, strokeLine/5, strokeLines/2, drawRoundedRectangle/6, drawText/4, getTextExtent/2]). @@ -35,13 +36,18 @@ -include_lib("wx/include/wx.hrl"). -include("observer_defs.hrl"). +-define(ID_REFRESH_INTERVAL, 102). + +-define(BW, 5). +-define(BH, 5). + -record(state, { - offset = 0.0, + time = #ti{}, active = false, parent, - windows, - data = {0, queue:new()}, + samples, %% Orig data store + wins=[], %% per window content panel, paint, appmon @@ -51,50 +57,50 @@ -record(paint, {font, small, pen, pen2, pens, usegc = false}). --define(RQ_W, 1). --define(MEM_W, 2). --define(IO_W, 3). - start_link(Notebook, Parent) -> wx_object:start_link(?MODULE, [Notebook, Parent], []). init([Notebook, Parent]) -> - try - Panel = wxPanel:new(Notebook), - Main = wxBoxSizer:new(?wxVERTICAL), + try + Panel = wxPanel:new(Notebook), + Main = wxBoxSizer:new(?wxVERTICAL), + MemIO = wxBoxSizer:new(?wxHORIZONTAL), + + CPU = make_win(runq, Panel, Main, ?wxALL), + MEM = make_win(memory, Panel, MemIO, ?wxLEFT), + IO = make_win(io, Panel, MemIO, ?wxLEFT bor ?wxRIGHT), + + wxSizer:add(Main, MemIO, [{flag, ?wxEXPAND bor ?wxDOWN}, + {proportion, 1}, {border, 5}]), + wxWindow:setSizer(Panel, Main), + Windows = [CPU, MEM, IO], + PaintInfo = setup_graph_drawing(Windows), + + process_flag(trap_exit, true), + State0 = #state{parent=Parent, + panel =Panel, + wins = Windows, + paint=PaintInfo, + samples=reset_data() + }, + {Panel, State0} + catch _:Err -> + io:format("~p crashed ~p: ~p~n",[?MODULE, Err, erlang:get_stacktrace()]), + {stop, Err} + end. + +make_win(Name, Parent, Sizer, Border) -> Style = ?wxFULL_REPAINT_ON_RESIZE bor ?wxCLIP_CHILDREN, - CPU = wxPanel:new(Panel, [{winid, ?RQ_W}, {style,Style}]), - wxSizer:add(Main, CPU, [{flag, ?wxEXPAND bor ?wxALL}, - {proportion, 1}, {border, 5}]), - MemIO = wxBoxSizer:new(?wxHORIZONTAL), - MEM = wxPanel:new(Panel, [{winid, ?MEM_W}, {style,Style}]), - IO = wxPanel:new(Panel, [{winid, ?IO_W}, {style,Style}]), - wxSizer:add(MemIO, MEM, [{flag, ?wxEXPAND bor ?wxLEFT}, - {proportion, 1}, {border, 5}]), - wxSizer:add(MemIO, IO, [{flag, ?wxEXPAND bor ?wxLEFT bor ?wxRIGHT}, - {proportion, 1}, {border, 5}]), - wxSizer:add(Main, MemIO, [{flag, ?wxEXPAND bor ?wxDOWN}, - {proportion, 1}, {border, 5}]), - wxWindow:setSizer(Panel, Main), - - PaintInfo = setup_graph_drawing([CPU, MEM, IO]), - - process_flag(trap_exit, true), - {Panel, #state{parent=Parent, - panel =Panel, - windows = {CPU, MEM, IO}, - paint=PaintInfo - }} - catch _:Err -> - io:format("~p crashed ~p: ~p~n",[?MODULE, Err, erlang:get_stacktrace()]), - {stop, Err} - end. + Panel = wxPanel:new(Parent, [{style,Style}]), + Opts = [{flag, ?wxEXPAND bor Border}, {proportion, 1}, {border, 5}], + wxSizer:add(Sizer, Panel, Opts), + #win{name=Name, panel=Panel}. setup_graph_drawing(Panels) -> IsWindows = element(1, os:type()) =:= win32, IgnoreCB = {callback, fun(_,_) -> ok end}, - Do = fun(Panel) -> - wxWindow:setBackgroundColour(Panel, ?wxWHITE), + Do = fun(#win{panel=Panel}) -> + wxWindow:setBackgroundStyle(Panel, ?wxBG_STYLE_SYSTEM), wxPanel:connect(Panel, paint, [callback]), IsWindows andalso wxPanel:connect(Panel, erase_background, [IgnoreCB]) @@ -117,8 +123,8 @@ setup_graph_drawing(Panels) -> SF = wxFont:new(DefSize-2, DefFamily, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_NORMAL), {F, SF} end, - BlackPen = wxPen:new({0,0,0}, [{width, 2}]), - Pens = [wxPen:new(Col, [{width, 3}]) || Col <- tuple_to_list(colors())], + BlackPen = wxPen:new({0,0,0}, [{width, 1}]), + Pens = [wxPen:new(Col, [{width, 1}]) || Col <- tuple_to_list(colors())], #paint{usegc = UseGC, font = Font, small = SmallFont, @@ -129,7 +135,18 @@ setup_graph_drawing(Panels) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - +handle_event(#wx{id=?ID_REFRESH_INTERVAL, event=#wxCommand{type=command_menu_selected}}, + #state{panel=Panel, appmon=Old, wins=Wins0, time=#ti{fetch=F0} = Ti0} = State) -> + case interval_dialog(Panel, Ti0) of + Ti0 -> {noreply, State}; + #ti{fetch=F0} = Ti -> %% Same fetch interval force refresh + Wins = [W#win{max=undefined} || W <- Wins0], + {noreply, precalc(State#state{time=Ti, wins=Wins})}; + Ti when Old =:= undefined -> + {noreply, State#state{time=Ti}}; + Ti -> %% Changed fetch interval, drop all data + {noreply, restart_fetcher(node(Old), State#state{time=Ti})} + end; handle_event(#wx{event=#wxCommand{type=command_menu_selected}}, State = #state{}) -> {noreply, State}; @@ -139,41 +156,21 @@ handle_event(Event, _State) -> %%%%%%%%%% handle_sync_event(#wx{obj=Panel, event = #wxPaint{}},_, - #state{active=Active, offset=Offset, paint=Paint, - windows=Windows, data=Data}) -> + #state{active=Active, time=Ti, paint=Paint, wins=Windows}) -> %% Sigh workaround bug on MacOSX (Id in paint event is always 0) %% Panel = element(Id, Windows), - Id = if Panel =:= element(?RQ_W, Windows) -> runq; - Panel =:= element(?MEM_W, Windows) -> memory; - Panel =:= element(?IO_W, Windows) -> io - end, - - refresh_panel(Panel, Id, Offset, Data, Active, Paint), + Win = lists:keyfind(Panel, #win.panel, Windows), + refresh_panel(Active, Win, Ti, Paint), ok. -refresh_panel(Panel, Id, Offset, Data, Active, #paint{usegc=UseGC} = Paint) -> +refresh_panel(Active, #win{name=_Id, panel=Panel}=Win, Ti, #paint{usegc=UseGC}=Paint) -> %% PaintDC must be created in a callback to work on windows. - IsWindows = element(1, os:type()) =:= win32, - DC = if IsWindows -> - %% Ugly hack to aviod flickering on windows, works on windows only - %% But the other platforms are doublebuffered by default - wx:typeCast(wxBufferedPaintDC:new(Panel), wxPaintDC); - true -> - wxPaintDC:new(Panel) - end, - IsWindows andalso wxDC:clear(DC), - GC = if UseGC -> ?wxGC:create(DC); - true -> DC - end, %% Nothing is drawn until wxPaintDC is destroyed. - try - draw(Offset, Id, {UseGC, GC}, Panel, Paint, Data, Active) - catch _:Err -> - io:format("Internal error ~p ~p~n",[Err, erlang:get_stacktrace()]) + GC = make_gc(Panel, UseGC), + if Active -> draw_win(GC, Win, Ti, Paint); + true -> ignore end, - UseGC andalso ?wxGC:destroy(GC), - wxPaintDC:destroy(DC). - + destroy_gc(GC). %%%%%%%%%% handle_call(Event, From, _State) -> @@ -182,41 +179,42 @@ handle_call(Event, From, _State) -> handle_cast(Event, _State) -> error({unhandled_cast, Event}). %%%%%%%%%% -handle_info(Stats = {stats, 1, _, _, _}, - State = #state{panel=Panel, data=Data, active=Active}) -> +handle_info({stats, 1, _, _, _} = Stats, + #state{panel=Panel, samples=Data, active=Active, wins=Wins0, + time=#ti{tick=Tick, disp=Disp0}=Ti} = State0) -> if Active -> + Disp = trunc(Disp0), + Next = max(Tick - Disp, 0), + erlang:send_after(1000 div ?DISP_FREQ, self(), {refresh, Next}), + {Wins, Samples} = add_data(Stats, Data, Wins0, Ti, Active), + State = precalc(State0#state{time=Ti#ti{tick=Next}, wins=Wins, samples=Samples}), wxWindow:refresh(Panel), - Freq = 6, - erlang:send_after(trunc(1000 / Freq), self(), {refresh, 1, Freq}); - true -> ignore - end, - {noreply, State#state{offset=0.0, data = add_data(Stats, Data)}}; - -handle_info({refresh, Seq, Freq}, State = #state{panel=Panel, offset=Prev}) -> - wxWindow:refresh(Panel), - Next = Seq+1, - if Seq > 1, Prev =:= 0.0 -> - %% We didn't have time to handle the refresh {noreply, State}; - Next < Freq -> - erlang:send_after(trunc(1000 / Freq), self(), {refresh, Next, Freq}), - {noreply, State#state{offset=Seq/Freq}}; true -> - {noreply, State#state{offset=Seq/Freq}} + {Wins1, Samples} = add_data(Stats, Data, Wins0, Ti, Active), + Wins = [W#win{max=undefined} || W <- Wins1], + {noreply, State0#state{samples=Samples, wins=Wins, time=Ti#ti{tick=0}}} end; -handle_info({active, Node}, State = #state{parent=Parent, panel=Panel, appmon=Old}) -> +handle_info({refresh, Seq}, #state{panel=Panel, time=#ti{tick=Seq, disp=DispF}=Ti} = State0) + when (Seq+1) < (DispF*1.5) -> + Next = Seq+1, + erlang:send_after(1000 div ?DISP_FREQ, self(), {refresh, Next}), + State = precalc(State0#state{time=Ti#ti{tick=Next}}), + catch wxWindow:refresh(Panel), + {noreply, State}; +handle_info({refresh, _}, State) -> + {noreply, State}; + +handle_info({active, Node}, #state{parent=Parent, panel=Panel, appmon=Old, time=_Ti} = State) -> create_menus(Parent, []), try Node = node(Old), wxWindow:refresh(Panel), + erlang:send_after(1000 div ?DISP_FREQ, self(), {refresh, 0}), {noreply, State#state{active=true}} catch _:_ -> - catch Old ! exit, - Me = self(), - Pid = spawn_link(Node, observer_backend, fetch_stats, [Me, 1000]), - wxWindow:refresh(Panel), - {noreply, State#state{active=true, appmon=Pid, data={0, queue:new()}}} + {noreply,restart_fetcher(Node, State)} end; handle_info(not_active, State = #state{appmon=_Pid}) -> @@ -237,173 +235,337 @@ terminate(_Event, #state{appmon=Pid}) -> code_change(_, _, State) -> State. -add_data(Stats, {N, Q}) when N > 60 -> - {N, queue:drop(queue:in(Stats, Q))}; -add_data(Stats, {N, Q}) -> - {N+1, queue:in(Stats, Q)}. +restart_fetcher(Node, #state{appmon=Old, panel=Panel, time=#ti{fetch=Freq}=Ti}=State) -> + catch Old ! exit, + Me = self(), + Pid = spawn_link(Node, observer_backend, fetch_stats, [Me, round(1000/Freq)]), + wxWindow:refresh(Panel), + precalc(State#state{active=true, appmon=Pid, samples=reset_data(), time=Ti#ti{tick=0}}). + +reset_data() -> + {0, queue:new()}. + +add_data(Stats, {N, Q0}, Wins, #ti{fetch=Fetch, secs=Secs}, Active) when N > (Secs*Fetch+1) -> + {{value, Drop}, Q} = queue:out(Q0), + add_data_1(Wins, Stats, N, {Drop,Q}, Active); +add_data(Stats, {N, Q}, Wins, _, Active) -> + add_data_1(Wins, Stats, N+1, {empty, Q}, Active). + +add_data_1([#win{state={_,St}}|_]=Wins0, Last, N, {Drop, Q}, Active) + when St /= undefined -> + {Wins, Stat} = + lists:mapfoldl(fun(Win0, Entry) -> + {Win1,Stat} = add_data_2(Win0, Last, Entry), + case Active of + true -> + Win = add_data_3(Win1, N, Drop, Stat, Q), + {Win, Stat}; + false -> + {Win1, Stat} + end + end, #{}, Wins0), + {Wins, {N,queue:in(Stat#{}, Q)}}; +add_data_1(Wins, Stats, 1, {_, Q}, _) -> + {[Win#win{state=init_data(Id, Stats), + info = info(Id, Stats)} + || #win{name=Id}=Win <- Wins], {0,Q}}. + +add_data_2(#win{name=Id, state=S0}=Win, Stats, Map) -> + {V1, S1} = collect_data(Id, Stats, S0), + {Win#win{state=S1}, Map#{Id=>V1}}. + +add_data_3(#win{name=Id, max={{OldMax, OldEntry},_,_,_}, + geom=#{scale:={WS,HS}}, state={Max,_}, + graphs=Graphs}=Win, + N, Drop0, Last, Q1) + when N > 3 -> + Drop = case Drop0 of + #{Id:=D} -> D; + _ -> Drop0 + end, + case {max_value(Max), Drop =:= OldEntry} of + {OldMax, false} -> + #{Id:=V4} = Last, + {{value, #{Id:=V3}},Q2} = queue:out_r(Q1), + {{value, #{Id:=V2}},Q3} = queue:out_r(Q2), + {{value, #{Id:=V1}},_} = queue:out_r(Q3), + Vals = [V1,V2,V3,V4], + Gs = tuple_size(V1), + Info = lists:zip(lists:seq(Gs, 1, -1), Graphs), + Lines = [add_lines(Vals, Drop, Prev, I, WS, HS) || {I, Prev} <- Info], + Win#win{graphs=Lines, no_samples=N}; + _W -> %% Max changed Trigger complete recalc + Win#win{max=undefined} + end; +add_data_3(Win, _, _, _,_) -> + %% Trigger complete recalc + Win#win{max=undefined}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% create_menus(Parent, _) -> - MenuEntries = - [{"File", - [ - ]} - ], - observer_wx:create_menus(Parent, MenuEntries). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -collect_data(runq, {N, Q}) -> - case queue:to_list(Q) of - [] -> {0, 0, [], []}; - [_] -> {0, 0, [], []}; - [{stats, _Ver, Init0, _IO, _Mem}|Data0] -> - Init = lists:sort(Init0), - [_|Data=[First|_]] = lists:foldl(fun({stats, _, T0, _, _}, [Prev|Acc]) -> - TN = lists:sort(T0), - Delta = calc_delta(TN, Prev), - [TN, list_to_tuple(Delta)|Acc] - end, [Init], Data0), - NoGraphs = tuple_size(First), - {N, lmax(Data), lists:reverse([First|Data]), lists:seq(1, NoGraphs)} - end; -collect_data(memory, {N, Q}) -> - MemT = mem_types(), - Data = [list_to_tuple([Value || {Type,Value} <- MemInfo, - lists:member(Type, MemT)]) - || {stats, _Ver, _RQ, _IO, MemInfo} <- queue:to_list(Q)], - {N, lmax(Data), Data, MemT}; -collect_data(io, {N, Q}) -> - case queue:to_list(Q) of - [] -> {0, 0, [], []}; - [_] -> {0, 0, [], []}; - [{stats, _Ver, _RQ, {{_,In0}, {_,Out0}}, _Mem}|Data0] -> - [_,_|Data=[First|_]] = - lists:foldl(fun({stats, _, _, {{_,In}, {_,Out}}, _}, [PIn,Pout|Acc]) -> - [In,Out,{In-PIn,Out-Pout}|Acc] - end, [In0,Out0], Data0), - {N, lmax(Data), lists:reverse([First|Data]), [input, output]} - end; -collect_data(alloc, {N, Q}) -> - List = queue:to_list(Q), - Data = [list_to_tuple([Carrier || {_Type,_Block,Carrier} <- MemInfo]) - || MemInfo <- List], - Info = case List of %% Varies depending on erlang build config/platform - [MInfo|_] -> [Type || {Type, _, _} <- MInfo]; - _ -> [] - end, - {N, lmax(Data), Data, Info}; - -collect_data(utilz, {N, Q}) -> - List = queue:to_list(Q), - Data = [list_to_tuple([round(100*Block/Carrier) || {_Type,Block,Carrier} <- MemInfo]) - || MemInfo <- List], - Info = case List of %% Varies depending on erlang build config/platform - [MInfo|_] -> [Type || {Type, _, _} <- MInfo]; - _ -> [] - end, - {N, lmax(Data), Data, Info}. + View = {"View", [#create_menu{id = ?ID_REFRESH_INTERVAL, text = "Graph Settings"}]}, + observer_wx:create_menus(Parent, [{"File", []}, View]). + +interval_dialog(Parent0, #ti{fetch=Fetch0, secs=Secs0}=Ti) -> + Parent = observer_lib:get_wx_parent(Parent0), + Dialog = wxDialog:new(Parent, ?wxID_ANY, "Load Chart Settings", + [{style, ?wxDEFAULT_DIALOG_STYLE bor + ?wxRESIZE_BORDER}]), + {Sl1,FetchSl} = slider(Dialog, "Sample (ms)", trunc(1000 / Fetch0), 100, 10000), + {Sl2, SecsSl} = slider(Dialog, "Length (min)", Secs0 div 60, 1, 10), + TopSizer = wxBoxSizer:new(?wxVERTICAL), + Flags = [{flag, ?wxEXPAND bor ?wxTOP bor ?wxLEFT bor ?wxRIGHT}, + {border, 5}, {proportion, 1}], + wxSizer:add(TopSizer, Sl1, Flags), + wxSizer:add(TopSizer, Sl2, Flags), + wxSizer:add(TopSizer, wxDialog:createButtonSizer(Dialog, ?wxOK bor ?wxCANCEL), Flags), + wxWindow:setSizerAndFit(Dialog, TopSizer), + wxSizer:setSizeHints(TopSizer, Dialog), + Res = case wxDialog:showModal(Dialog) of + ?wxID_OK -> + Fetch = 1000 / wxSlider:getValue(FetchSl), + Secs = wxSlider:getValue(SecsSl) * 60, + Ti#ti{fetch=Fetch, secs=Secs, disp=?DISP_FREQ/Fetch}; + ?wxID_CANCEL -> + Ti + end, + wxDialog:destroy(Dialog), + Res. + +slider(Parent, Str, Value, Min, Max) -> + Sz = wxBoxSizer:new(?wxHORIZONTAL), + Center = [{flag, ?wxALIGN_CENTER_VERTICAL}], + wxSizer:add(Sz, wxStaticText:new(Parent, ?wxID_ANY, Str), [{proportion, 1}|Center]), + Opt = [{style, ?wxSL_HORIZONTAL bor ?wxSL_LABELS}], + Slider = wxSlider:new(Parent, ?wxID_ANY, Value, Min, Max, Opt), + wxSizer:add(Sz, Slider, [{proportion, 2}|Center]), + case Min > 1 of + false -> + {Sz, Slider}; + true -> + CB = fun(#wx{event=Ev},_) -> step(Ev, Slider, Min) end, + wxSlider:connect(Slider, scroll_thumbtrack, [{callback, CB}]), + wxSlider:connect(Slider, scroll_changed, [{callback, CB}]), + {Sz, Slider} + end. +step(_Ev = #wxScroll{commandInt=Value}, Slider, Min) -> + Val = Min * round(Value / Min), + wxSlider:setValue(Slider, Val), + ok. -mem_types() -> - [total, processes, atom, binary, code, ets]. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -lmax([]) -> 0; -lmax(List) -> - Max = [lists:max(tuple_to_list(T)) || T <- List, - tuple_size(T) > 0], - case Max of - [] -> 0; - _ -> lists:max(Max) +mk_max() -> {0, undefined}. +max_value({Max,_}) -> Max. +%% max_data({_,Data}) -> Data. matched in function head + +lmax(MState, Tuple, Tuple) when is_tuple(Tuple) -> + lmax(MState, tuple_to_list(Tuple), Tuple); +lmax(MState, Values, State) -> + Max = max_value(MState), + New = lists:max([Max|Values]), + case New >= Max of + false -> MState; + true -> {New, State} end. +init_data(runq, {stats, _, T0, _, _}) -> {mk_max(),lists:sort(T0)}; +init_data(io, {stats, _, _, {{_,In0}, {_,Out0}}, _}) -> {mk_max(), {In0,Out0}}; +init_data(memory, _) -> {mk_max(), info(memory, undefined)}; +init_data(alloc, _) -> {mk_max(), ok}; +init_data(utilz, _) -> {mk_max(), ok}. + +info(runq, {stats, _, T0, _, _}) -> lists:seq(1, length(T0)); +info(memory, _) -> [total, processes, atom, binary, code, ets]; +info(io, _) -> [input, output]; +info(alloc, First) -> [Type || {Type, _, _} <- First]; +info(utilz, First) -> [Type || {Type, _, _} <- First]; +info(_, []) -> []. + +collect_data(runq, {stats, _, T0, _, _}, {Max,S0}) -> + S1 = lists:sort(T0), + Delta = calc_delta(S1, S0), + Sample = list_to_tuple(Delta), + {Sample, {lmax(Max,Delta,Sample), S1}}; +collect_data(io, {stats, _, _, {{_,In0}, {_,Out0}}, _}, {Max,{PIn,POut}}) -> + In = In0-PIn, + Out = Out0-POut, + Sample = {In, Out}, + {Sample, {lmax(Max, [In,Out], Sample), {In0, Out0}}}; +collect_data(memory, {stats, _, _, _, MemInfo}, {Max, MemTypes}) -> + Vs = [Value || {Type,Value} <- MemInfo, lists:member(Type, MemTypes)], + Sample = list_to_tuple(Vs), + {Sample, {lmax(Max, Vs, Sample),MemTypes}}; +collect_data(alloc, MemInfo, Max) -> + Vs = [Carrier || {_Type,_Block,Carrier} <- MemInfo], + Sample = list_to_tuple(Vs), + {Sample, lmax(Max, Vs, Sample)}; +collect_data(utilz, MemInfo, Max) -> + Vs = [round(100*Block/Carrier) || {_Type,Block,Carrier} <- MemInfo], + Sample = list_to_tuple(Vs), + {Sample, lmax(Max,Vs,Sample)}. + calc_delta([{Id, WN, TN}|Ss], [{Id, WP, TP}|Ps]) -> [100*(WN-WP) div (TN-TP)|calc_delta(Ss, Ps)]; calc_delta([], []) -> []. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -draw(Offset, Id, DC, Panel, Paint=#paint{pens=Pens, small=Small}, Data, Active) -> - %% This can be optimized a lot by collecting data once - %% and draw to memory and then blit memory and only draw new entries in new memory - %% area. Hmm now rewritten to use ?wxGC I don't now if it is feasable. - {Len, Max0, Hs, Info} = collect_data(Id, Data), - {Max,_,_} = MaxDisp = calc_max(Id, Max0), +precalc(#state{samples=Data0, paint=Paint, time=Ti, wins=Wins0}=State) -> + Wins = [precalc(Ti, Data0, Paint, Win) || Win <- Wins0], + State#state{wins=Wins}. + +precalc(Ti, {NoSamples,Q}, Paint, #win{name=Id, panel=Panel}=Win) -> Size = wxWindow:getClientSize(Panel), - {X0,Y0,WS,HS, DrawBs} = draw_borders(Id, Info, DC, Size, MaxDisp, Paint), - Last = 60*WS+X0-1, - Start = max(61-Len, 0)*WS+X0 - Offset*WS, - Samples = length(Hs), - NoGraphs = try tuple_size(hd(Hs)) catch _:_ -> 0 end, - 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)], - DrawBs(); - false -> - DrawBs(), - Text = case Active andalso Samples =< 1 of + case Win of + #win{max=Max, no_samples=NoSamples, size=Size} when is_tuple(Max) -> + Win; + _SomeThingChanged -> + Hs = [Vals || #{Id:=Vals} <- queue:to_list(Q)], + Max = lists:foldl(fun(Vals,Max) -> lmax(Max, Vals, Vals) end, + mk_max(), Hs), + MaxDisp = calc_max(Id, Max), + #{scale:={WS,HS}} = Props = window_geom(Size, MaxDisp, Ti, Panel, Paint), + NoGraphs = try tuple_size(hd(Hs)) catch _:_ -> 0 end, + Graphs = [make_lines(Hs, I, WS, HS) || I <- lists:seq(NoGraphs, 1, -1)], + State = case Win#win.state of + undefined -> {Max, undefined}; + {_, St} -> {Max, St} + end, + Win#win{geom=Props, size=Size, + max=MaxDisp, + graphs=Graphs, + no_samples=NoSamples, + state=State} + end. + +window_geom({W,H}, {_, Max, _Unit, MaxUnit}, + #ti{secs=Secs, fetch=FetchFreq}, + Panel, #paint{font=Font}) -> + Str1 = observer_lib:to_str(MaxUnit), + Str2 = observer_lib:to_str(MaxUnit div 2), + Str3 = observer_lib:to_str(0), + {TW,TH,_,_} = wxWindow:getTextExtent(Panel, Str1, [{theFont, Font}]), + {SpaceW, _,_,_} = wxWindow:getTextExtent(Panel, "W", [{theFont, Font}]), + X0 = ?BW+TW+?BW, + X1 = W-?BW*4, + MaxTextY = TH+?BH, + BottomTextY = H-?BH-TH, + Y0 = MaxTextY + (TH / 2), + Y1 = BottomTextY - TH - ?BH, + + ScaleW = (X1-X0-1)/(Secs*FetchFreq), + ScaleH = (Y1-Y0-1) / Max, + #{p0=>{X0,Y0}, p1=>{X1,Y1}, scale=>{ScaleW, ScaleH}, + txsz=>{TW,TH,SpaceW}, txt=>{BottomTextY, MaxTextY}, strs=>{Str1,Str2,Str3}}. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +draw_win(DC, #win{no_samples=Samples, geom=#{scale:={WS,HS}}, graphs=Graphs, max={_,Max,_,_}}=Win, + #ti{tick=Tick, fetch=FetchFreq, secs=Secs, disp=DispFreq}=Ti, + Paint=#paint{pens=Pens}) when Samples >= 2, Graphs =/= [] -> + %% Draw graphs + {X0,Y0,DrawBs} = draw_borders(DC, Ti, Win, Paint), + Offset = Tick / DispFreq, + Full = case Samples > (1+Secs*FetchFreq) of + true -> 1; + false -> 2 + end, + Start = X0 + (max(Secs*FetchFreq+Full-Samples, 0) - Offset)*WS, + Last = Secs*FetchFreq*WS+X0, + Draw = fun(Lines0, N) -> + setPen(DC, element(1+ ((N-1) rem tuple_size(Pens)), Pens)), + Order = lists:reverse(Lines0), + [{_,Y}|Lines] = translate(Order, {Start, Y0}, 0, WS, {X0,Max*HS,Last}, []), + strokeLines(DC, [{Last,Y}|Lines]), + N-1 + end, + lists:foldl(Draw, length(Graphs), Graphs), + DrawBs(), + ok; + +draw_win(DC, #win{no_samples=Samples} = Win,Ti, #paint{small=Small}=Paint) -> + %% Draw Error Msg + try draw_borders(DC, Ti, Win, Paint) of + {X0,_Y0,DrawBs} -> + Text = case Samples =< 1 of true -> "Waiting for data"; false -> "Information not available" end, setFont(DC, Small, {0,0,0}), - drawText(DC, Text, X0 + 100, element(2,Size) div 2) - end, - ok. + {_,WW} = getSize(DC), + drawText(DC, Text, X0 + 100, WW div 2), + DrawBs(), + ok + catch _:_ -> %% Early redraws fail + ok + end. -make_lines(Ds = [Data|_], PX, N, Clip, ZeroY, WS, HS) -> +translate([{X0,Y}|Rest], {Sx,Sy}=Start, N, WS, {Cx,Cy,Cw}=Clip, Acc) -> + X = min((N-X0)*WS+Sx,Cw), + Next = if X0 > 0 -> N; true -> N+1 end, + case X =< Cx of + true -> + translate(Rest, Start, Next, WS, Clip, [{Cx,Sy-min(Cy,Y)}]); + false -> + translate(Rest, Start, Next, WS, Clip, [{X,Sy-min(Cy,Y)}|Acc]) + end; +translate([], _, _, _, _, Acc) -> + Acc. + +add_lines(Vals, Drop, OldLines, I, WS, HS) -> + Lines = strip(OldLines, Drop, 2), + New = make_lines(Vals, I, WS, HS), + New ++ Lines. + +strip([{X,_}|Rest], Drop, N) when X > 0.0001, N > 0 -> + strip(Rest, Drop, N); +strip([_|Rest], Drop, N) when N > 0 -> + strip(Rest, Drop, N-1); +strip(List, empty, _) -> List; +strip(List, _, _) -> + lists:reverse(strip(lists:reverse(List), empty, 1)). + +make_lines(Ds = [Data|_], N, WS, HS) -> Y = element(N,Data), - make_lines(Ds, PX, N, Clip, ZeroY, WS, HS, Y, []). + make_lines(Ds, N, WS, HS, Y, []). -make_lines([D1 | Ds = [D2|Rest]], PX, N, Clip={Cx,Cy, _}, ZeroY, WS, HS, Y0, Acc0) -> +make_lines([D1 | Ds = [D2|Rest]], N, WS, HS, Y0, Acc0) -> Y1 = element(N,D1), Y2 = element(N,D2), Y3 = case Rest of [D3|_] -> element(N,D3); [] -> Y2 end, - This = {max(Cx, PX),ZeroY-min(Cy,Y1*HS)}, + This = {0, Y1*HS}, Acc = if (abs(Y1-Y2) * HS) < 3.0 -> [This|Acc0]; WS < 3.0 -> [This|Acc0]; - PX < Cx -> - make_splines(Y0,Y1,Y2,Y3,PX,Clip,ZeroY,WS,HS,Acc0); - true -> - make_splines(Y0,Y1,Y2,Y3,PX,Clip,ZeroY,WS,HS,[This|Acc0]) + true -> make_splines(Y0,Y1,Y2,Y3,WS,HS,[This|Acc0]) end, - make_lines(Ds, PX+WS, N, Clip, ZeroY, WS, HS, Y1, Acc); -make_lines([D1], _PX, N, {_,Cy,Last}, ZeroY, _WS, HS, _Y0, Acc) -> - Y1 = element(N,D1), - [{Last,ZeroY-min(Cy, Y1*HS)}|Acc]. + make_lines(Ds, N, WS, HS, Y1, Acc); +make_lines([_D1], _N, _WS, _HS, _Y0, Acc) -> + Acc. -make_splines(Y00,Y10,Y20,Y30,PX,Clip,ZeroY,WS,HS,Acc) -> +make_splines(Y00,Y10,Y20,Y30,WS,HS,Acc) -> Y1 = Y10*HS, Y2 = Y20*HS, - Steps = min(abs(Y1-Y2), WS), + Steps = min(abs(Y1-Y2), WS/2), if Steps > 2 -> Y0 = Y00*HS, Y3 = Y30*HS, Tan = spline_tan(Y0,Y1,Y2,Y3), Delta = 1/Steps, - splines(Steps-1, 0.0, Delta, Tan, Y1,Y2, PX, Clip,ZeroY, Delta*WS, Acc); + splines(Steps-1, 0.0, Delta, Tan, Y1,Y2, Acc); true -> Acc end. -splines(N, XD, XD0, Tan, Y1,Y2, PX0, Clip={Cx,Cy,_},ZeroY, WS, Acc) when N > 0 -> - PX = PX0+WS, +splines(N, XD, XD0, Tan, Y1,Y2, Acc) when N > 0 -> Delta = XD+XD0, - if PX < Cx -> - splines(N-1, Delta, XD0, Tan, Y1, Y2, PX, Clip,ZeroY, WS, Acc); - true -> - Y = min(Cy, max(0,spline(Delta, Tan, Y1,Y2))), - splines(N-1, Delta, XD0, Tan, Y1, Y2, PX, Clip,ZeroY, WS, - [{PX, ZeroY-Y}|Acc]) - end; -splines(_N, _XD, _XD0, _Tan, _Y1,_Y2, _PX, _Clip,_ZeroY, _WS, Acc) -> Acc. + Y = max(0, spline(Delta, Tan, Y1,Y2)), + splines(N-1, Delta, XD0, Tan, Y1, Y2, [{1.0-Delta, Y}|Acc]); +splines(_N, _XD, _XD0, _Tan, _Y1,_Y2, Acc) -> + Acc. spline(T, {M1, M2}, Y1, Y2) -> %% Hermite Basis Funcs @@ -423,34 +585,19 @@ spline_tan(Y0, Y1, Y2, Y3) -> M2 = S*C*(Y3-Y1), {M1,M2}. --define(BW, 5). --define(BH, 5). - -draw_borders(Type, Info, DC, {W,H}, {Max, Unit, MaxUnit}, +draw_borders(DC, #ti{secs=Secs, fetch=FetchFreq}, + #win{name=Type, geom=Geom, info=Info, max={_,_,Unit,_}}, #paint{pen=Pen, pen2=Pen2, font=Font, small=Small}) -> - Str1 = observer_lib:to_str(MaxUnit), - Str2 = observer_lib:to_str(MaxUnit div 2), - Str3 = observer_lib:to_str(0), + #{p0:={GraphX0, GraphY0}, p1:={GraphX1,GraphY1}, scale:={ScaleW0,_}, + txsz:={TW,TH,SpaceW}, txt:={BottomTextY, MaxTextY}, strs:={Str1,Str2,Str3}} = Geom, - setFont(DC, Font, {0,0,0}), - {TW,TH} = getTextExtent(DC, Str1), - {SpaceW, _} = getTextExtent(DC, "W"), - - GraphX0 = ?BW+TW+?BW, - GraphX1 = W-?BW*4, + ScaleW = ScaleW0*FetchFreq, TopTextX = ?BW*3+TW, - MaxTextY = TH+?BH, - BottomTextY = H-?BH-TH, SecondsY = BottomTextY - TH, - GraphY0 = MaxTextY + (TH / 2), - GraphY1 = SecondsY - ?BH, - GraphW = GraphX1-GraphX0-1, - GraphH = GraphY1-GraphY0-1, + GraphY25 = GraphY0 + (GraphY1 - GraphY0) / 4, GraphY50 = GraphY0 + (GraphY1 - GraphY0) / 2, GraphY75 = GraphY0 + 3*(GraphY1 - GraphY0) / 4, - ScaleW = GraphW / 60, - ScaleH = GraphH / Max, setFont(DC, Small, {0,0,0}), Align = fun(Str, Y) -> @@ -462,14 +609,21 @@ draw_borders(Type, Info, DC, {W,H}, {Max, Unit, MaxUnit}, Align(Str3, GraphY1 - (TH / 2) + 1), setPen(DC, Pen), - DrawSecs = fun(Secs, Pos) -> - Str = [observer_lib:to_str(Secs)|" s"], + DrawSecs = fun(Sec, {Pos, Prev}) -> + Str = observer_lib:to_str(Sec) ++ "s", X = GraphX0+Pos, - drawText(DC, Str, X-SpaceW, SecondsY), strokeLine(DC, X, GraphY0, X, GraphY1+5), - Pos + 10*ScaleW + TxtX = X-SpaceW, + case TxtX > Prev of + true -> + drawText(DC, Str, TxtX, SecondsY), + TxtW = SpaceW*length(Str), + {Pos + 10*ScaleW, TxtX+TxtW}; + false -> + {Pos + 10*ScaleW, Prev} + end end, - lists:foldl(DrawSecs, 0, lists:seq(60,0, -10)), + lists:foldl(DrawSecs, {0, 0}, lists:seq(Secs,0, -10)), strokeLine(DC, GraphX0-3, GraphY25, GraphX1, GraphY25), strokeLine(DC, GraphX0-3, GraphY50, GraphX1, GraphY50), @@ -526,7 +680,7 @@ draw_borders(Type, Info, DC, {W,H}, {Max, Unit, MaxUnit}, {GraphX1, GraphY1+1}, {GraphX1, GraphY0-1}, {GraphX0, GraphY0-1}]) end, - {GraphX0+1, GraphY1, ScaleW, ScaleH, DrawBorder}. + {GraphX0+1, GraphY1, DrawBorder}. to_string(Atom) -> Name = atom_to_list(Atom), @@ -543,43 +697,44 @@ uppercase([C|Rest]) -> calc_max(Type, Max) -> bytes(Type, Max). -calc_max1(Max) when Max < 10 -> - 10; -calc_max1(Max) -> - case Max div 10 of - X when X < 10 -> - case Max rem 10 of - 0 -> Max; - _ -> - (X+1)*10 - end; - X -> - 10*calc_max1(X) - end. - -bytes(runq, Val) -> - Upper = calc_max1(Val), - {Upper, "", Upper}; -bytes(utilz, Val) -> - Upper = calc_max1(Val), - {Upper, "", Upper}; -bytes(_, B) -> +bytes(runq, Max) -> + Upper = calc_max1(max_value(Max)), + {Max, Upper, "", Upper}; +bytes(utilz, Max) -> + Upper = calc_max1(max_value(Max)), + {Max, Upper, "", Upper}; +bytes(_, Max) -> + B = max_value(Max), KB = B div 1024, MB = KB div 1024, GB = MB div 1024, if GB > 10 -> Upper = calc_max1(GB), - {Upper*1024*1024*1024, "(GB)", Upper}; + {Max, Upper*1024*1024*1024, "(GB)", Upper}; MB > 10 -> Upper = calc_max1(MB), - {Upper*1024*1024, "(MB)", Upper}; + {Max, Upper*1024*1024, "(MB)", Upper}; KB > 0 -> Upper = calc_max1(KB), - {Upper*1024, "(KB)", Upper}; + {Max, Upper*1024, "(KB)", Upper}; true -> Upper = calc_max1(B), - {Upper, "(B)", Upper} + {Max, Upper, "(B)", Upper} + end. + +calc_max1(Max) when Max < 10 -> + 10; +calc_max1(Max) -> + case Max div 10 of + X when X < 10 -> + case Max rem 10 of + 0 -> Max; + _ -> + (X+1)*10 + end; + X -> + 10*calc_max1(X) end. colors() -> @@ -592,6 +747,28 @@ colors() -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% wxDC and ?wxGC wrappers +make_gc(Panel,UseGC) -> + DC = case os:type() of + {win32, _} -> + %% Ugly hack to avoid flickering on windows, works on windows only + %% But the other platforms are doublebuffered by default + DC0 = wx:typeCast(wxBufferedPaintDC:new(Panel), wxPaintDC), + wxDC:clear(DC0), + DC0; + _ -> + wxPaintDC:new(Panel) + end, + if UseGC -> {?wxGC:create(DC), DC}; + true -> {false, DC} + end. + +destroy_gc({GC, DC}) -> + (GC =/= false) andalso ?wxGC:destroy(GC), + case DC =/= false andalso wx:getObjectType(DC) of + false -> ok; + Type -> Type:destroy(DC) + end. + haveGC() -> try wxGraphicsRenderer:getDefaultRenderer(), @@ -599,44 +776,48 @@ haveGC() -> catch _:_ -> false end. +getSize({_, DC}) -> + wxDC:getSize(DC). + setPen({false, DC}, Pen) -> wxDC:setPen(DC, Pen); -setPen({true, GC}, Pen) -> +setPen({GC, _}, Pen) -> ?wxGC:setPen(GC, Pen). setFont({false, DC}, Font, Color) -> wxDC:setTextForeground(DC, Color), wxDC:setFont(DC, Font); -setFont({true, GC}, Font, Color) -> +setFont({GC, _}, Font, Color) -> ?wxGC:setFont(GC, Font, Color). setBrush({false, DC}, Brush) -> wxDC:setBrush(DC, Brush); -setBrush({true, GC}, Brush) -> +setBrush({GC, _}, Brush) -> ?wxGC:setBrush(GC, Brush). strokeLine({false, DC}, X0, Y0, X1, Y1) -> wxDC:drawLine(DC, {round(X0), round(Y0)}, {round(X1), round(Y1)}); -strokeLine({true, GC}, X0, Y0, X1, Y1) -> +strokeLine({GC, _}, X0, Y0, X1, Y1) -> ?wxGC:strokeLine(GC, X0, Y0, X1, Y1). +strokeLines(_, [_]) -> ok; strokeLines({false, DC}, Lines) -> wxDC:drawLines(DC, [{round(X), round(Y)} || {X,Y} <- Lines]); -strokeLines({true, GC}, Lines) -> +strokeLines({GC, _}, Lines) -> ?wxGC:strokeLines(GC, Lines). drawRoundedRectangle({false, DC}, X0, Y0, X1, Y1, R) -> wxDC:drawRoundedRectangle(DC, {round(X0), round(Y0)}, {round(X1), round(Y1)}, round(R)); -drawRoundedRectangle({true, GC}, X0, Y0, X1, Y1, R) -> +drawRoundedRectangle({GC, _}, X0, Y0, X1, Y1, R) -> ?wxGC:drawRoundedRectangle(GC, X0, Y0, X1, Y1, R). drawText({false, DC}, Str, X, Y) -> wxDC:drawText(DC, Str, {round(X),round(Y)}); -drawText({true, GC}, Str, X, Y) -> +drawText({GC, _}, Str, X, Y) -> ?wxGC:drawText(GC, Str, X, Y). getTextExtent({false, DC}, Str) -> wxDC:getTextExtent(DC, Str); -getTextExtent({true, GC}, Str) -> +getTextExtent({GC, _}, Str) -> {W,H,_,_} = ?wxGC:getTextExtent(GC, Str), {W,H}. diff --git a/lib/observer/src/observer_pro_wx.erl b/lib/observer/src/observer_pro_wx.erl index dd3441e482..bd914cdf65 100644 --- a/lib/observer/src/observer_pro_wx.erl +++ b/lib/observer/src/observer_pro_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/observer_procinfo.erl b/lib/observer/src/observer_procinfo.erl index 871ef603db..cff5fbb474 100644 --- a/lib/observer/src/observer_procinfo.erl +++ b/lib/observer/src/observer_procinfo.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2014. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -125,11 +125,11 @@ handle_event(#wx{event=#wxMouse{type=left_down}, userData=TargetPid}, State) -> {noreply, State}; handle_event(#wx{obj=Obj, event=#wxMouse{type=enter_window}}, State) -> - wxTextCtrl:setForegroundColour(Obj,{0,0,100,255}), + wxStaticText:setForegroundColour(Obj,{0,0,100,255}), {noreply, State}; handle_event(#wx{obj=Obj, event=#wxMouse{type=leave_window}}, State) -> - wxTextCtrl:setForegroundColour(Obj,?wxBLUE), + wxStaticText:setForegroundColour(Obj,?wxBLUE), {noreply, State}; handle_event(#wx{event=#wxHtmlLink{linkInfo=#wxHtmlLinkInfo{href=Href}}}, diff --git a/lib/observer/src/observer_sys_wx.erl b/lib/observer/src/observer_sys_wx.erl index dfd15380f2..b9b407cb0a 100644 --- a/lib/observer/src/observer_sys_wx.erl +++ b/lib/observer/src/observer_sys_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/observer_trace_wx.erl b/lib/observer/src/observer_trace_wx.erl index 11c2acb561..9c0243e4a7 100644 --- a/lib/observer/src/observer_trace_wx.erl +++ b/lib/observer/src/observer_trace_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2012. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/observer_tv.hrl b/lib/observer/src/observer_tv.hrl index 8d57a6fa2b..318a989750 100644 --- a/lib/observer/src/observer_tv.hrl +++ b/lib/observer/src/observer_tv.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/observer_tv_wx.erl b/lib/observer/src/observer_tv_wx.erl index de498ff442..1860f2f469 100644 --- a/lib/observer/src/observer_tv_wx.erl +++ b/lib/observer/src/observer_tv_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2014. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/observer_wx.erl b/lib/observer/src/observer_wx.erl index 68e814e01a..eba603eab5 100644 --- a/lib/observer/src/observer_wx.erl +++ b/lib/observer/src/observer_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2014. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/src/ttb.erl b/lib/observer/src/ttb.erl index 3cba3b97b0..4d6eb3ba8d 100644 --- a/lib/observer/src/ttb.erl +++ b/lib/observer/src/ttb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2011. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -434,7 +434,9 @@ procs(Procs) when is_list(Procs) -> procs(Proc) -> proc(Proc). -proc(Procs) when Procs=:=all; Procs=:=existing; Procs=:=new -> +proc(Procs) when Procs=:=all; Procs=:=ports; Procs=:=processes; + Procs=:=existing; Procs=:=existing_ports; Procs=:=existing_processes; + Procs=:=new; Procs=:=new_ports; Procs=:=new_processes -> [Procs]; proc(Name) when is_atom(Name) -> [Name]; % can be registered on this node or other node diff --git a/lib/observer/src/ttb_et.erl b/lib/observer/src/ttb_et.erl index 683dd6c9a2..95e8e9aa07 100644 --- a/lib/observer/src/ttb_et.erl +++ b/lib/observer/src/ttb_et.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/observer/test/Makefile b/lib/observer/test/Makefile index e8bb7d0a52..6100af5e17 100644 --- a/lib/observer/test/Makefile +++ b/lib/observer/test/Makefile @@ -45,8 +45,8 @@ RELSYSDIR = $(RELEASE_PATH)/observer_test # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -ERL_MAKE_FLAGS += -pa $(ERL_TOP)/lib/test_server/ebin -ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include +ERL_MAKE_FLAGS += +ERL_COMPILE_FLAGS += EBIN = . @@ -60,8 +60,6 @@ make_emakefile: $(MODULES) > $(EMAKEFILE) tests debug opt: make_emakefile - cd $(ERL_TOP)/lib/test_server/src && \ - $(MAKE) ../ebin/test_server_line.beam erl $(ERL_MAKE_FLAGS) -make clean: diff --git a/lib/observer/test/crashdump_helper.erl b/lib/observer/test/crashdump_helper.erl index eea82d8c3c..4239a3d0d1 100644 --- a/lib/observer/test/crashdump_helper.erl +++ b/lib/observer/test/crashdump_helper.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2013. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ -module(crashdump_helper). -export([n1_proc/2,remote_proc/2]). -compile(r13). --include("test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). n1_proc(N2,Creator) -> spawn(fun() -> n1_proc(Creator,N2,x,y,[]) end). diff --git a/lib/observer/test/crashdump_viewer_SUITE.erl b/lib/observer/test/crashdump_viewer_SUITE.erl index eae4ee01b9..73ed890802 100644 --- a/lib/observer/test/crashdump_viewer_SUITE.erl +++ b/lib/observer/test/crashdump_viewer_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2014. All Rights Reserved. +%% Copyright Ericsson AB 2003-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -30,7 +30,6 @@ -export([init_per_testcase/2, end_per_testcase/2]). -include_lib("common_test/include/ct.hrl"). --include("test_server_line.hrl"). -include_lib("kernel/include/file.hrl"). -define(failed_file,"failed-cases.txt"). @@ -102,7 +101,7 @@ end_per_group(_GroupName, Config) -> init_per_suite(Config) when is_list(Config) -> delete_saved(Config), DataDir = ?config(data_dir,Config), - Rels = [R || R <- [r16b,'17'], ?t:is_release_available(R)] ++ [current], + Rels = [R || R <- ['17','18'], ?t:is_release_available(R)] ++ [current], io:format("Creating crash dumps for the following releases: ~p", [Rels]), AllDumps = create_dumps(DataDir,Rels), [{dumps,AllDumps}|Config]. @@ -607,21 +606,21 @@ dos_dump(DataDir,Rel,Dump) -> rel_opt(Rel) -> case Rel of - r16b -> [{erl,[{release,"r16b_latest"}]}]; '17' -> [{erl,[{release,"17_latest"}]}]; + '18' -> [{erl,[{release,"18_latest"}]}]; current -> [] end. dump_prefix(Rel) -> case Rel of - r16b -> "r16b_dump."; '17' -> "r17_dump."; - current -> "r18_dump." + '18' -> "r18_dump."; + current -> "r19_dump." end. compat_rel(Rel) -> case Rel of - r16b -> "+R16 "; '17' -> "+R17 "; + '18' -> "+R18 "; current -> "" end. diff --git a/lib/observer/test/etop_SUITE.erl b/lib/observer/test/etop_SUITE.erl index d4857c5e2f..7614989f1f 100644 --- a/lib/observer/test/etop_SUITE.erl +++ b/lib/observer/test/etop_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2013. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ -export([text/1,text/2,text_tracing_off/1,text_tracing_off/2]). -export([init_per_testcase/2, end_per_testcase/2]). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -define(default_timeout, ?t:minutes(1)). diff --git a/lib/observer/test/observer_SUITE.erl b/lib/observer/test/observer_SUITE.erl index 7f96d72e59..3dc3e4772b 100644 --- a/lib/observer/test/observer_SUITE.erl +++ b/lib/observer/test/observer_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2014. All Rights Reserved. +%% Copyright Ericsson AB 2006-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ %% -module(observer_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include_lib("wx/include/wx.hrl"). -include_lib("observer/src/observer_tv.hrl"). diff --git a/lib/observer/test/ttb_SUITE.erl b/lib/observer/test/ttb_SUITE.erl index bdf10f507d..c06ec21f36 100644 --- a/lib/observer/test/ttb_SUITE.erl +++ b/lib/observer/test/ttb_SUITE.erl @@ -2,7 +2,7 @@ %% %CopyrightBegin% %% %% -%% Copyright Ericsson AB 2002-2013. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ -export([init_per_testcase/2, end_per_testcase/2]). -export([foo/0]). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -define(default_timeout, ?t:minutes(1)). -define(OUTPUT, "handler_output"). @@ -819,6 +819,7 @@ myhandler(_Fd,Trace,_,Relay) -> simple_call_handler() -> {fun(A, {trace_ts, _, call, _, _} ,_,_) -> io:format(A, "ok.~n", []); + (A, {drop, N}, _, _) -> io:format(A, "{drop, ~p}.", [N]); (_, end_of_trace, _, _) -> ok end, []}. marking_call_handler() -> @@ -954,17 +955,24 @@ begin_trace_local(ServerNode, ClientNode, Dest) -> ?line ttb:tpl(client, get, []). check_size(N, Dest, Output, ServerNode, ClientNode) -> - ?line begin_trace(ServerNode, ClientNode, Dest), - ?line case Dest of + begin_trace(ServerNode, ClientNode, Dest), + case Dest of {local, _} -> - ?line ttb_helper:msgs_ip(N); + ttb_helper:msgs_ip(N); _ -> - ?line ttb_helper:msgs(N) + ttb_helper:msgs(N) end, - ?line {_, D} = ttb:stop([fetch, return_fetch_dir]), - ?line ttb:format(D, [{out, Output}, {handler, simple_call_handler()}]), - ?line {ok, Ret} = file:consult(Output), - ?line true = (N + 1 == length(Ret)). + {_, D} = ttb:stop([fetch, return_fetch_dir]), + ttb:format(D, [{out, Output}, {handler, simple_call_handler()}]), + {ok, Ret} = file:consult(Output), + check_output(N+1, Ret). + +check_output(Expected, Ret) + when length(Ret) =:= Expected -> ok; +check_output(Expected, Ret) -> + io:format("~p~n",[Ret]), + io:format("Expected ~p got ~p ~n",[Expected, length(Ret)]), + Expected = length(Ret). fetch_when_no_option_given(suite) -> []; @@ -1166,8 +1174,8 @@ changing_cwd_on_control_node(Config) when is_list(Config) -> ?line {_, D} = ttb:stop([fetch, return_fetch_dir]), ?line ttb:format(D, [{out, ?OUTPUT}, {handler, simple_call_handler()}]), ?line {ok, Ret} = file:consult(?OUTPUT), - ?line true = (2*(NumMsgs + 1) == length(Ret)), - ?line ok = file:set_cwd(OldDir). + check_output(2*(NumMsgs + 1),Ret), + ok = file:set_cwd(OldDir). changing_cwd_on_control_node(cleanup,_Config) -> ?line stop_client_and_server(). @@ -1176,18 +1184,19 @@ changing_cwd_on_control_node_with_local_trace(suite) -> changing_cwd_on_control_node_with_local_trace(doc) -> ["Changing cwd on control node during local tracing is safe"]; changing_cwd_on_control_node_with_local_trace(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), - ?line {ServerNode, ClientNode} = start_client_and_server(), - ?line begin_trace(ServerNode, ClientNode, {local, ?FNAME}), - ?line NumMsgs = 3, - ?line ttb_helper:msgs_ip(NumMsgs), - ?line ok = file:set_cwd(".."), - ?line ttb_helper:msgs_ip(NumMsgs), - ?line {_, D} = ttb:stop([fetch, return_fetch_dir]), - ?line ttb:format(D, [{out, ?OUTPUT}, {handler, simple_call_handler()}]), - ?line {ok, Ret} = file:consult(?OUTPUT), - ?line true = (2*(NumMsgs + 1) == length(Ret)), - ?line ok = file:set_cwd(OldDir). + {ok, OldDir} = file:get_cwd(), + {ServerNode, ClientNode} = start_client_and_server(), + begin_trace(ServerNode, ClientNode, {local, ?FNAME}), + NumMsgs = 3, + ttb_helper:msgs_ip(NumMsgs), + ok = file:set_cwd(".."), + ttb_helper:msgs_ip(NumMsgs), + {_, D} = ttb:stop([fetch, return_fetch_dir]), + ttb:format(D, [{out, ?OUTPUT}, {handler, simple_call_handler()}]), + {ok, Ret} = file:consult(?OUTPUT), + Expected = 2*(NumMsgs + 1), + check_output(Expected, Ret), + ok = file:set_cwd(OldDir). changing_cwd_on_control_node_with_local_trace(cleanup,_Config) -> ?line stop_client_and_server(). @@ -1205,7 +1214,7 @@ changing_cwd_on_remote_node(Config) when is_list(Config) -> ?line {_, D} = ttb:stop([fetch, return_fetch_dir]), ?line ttb:format(D, [{out, ?OUTPUT}, {handler, simple_call_handler()}]), ?line {ok, Ret} = file:consult(?OUTPUT), - ?line true = (2*(NumMsgs + 1) == length(Ret)). + check_output(2*(NumMsgs + 1),Ret). changing_cwd_on_remote_node(cleanup,_Config) -> ?line stop_client_and_server(). @@ -1497,7 +1506,7 @@ logic(N, M, TracingType) -> ct:log("formatted ~p",[{D,?OUTPUT}]), ?line {ok, Ret} = file:consult(?OUTPUT), ct:log("consulted: ~p",[Ret]), - ?line M = length(Ret). + check_output(M,Ret). begin_trace_with_resume(ServerNode, ClientNode, Dest) -> ?line {ok, _} = ttb:tracer([ServerNode,ClientNode], [{file, Dest}, resume]), |