From 7e51fd25571dbcc7e1aeb2d23a6dca521f984f80 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 19 Apr 2012 23:19:40 +0200 Subject: font works again --- docs/BUGS | 1 + docs/CHANGELOG | 139 ++++++ docs/COPYING | 280 +++++++++++ docs/COPYING.FONT | 280 +++++++++++ docs/HELP | 60 +++ docs/README | 33 ++ docs/WISHLIST | 6 + fonts/font.png | Bin 0 -> 14883 bytes lib/Loadbars/Constants.pm | 39 ++ lib/Loadbars/HelpDispatch.pm | 350 ++++++++++++++ lib/Loadbars/Main.pm | 931 +++++++++++++++++++++++++++++++++++++ lib/Loadbars/Shared.pm | 52 +++ loadbars | 8 +- share/docs/BUGS | 1 - share/docs/CHANGELOG | 139 ------ share/docs/COPYING | 280 ----------- share/docs/COPYING.FONT | 280 ----------- share/docs/HELP | 60 --- share/docs/README | 33 -- share/docs/WISHLIST | 6 - share/fonts/font.png | Bin 14883 -> 0 bytes share/lib/Loadbars/Constants.pm | 39 -- share/lib/Loadbars/HelpDispatch.pm | 350 -------------- share/lib/Loadbars/Main.pm | 922 ------------------------------------ share/lib/Loadbars/Shared.pm | 52 --- 25 files changed, 2177 insertions(+), 2164 deletions(-) create mode 100644 docs/BUGS create mode 100644 docs/CHANGELOG create mode 100644 docs/COPYING create mode 100644 docs/COPYING.FONT create mode 100644 docs/HELP create mode 100644 docs/README create mode 100644 docs/WISHLIST create mode 100644 fonts/font.png create mode 100644 lib/Loadbars/Constants.pm create mode 100644 lib/Loadbars/HelpDispatch.pm create mode 100644 lib/Loadbars/Main.pm create mode 100644 lib/Loadbars/Shared.pm delete mode 100644 share/docs/BUGS delete mode 100644 share/docs/CHANGELOG delete mode 100644 share/docs/COPYING delete mode 100644 share/docs/COPYING.FONT delete mode 100644 share/docs/HELP delete mode 100644 share/docs/README delete mode 100644 share/docs/WISHLIST delete mode 100644 share/fonts/font.png delete mode 100644 share/lib/Loadbars/Constants.pm delete mode 100644 share/lib/Loadbars/HelpDispatch.pm delete mode 100644 share/lib/Loadbars/Main.pm delete mode 100644 share/lib/Loadbars/Shared.pm diff --git a/docs/BUGS b/docs/BUGS new file mode 100644 index 0000000..40b75cd --- /dev/null +++ b/docs/BUGS @@ -0,0 +1 @@ +* No known bugs ATM diff --git a/docs/CHANGELOG b/docs/CHANGELOG new file mode 100644 index 0000000..da29f6d --- /dev/null +++ b/docs/CHANGELOG @@ -0,0 +1,139 @@ +Thu Apr 19 21:41:52 CEST 2012 +* Minor change, sleep 0.5s instead of 3s if ssh command fails + +Fri Apr 6 10:17:30 CEST 2012 +* Minor fixes such as redraw background on toggle text display which + should fix some weird display bugs. + +Fri Mar 16 07:20:50 CET 2012 +* Release v0.5.1.1 +* Dropped FreeBSD support / focus is Linux +* On shutdown all sub-processes are gonna be terminated instantly + (was old bug). Needs Proc::ProcessTable module. +* Dont quit loadbars if ~/.loadbarsrc can not be overwritten + +Sat Feb 25 20:09:02 CET 2012 +* Release v0.5.1 +* Add config file support (~/.loadbarsrc) and it's possible to configure + any option you find in --help but without leading '--'. For comments + just use the '#' sign. Sample config: + showcores=1 # Always show cores on startup + showtext=0 # Always don't display text on startup +* Add hotkey 'w' which writes current settings to the configfile +* Remove --title option (no need anyway) +* Some code cleanups +* Some bugfixes + +Sat Feb 4 10:56:27 CET 2012 +* Release v0.5.0 +* Add stats for rudimentary memory and swap usage (--showmem option or m hotkey) +* Remove --width and --inter options +* Add --barwidth option, each bar is barwidth pixels now +* Add --maxwidth option, which represents the max total window width +* Auto disable text display if text does not fit into window (maxwidth) pixels +* Auto re-enable text display if text does fit again into window +* Key right increases window width by 100px and left decreases by 100px +* Key down increases window height by 100px and up decreases by 100px +* Set 'samples' default values from 1000 down to 500. +* Displays a text warning on stdout if computer may be too slow +* No sporadic crashes on shutdown anymore +* Some internal tweaks, no separate event thread needed anymore. This fixes + some sporadic bugs. + +Sun Jan 21 14:16:37 CET 2012 +* Released v0.4.0 +* Also show stats for idle, iowait, irq, softirq, steal and guest cpu time +* Some parameters have been renamed (see --help) +* Introduced extended mode (use --extended 1 at startup or 'e' hotkey) +* Modified the bar colors a little bit (see --help) +* Some Bugfixes + +Tue Dec 27 12:28:40 CET 2011 +* Released v0.3.1 +* --cluster option (which reads the ClusterSSH config file /etc/clusters/) + also supports clusters of clusters. e.g.: + $ cat /etc/clusters + clusterA server01 server02 + clusterB clusterA server03 + So --cluster clusterB will connect to server01 server02 and server03 +* --hosts option supports username to be specified. E.g.: + # ./loadbars --hosts user1@server01,user2@server02 + will connect to server01 using user1 and server02 with user2. + +Mon Dec 26 14:46:25 CET 2011 +* Released v0.3.0 +* Peak CPU load is not displayed by default anymore. User 'p' command or + the --togglepeak 1 startup option. +* Peak CPU load is now also displayd in text format (marked as pk) +* New option --cluster which brings rudimentary ClusterSSH config file + support. E.g. './loadbars --cluster server' reads cluster server from + the /etc/clusters file. + +Sat Nov 19 11:54:51 CET 2011 +* Released v0.2.2 +* Added a 1px horizontal line to each bar which represent the max. peak + of user and system cpu load of the last N samples (max. of the last 15 + samples by default, it can be configured using --average) +* Default value for --average has been decreased from 30 to 15 sample + values + +Fr 12. Aug 21:41:46 CEST 2011 +* Released v0.2.1 + +Di 9. Aug 20:42:43 CEST 2011 +* Released v0.2.0.2 (Bugfixes only; Bar width was wrong by 1px) + +So 7. Aug 15:53:08 CEST 2011 +* Added grey separator lines between each hosts during CPU toggle mode +* More intelligent CPU core numbering during CPU toggle mode +* FreeBSD server support for CPU graphs has been tested and is working using + linprocfs mounted on /compat/linux/proc. +* Changed licence to GPL 2 +* Some more documentation +* Some minor bugfixes + +So 7. Aug 14:06:45 CEST 2011 +* Released v0.2.0.1 (Bugfixes only) + +Sa 6. Aug 22:04:15 CEST 2011 +* Released v0.2.0 (new major version) +* No interactive CLI shell anymore but instead hotkeys for the + SDL interface (press h and see). +* Bugfixes (E.g. Loadbars does not hang anymore after typing commands) +* Major code refactoring + +Fr 5. Aug 23:52:49 CEST 2011 +* Released v0.1.3.1 +* Some more minor bugfixes + +Fr 5. Aug 23:29:19 CEST 2011 +* Released v0.1.3 +* Fixed a segfault bug on SDL::Font using threads +* Added an advanced help option (h vs. H) +* Added new toggle option: Displaying bar number vs. hostname +* Some little code refactoring + +Fr 22. Apr 13:08:08 CEST 2011 +* Released v0.1.2.1 + +Mi 20. Apr 08:37:49 CEST 2011 +* Added ./BUGS which includes a summary of all current known bugs + +Fri Jan 14 23:03:47 CET 2011 +* Released v0.1.2 +* Added 'toggle summary' option +* Removed all old screenshots +* Added a newer one +* Fixed lots of bugs (including segfaults) +* Cosmetic code fixes + +Tue Jan 11 14:01:32 CET 2011 +* Released v0.1.1 +* Extended help text ('h' command) +* Added CHANGELOG and README files +* Fixed a typo + +Tue Jan 11 13:??:?? CET 2011 +* Released v0.1.0 +* With initial font support (text display of the stats) +* Everything else which has been implemented up to 0.1-beta8-pre6 diff --git a/docs/COPYING b/docs/COPYING new file mode 100644 index 0000000..d4b4b89 --- /dev/null +++ b/docs/COPYING @@ -0,0 +1,280 @@ +GNU GENERAL PUBLIC LICENSE Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + diff --git a/docs/COPYING.FONT b/docs/COPYING.FONT new file mode 100644 index 0000000..d4b4b89 --- /dev/null +++ b/docs/COPYING.FONT @@ -0,0 +1,280 @@ +GNU GENERAL PUBLIC LICENSE Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + diff --git a/docs/HELP b/docs/HELP new file mode 100644 index 0000000..e077c51 --- /dev/null +++ b/docs/HELP @@ -0,0 +1,60 @@ +==> Reading configuration from /home/pb/.loadbarsrc +==> Setting showcores=1, it might be overwritten by command line params. +==> Setting showtext=0, it might be overwritten by command line params. +==> Setting extended=1, it might be overwritten by command line params. +==> Setting showmem=1, it might be overwritten by command line params. +CPU stuff: + st = Steal in % [see man proc] (extended) + Color: Red + gt = Guest in % [see man proc] (extended) + Color: Red + sr = Soft IRQ usage in % (extended) + Color: White + ir = IRQ usage in % (extended) + Color: White + io = IOwait cpu sage in % + Color: Purple + id = Idle cpu usage in % (extended) + Color: Black + ni = Nice cpu usage in % + Color: Green + us = User cpu usage in % + Color: Yellow, dark yellow if to>50%, orange if to>50% + sy = System cpu sage in % + Blue, lighter blue if >30% + to = Total CPU usage, which is (100% - id) + pk = Max us+sy peak of last avg. samples (extended) + avg = System load average; desc. order: 1, 5 and 15 min. avg. + 1px horizontal line: Maximum sy+us+io of last 'avg' samples (extended) + Extended means: text display only if extended mode is turned on +Memory stuff: + Ram: System ram usage in % + Color: Dark grey + Swp: System swap usage in % + Color: Grey +Config file support: + Loadbars tries to read ~/.loadbarsrc and it's possible to configure any + option you find in --help but without leading '--'. For comments just use + the '#' sign. Sample config: + showcores=1 # Always show cores on startup + showtext=0 # Always don't display text on startup + extended=1 # Always use extended mode on startup + will always show all CPU cores in extended mode but no text display. +Examples: + loadbars --extended 1 --showcores 1 --height 300 --hosts localhost + loadbars --hosts localhost,server1.example.com,server2.example.com + loadbars --cluster foocluster (foocluster is in /etc/clusters [ClusterSSH]) +--average - Num of samples for avg. (more fluent animations) +--barwidth - Set bar width +--cluster - Cluster name from /etc/clusters +--extended - Toggle extended display (0 or 1) +--factor - Set graph scale factor (1.0 means 100%) +--height - Set windows height +--hosts - Comma sep. list of hosts; optional: user@ in front to each host +--maxwidth - Set max width +--samples - Set number of samples until ssh reconnects +--showcores - Toggle core display (0 or 1) +--showmem - Toggle mem display (0 or 1) +--showtexthost - Toggle hostname/num text display (0 or 1) +--showtext - Toggle text display (0 or 1) +--sshopts - Set SSH options diff --git a/docs/README b/docs/README new file mode 100644 index 0000000..d839d8d --- /dev/null +++ b/docs/README @@ -0,0 +1,33 @@ +For general program informations see http://loadbars.buetow.org + +For legal informations see COPYING and COPYING.FONT + +For any program help check out --help on command line or 'h' during program +execution. + +For a list of features which might be added in the future see WHISHLIST + +For a changelog see CHANGELOG + +For a list of all known bugs see BUGS + +Supported platforms are: Linux + +the latter may not have full functionality). + +For Linux at least a 2.6 Kernel is required. + +Versioning schema: a.b.c[.d][.e], where + a = Don't know yet. Maybe will stay forever 0. + b = Major release (new major features) + c = Minor release (new minor features or code refactoring) + d = Optional, bugfixes only release + e = Optional, cosmetic fixes only release + + It's not a release if there is a -master suffix. It's a stable + version (master branch) then. + + It's not a release if there is a -devel suffix. It's a development + version (devel branch) then. + +For some help/usage please consult the HELP file. diff --git a/docs/WISHLIST b/docs/WISHLIST new file mode 100644 index 0000000..ea234ff --- /dev/null +++ b/docs/WISHLIST @@ -0,0 +1,6 @@ +* More stats for memory +* Stats for network +* .deb for Debian and Ubuntu +* Auto detect single core boxes +* Make code modular (script is growing...) +* Optimize code (too much cpu usage if there are too many hosts involved) diff --git a/fonts/font.png b/fonts/font.png new file mode 100644 index 0000000..02e9eb1 Binary files /dev/null and b/fonts/font.png differ diff --git a/lib/Loadbars/Constants.pm b/lib/Loadbars/Constants.pm new file mode 100644 index 0000000..af242bd --- /dev/null +++ b/lib/Loadbars/Constants.pm @@ -0,0 +1,39 @@ +package Loadbars::Constants; + +use strict; +use warnings; + +use SDL::Color; + +use constant { + VERSION => 'loadbars v0.5.2-devel', + COPYRIGHT => '2010-2012 (c) Paul Buetow ', + CONFFILE => $ENV{HOME} . '/.loadbarsrc', + CSSH_CONFFILE => '/etc/clusters', + CSSH_MAX_RECURSION => 10, + COLOR_DEPTH => 8, + BLACK => SDL::Color->new( -r => 0x00, -g => 0x00, -b => 0x00 ), + BLUE0 => SDL::Color->new( -r => 0x00, -g => 0x00, -b => 0xff ), + BLUE => SDL::Color->new( -r => 0x00, -g => 0x00, -b => 0x88 ), + GREEN => SDL::Color->new( -r => 0x00, -g => 0x90, -b => 0x00 ), + ORANGE => SDL::Color->new( -r => 0xff, -g => 0x70, -b => 0x00 ), + PURPLE => SDL::Color->new( -r => 0xa0, -g => 0x20, -b => 0xf0 ), + RED => SDL::Color->new( -r => 0xff, -g => 0x00, -b => 0x00 ), + WHITE => SDL::Color->new( -r => 0xff, -g => 0xff, -b => 0xff ), + GREY0 => SDL::Color->new( -r => 0x11, -g => 0x11, -b => 0x11 ), + GREY => SDL::Color->new( -r => 0xaa, -g => 0xaa, -b => 0xaa ), + DARK_GREY => SDL::Color->new( -r => 0x15, -g => 0x15, -b => 0x15 ), + YELLOW0 => SDL::Color->new( -r => 0xff, -g => 0xa0, -b => 0x00 ), + YELLOW => SDL::Color->new( -r => 0xff, -g => 0xc0, -b => 0x00 ), + SYSTEM_BLUE0 => 30, + USER_ORANGE => 70, + USER_YELLOW0 => 50, + INTERVAL => 0.1, + INTERVAL_WARN => 1.0, + SUCCESS => 0, + E_UNKNOWN => 1, + E_NOHOST => 2, +}; + +1; + diff --git a/lib/Loadbars/HelpDispatch.pm b/lib/Loadbars/HelpDispatch.pm new file mode 100644 index 0000000..dfee7f5 --- /dev/null +++ b/lib/Loadbars/HelpDispatch.pm @@ -0,0 +1,350 @@ +package Loadbars::HelpDispatch; + +use strict; +use warnings; + +use Loadbars::Constants; +use Loadbars::Shared; + +sub create () { + my $hosts = ''; + + my $textdesc = <50%, orange if to>50% + sy = System cpu sage in % + Blue, lighter blue if >30% + to = Total CPU usage, which is (100% - id) + pk = Max us+sy peak of last avg. samples (extended) + avg = System load average; desc. order: 1, 5 and 15 min. avg. + 1px horizontal line: Maximum sy+us+io of last 'avg' samples (extended) + Extended means: text display only if extended mode is turned on +Memory stuff: + Ram: System ram usage in % + Color: Dark grey + Swp: System swap usage in % + Color: Grey +Config file support: + Loadbars tries to read ~/.loadbarsrc and it's possible to configure any + option you find in --help but without leading '--'. For comments just use + the '#' sign. Sample config: + showcores=1 # Always show cores on startup + showtext=0 # Always don't display text on startup + extended=1 # Always use extended mode on startup + will always show all CPU cores in extended mode but no text display. +Examples: + loadbars --extended 1 --showcores 1 --height 300 --hosts localhost + loadbars --hosts localhost,server1.example.com,server2.example.com + loadbars --cluster foocluster (foocluster is in /etc/clusters [ClusterSSH]) +END + + # mode 1: Option is shown in the online help menu (stdout not sdl) + # mode 2: Option is shown in the 'usage' screen from the command line + # mode 4: Option is used to generate the GetOptions parameters for Getopt::Long + # Combinations: Like chmod(1) + + my %d = ( + average => { + menupos => 3, + help => 'Num of samples for avg. (more fluent animations)', + mode => 6, + type => 'i' + }, + average_hot_up => { + menupos => 4, + cmd => 'a', + help => 'Increases number of samples for calculating avg. by 1', + mode => 1 + }, + average_hot_dn => { + menupos => 5, + cmd => 'y', + help => 'Decreases number of samples for calculating avg. by 1', + mode => 1 + }, + + barwidth => { + menupos => 5, + help => 'Set bar width', + mode => 6, + type => 'i' + }, + windowwidth_hot_up => { + menupos => 90, + help => 'Increase window width by 100px', + cmd => 'right', + mode => 1, + }, + windowwidth_hot_dn => { + menupos => 91, + help => 'Decrease window width by 100px', + cmd => 'left', + mode => 1, + }, + windowheight_hot_up => { + menupos => 92, + help => 'Increase window height by 100px', + cmd => 'down', + mode => 1, + }, + windowheight_hot_dn => { + menupos => 93, + help => 'Decrease window height by 100px', + cmd => 'up', + mode => 1, + }, + + cluster => { + menupos => 6, + help => 'Cluster name from /etc/clusters', + var => \$C{cluster}, + mode => 6, + type => 's' + }, + configuration => { + menupos => 6, + cmd => 'c', + help => 'Show current configuration', + mode => 4 + }, + + extended => { + menupos => 6, + help => 'Toggle extended display (0 or 1)', + mode => 7, + type => 'i' + }, + extended_hot => { + menupos => 23, + cmd => 'e', + help => 'Toggle extended mode', + mode => 1 + }, + + factor => { + menupos => 7, + help => 'Set graph scale factor (1.0 means 100%)', + mode => 6, + type => 's' + }, + factor_hot_up => { + menupos => 8, + cmd => 's', + help => 'Increases graph scale factor by 0.1', + mode => 1 + }, + factor_hot_dn => { + menupos => 9, + cmd => 'x', + help => 'Decreases graph scale factor by 0.1', + mode => 1 + }, + + height => { + menupos => 10, + help => 'Set windows height', + mode => 6, + type => 'i' + }, + + help_hot => { + menupos => 11, + cmd => 'h', + help => 'Prints this help screen', + mode => 1 + }, + + hosts => { + menupos => 12, + help => + 'Comma sep. list of hosts; optional: user@ in front to each host', + var => \$hosts, + mode => 6, + type => 's' + }, + + maxwidth => { + menupos => 16, + help => 'Set max width', + mode => 6, + type => 'i' + }, + + quit_hot => { menupos => 16, cmd => 'q', help => 'Quits', mode => 1 }, + writeconfig_hot => { + menupos => 16, + cmd => 'w', + help => 'Write config to config file', + mode => 1 + }, + + samples => { + menupos => 17, + help => 'Set number of samples until ssh reconnects', + mode => 6, + type => 'i' + }, + + showcores => { + menupos => 17, + help => 'Toggle core display (0 or 1)', + mode => 7, + type => 'i' + }, + showcores_hot => + { menupos => 17, cmd => '1', help => 'Toggle show cores', mode => 1 }, + + showmem => { + menupos => 17, + help => 'Toggle mem display (0 or 1)', + mode => 7, + type => 'i' + }, + showmem_hot => + { menupos => 17, cmd => 'm', help => 'Toggle show mem', mode => 1 }, + + showtexthost => { + menupos => 18, + help => 'Toggle hostname/num text display (0 or 1)', + mode => 7, + type => 'i' + }, + showtexthost_hot => { + menupos => 18, + cmd => 'u', + help => 'Toggle hostname/num text display', + mode => 1 + }, + + showtext => { + menupos => 19, + help => 'Toggle text display (0 or 1)', + mode => 7, + type => 'i' + }, + showtext_hot => { + menupos => 19, + cmd => 't', + help => 'Toggle text display', + mode => 1 + }, + + sshopts => + { menupos => 20, help => 'Set SSH options', mode => 6, type => 's' }, + ); + + my %d_by_short = map { + $d{$_}{cmd} => $d{$_} + + } grep { + exists $d{$_}{cmd} + + } keys %d; + + my $closure = sub ($;$) { + my ( $arg, @rest ) = @_; + + if ( $arg eq 'command' ) { + my ( $cmd, @args ) = @rest; + + my $cb = $d{$cmd}; + $cb = $d_by_short{$cmd} unless defined $cb; + + unless ( defined $cb ) { + system $cmd; + return 0; + } + + if ( length $cmd == 1 ) { + for my $key ( grep { exists $d{$_}{cmd} } keys %d ) { + do { $cmd = $key; last } if $d{$key}{cmd} eq $cmd; + } + } + + } + elsif ( $arg eq 'hotkeys' ) { + $textdesc . "Hotkeys:\n" . ( + join "\n", + map { + "$_\t- $d_by_short{$_}{help}" + + } grep { + $d_by_short{$_}{mode} & 1 and exists $d_by_short{$_}{help}; + + } sort { $d_by_short{$a}{menupos} <=> $d_by_short{$b}{menupos} } + sort keys %d_by_short + ); + + } + elsif ( $arg eq 'usage' ) { + $textdesc . ( + join "\n", + map { + if ( $_ eq 'help' ) + { + "--$_\t\t- $d{$_}{help}"; + } + else { + "--$_ \t- $d{$_}{help}"; + } + + } grep { + $d{$_}{mode} & 2 + and exists $d{$_}{help} + + } sort { $d{$a}{menupos} <=> $d{$b}{menupos} } sort keys %d + ); + + } + elsif ( $arg eq 'options' ) { + map { + "$_=" + . $d{$_}{type} => ( + defined $d{$_}{var} + ? $d{$_}{var} + : \$C{$_} + ); + + } grep { + $d{$_}{mode} & 4 and exists $d{$_}{type}; + + } sort keys %d; + } + }; + + $d{configuration}{cb} = sub { + Loadbars::Main::say sort map { + "$_->[0] = $_->[1]" + + } grep { + defined $_->[1] + + } map { + [ + $_ => exists $d{$_}{var} + ? ${ $d{$_}{var} } + : $C{$_} + ] + + } keys %d; + }; + + return ( \$hosts, $closure ); +} + +1; diff --git a/lib/Loadbars/Main.pm b/lib/Loadbars/Main.pm new file mode 100644 index 0000000..b44929b --- /dev/null +++ b/lib/Loadbars/Main.pm @@ -0,0 +1,931 @@ + +package Loadbars::Main; + +use strict; +use warnings; + +use SDL; +use SDL::App; +use SDL::Rect; +use SDL::Event; + +use SDL::Surface; +use SDL::Font; + +use Time::HiRes qw(usleep gettimeofday); + +use Proc::ProcessTable; + +use threads; +use threads::shared; + +use Loadbars::Config; +use Loadbars::Constants; +use Loadbars::Shared; +use Loadbars::Utils; + +$| = 1; + +sub set_showcores_regexp () { + $I{cpuregexp} = $C{showcores} ? 'cpu' : 'cpu '; +} + +sub percentage ($$) { + my ( $total, $part ) = @_; + + return int( null($part) / notnull( null($total) / 100 ) ); +} + +sub norm ($) { + my $n = shift; + + return $n if $C{factor} != 1; + return $n > 100 ? 100 : ( $n < 0 ? 0 : $n ); +} + +sub parse_cpu_line ($) { + my $line = shift; + my ( $name, %load ); + + ( $name, @load{qw(user nice system idle iowait irq softirq steal guest)} ) = + split ' ', $line; + + # Not all kernels support this + $load{steal} = 0 unless defined $load{steal}; + $load{guest} = 0 unless defined $load{guest}; + + $load{TOTAL} = + sum( @load{qw(user nice system idle iowait irq softirq steal guest)} ); + + return ( $name, \%load ); +} + +sub terminate_pids (@) { + my @threads = @_; + + display_info 'Terminating sub-processes, hasta la vista!'; + $_->kill('TERM') for @threads; + display_info_no_nl 'Terminating PIDs'; + for my $pid ( keys %PIDS ) { + my $proc_table = Proc::ProcessTable->new(); + for my $proc ( @{ $proc_table->table() } ) { + if ( $proc->ppid == $pid ) { + print $proc->pid . ' '; + kill 'TERM', $proc->pid if $proc->ppid == $pid; + } + } + + print $pid . ' '; + kill 'TERM', $pid; + } + + say ''; + + display_info 'Terminating done. I\'ll be back!'; +} + +sub stats_thread ($;$) { + my ( $host, $user ) = @_; + $user = defined $user ? "-l $user" : ''; + + my ( $sigusr1, $sigterm ) = ( 0, 0 ); + my $loadavgexp = qr/(\d+\.\d{2}) (\d+\.\d{2}) (\d+\.\d{2})/; + my $inter = Loadbars::Constants->INTERVAL; + + until ($sigterm) { + my $bash = <<"BASH"; + loadavg=/proc/loadavg + stat=/proc/stat + meminfo=/proc/meminfo + + for i in \$(seq $C{samples}); do + echo CPUSTATS + cat \$loadavg \$stat + echo MEMSTATS + cat \$meminfo + sleep $inter + done +BASH + + my $cmd = + ( $host eq 'localhost' || $host eq '127.0.0.1' ) + ? $bash + : "ssh $user -o StrictHostKeyChecking=no $C{sshopts} $host '$bash'"; + + my $pid = open my $pipe, "$cmd |" or do { + say "Warning: $!"; + sleep 0.5; + next; + }; + + $PIDS{$pid} = 1; + + # Toggle CPUs + $SIG{USR1} = sub { $sigusr1 = 1 }; + $SIG{TERM} = sub { $sigterm = 1 }; + + my $cpuregexp = qr/$I{cpuregexp}/; + + # 1=cpu, 2=mem, 3=net + my $mode = 0; + + while (<$pipe>) { + chomp; + + if ( $mode == 0 ) { + if ( $_ eq 'MEMSTATS' ) { + $mode = 1; + + } + elsif (/^$loadavgexp/) { + $AVGSTATS{$host} = "$1;$2;$3"; + + } + elsif (/$cpuregexp/) { + my ( $name, $load ) = parse_cpu_line $_; + $CPUSTATS{"$host;$name"} = join ';', + map { $_ . '=' . $load->{$_} } + grep { defined $load->{$_} } keys %$load; + } + } + elsif ( $mode == 1 ) { + if ( $_ eq 'CPUSTATS' ) { + $mode = 0; + + } + else { + for my $meminfo ( + qw(MemTotal MemFree Buffers Cached SwapTotal SwapFree)) + { + + # TODO: Precompile regexp + if (/^$meminfo: *(\d+)/) { + $MEMSTATS_HAS{$host} = 1; + $MEMSTATS{"$host;$meminfo"} = $1; + } + } + } + } + + if ($sigusr1) { + + # TODO: Use index instead of regexp for cpuregexp + $cpuregexp = qr/$I{cpuregexp}/; + $sigusr1 = 0; + + } + elsif ($sigterm) { + close $pipe; + last; + } + } + + delete $PIDS{$pid}; + } + + return undef; +} + +sub get_rect ($$) { + my ( $rects, $name ) = @_; + + return $rects->{$name} if exists $rects->{$name}; + return $rects->{$name} = SDL::Rect->new(); +} + +sub normalize_loads (%) { + my %loads = @_; + + return %loads unless exists $loads{TOTAL}; + + my $total = $loads{TOTAL} == 0 ? 1 : $loads{TOTAL}; + return map { $_ => $loads{$_} / ( $total / 100 ) } keys %loads; +} + +sub get_cpuaverage ($@) { + my ( $factor, @loads ) = @_; + my ( %cpumax, %cpuaverage ); + + for my $l (@loads) { + for ( keys %$l ) { + $cpuaverage{$_} += $l->{$_}; + + $cpumax{$_} = $l->{$_} + if not exists $cpumax{$_} + or $cpumax{$_} < $l->{$_}; + } + } + + my $div = @loads / $factor; + + for ( keys %cpuaverage ) { + $cpuaverage{$_} /= $div; + $cpumax{$_} /= $factor; + } + + return ( \%cpumax, \%cpuaverage ); +} + +sub draw_background ($$) { + my ( $app, $rects ) = @_; + my $rect = get_rect $rects, 'background'; + + $rect->width( $C{width} ); + $rect->height( $C{height} ); + $app->fill( $rect, Loadbars::Constants->BLACK ); + $app->update($rect); + + return undef; +} + +sub create_threads (@) { + return map { $_->detach(); $_ } + map { threads->create( 'stats_thread', split ':' ) } @_; +} + +sub auto_off_text ($) { + my ($barwidth) = @_; + + if ( $barwidth < $C{barwidth} - 1 && $I{showtextoff} == 0 ) { + return unless $C{showtext}; + display_warn +'Disabling text display, text does not fit into window. Use \'t\' to re-enable.'; + $I{showtextoff} = 1; + $C{showtext} = 0; + + } + elsif ( $I{showtextoff} == 1 && $barwidth >= $C{barwidth} - 1 ) { + display_info 'Re-enabling text display, text fits into window now.'; + $C{showtext} = 1; + $I{showtextoff} = 0; + } + + return undef; +} + +sub set_dimensions ($$) { + my ( $width, $height ) = @_; + my $display_info = 0; + + if ( $width < 1 ) { + $C{width} = 1 if $C{width} != 1; + + } + elsif ( $width > $C{maxwidth} ) { + $C{width} = $C{maxwidth} if $C{width} != $C{maxwidth}; + + } + elsif ( $C{width} != $width ) { + $C{width} = $width; + } + + if ( $height < 1 ) { + $C{height} = 1 if $C{height} != 1; + + } + elsif ( $C{height} != $height ) { + $C{height} = $height; + } +} + +sub main_loop ($@) { + my ( $dispatch, @threads ) = @_; + + my $num_stats = 1; + $C{width} = $C{barwidth}; + + my $app = SDL::App->new( + -title => Loadbars::Constants->VERSION + . ' (press h for help on stdout)', + -icon_title => Loadbars::Constants->VERSION, + -width => $C{width}, + -height => $C{height}, + -depth => Loadbars::Constants->COLOR_DEPTH, + -resizeable => 1, + ); + + my $fontbase = 'fonts/font.png'; + + if ( -f "./$fontbase") { + $C{font} = "./$fontbase"; + + } elsif (-f "/usr/share/loadbars/$fontbase") { + $C{font} = "/usr/share/loadbars/$fontbase"; + } + + say("Foo:".$C{font}); + SDL::Font->new($C{font})->use(); + + my $rects = {}; + my %prev_stats; + my %last_loads; + + my $redraw_background = 0; + my $font_height = 14; + + my $infotxt : shared = ''; + my $quit : shared = 0; + my $resize_window : shared = 0; + my %newsize : shared; + my $event = SDL::Event->new(); + + my ( $t1, $t2 ) = ( Time::HiRes::time(), undef ); + + # Closure for event handling + my $event_handler = sub { + + # While there are events to poll, poll them all! + while ( $event->poll() == 1 ) { + next if $event->type() != 2; + my $key_name = $event->key_name(); + + if ( $key_name eq '1' ) { + $C{showcores} = !$C{showcores}; + set_showcores_regexp; + $_->kill('USR1') for @threads; + %AVGSTATS = (); + %CPUSTATS = (); + $redraw_background = 1; + display_info 'Toggled CPUs'; + + } + elsif ( $key_name eq 'e' ) { + $C{extended} = !$C{extended}; + $redraw_background = 1; + display_info 'Toggled extended display'; + + } + elsif ( $key_name eq 'h' ) { + say '=> Hotkeys to use in the SDL interface'; + say $dispatch->('hotkeys'); + display_info 'Hotkeys help printed on terminal stdout'; + + } + elsif ( $key_name eq 'm' ) { + $C{showmem} = !$C{showmem}; + display_info 'Toggled show mem'; + + } + elsif ( $key_name eq 't' ) { + $C{showtext} = !$C{showtext}; + $redraw_background = 1; + display_info 'Toggled text display'; + + } + elsif ( $key_name eq 'u' ) { + $C{showtexthost} = !$C{showtexthost}; + $redraw_background = 1; + display_info 'Toggled number/hostname display'; + + } + elsif ( $key_name eq 'q' ) { + terminate_pids @threads; + $quit = 1; + return; + + } + elsif ( $key_name eq 'w' ) { + Loadbars::Config::write; + + } + elsif ( $key_name eq 'a' ) { + ++$C{average}; + display_info "Set sample average to $C{average}"; + } + elsif ( $key_name eq 'y' or $key_name eq 'z' ) { + my $avg = $C{average}; + --$avg; + $C{average} = $avg > 1 ? $avg : 2; + display_info "Set sample average to $C{average}"; + + } + elsif ( $key_name eq 's' ) { + $C{factor} += 0.1; + display_info "Set scale factor to $C{factor}"; + } + elsif ( $key_name eq 'x' or $key_name eq 'z' ) { + $C{factor} -= 0.1; + display_info "Set scale factor to $C{factor}"; + + } + elsif ( $key_name eq 'left' ) { + $newsize{width} = $C{width} - 100; + $newsize{height} = $C{height}; + $resize_window = 1; + } + elsif ( $key_name eq 'right' ) { + $newsize{width} = $C{width} + 100; + $newsize{height} = $C{height}; + $resize_window = 1; + + } + elsif ( $key_name eq 'up' ) { + $newsize{width} = $C{width}; + $newsize{height} = $C{height} - 100; + $resize_window = 1; + } + elsif ( $key_name eq 'down' ) { + $newsize{width} = $C{width}; + $newsize{height} = $C{height} + 100; + $resize_window = 1; + } + } + }; + + do { + my ( $x, $y ) = ( 0, 0 ); + + # Also substract 1 (each bar is followed by an 1px separator bar) + my $width = $C{width} / notnull($num_stats) - 1; + + my ( $current_barnum, $current_corenum ) = ( -1, -1 ); + + for my $key ( sort keys %CPUSTATS ) { + last if ( ++$current_barnum > $num_stats ); + ++$current_corenum; + my ( $host, $name ) = split ';', $key; + + next unless defined $CPUSTATS{$key}; + + my %stat = map { + my ( $k, $v ) = split '='; + $k => $v + + } split ';', $CPUSTATS{$key}; + + unless ( exists $prev_stats{$key} ) { + $prev_stats{$key} = \%stat; + next; + } + + my $prev_stat = $prev_stats{$key}; + my %loads = + null $stat{TOTAL} == null $prev_stat->{TOTAL} + ? %stat + : map { $_ => $stat{$_} - $prev_stat->{$_} } keys %stat; + + $prev_stats{$key} = \%stat; + + %loads = normalize_loads %loads; + push @{ $last_loads{$key} }, \%loads; + shift @{ $last_loads{$key} } + while @{ $last_loads{$key} } >= $C{average}; + + my ( $cpumax, $cpuaverage ) = get_cpuaverage $C{factor}, + @{ $last_loads{$key} }; + + my %heights = map { + $_ => defined $cpuaverage->{$_} + ? $cpuaverage->{$_} * ( $C{height} / 100 ) + : 1 + } keys %$cpuaverage; + + my $is_host_summary = $name eq 'cpu' ? 1 : 0; + + my $rect_separator = undef; + + my $rect_idle = get_rect $rects, "$key;idle"; + my $rect_steal = get_rect $rects, "$key;steal"; + my $rect_guest = get_rect $rects, "$key;guest"; + my $rect_irq = get_rect $rects, "$key;irq"; + my $rect_softirq = get_rect $rects, "$key;softirq"; + my $rect_nice = get_rect $rects, "$key;nice"; + my $rect_iowait = get_rect $rects, "$key;iowait"; + my $rect_user = get_rect $rects, "$key;user"; + my $rect_system = get_rect $rects, "$key;system"; + + my $rect_peak; + + $y = $C{height} - $heights{system}; + $rect_system->width($width); + $rect_system->height( $heights{system} ); + $rect_system->x($x); + $rect_system->y($y); + + $y -= $heights{user}; + $rect_user->width($width); + $rect_user->height( $heights{user} ); + $rect_user->x($x); + $rect_user->y($y); + + $y -= $heights{nice}; + $rect_nice->width($width); + $rect_nice->height( $heights{nice} ); + $rect_nice->x($x); + $rect_nice->y($y); + + $y -= $heights{idle}; + $rect_idle->width($width); + $rect_idle->height( $heights{idle} ); + $rect_idle->x($x); + $rect_idle->y($y); + + $y -= $heights{iowait}; + $rect_iowait->width($width); + $rect_iowait->height( $heights{iowait} ); + $rect_iowait->x($x); + $rect_iowait->y($y); + + $y -= $heights{irq}; + $rect_irq->width($width); + $rect_irq->height( $heights{irq} ); + $rect_irq->x($x); + $rect_irq->y($y); + + $y -= $heights{softirq}; + $rect_softirq->width($width); + $rect_softirq->height( $heights{softirq} ); + $rect_softirq->x($x); + $rect_softirq->y($y); + + $y -= $heights{guest}; + $rect_guest->width($width); + $rect_guest->height( $heights{guest} ); + $rect_guest->x($x); + $rect_guest->y($y); + + $y -= $heights{steal}; + $rect_steal->width($width); + $rect_steal->height( $heights{steal} ); + $rect_steal->x($x); + $rect_steal->y($y); + + my $all = 100 - $cpuaverage->{idle}; + my $max_all = 0; + + $app->fill( $rect_idle, Loadbars::Constants->BLACK ); + $app->fill( $rect_steal, Loadbars::Constants->RED ); + $app->fill( $rect_guest, Loadbars::Constants->RED ); + $app->fill( $rect_irq, Loadbars::Constants->WHITE ); + $app->fill( $rect_softirq, Loadbars::Constants->WHITE ); + $app->fill( $rect_nice, Loadbars::Constants->GREEN ); + $app->fill( $rect_iowait, Loadbars::Constants->PURPLE ); + + my $add_x = 0; + my $rect_memused = get_rect $rects, "$host;memused"; + my $rect_memfree = get_rect $rects, "$host;memfree"; + my $rect_buffers = get_rect $rects, "$host;buffers"; + my $rect_cached = get_rect $rects, "$host;cached"; + my $rect_swapused = get_rect $rects, "$host;swapused"; + my $rect_swapfree = get_rect $rects, "$host;swapfree"; + + my %meminfo; + if ($is_host_summary) { + if ( $C{showmem} ) { + $add_x = $width + 1; + + my $ram_per = percentage $MEMSTATS{"$host;MemTotal"}, + $MEMSTATS{"$host;MemFree"}; + my $swap_per = percentage $MEMSTATS{"$host;SwapTotal"}, + $MEMSTATS{"$host;SwapFree"}; + + %meminfo = ( + ram_per => $ram_per, + swap_per => $swap_per, + ); + + my %heights = ( + MemFree => $ram_per * ( $C{height} / 100 ), + MemUsed => ( 100 - $ram_per ) * ( $C{height} / 100 ), + SwapFree => $swap_per * ( $C{height} / 100 ), + SwapUsed => ( 100 - $swap_per ) * ( $C{height} / 100 ), + ); + + my $half_width = $width / 2; + $y = $C{height} - $heights{MemUsed}; + $rect_memused->width($half_width); + $rect_memused->height( $heights{MemUsed} ); + $rect_memused->x( $x + $add_x ); + $rect_memused->y($y); + + $y -= $heights{MemFree}; + $rect_memfree->width($half_width); + $rect_memfree->height( $heights{MemFree} ); + $rect_memfree->x( $x + $add_x ); + $rect_memfree->y($y); + + $y = $C{height} - $heights{SwapUsed}; + $rect_swapused->width($half_width); + $rect_swapused->height( $heights{SwapUsed} ); + $rect_swapused->x( $x + $add_x + $half_width ); + $rect_swapused->y($y); + + $y -= $heights{SwapFree}; + $rect_swapfree->width($half_width); + $rect_swapfree->height( $heights{SwapFree} ); + $rect_swapfree->x( $x + $add_x + $half_width ); + $rect_swapfree->y($y); + + $app->fill( $rect_memused, Loadbars::Constants->DARK_GREY ); + $app->fill( $rect_memfree, Loadbars::Constants->BLACK ); + + $app->fill( $rect_swapused, Loadbars::Constants->GREY ); + $app->fill( $rect_swapfree, Loadbars::Constants->BLACK ); + } + + if ( $C{showcores} ) { + $current_corenum = 0; + $rect_separator = get_rect $rects, "$key;separator"; + $rect_separator->width(1); + $rect_separator->height( $C{height} ); + $rect_separator->x( $x - 1 ); + $rect_separator->y(0); + $app->fill( $rect_separator, Loadbars::Constants->GREY ); + } + } + + if ( $C{extended} ) { + my %maxheights = map { + $_ => defined $cpumax->{$_} + ? $cpumax->{$_} * ( $C{height} / 100 ) + : 1 + } keys %$cpumax; + + $rect_peak = get_rect $rects, "$key;max"; + $rect_peak->width($width); + $rect_peak->height(1); + $rect_peak->x($x); + $rect_peak->y( + $C{height} - $maxheights{system} - $maxheights{user} ); + + $max_all = + sum @{$cpumax} + {qw(user system iowait irq softirq steal guest)}; + + $app->fill( + $rect_peak, + $max_all > Loadbars::Constants->USER_ORANGE + ? Loadbars::Constants->ORANGE + : ( + $max_all > Loadbars::Constants->USER_YELLOW0 + ? Loadbars::Constants->YELLOW0 + : ( Loadbars::Constants->YELLOW ) + ) + ); + } + + $app->fill( + $rect_user, + $all > Loadbars::Constants->USER_ORANGE + ? Loadbars::Constants->ORANGE + : ( + $all > Loadbars::Constants->USER_YELLOW0 + ? Loadbars::Constants->YELLOW0 + : ( Loadbars::Constants->YELLOW ) + ) + ); + $app->fill( $rect_system, + $cpuaverage->{system} > Loadbars::Constants->SYSTEM_BLUE0 + ? Loadbars::Constants->BLUE0 + : Loadbars::Constants->BLUE ); + + my ( $y, $space ) = ( 5, $font_height ); + + my @loadavg = split ';', $AVGSTATS{$host}; + + if ( $C{showtext} ) { + if ( $C{showmem} && $is_host_summary ) { + my $y_ = $y; + $app->print( $x + $add_x, $y_, 'Ram:' ); + $app->print( + $x + $add_x, + $y_ += $space, + sprintf '%02d', + ( 100 - $meminfo{ram_per} ) + ); + $app->print( $x + $add_x, $y_ += $space, 'Swp:' ); + $app->print( + $x + $add_x, + $y_ += $space, + sprintf '%02d', + ( 100 - $meminfo{swap_per} ) + ); + } + if ( $C{showtexthost} && $is_host_summary ) { + + # If hostname is printed don't use FQDN + # because of its length. + $host =~ /([^\.]*)/; + $app->print( $x, $y, sprintf '%s:', $1 ); + + } + else { + $app->print( $x, $y, sprintf '%i:', + $C{showcores} + ? $current_corenum + : $current_barnum + 1 ); + } + + if ( $C{extended} ) { + $app->print( + $x, + $y += $space, + sprintf '%02d%s', + norm $cpuaverage->{steal}, 'st' + ); + $app->print( + $x, + $y += $space, + sprintf '%02d%s', + norm $cpuaverage->{guest}, 'gt' + ); + $app->print( + $x, + $y += $space, + sprintf '%02d%s', + norm $cpuaverage->{softirq}, 'sr' + ); + $app->print( + $x, + $y += $space, + sprintf '%02d%s', + norm $cpuaverage->{irq}, 'ir' + ); + } + + $app->print( + $x, + $y += $space, + sprintf '%02d%s', + norm $cpuaverage->{iowait}, 'io' + ); + + $app->print( + $x, + $y += $space, + sprintf '%02d%s', + norm $cpuaverage->{idle}, 'id' + ) if $C{extended}; + + $app->print( + $x, + $y += $space, + sprintf '%02d%s', + norm $cpuaverage->{nice}, 'ni' + ); + $app->print( + $x, + $y += $space, + sprintf '%02d%s', + norm $cpuaverage->{user}, 'us' + ); + $app->print( + $x, + $y += $space, + sprintf '%02d%s', + norm $cpuaverage->{system}, 'sy' + ); + $app->print( + $x, + $y += $space, + sprintf '%02d%s', + norm $all, 'to' + ); + + $app->print( + $x, + $y += $space, + sprintf '%02d%s', + norm $max_all, 'pk' + ) if $C{extended}; + + if ($is_host_summary) { + if ( defined $loadavg[0] ) { + $app->print( $x, $y += $space, 'Avg:' ); + $app->print( + $x, + $y += $space, + sprintf "%.2f", + $loadavg[0] + ); + $app->print( + $x, + $y += $space, + sprintf "%.2f", + $loadavg[1] + ); + $app->print( + $x, + $y += $space, + sprintf "%.2f", + $loadavg[2] + ); + } + } + } + + $app->update( + $rect_idle, $rect_iowait, $rect_irq, + $rect_nice, $rect_softirq, $rect_steal, + $rect_guest, $rect_system, $rect_user, + ); + + $app->update( + $rect_memfree, $rect_memused, + $rect_swapused, $rect_swapfree + ) if $C{showmem}; + $app->update($rect_separator) if defined $rect_separator; + + $x += $width + 1 + $add_x; + + } + + TIMEKEEPER: + $t2 = Time::HiRes::time(); + my $t_diff = $t2 - $t1; + + if ( Loadbars::Constants->INTERVAL > $t_diff ) { + usleep 10000; + + # Goto is OK as long you don't produce spaghetti code + goto TIMEKEEPER; + + } + elsif ( Loadbars::Constants->INTERVAL_WARN < $t_diff ) { + display_warn +"WARN: Loop is behind $t_diff seconds, your computer may be too slow"; + } + + $t1 = $t2; + $event_handler->(); + + my $new_num_stats = keys %CPUSTATS; + $new_num_stats += keys %MEMSTATS_HAS if $C{showmem}; + + if ( $new_num_stats != $num_stats ) { + %prev_stats = (); + %last_loads = (); + + $num_stats = $new_num_stats; + $newsize{width} = $C{barwidth} * $num_stats; + $newsize{height} = $C{height}; + $resize_window = 1; + } + + if ($resize_window) { + set_dimensions $newsize{width}, $newsize{height}; + $app->resize( $C{width}, $C{height} ); + $resize_window = 0; + $redraw_background = 1; + } + + if ($redraw_background) { + draw_background $app, $rects; + $redraw_background = 0; + } + + auto_off_text $width; + + } until $quit; + + say "Good bye"; + + exit Loadbars::Constants->SUCCESS; +} + +# Recursuve function +sub get_cluster_hosts ($;$); + +sub get_cluster_hosts ($;$) { + my ( $cluster, $recursion ) = @_; + + unless ( defined $recursion ) { + $recursion = 1; + + } + elsif ( $recursion > Loadbars::Constants->CSSH_MAX_RECURSION ) { + error( "CSSH_MAX_RECURSION reached. Infinite circle loop in " + . Loadbars::Constants->CSSH_CONFFILE + . "?" ); + } + + open my $fh, Loadbars::Constants->CSSH_CONFFILE + or error( "$!: " . Loadbars::Constants->CSSH_CONFFILE ); + my $hosts; + + while (<$fh>) { + if (/^$cluster\s*(.*)/) { + $hosts = $1; + last; + } + } + + close $fh; + + unless ( defined $hosts ) { + error( "No such cluster in " + . Loadbars::Constants->CSSH_CONFFILE + . ": $cluster" ) + unless defined $recursion; + + return ($cluster); + } + + my @hosts; + push @hosts, get_cluster_hosts $_, ( $recursion + 1 ) + for ( split /\s+/, $hosts ); + + return @hosts; +} + +1; diff --git a/lib/Loadbars/Shared.pm b/lib/Loadbars/Shared.pm new file mode 100644 index 0000000..0f02b7e --- /dev/null +++ b/lib/Loadbars/Shared.pm @@ -0,0 +1,52 @@ +package Loadbars::Shared; + +use Exporter; + +use base 'Exporter'; + +our @EXPORT = qw( + %PIDS + %AVGSTATS + %CPUSTATS + %MEMSTATS + %MEMSTATS_HAS + %C + %I +); + +our %PIDS : shared; +our %AVGSTATS : shared; +our %CPUSTATS : shared; +our %MEMSTATS : shared; +our %MEMSTATS_HAS : shared; + +#my %NETSTATS : shared; +#my %NETSTATS_HAS : shared; + +# Global configuration hash +our %C : shared; + +# Global configuration hash for internal settings (not configurable) +our %I : shared; + +# Setting defaults +%C = ( + average => 15, + barwidth => 35, + extended => 0, + factor => 1, + height => 230, + maxwidth => 1280, + samples => 1000, + showcores => 0, + showmem => 0, + showtext => 1, + showtexthost => 0, + sshopts => '', +); + +%I = ( + cpuregexp => 'cpu', + showtextoff => 0, +); + diff --git a/loadbars b/loadbars index 870fd78..8eb08d9 100755 --- a/loadbars +++ b/loadbars @@ -9,15 +9,19 @@ use warnings; use Getopt::Long; +use lib 'lib'; + use Loadbars::Main; use Loadbars::Constants; use Loadbars::HelpDispatch; +use Loadbars::Shared; +use Loadbars::Utils; sub main () { my ( $hosts, $dispatch ) = Loadbars::HelpDispatch::create; my $usage; - Loadbars::Main::say(Loadbars::Constants->VERSION . ' ' . Loadbars::Constants->COPYRIGHT); + say(Loadbars::Constants->VERSION . ' ' . Loadbars::Constants->COPYRIGHT); Loadbars::Config::read; @@ -36,7 +40,7 @@ sub main () { } split ',', $$hosts; if ( @hosts || defined $Loadbars::Main::C{cluster} ) { - push @hosts, Loadbars::Main::get_cluster_hosts $Loadbars::Main::C{cluster} + push @hosts, Loadbars::Main::get_cluster_hosts $C{cluster} if defined $Loadbars::Main::C{cluster}; system 'ssh-add'; diff --git a/share/docs/BUGS b/share/docs/BUGS deleted file mode 100644 index 40b75cd..0000000 --- a/share/docs/BUGS +++ /dev/null @@ -1 +0,0 @@ -* No known bugs ATM diff --git a/share/docs/CHANGELOG b/share/docs/CHANGELOG deleted file mode 100644 index da29f6d..0000000 --- a/share/docs/CHANGELOG +++ /dev/null @@ -1,139 +0,0 @@ -Thu Apr 19 21:41:52 CEST 2012 -* Minor change, sleep 0.5s instead of 3s if ssh command fails - -Fri Apr 6 10:17:30 CEST 2012 -* Minor fixes such as redraw background on toggle text display which - should fix some weird display bugs. - -Fri Mar 16 07:20:50 CET 2012 -* Release v0.5.1.1 -* Dropped FreeBSD support / focus is Linux -* On shutdown all sub-processes are gonna be terminated instantly - (was old bug). Needs Proc::ProcessTable module. -* Dont quit loadbars if ~/.loadbarsrc can not be overwritten - -Sat Feb 25 20:09:02 CET 2012 -* Release v0.5.1 -* Add config file support (~/.loadbarsrc) and it's possible to configure - any option you find in --help but without leading '--'. For comments - just use the '#' sign. Sample config: - showcores=1 # Always show cores on startup - showtext=0 # Always don't display text on startup -* Add hotkey 'w' which writes current settings to the configfile -* Remove --title option (no need anyway) -* Some code cleanups -* Some bugfixes - -Sat Feb 4 10:56:27 CET 2012 -* Release v0.5.0 -* Add stats for rudimentary memory and swap usage (--showmem option or m hotkey) -* Remove --width and --inter options -* Add --barwidth option, each bar is barwidth pixels now -* Add --maxwidth option, which represents the max total window width -* Auto disable text display if text does not fit into window (maxwidth) pixels -* Auto re-enable text display if text does fit again into window -* Key right increases window width by 100px and left decreases by 100px -* Key down increases window height by 100px and up decreases by 100px -* Set 'samples' default values from 1000 down to 500. -* Displays a text warning on stdout if computer may be too slow -* No sporadic crashes on shutdown anymore -* Some internal tweaks, no separate event thread needed anymore. This fixes - some sporadic bugs. - -Sun Jan 21 14:16:37 CET 2012 -* Released v0.4.0 -* Also show stats for idle, iowait, irq, softirq, steal and guest cpu time -* Some parameters have been renamed (see --help) -* Introduced extended mode (use --extended 1 at startup or 'e' hotkey) -* Modified the bar colors a little bit (see --help) -* Some Bugfixes - -Tue Dec 27 12:28:40 CET 2011 -* Released v0.3.1 -* --cluster option (which reads the ClusterSSH config file /etc/clusters/) - also supports clusters of clusters. e.g.: - $ cat /etc/clusters - clusterA server01 server02 - clusterB clusterA server03 - So --cluster clusterB will connect to server01 server02 and server03 -* --hosts option supports username to be specified. E.g.: - # ./loadbars --hosts user1@server01,user2@server02 - will connect to server01 using user1 and server02 with user2. - -Mon Dec 26 14:46:25 CET 2011 -* Released v0.3.0 -* Peak CPU load is not displayed by default anymore. User 'p' command or - the --togglepeak 1 startup option. -* Peak CPU load is now also displayd in text format (marked as pk) -* New option --cluster which brings rudimentary ClusterSSH config file - support. E.g. './loadbars --cluster server' reads cluster server from - the /etc/clusters file. - -Sat Nov 19 11:54:51 CET 2011 -* Released v0.2.2 -* Added a 1px horizontal line to each bar which represent the max. peak - of user and system cpu load of the last N samples (max. of the last 15 - samples by default, it can be configured using --average) -* Default value for --average has been decreased from 30 to 15 sample - values - -Fr 12. Aug 21:41:46 CEST 2011 -* Released v0.2.1 - -Di 9. Aug 20:42:43 CEST 2011 -* Released v0.2.0.2 (Bugfixes only; Bar width was wrong by 1px) - -So 7. Aug 15:53:08 CEST 2011 -* Added grey separator lines between each hosts during CPU toggle mode -* More intelligent CPU core numbering during CPU toggle mode -* FreeBSD server support for CPU graphs has been tested and is working using - linprocfs mounted on /compat/linux/proc. -* Changed licence to GPL 2 -* Some more documentation -* Some minor bugfixes - -So 7. Aug 14:06:45 CEST 2011 -* Released v0.2.0.1 (Bugfixes only) - -Sa 6. Aug 22:04:15 CEST 2011 -* Released v0.2.0 (new major version) -* No interactive CLI shell anymore but instead hotkeys for the - SDL interface (press h and see). -* Bugfixes (E.g. Loadbars does not hang anymore after typing commands) -* Major code refactoring - -Fr 5. Aug 23:52:49 CEST 2011 -* Released v0.1.3.1 -* Some more minor bugfixes - -Fr 5. Aug 23:29:19 CEST 2011 -* Released v0.1.3 -* Fixed a segfault bug on SDL::Font using threads -* Added an advanced help option (h vs. H) -* Added new toggle option: Displaying bar number vs. hostname -* Some little code refactoring - -Fr 22. Apr 13:08:08 CEST 2011 -* Released v0.1.2.1 - -Mi 20. Apr 08:37:49 CEST 2011 -* Added ./BUGS which includes a summary of all current known bugs - -Fri Jan 14 23:03:47 CET 2011 -* Released v0.1.2 -* Added 'toggle summary' option -* Removed all old screenshots -* Added a newer one -* Fixed lots of bugs (including segfaults) -* Cosmetic code fixes - -Tue Jan 11 14:01:32 CET 2011 -* Released v0.1.1 -* Extended help text ('h' command) -* Added CHANGELOG and README files -* Fixed a typo - -Tue Jan 11 13:??:?? CET 2011 -* Released v0.1.0 -* With initial font support (text display of the stats) -* Everything else which has been implemented up to 0.1-beta8-pre6 diff --git a/share/docs/COPYING b/share/docs/COPYING deleted file mode 100644 index d4b4b89..0000000 --- a/share/docs/COPYING +++ /dev/null @@ -1,280 +0,0 @@ -GNU GENERAL PUBLIC LICENSE Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - diff --git a/share/docs/COPYING.FONT b/share/docs/COPYING.FONT deleted file mode 100644 index d4b4b89..0000000 --- a/share/docs/COPYING.FONT +++ /dev/null @@ -1,280 +0,0 @@ -GNU GENERAL PUBLIC LICENSE Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - diff --git a/share/docs/HELP b/share/docs/HELP deleted file mode 100644 index e077c51..0000000 --- a/share/docs/HELP +++ /dev/null @@ -1,60 +0,0 @@ -==> Reading configuration from /home/pb/.loadbarsrc -==> Setting showcores=1, it might be overwritten by command line params. -==> Setting showtext=0, it might be overwritten by command line params. -==> Setting extended=1, it might be overwritten by command line params. -==> Setting showmem=1, it might be overwritten by command line params. -CPU stuff: - st = Steal in % [see man proc] (extended) - Color: Red - gt = Guest in % [see man proc] (extended) - Color: Red - sr = Soft IRQ usage in % (extended) - Color: White - ir = IRQ usage in % (extended) - Color: White - io = IOwait cpu sage in % - Color: Purple - id = Idle cpu usage in % (extended) - Color: Black - ni = Nice cpu usage in % - Color: Green - us = User cpu usage in % - Color: Yellow, dark yellow if to>50%, orange if to>50% - sy = System cpu sage in % - Blue, lighter blue if >30% - to = Total CPU usage, which is (100% - id) - pk = Max us+sy peak of last avg. samples (extended) - avg = System load average; desc. order: 1, 5 and 15 min. avg. - 1px horizontal line: Maximum sy+us+io of last 'avg' samples (extended) - Extended means: text display only if extended mode is turned on -Memory stuff: - Ram: System ram usage in % - Color: Dark grey - Swp: System swap usage in % - Color: Grey -Config file support: - Loadbars tries to read ~/.loadbarsrc and it's possible to configure any - option you find in --help but without leading '--'. For comments just use - the '#' sign. Sample config: - showcores=1 # Always show cores on startup - showtext=0 # Always don't display text on startup - extended=1 # Always use extended mode on startup - will always show all CPU cores in extended mode but no text display. -Examples: - loadbars --extended 1 --showcores 1 --height 300 --hosts localhost - loadbars --hosts localhost,server1.example.com,server2.example.com - loadbars --cluster foocluster (foocluster is in /etc/clusters [ClusterSSH]) ---average - Num of samples for avg. (more fluent animations) ---barwidth - Set bar width ---cluster - Cluster name from /etc/clusters ---extended - Toggle extended display (0 or 1) ---factor - Set graph scale factor (1.0 means 100%) ---height - Set windows height ---hosts - Comma sep. list of hosts; optional: user@ in front to each host ---maxwidth - Set max width ---samples - Set number of samples until ssh reconnects ---showcores - Toggle core display (0 or 1) ---showmem - Toggle mem display (0 or 1) ---showtexthost - Toggle hostname/num text display (0 or 1) ---showtext - Toggle text display (0 or 1) ---sshopts - Set SSH options diff --git a/share/docs/README b/share/docs/README deleted file mode 100644 index d839d8d..0000000 --- a/share/docs/README +++ /dev/null @@ -1,33 +0,0 @@ -For general program informations see http://loadbars.buetow.org - -For legal informations see COPYING and COPYING.FONT - -For any program help check out --help on command line or 'h' during program -execution. - -For a list of features which might be added in the future see WHISHLIST - -For a changelog see CHANGELOG - -For a list of all known bugs see BUGS - -Supported platforms are: Linux - -the latter may not have full functionality). - -For Linux at least a 2.6 Kernel is required. - -Versioning schema: a.b.c[.d][.e], where - a = Don't know yet. Maybe will stay forever 0. - b = Major release (new major features) - c = Minor release (new minor features or code refactoring) - d = Optional, bugfixes only release - e = Optional, cosmetic fixes only release - - It's not a release if there is a -master suffix. It's a stable - version (master branch) then. - - It's not a release if there is a -devel suffix. It's a development - version (devel branch) then. - -For some help/usage please consult the HELP file. diff --git a/share/docs/WISHLIST b/share/docs/WISHLIST deleted file mode 100644 index ea234ff..0000000 --- a/share/docs/WISHLIST +++ /dev/null @@ -1,6 +0,0 @@ -* More stats for memory -* Stats for network -* .deb for Debian and Ubuntu -* Auto detect single core boxes -* Make code modular (script is growing...) -* Optimize code (too much cpu usage if there are too many hosts involved) diff --git a/share/fonts/font.png b/share/fonts/font.png deleted file mode 100644 index 02e9eb1..0000000 Binary files a/share/fonts/font.png and /dev/null differ diff --git a/share/lib/Loadbars/Constants.pm b/share/lib/Loadbars/Constants.pm deleted file mode 100644 index af242bd..0000000 --- a/share/lib/Loadbars/Constants.pm +++ /dev/null @@ -1,39 +0,0 @@ -package Loadbars::Constants; - -use strict; -use warnings; - -use SDL::Color; - -use constant { - VERSION => 'loadbars v0.5.2-devel', - COPYRIGHT => '2010-2012 (c) Paul Buetow ', - CONFFILE => $ENV{HOME} . '/.loadbarsrc', - CSSH_CONFFILE => '/etc/clusters', - CSSH_MAX_RECURSION => 10, - COLOR_DEPTH => 8, - BLACK => SDL::Color->new( -r => 0x00, -g => 0x00, -b => 0x00 ), - BLUE0 => SDL::Color->new( -r => 0x00, -g => 0x00, -b => 0xff ), - BLUE => SDL::Color->new( -r => 0x00, -g => 0x00, -b => 0x88 ), - GREEN => SDL::Color->new( -r => 0x00, -g => 0x90, -b => 0x00 ), - ORANGE => SDL::Color->new( -r => 0xff, -g => 0x70, -b => 0x00 ), - PURPLE => SDL::Color->new( -r => 0xa0, -g => 0x20, -b => 0xf0 ), - RED => SDL::Color->new( -r => 0xff, -g => 0x00, -b => 0x00 ), - WHITE => SDL::Color->new( -r => 0xff, -g => 0xff, -b => 0xff ), - GREY0 => SDL::Color->new( -r => 0x11, -g => 0x11, -b => 0x11 ), - GREY => SDL::Color->new( -r => 0xaa, -g => 0xaa, -b => 0xaa ), - DARK_GREY => SDL::Color->new( -r => 0x15, -g => 0x15, -b => 0x15 ), - YELLOW0 => SDL::Color->new( -r => 0xff, -g => 0xa0, -b => 0x00 ), - YELLOW => SDL::Color->new( -r => 0xff, -g => 0xc0, -b => 0x00 ), - SYSTEM_BLUE0 => 30, - USER_ORANGE => 70, - USER_YELLOW0 => 50, - INTERVAL => 0.1, - INTERVAL_WARN => 1.0, - SUCCESS => 0, - E_UNKNOWN => 1, - E_NOHOST => 2, -}; - -1; - diff --git a/share/lib/Loadbars/HelpDispatch.pm b/share/lib/Loadbars/HelpDispatch.pm deleted file mode 100644 index dfee7f5..0000000 --- a/share/lib/Loadbars/HelpDispatch.pm +++ /dev/null @@ -1,350 +0,0 @@ -package Loadbars::HelpDispatch; - -use strict; -use warnings; - -use Loadbars::Constants; -use Loadbars::Shared; - -sub create () { - my $hosts = ''; - - my $textdesc = <50%, orange if to>50% - sy = System cpu sage in % - Blue, lighter blue if >30% - to = Total CPU usage, which is (100% - id) - pk = Max us+sy peak of last avg. samples (extended) - avg = System load average; desc. order: 1, 5 and 15 min. avg. - 1px horizontal line: Maximum sy+us+io of last 'avg' samples (extended) - Extended means: text display only if extended mode is turned on -Memory stuff: - Ram: System ram usage in % - Color: Dark grey - Swp: System swap usage in % - Color: Grey -Config file support: - Loadbars tries to read ~/.loadbarsrc and it's possible to configure any - option you find in --help but without leading '--'. For comments just use - the '#' sign. Sample config: - showcores=1 # Always show cores on startup - showtext=0 # Always don't display text on startup - extended=1 # Always use extended mode on startup - will always show all CPU cores in extended mode but no text display. -Examples: - loadbars --extended 1 --showcores 1 --height 300 --hosts localhost - loadbars --hosts localhost,server1.example.com,server2.example.com - loadbars --cluster foocluster (foocluster is in /etc/clusters [ClusterSSH]) -END - - # mode 1: Option is shown in the online help menu (stdout not sdl) - # mode 2: Option is shown in the 'usage' screen from the command line - # mode 4: Option is used to generate the GetOptions parameters for Getopt::Long - # Combinations: Like chmod(1) - - my %d = ( - average => { - menupos => 3, - help => 'Num of samples for avg. (more fluent animations)', - mode => 6, - type => 'i' - }, - average_hot_up => { - menupos => 4, - cmd => 'a', - help => 'Increases number of samples for calculating avg. by 1', - mode => 1 - }, - average_hot_dn => { - menupos => 5, - cmd => 'y', - help => 'Decreases number of samples for calculating avg. by 1', - mode => 1 - }, - - barwidth => { - menupos => 5, - help => 'Set bar width', - mode => 6, - type => 'i' - }, - windowwidth_hot_up => { - menupos => 90, - help => 'Increase window width by 100px', - cmd => 'right', - mode => 1, - }, - windowwidth_hot_dn => { - menupos => 91, - help => 'Decrease window width by 100px', - cmd => 'left', - mode => 1, - }, - windowheight_hot_up => { - menupos => 92, - help => 'Increase window height by 100px', - cmd => 'down', - mode => 1, - }, - windowheight_hot_dn => { - menupos => 93, - help => 'Decrease window height by 100px', - cmd => 'up', - mode => 1, - }, - - cluster => { - menupos => 6, - help => 'Cluster name from /etc/clusters', - var => \$C{cluster}, - mode => 6, - type => 's' - }, - configuration => { - menupos => 6, - cmd => 'c', - help => 'Show current configuration', - mode => 4 - }, - - extended => { - menupos => 6, - help => 'Toggle extended display (0 or 1)', - mode => 7, - type => 'i' - }, - extended_hot => { - menupos => 23, - cmd => 'e', - help => 'Toggle extended mode', - mode => 1 - }, - - factor => { - menupos => 7, - help => 'Set graph scale factor (1.0 means 100%)', - mode => 6, - type => 's' - }, - factor_hot_up => { - menupos => 8, - cmd => 's', - help => 'Increases graph scale factor by 0.1', - mode => 1 - }, - factor_hot_dn => { - menupos => 9, - cmd => 'x', - help => 'Decreases graph scale factor by 0.1', - mode => 1 - }, - - height => { - menupos => 10, - help => 'Set windows height', - mode => 6, - type => 'i' - }, - - help_hot => { - menupos => 11, - cmd => 'h', - help => 'Prints this help screen', - mode => 1 - }, - - hosts => { - menupos => 12, - help => - 'Comma sep. list of hosts; optional: user@ in front to each host', - var => \$hosts, - mode => 6, - type => 's' - }, - - maxwidth => { - menupos => 16, - help => 'Set max width', - mode => 6, - type => 'i' - }, - - quit_hot => { menupos => 16, cmd => 'q', help => 'Quits', mode => 1 }, - writeconfig_hot => { - menupos => 16, - cmd => 'w', - help => 'Write config to config file', - mode => 1 - }, - - samples => { - menupos => 17, - help => 'Set number of samples until ssh reconnects', - mode => 6, - type => 'i' - }, - - showcores => { - menupos => 17, - help => 'Toggle core display (0 or 1)', - mode => 7, - type => 'i' - }, - showcores_hot => - { menupos => 17, cmd => '1', help => 'Toggle show cores', mode => 1 }, - - showmem => { - menupos => 17, - help => 'Toggle mem display (0 or 1)', - mode => 7, - type => 'i' - }, - showmem_hot => - { menupos => 17, cmd => 'm', help => 'Toggle show mem', mode => 1 }, - - showtexthost => { - menupos => 18, - help => 'Toggle hostname/num text display (0 or 1)', - mode => 7, - type => 'i' - }, - showtexthost_hot => { - menupos => 18, - cmd => 'u', - help => 'Toggle hostname/num text display', - mode => 1 - }, - - showtext => { - menupos => 19, - help => 'Toggle text display (0 or 1)', - mode => 7, - type => 'i' - }, - showtext_hot => { - menupos => 19, - cmd => 't', - help => 'Toggle text display', - mode => 1 - }, - - sshopts => - { menupos => 20, help => 'Set SSH options', mode => 6, type => 's' }, - ); - - my %d_by_short = map { - $d{$_}{cmd} => $d{$_} - - } grep { - exists $d{$_}{cmd} - - } keys %d; - - my $closure = sub ($;$) { - my ( $arg, @rest ) = @_; - - if ( $arg eq 'command' ) { - my ( $cmd, @args ) = @rest; - - my $cb = $d{$cmd}; - $cb = $d_by_short{$cmd} unless defined $cb; - - unless ( defined $cb ) { - system $cmd; - return 0; - } - - if ( length $cmd == 1 ) { - for my $key ( grep { exists $d{$_}{cmd} } keys %d ) { - do { $cmd = $key; last } if $d{$key}{cmd} eq $cmd; - } - } - - } - elsif ( $arg eq 'hotkeys' ) { - $textdesc . "Hotkeys:\n" . ( - join "\n", - map { - "$_\t- $d_by_short{$_}{help}" - - } grep { - $d_by_short{$_}{mode} & 1 and exists $d_by_short{$_}{help}; - - } sort { $d_by_short{$a}{menupos} <=> $d_by_short{$b}{menupos} } - sort keys %d_by_short - ); - - } - elsif ( $arg eq 'usage' ) { - $textdesc . ( - join "\n", - map { - if ( $_ eq 'help' ) - { - "--$_\t\t- $d{$_}{help}"; - } - else { - "--$_ \t- $d{$_}{help}"; - } - - } grep { - $d{$_}{mode} & 2 - and exists $d{$_}{help} - - } sort { $d{$a}{menupos} <=> $d{$b}{menupos} } sort keys %d - ); - - } - elsif ( $arg eq 'options' ) { - map { - "$_=" - . $d{$_}{type} => ( - defined $d{$_}{var} - ? $d{$_}{var} - : \$C{$_} - ); - - } grep { - $d{$_}{mode} & 4 and exists $d{$_}{type}; - - } sort keys %d; - } - }; - - $d{configuration}{cb} = sub { - Loadbars::Main::say sort map { - "$_->[0] = $_->[1]" - - } grep { - defined $_->[1] - - } map { - [ - $_ => exists $d{$_}{var} - ? ${ $d{$_}{var} } - : $C{$_} - ] - - } keys %d; - }; - - return ( \$hosts, $closure ); -} - -1; diff --git a/share/lib/Loadbars/Main.pm b/share/lib/Loadbars/Main.pm deleted file mode 100644 index 210f07a..0000000 --- a/share/lib/Loadbars/Main.pm +++ /dev/null @@ -1,922 +0,0 @@ - -package Loadbars::Main; - -use strict; -use warnings; - -use Loadbars::Config; - -use SDL; -use SDL::App; -use SDL::Rect; -use SDL::Event; - -use SDL::Surface; -use SDL::Font; - -use Time::HiRes qw(usleep gettimeofday); - -use Proc::ProcessTable; - -use threads; -use threads::shared; - -use Loadbars::Constants; -use Loadbars::Utils; -use Loadbars::Shared; - -$| = 1; - -sub set_showcores_regexp () { - $I{cpuregexp} = $C{showcores} ? 'cpu' : 'cpu '; -} - -sub percentage ($$) { - my ( $total, $part ) = @_; - - return int( null($part) / notnull( null($total) / 100 ) ); -} - -sub norm ($) { - my $n = shift; - - return $n if $C{factor} != 1; - return $n > 100 ? 100 : ( $n < 0 ? 0 : $n ); -} - -sub parse_cpu_line ($) { - my $line = shift; - my ( $name, %load ); - - ( $name, @load{qw(user nice system idle iowait irq softirq steal guest)} ) = - split ' ', $line; - - # Not all kernels support this - $load{steal} = 0 unless defined $load{steal}; - $load{guest} = 0 unless defined $load{guest}; - - $load{TOTAL} = - sum( @load{qw(user nice system idle iowait irq softirq steal guest)} ); - - return ( $name, \%load ); -} - -sub terminate_pids (@) { - my @threads = @_; - - display_info 'Terminating sub-processes, hasta la vista!'; - $_->kill('TERM') for @threads; - display_info_no_nl 'Terminating PIDs'; - for my $pid ( keys %PIDS ) { - my $proc_table = Proc::ProcessTable->new(); - for my $proc ( @{ $proc_table->table() } ) { - if ( $proc->ppid == $pid ) { - print $proc->pid . ' '; - kill 'TERM', $proc->pid if $proc->ppid == $pid; - } - } - - print $pid . ' '; - kill 'TERM', $pid; - } - - say ''; - - display_info 'Terminating done. I\'ll be back!'; -} - -sub stats_thread ($;$) { - my ( $host, $user ) = @_; - $user = defined $user ? "-l $user" : ''; - - my ( $sigusr1, $sigterm ) = ( 0, 0 ); - my $loadavgexp = qr/(\d+\.\d{2}) (\d+\.\d{2}) (\d+\.\d{2})/; - my $inter = Loadbars::Constants->INTERVAL; - - until ($sigterm) { - my $bash = <<"BASH"; - loadavg=/proc/loadavg - stat=/proc/stat - meminfo=/proc/meminfo - - for i in \$(seq $C{samples}); do - echo CPUSTATS - cat \$loadavg \$stat - echo MEMSTATS - cat \$meminfo - sleep $inter - done -BASH - - my $cmd = - ( $host eq 'localhost' || $host eq '127.0.0.1' ) - ? $bash - : "ssh $user -o StrictHostKeyChecking=no $C{sshopts} $host '$bash'"; - - my $pid = open my $pipe, "$cmd |" or do { - say "Warning: $!"; - sleep 0.5; - next; - }; - - $PIDS{$pid} = 1; - - # Toggle CPUs - $SIG{USR1} = sub { $sigusr1 = 1 }; - $SIG{TERM} = sub { $sigterm = 1 }; - - my $cpuregexp = qr/$I{cpuregexp}/; - - # 1=cpu, 2=mem, 3=net - my $mode = 0; - - while (<$pipe>) { - chomp; - - if ( $mode == 0 ) { - if ( $_ eq 'MEMSTATS' ) { - $mode = 1; - - } - elsif (/^$loadavgexp/) { - $AVGSTATS{$host} = "$1;$2;$3"; - - } - elsif (/$cpuregexp/) { - my ( $name, $load ) = parse_cpu_line $_; - $CPUSTATS{"$host;$name"} = join ';', - map { $_ . '=' . $load->{$_} } - grep { defined $load->{$_} } keys %$load; - } - } - elsif ( $mode == 1 ) { - if ( $_ eq 'CPUSTATS' ) { - $mode = 0; - - } - else { - for my $meminfo ( - qw(MemTotal MemFree Buffers Cached SwapTotal SwapFree)) - { - - # TODO: Precompile regexp - if (/^$meminfo: *(\d+)/) { - $MEMSTATS_HAS{$host} = 1; - $MEMSTATS{"$host;$meminfo"} = $1; - } - } - } - } - - if ($sigusr1) { - - # TODO: Use index instead of regexp for cpuregexp - $cpuregexp = qr/$I{cpuregexp}/; - $sigusr1 = 0; - - } - elsif ($sigterm) { - close $pipe; - last; - } - } - - delete $PIDS{$pid}; - } - - return undef; -} - -sub get_rect ($$) { - my ( $rects, $name ) = @_; - - return $rects->{$name} if exists $rects->{$name}; - return $rects->{$name} = SDL::Rect->new(); -} - -sub normalize_loads (%) { - my %loads = @_; - - return %loads unless exists $loads{TOTAL}; - - my $total = $loads{TOTAL} == 0 ? 1 : $loads{TOTAL}; - return map { $_ => $loads{$_} / ( $total / 100 ) } keys %loads; -} - -sub get_cpuaverage ($@) { - my ( $factor, @loads ) = @_; - my ( %cpumax, %cpuaverage ); - - for my $l (@loads) { - for ( keys %$l ) { - $cpuaverage{$_} += $l->{$_}; - - $cpumax{$_} = $l->{$_} - if not exists $cpumax{$_} - or $cpumax{$_} < $l->{$_}; - } - } - - my $div = @loads / $factor; - - for ( keys %cpuaverage ) { - $cpuaverage{$_} /= $div; - $cpumax{$_} /= $factor; - } - - return ( \%cpumax, \%cpuaverage ); -} - -sub draw_background ($$) { - my ( $app, $rects ) = @_; - my $rect = get_rect $rects, 'background'; - - $rect->width( $C{width} ); - $rect->height( $C{height} ); - $app->fill( $rect, Loadbars::Constants->BLACK ); - $app->update($rect); - - return undef; -} - -sub create_threads (@) { - return map { $_->detach(); $_ } - map { threads->create( 'stats_thread', split ':' ) } @_; -} - -sub auto_off_text ($) { - my ($barwidth) = @_; - - if ( $barwidth < $C{barwidth} - 1 && $I{showtextoff} == 0 ) { - return unless $C{showtext}; - display_warn -'Disabling text display, text does not fit into window. Use \'t\' to re-enable.'; - $I{showtextoff} = 1; - $C{showtext} = 0; - - } - elsif ( $I{showtextoff} == 1 && $barwidth >= $C{barwidth} - 1 ) { - display_info 'Re-enabling text display, text fits into window now.'; - $C{showtext} = 1; - $I{showtextoff} = 0; - } - - return undef; -} - -sub set_dimensions ($$) { - my ( $width, $height ) = @_; - my $display_info = 0; - - if ( $width < 1 ) { - $C{width} = 1 if $C{width} != 1; - - } - elsif ( $width > $C{maxwidth} ) { - $C{width} = $C{maxwidth} if $C{width} != $C{maxwidth}; - - } - elsif ( $C{width} != $width ) { - $C{width} = $width; - } - - if ( $height < 1 ) { - $C{height} = 1 if $C{height} != 1; - - } - elsif ( $C{height} != $height ) { - $C{height} = $height; - } -} - -sub main_loop ($@) { - my ( $dispatch, @threads ) = @_; - - my $num_stats = 1; - $C{width} = $C{barwidth}; - - my $app = SDL::App->new( - -title => Loadbars::Constants->VERSION - . ' (press h for help on stdout)', - -icon_title => Loadbars::Constants->VERSION, - -width => $C{width}, - -height => $C{height}, - -depth => Loadbars::Constants->COLOR_DEPTH, - -resizeable => 1, - ); - - SDL::Font->new('font.png')->use(); - - my $rects = {}; - my %prev_stats; - my %last_loads; - - my $redraw_background = 0; - my $font_height = 14; - - my $infotxt : shared = ''; - my $quit : shared = 0; - my $resize_window : shared = 0; - my %newsize : shared; - my $event = SDL::Event->new(); - - my ( $t1, $t2 ) = ( Time::HiRes::time(), undef ); - - # Closure for event handling - my $event_handler = sub { - - # While there are events to poll, poll them all! - while ( $event->poll() == 1 ) { - next if $event->type() != 2; - my $key_name = $event->key_name(); - - if ( $key_name eq '1' ) { - $C{showcores} = !$C{showcores}; - set_showcores_regexp; - $_->kill('USR1') for @threads; - %AVGSTATS = (); - %CPUSTATS = (); - $redraw_background = 1; - display_info 'Toggled CPUs'; - - } - elsif ( $key_name eq 'e' ) { - $C{extended} = !$C{extended}; - $redraw_background = 1; - display_info 'Toggled extended display'; - - } - elsif ( $key_name eq 'h' ) { - say '=> Hotkeys to use in the SDL interface'; - say $dispatch->('hotkeys'); - display_info 'Hotkeys help printed on terminal stdout'; - - } - elsif ( $key_name eq 'm' ) { - $C{showmem} = !$C{showmem}; - display_info 'Toggled show mem'; - - } - elsif ( $key_name eq 't' ) { - $C{showtext} = !$C{showtext}; - $redraw_background = 1; - display_info 'Toggled text display'; - - } - elsif ( $key_name eq 'u' ) { - $C{showtexthost} = !$C{showtexthost}; - $redraw_background = 1; - display_info 'Toggled number/hostname display'; - - } - elsif ( $key_name eq 'q' ) { - terminate_pids @threads; - $quit = 1; - return; - - } - elsif ( $key_name eq 'w' ) { - Loadbars::Config::write; - - } - elsif ( $key_name eq 'a' ) { - ++$C{average}; - display_info "Set sample average to $C{average}"; - } - elsif ( $key_name eq 'y' or $key_name eq 'z' ) { - my $avg = $C{average}; - --$avg; - $C{average} = $avg > 1 ? $avg : 2; - display_info "Set sample average to $C{average}"; - - } - elsif ( $key_name eq 's' ) { - $C{factor} += 0.1; - display_info "Set scale factor to $C{factor}"; - } - elsif ( $key_name eq 'x' or $key_name eq 'z' ) { - $C{factor} -= 0.1; - display_info "Set scale factor to $C{factor}"; - - } - elsif ( $key_name eq 'left' ) { - $newsize{width} = $C{width} - 100; - $newsize{height} = $C{height}; - $resize_window = 1; - } - elsif ( $key_name eq 'right' ) { - $newsize{width} = $C{width} + 100; - $newsize{height} = $C{height}; - $resize_window = 1; - - } - elsif ( $key_name eq 'up' ) { - $newsize{width} = $C{width}; - $newsize{height} = $C{height} - 100; - $resize_window = 1; - } - elsif ( $key_name eq 'down' ) { - $newsize{width} = $C{width}; - $newsize{height} = $C{height} + 100; - $resize_window = 1; - } - } - }; - - do { - my ( $x, $y ) = ( 0, 0 ); - - # Also substract 1 (each bar is followed by an 1px separator bar) - my $width = $C{width} / notnull($num_stats) - 1; - - my ( $current_barnum, $current_corenum ) = ( -1, -1 ); - - for my $key ( sort keys %CPUSTATS ) { - last if ( ++$current_barnum > $num_stats ); - ++$current_corenum; - my ( $host, $name ) = split ';', $key; - - next unless defined $CPUSTATS{$key}; - - my %stat = map { - my ( $k, $v ) = split '='; - $k => $v - - } split ';', $CPUSTATS{$key}; - - unless ( exists $prev_stats{$key} ) { - $prev_stats{$key} = \%stat; - next; - } - - my $prev_stat = $prev_stats{$key}; - my %loads = - null $stat{TOTAL} == null $prev_stat->{TOTAL} - ? %stat - : map { $_ => $stat{$_} - $prev_stat->{$_} } keys %stat; - - $prev_stats{$key} = \%stat; - - %loads = normalize_loads %loads; - push @{ $last_loads{$key} }, \%loads; - shift @{ $last_loads{$key} } - while @{ $last_loads{$key} } >= $C{average}; - - my ( $cpumax, $cpuaverage ) = get_cpuaverage $C{factor}, - @{ $last_loads{$key} }; - - my %heights = map { - $_ => defined $cpuaverage->{$_} - ? $cpuaverage->{$_} * ( $C{height} / 100 ) - : 1 - } keys %$cpuaverage; - - my $is_host_summary = $name eq 'cpu' ? 1 : 0; - - my $rect_separator = undef; - - my $rect_idle = get_rect $rects, "$key;idle"; - my $rect_steal = get_rect $rects, "$key;steal"; - my $rect_guest = get_rect $rects, "$key;guest"; - my $rect_irq = get_rect $rects, "$key;irq"; - my $rect_softirq = get_rect $rects, "$key;softirq"; - my $rect_nice = get_rect $rects, "$key;nice"; - my $rect_iowait = get_rect $rects, "$key;iowait"; - my $rect_user = get_rect $rects, "$key;user"; - my $rect_system = get_rect $rects, "$key;system"; - - my $rect_peak; - - $y = $C{height} - $heights{system}; - $rect_system->width($width); - $rect_system->height( $heights{system} ); - $rect_system->x($x); - $rect_system->y($y); - - $y -= $heights{user}; - $rect_user->width($width); - $rect_user->height( $heights{user} ); - $rect_user->x($x); - $rect_user->y($y); - - $y -= $heights{nice}; - $rect_nice->width($width); - $rect_nice->height( $heights{nice} ); - $rect_nice->x($x); - $rect_nice->y($y); - - $y -= $heights{idle}; - $rect_idle->width($width); - $rect_idle->height( $heights{idle} ); - $rect_idle->x($x); - $rect_idle->y($y); - - $y -= $heights{iowait}; - $rect_iowait->width($width); - $rect_iowait->height( $heights{iowait} ); - $rect_iowait->x($x); - $rect_iowait->y($y); - - $y -= $heights{irq}; - $rect_irq->width($width); - $rect_irq->height( $heights{irq} ); - $rect_irq->x($x); - $rect_irq->y($y); - - $y -= $heights{softirq}; - $rect_softirq->width($width); - $rect_softirq->height( $heights{softirq} ); - $rect_softirq->x($x); - $rect_softirq->y($y); - - $y -= $heights{guest}; - $rect_guest->width($width); - $rect_guest->height( $heights{guest} ); - $rect_guest->x($x); - $rect_guest->y($y); - - $y -= $heights{steal}; - $rect_steal->width($width); - $rect_steal->height( $heights{steal} ); - $rect_steal->x($x); - $rect_steal->y($y); - - my $all = 100 - $cpuaverage->{idle}; - my $max_all = 0; - - $app->fill( $rect_idle, Loadbars::Constants->BLACK ); - $app->fill( $rect_steal, Loadbars::Constants->RED ); - $app->fill( $rect_guest, Loadbars::Constants->RED ); - $app->fill( $rect_irq, Loadbars::Constants->WHITE ); - $app->fill( $rect_softirq, Loadbars::Constants->WHITE ); - $app->fill( $rect_nice, Loadbars::Constants->GREEN ); - $app->fill( $rect_iowait, Loadbars::Constants->PURPLE ); - - my $add_x = 0; - my $rect_memused = get_rect $rects, "$host;memused"; - my $rect_memfree = get_rect $rects, "$host;memfree"; - my $rect_buffers = get_rect $rects, "$host;buffers"; - my $rect_cached = get_rect $rects, "$host;cached"; - my $rect_swapused = get_rect $rects, "$host;swapused"; - my $rect_swapfree = get_rect $rects, "$host;swapfree"; - - my %meminfo; - if ($is_host_summary) { - if ( $C{showmem} ) { - $add_x = $width + 1; - - my $ram_per = percentage $MEMSTATS{"$host;MemTotal"}, - $MEMSTATS{"$host;MemFree"}; - my $swap_per = percentage $MEMSTATS{"$host;SwapTotal"}, - $MEMSTATS{"$host;SwapFree"}; - - %meminfo = ( - ram_per => $ram_per, - swap_per => $swap_per, - ); - - my %heights = ( - MemFree => $ram_per * ( $C{height} / 100 ), - MemUsed => ( 100 - $ram_per ) * ( $C{height} / 100 ), - SwapFree => $swap_per * ( $C{height} / 100 ), - SwapUsed => ( 100 - $swap_per ) * ( $C{height} / 100 ), - ); - - my $half_width = $width / 2; - $y = $C{height} - $heights{MemUsed}; - $rect_memused->width($half_width); - $rect_memused->height( $heights{MemUsed} ); - $rect_memused->x( $x + $add_x ); - $rect_memused->y($y); - - $y -= $heights{MemFree}; - $rect_memfree->width($half_width); - $rect_memfree->height( $heights{MemFree} ); - $rect_memfree->x( $x + $add_x ); - $rect_memfree->y($y); - - $y = $C{height} - $heights{SwapUsed}; - $rect_swapused->width($half_width); - $rect_swapused->height( $heights{SwapUsed} ); - $rect_swapused->x( $x + $add_x + $half_width ); - $rect_swapused->y($y); - - $y -= $heights{SwapFree}; - $rect_swapfree->width($half_width); - $rect_swapfree->height( $heights{SwapFree} ); - $rect_swapfree->x( $x + $add_x + $half_width ); - $rect_swapfree->y($y); - - $app->fill( $rect_memused, Loadbars::Constants->DARK_GREY ); - $app->fill( $rect_memfree, Loadbars::Constants->BLACK ); - - $app->fill( $rect_swapused, Loadbars::Constants->GREY ); - $app->fill( $rect_swapfree, Loadbars::Constants->BLACK ); - } - - if ( $C{showcores} ) { - $current_corenum = 0; - $rect_separator = get_rect $rects, "$key;separator"; - $rect_separator->width(1); - $rect_separator->height( $C{height} ); - $rect_separator->x( $x - 1 ); - $rect_separator->y(0); - $app->fill( $rect_separator, Loadbars::Constants->GREY ); - } - } - - if ( $C{extended} ) { - my %maxheights = map { - $_ => defined $cpumax->{$_} - ? $cpumax->{$_} * ( $C{height} / 100 ) - : 1 - } keys %$cpumax; - - $rect_peak = get_rect $rects, "$key;max"; - $rect_peak->width($width); - $rect_peak->height(1); - $rect_peak->x($x); - $rect_peak->y( - $C{height} - $maxheights{system} - $maxheights{user} ); - - $max_all = - sum @{$cpumax} - {qw(user system iowait irq softirq steal guest)}; - - $app->fill( - $rect_peak, - $max_all > Loadbars::Constants->USER_ORANGE - ? Loadbars::Constants->ORANGE - : ( - $max_all > Loadbars::Constants->USER_YELLOW0 - ? Loadbars::Constants->YELLOW0 - : ( Loadbars::Constants->YELLOW ) - ) - ); - } - - $app->fill( - $rect_user, - $all > Loadbars::Constants->USER_ORANGE - ? Loadbars::Constants->ORANGE - : ( - $all > Loadbars::Constants->USER_YELLOW0 - ? Loadbars::Constants->YELLOW0 - : ( Loadbars::Constants->YELLOW ) - ) - ); - $app->fill( $rect_system, - $cpuaverage->{system} > Loadbars::Constants->SYSTEM_BLUE0 - ? Loadbars::Constants->BLUE0 - : Loadbars::Constants->BLUE ); - - my ( $y, $space ) = ( 5, $font_height ); - - my @loadavg = split ';', $AVGSTATS{$host}; - - if ( $C{showtext} ) { - if ( $C{showmem} && $is_host_summary ) { - my $y_ = $y; - $app->print( $x + $add_x, $y_, 'Ram:' ); - $app->print( - $x + $add_x, - $y_ += $space, - sprintf '%02d', - ( 100 - $meminfo{ram_per} ) - ); - $app->print( $x + $add_x, $y_ += $space, 'Swp:' ); - $app->print( - $x + $add_x, - $y_ += $space, - sprintf '%02d', - ( 100 - $meminfo{swap_per} ) - ); - } - if ( $C{showtexthost} && $is_host_summary ) { - - # If hostname is printed don't use FQDN - # because of its length. - $host =~ /([^\.]*)/; - $app->print( $x, $y, sprintf '%s:', $1 ); - - } - else { - $app->print( $x, $y, sprintf '%i:', - $C{showcores} - ? $current_corenum - : $current_barnum + 1 ); - } - - if ( $C{extended} ) { - $app->print( - $x, - $y += $space, - sprintf '%02d%s', - norm $cpuaverage->{steal}, 'st' - ); - $app->print( - $x, - $y += $space, - sprintf '%02d%s', - norm $cpuaverage->{guest}, 'gt' - ); - $app->print( - $x, - $y += $space, - sprintf '%02d%s', - norm $cpuaverage->{softirq}, 'sr' - ); - $app->print( - $x, - $y += $space, - sprintf '%02d%s', - norm $cpuaverage->{irq}, 'ir' - ); - } - - $app->print( - $x, - $y += $space, - sprintf '%02d%s', - norm $cpuaverage->{iowait}, 'io' - ); - - $app->print( - $x, - $y += $space, - sprintf '%02d%s', - norm $cpuaverage->{idle}, 'id' - ) if $C{extended}; - - $app->print( - $x, - $y += $space, - sprintf '%02d%s', - norm $cpuaverage->{nice}, 'ni' - ); - $app->print( - $x, - $y += $space, - sprintf '%02d%s', - norm $cpuaverage->{user}, 'us' - ); - $app->print( - $x, - $y += $space, - sprintf '%02d%s', - norm $cpuaverage->{system}, 'sy' - ); - $app->print( - $x, - $y += $space, - sprintf '%02d%s', - norm $all, 'to' - ); - - $app->print( - $x, - $y += $space, - sprintf '%02d%s', - norm $max_all, 'pk' - ) if $C{extended}; - - if ($is_host_summary) { - if ( defined $loadavg[0] ) { - $app->print( $x, $y += $space, 'Avg:' ); - $app->print( - $x, - $y += $space, - sprintf "%.2f", - $loadavg[0] - ); - $app->print( - $x, - $y += $space, - sprintf "%.2f", - $loadavg[1] - ); - $app->print( - $x, - $y += $space, - sprintf "%.2f", - $loadavg[2] - ); - } - } - } - - $app->update( - $rect_idle, $rect_iowait, $rect_irq, - $rect_nice, $rect_softirq, $rect_steal, - $rect_guest, $rect_system, $rect_user, - ); - - $app->update( - $rect_memfree, $rect_memused, - $rect_swapused, $rect_swapfree - ) if $C{showmem}; - $app->update($rect_separator) if defined $rect_separator; - - $x += $width + 1 + $add_x; - - } - - TIMEKEEPER: - $t2 = Time::HiRes::time(); - my $t_diff = $t2 - $t1; - - if ( Loadbars::Constants->INTERVAL > $t_diff ) { - usleep 10000; - - # Goto is OK as long you don't produce spaghetti code - goto TIMEKEEPER; - - } - elsif ( Loadbars::Constants->INTERVAL_WARN < $t_diff ) { - display_warn -"WARN: Loop is behind $t_diff seconds, your computer may be too slow"; - } - - $t1 = $t2; - $event_handler->(); - - my $new_num_stats = keys %CPUSTATS; - $new_num_stats += keys %MEMSTATS_HAS if $C{showmem}; - - if ( $new_num_stats != $num_stats ) { - %prev_stats = (); - %last_loads = (); - - $num_stats = $new_num_stats; - $newsize{width} = $C{barwidth} * $num_stats; - $newsize{height} = $C{height}; - $resize_window = 1; - } - - if ($resize_window) { - set_dimensions $newsize{width}, $newsize{height}; - $app->resize( $C{width}, $C{height} ); - $resize_window = 0; - $redraw_background = 1; - } - - if ($redraw_background) { - draw_background $app, $rects; - $redraw_background = 0; - } - - auto_off_text $width; - - } until $quit; - - say "Good bye"; - - exit Loadbars::Constants->SUCCESS; -} - -# Recursuve function -sub get_cluster_hosts ($;$); - -sub get_cluster_hosts ($;$) { - my ( $cluster, $recursion ) = @_; - - unless ( defined $recursion ) { - $recursion = 1; - - } - elsif ( $recursion > Loadbars::Constants->CSSH_MAX_RECURSION ) { - error( "CSSH_MAX_RECURSION reached. Infinite circle loop in " - . Loadbars::Constants->CSSH_CONFFILE - . "?" ); - } - - open my $fh, Loadbars::Constants->CSSH_CONFFILE - or error( "$!: " . Loadbars::Constants->CSSH_CONFFILE ); - my $hosts; - - while (<$fh>) { - if (/^$cluster\s*(.*)/) { - $hosts = $1; - last; - } - } - - close $fh; - - unless ( defined $hosts ) { - error( "No such cluster in " - . Loadbars::Constants->CSSH_CONFFILE - . ": $cluster" ) - unless defined $recursion; - - return ($cluster); - } - - my @hosts; - push @hosts, get_cluster_hosts $_, ( $recursion + 1 ) - for ( split /\s+/, $hosts ); - - return @hosts; -} - -1; diff --git a/share/lib/Loadbars/Shared.pm b/share/lib/Loadbars/Shared.pm deleted file mode 100644 index 0f02b7e..0000000 --- a/share/lib/Loadbars/Shared.pm +++ /dev/null @@ -1,52 +0,0 @@ -package Loadbars::Shared; - -use Exporter; - -use base 'Exporter'; - -our @EXPORT = qw( - %PIDS - %AVGSTATS - %CPUSTATS - %MEMSTATS - %MEMSTATS_HAS - %C - %I -); - -our %PIDS : shared; -our %AVGSTATS : shared; -our %CPUSTATS : shared; -our %MEMSTATS : shared; -our %MEMSTATS_HAS : shared; - -#my %NETSTATS : shared; -#my %NETSTATS_HAS : shared; - -# Global configuration hash -our %C : shared; - -# Global configuration hash for internal settings (not configurable) -our %I : shared; - -# Setting defaults -%C = ( - average => 15, - barwidth => 35, - extended => 0, - factor => 1, - height => 230, - maxwidth => 1280, - samples => 1000, - showcores => 0, - showmem => 0, - showtext => 1, - showtexthost => 0, - sshopts => '', -); - -%I = ( - cpuregexp => 'cpu', - showtextoff => 0, -); - -- cgit v1.2.3