mirror of https://gitee.com/openkylin/sysstat.git
Import Upstream version 12.6.1
This commit is contained in:
commit
1b5eb75187
|
@ -0,0 +1 @@
|
|||
custom: "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=45U6F9R73ESFQ"
|
|
@ -0,0 +1,58 @@
|
|||
# Lines starting with '#' are considered comments.
|
||||
# List of files to ignore:
|
||||
Makefile
|
||||
*.[oa]
|
||||
sa1
|
||||
sa2
|
||||
sysstat
|
||||
crontab
|
||||
version.h
|
||||
sysconfig.h
|
||||
sysstat.sysconfig
|
||||
sysstat.service
|
||||
sysstat.crond
|
||||
sysstat.cron.daily
|
||||
sysstat.cron.hourly
|
||||
sysstat.crond.sample
|
||||
sysstat.crond.sample.in
|
||||
cron/sysstat-collect.service
|
||||
cron/sysstat-collect.timer
|
||||
cron/sysstat-summary.service
|
||||
cron/sysstat-summary.timer
|
||||
cron/sysstat.sleep
|
||||
man/sa1.8
|
||||
man/sa2.8
|
||||
man/sadc.8
|
||||
man/sysstat.5
|
||||
man/sadf.1
|
||||
man/sar.1
|
||||
man/iostat.1
|
||||
man/cifsiostat.1
|
||||
*.log
|
||||
config.status
|
||||
autom4te.cache/
|
||||
*.save
|
||||
*.old
|
||||
.*.swp
|
||||
data
|
||||
*~
|
||||
man/*~
|
||||
build/*~
|
||||
sadc
|
||||
sar
|
||||
sadf
|
||||
iostat
|
||||
tapestat
|
||||
mpstat
|
||||
pidstat
|
||||
cifsiostat
|
||||
core
|
||||
TAGS
|
||||
nls/*.gmo
|
||||
tests/*.tmp
|
||||
tests/sa[0123]*
|
||||
tests/variables
|
||||
tests/pcpar.*
|
||||
inisar
|
||||
sar32
|
||||
sadc32
|
|
@ -0,0 +1,2 @@
|
|||
language: c
|
||||
script: ./do_test
|
|
@ -0,0 +1,20 @@
|
|||
This file contains the data that you should provide to report a bug:
|
||||
|
||||
System info: [Include sysstat version (e.g., the output of "sar -V" or "iostat -V" etc.),
|
||||
operating system name (e.g., the output of "uname -a"), and other relevant details]
|
||||
|
||||
Steps to reproduce:
|
||||
|
||||
[First Step]
|
||||
[Second Step]
|
||||
[and so on...]
|
||||
|
||||
Expected behavior: [What you expected to happen]
|
||||
|
||||
Actual behavior: [What actually happened]
|
||||
|
||||
Additional info: [Include gist of relevant binary system activity datafile, config, logs, etc.
|
||||
or send them directly to me at sysstat <at> orange_dot_fr]
|
||||
|
||||
Opening an issue on GitHub is the preferred way to report a bug.
|
||||
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{description}
|
||||
Copyright (C) {year} {fullname}
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
{signature of Ty Coon}, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,263 @@
|
|||
The following people have contributed to 'sysstat' in one way or another:
|
||||
|
||||
First I would like to thank Michael <michael [at] roka.net>: He is the
|
||||
very first person to have given me feedback about sysstat, and to
|
||||
point out to me that certain fields in /proc/stat didn't have the
|
||||
meaning I thought they had. This was in 1999!
|
||||
|
||||
Many thanks to the translators involved in sysstat:
|
||||
|
||||
* Birko Bergt <birko.bergt [at] gmx.de> for his translation into
|
||||
German,
|
||||
* Fernando Félix Redondo <fernando.felix [at] rediris.es> for his
|
||||
translation into Spanish (now maintained by Muralito
|
||||
<muralito [at] montevideo.com.uy>),
|
||||
* Frederic L. W. Meunier <0 [at] pervalidus.net> for the
|
||||
Portuguese translation.
|
||||
* Gert Brits <gbrits [at] techconcepts.co.za> for the translation
|
||||
into Afrikaans.
|
||||
* Roy Sigurd Karlsbakk <roy [at] karlsbakk.net> for the Norwegian
|
||||
translation.
|
||||
* Stefano Barni <barninga [at] interfree.it> for the translation
|
||||
into Italian.
|
||||
* Dennis Selsky <selsky [at] siberia.net> for the Russian translation.
|
||||
* Eugen Hoanca <eugenh [at] urban-grafx.ro> for the Romanian
|
||||
translation.
|
||||
* Robert Luberda <robert [at] debian.org> for the translation into
|
||||
Polish.
|
||||
* Miroslav David <md20128 [at] decef.elf.stuba.sk> for the Slovak
|
||||
translation.
|
||||
* Hideki Yamane <henrich [at] samba.gr.jp> for the translation into
|
||||
Japanese.
|
||||
* Daniel Nylander <po [at] danielnylander.se> for the Swedish
|
||||
translation.
|
||||
* John Damm Sørensen <john [at] hovedpuden.dk> for the Danish
|
||||
translation.
|
||||
* Bram Schoenmakers <bramschoenmakers [at] kde.nl> for the Dutch
|
||||
translation.
|
||||
|
||||
Carl-Christian Weber <ccweber [at] itz-koeln.de> helped me to make sar
|
||||
work on SMP machines.
|
||||
|
||||
Stefan Majer <smajer [at] advance-bank.de> provided me with a patch to
|
||||
rotate daily system activity files.
|
||||
|
||||
Klaus Franken <klaus.franken [at] fth2.siemens.de> created the RPM
|
||||
packages. He also included a short initialization script for sar
|
||||
to start it as a daemon on boot.
|
||||
|
||||
Jason (Jay) R. Fink <jay_rf [at] exis.net> set up and maintained the
|
||||
first web site for sysstat.
|
||||
|
||||
Preston Brown <pbrown [at] redhat.com> sent me the RedHat patch to
|
||||
enable good packaging.
|
||||
|
||||
David Doubrava <linux_monitor [at] volny.cz> created the isag
|
||||
command (Interactive System Activity Graph).
|
||||
|
||||
Rik van Riel <riel [at] conectiva.com.br> explained me the meaning
|
||||
of several fields that were added in Linux kernel 2.4
|
||||
/proc/meminfo file.
|
||||
|
||||
Hubert Nueckel <hubert.nueckel [at] oracle.com> sent me a patch to
|
||||
fix CPU utilization displayed by sar, iostat and mpstat commands
|
||||
on IA64 machines.
|
||||
|
||||
Victor Hazlewood <victor [at] sdsc.edu> sent me a patch to implement
|
||||
a database friendly option for sar (option -H).
|
||||
|
||||
Christopher Blizzard <blizzard [at] redhat.com> added the ability to
|
||||
display kB/s transfers to devices in iostat reporting when
|
||||
option -x is used.
|
||||
|
||||
John Caruso <caruso [at] paradiso.umuc.edu> wrote the sargon script
|
||||
shell as a replacement for sa1/sa2 files.
|
||||
|
||||
Wilhelm Nuesser <wilhelm.nuesser [at] sap.com> sent me a patch to
|
||||
fix average wait times and service times displayed by iostat -x.
|
||||
|
||||
Rick Lindsley <ricklind [at] us.ibm.com> has played a great part in
|
||||
making sysstat work on kernels 2.5 and above.
|
||||
|
||||
John Salmon <John.Salmon [at] cw.com> wrote a patch to enable file
|
||||
locking for sadc (option -L).
|
||||
|
||||
Jim W. Jaszewski <grok [at] sprint.ca> fixed several typos in
|
||||
sysstat FAQ!
|
||||
|
||||
Charlie Bennett <ccb [at] redhat.com> sent me several patches to
|
||||
fix known problems with sysstat. He also added the sysstat.ioconf
|
||||
file support, and the -p option to sar.
|
||||
|
||||
Thomas Polliard <thomas [at] polliard.com> helped me define the XML
|
||||
output format for sadf. He also wrote the corresponding DTD.
|
||||
|
||||
Dwight Tovey <dtovey [at] emergecore.com> updated sysstat so that
|
||||
it may be installed on Slackware.
|
||||
|
||||
Bryce Harrington <bryce [at] osdl.org> helped me to add support for
|
||||
hotplug CPU to sysstat.
|
||||
|
||||
Ivana Varekova <varekova [at] redhat.com> added support for iostat
|
||||
NFS statistics. Ivana also added support for autoconf, and created
|
||||
cifsiostat command.
|
||||
|
||||
Nils Philippsen <nphilipp [at] redhat.com> made history configurable.
|
||||
|
||||
Robert Luberda <robert [at] debian.org> brought a few improvements
|
||||
to sysstat's code, and also reported several bugs.
|
||||
|
||||
Jeroen Roovers <jer [at] gentoo.org> sent me a patch to fix a rare
|
||||
parallel make issue creating archive libsyscom.a.
|
||||
|
||||
Livio Soares <livio [at] eecg.toronto.edu> sent me a patch to fix
|
||||
a bug where mpstat didn't parse /proc/interrupts correctly when
|
||||
some CPUs had been set offline.
|
||||
|
||||
Emil Glatz <Emil.Glatz [at] wescoglobal.com> wrote the XML Schema
|
||||
to be used with sadf option -x.
|
||||
|
||||
Eduardo Ferro Aldama <eduardo.ferro.aldama [at] gmail.com> added
|
||||
option -l to pidstat to display the process command name and
|
||||
arguments.
|
||||
|
||||
Mario Konrad <Mario.Konrad [at] gmx.net> added regular expressions
|
||||
support to pidstat'x option -C. He also added option -s to pidstat
|
||||
to display task stack statistics.
|
||||
|
||||
Jan Kaluza <jkaluza [at] redhat.com> contributed several patches
|
||||
to sysstat. Among them, he added some more power management
|
||||
statistics to sar.
|
||||
|
||||
Alain Chéreau <cheralain [at] googlemail.com> added support for
|
||||
disk groups statistics to iostat.
|
||||
|
||||
Cédric Marie <cedric.marie [at] openmailbox.org> sent me
|
||||
several patches to improve pidstat.
|
||||
|
||||
Robert Elliott <Elliott [at] hp.com> contributed the irqtop
|
||||
command, and Lance Shelton <Lance.Shelton [at] sandisk.com>
|
||||
the irqstat command.
|
||||
|
||||
Dimitrios Apostolou <jimis [at] gmx.net> contributed the
|
||||
sargraph2 plotting tool.
|
||||
|
||||
Shane M. SEYMOUR <shane.seymour [at] hpe.com> contributed the
|
||||
tapestat command.
|
||||
|
||||
I would also thank the following people for their hints or bug reports
|
||||
(in alphabetical order):
|
||||
|
||||
Des Atkinson <Des.Atkinson@met[...].uk>
|
||||
Alexander Bangert <bangert.alex@gma[...].com>
|
||||
Sravan Bhamidipati <bsravanin@gma[...].com>
|
||||
Chuck Blake <cb@mit[...].edu>
|
||||
Michael Blakeley <mike@bla[...].com>
|
||||
Pascal Bleser <pbleser@ato[...].com>
|
||||
Lodewijk Bonebakker <jlbonebakker@gma[...].com>
|
||||
Andrey Borzenkov <arvidjaar@gma[...].com>
|
||||
Jesse Brandeburg <jesse.brandeburg@int[...].com>
|
||||
Xavier Bru <xavier.bru@bul[...].net>
|
||||
Jason Burnett <jason@jnj[...].org>
|
||||
Fabricio Ceolin <ceolin@ule[...].com
|
||||
Vitezslav Cizek <vcizek@sus[...].cz>
|
||||
Mark J. Cox <mjc@red[...].com>
|
||||
Jean Dagenais <jean.dagenais@int[...].com>
|
||||
Nicolas Denis <denisn@wan[...].fr>
|
||||
Andrew Donkin <ard@wai[...].nz>
|
||||
Greg Edwards <edwardsg@sgi[...].com>
|
||||
Tony Ernst <tee@sgi[...].com>
|
||||
Chris Evans <chris@sca[...].org>
|
||||
Damien Faure <damien-jn.faure@bul[...].net>
|
||||
James Fraser <jameswfraser@gma[...].com>
|
||||
Dr. David Alan Gilbert <dave@tre[...].org>
|
||||
David Gesswein <djg@drs[...].com>
|
||||
Frank Glinka <glinkaf@uni[...].de>
|
||||
John Goodyear <johngood@us[...].com>
|
||||
Gurinder Shergill <gurinder.shergill@hp[...].com>
|
||||
Ladislav Hagara <ladislav.hagara@uno[...].cz>
|
||||
Don Harrop <don@swb[...].com>
|
||||
Mark Harvey <markh794@gma[...].com>
|
||||
Vasant Hegde <hegdevasant@lin[...].com>
|
||||
Jürgen Heinemann <heinemann.juergen@hjc[...].de>
|
||||
Kei Ishida <ishida.kei@oss[...].jp>
|
||||
Tatsuo Ito <tito@mir[...].com>
|
||||
David S. Jackson <dsj@syl[...].net>
|
||||
Erik Jacobson <erikj@sub[...].com>
|
||||
Jordan <ledzep37@hom[...].com>
|
||||
Jurriaan <thunder7@xs4[...].nl>
|
||||
Jonathan Kamens <jik@kam[...].us>
|
||||
Ilya Katsnelson <ilya.katsnelson@mot[...].com>
|
||||
Steve Kay <stevekay@gma[...].com>
|
||||
Sampsa Kiiskinen <tuplanolla@gma[...].com>
|
||||
Mike Kobler <mkobler@gma[...].com>
|
||||
John Lau <johnlcf@gma[...].com>
|
||||
Byeong-taek Lee <btlee@psy[...].kr>
|
||||
Breno Leitao <breno.leitao@gma[...].com>
|
||||
Ivo Letzas <letzas@for[...].nu>
|
||||
Wayne Lin <wlin@mvi[...].com>
|
||||
Gunnar Lindholm <lindholm.gunnar@gma[...].com>
|
||||
Neculai Macarie <macarie.neculai@nex[...].com>
|
||||
Robert Macaulay <Robert_Macaulay@Del[...].com>
|
||||
Pierre Machard <pmachard@deb[...].org>
|
||||
Jérôme Marchand <jmarchan@red[...].com>
|
||||
Alan Matsuoka <alanm@red[...].com>
|
||||
Rodney J. Mertz <rjm@elv[...].com>
|
||||
Roy Millar <100044.14@com[...].com>
|
||||
Chris Minshull <CMinshull@nyx[...].com>
|
||||
Pascal Monschein <ext.astek.monschein@snc[...].fr>
|
||||
Chris Morrow <cmorrow@ver[...].com>
|
||||
David J. Morse <David_J_Morse@Del[...].com>
|
||||
Hariprasad Nellitheertha <hari@in.[...].com>
|
||||
Christian Neukirchen <chneukirchen@gma[...].com>
|
||||
Muneyuki Noguchi <nogu.dev@gma[...].com>
|
||||
Giulio Orsero <giulioo@pob[...].com>
|
||||
Edouard G. Parmelan <edouard.parmelan@qua[...].fr>
|
||||
Oliver Paukstadt <oliver.paukstadt@mil[...].com>
|
||||
Plattner(?) <Plattner.external@inf[...].com>
|
||||
Peter Portante <peter.a.portante@gma[...].com>
|
||||
Gerardo Exequiel Pozzi <vmlinuz386@yah[...].ar>
|
||||
ReDragon <redragon@vns[...].net>
|
||||
Amir Rapson <amir.rapson@gma[...].com>
|
||||
Paul Rivoli <paul@kbs[...].au>
|
||||
Scott Rochford <Scott_Rochford@DEL[...].com>
|
||||
Rolphin <rolphin@fre[...].fr>
|
||||
Jeroen Roovers <jer@gen[...].org>
|
||||
Pavol Rusnak <prusnak@sus[...].cz>
|
||||
Joseph E. Sacco <jsacco@ear[...].net>
|
||||
Sachin Sant <sachinp@in.[...].com>
|
||||
Eivind Sarto <ivan@kas[...].com>
|
||||
Danilo Sartori <d.sartori@res[...].it>
|
||||
Tan Shao Yi <tansy@tan[...].org>
|
||||
Yibin Shen <zituan@taobao.com>
|
||||
Lee Schermerhorn <lee.schermerhorn@hp.[...].com>
|
||||
Peter Schiffer <pschiffe@red[...].com>
|
||||
Benno Schulenberg <bensberg@jus[...].net>
|
||||
Michal Sekletar <msekleta@red[...].com>
|
||||
Michel Simoni <m_simoni@clu[...].fr>
|
||||
Gabrielle Singleton <gelle@umi[...].edu>
|
||||
Rod Skinner <rod.skinner@int[...].com>
|
||||
Kevin C. Smallwood <kcs@lin[...].com>
|
||||
Dick Snippe <Dick.Snippe@tec[...].nl>
|
||||
Alexis Solanas <alexis@red[...].com>
|
||||
Graham Swallow <gps@tri[...].uk>
|
||||
Mike Sweger <mikesw@whi[...].net>
|
||||
Julian Taylor <jtaylor.debian@goo[...].com>
|
||||
Don Totten <dontotten@ibm[...].net>
|
||||
Alexander Troosh <trush@yan[...].ru>
|
||||
Stephen Tweedie <sct@red[...].com>
|
||||
Petr Uzel <petr.uzel@sus[...].cz>
|
||||
Thomas Weber <TWEBER@de.[...].com>
|
||||
Yongjun Wei <yjwei@nan[...].com>
|
||||
Stefan Wild <SWILD@de.[...].com>
|
||||
Thomas Winn <tcwinn@gma[...].com>
|
||||
Mike Winter <mike.winter@usa[...].ca>
|
||||
Holger Wolf <Holger.Wolf@de.[...].com>
|
||||
Urban Widmark <urban@sve[...].se>
|
||||
Yu Yongcong <yuyc@cn.[...].com>
|
||||
Peter Zaitsev <pz@spy[...].ru>
|
||||
Zhen Zhang <furykerry@gma[...].com>
|
||||
|
||||
--
|
||||
Sebastien Godard (sysstat <at> orange.fr) is the author and the current
|
||||
maintainer of this package.
|
|
@ -0,0 +1,774 @@
|
|||
## Welcome to the sysstat's Frequently Asked Questions!
|
||||
|
||||
### Table of contents
|
||||
|
||||
**[1. General questions](#general)**
|
||||
|
||||
[1.1.](#1_1) When I compile sysstat, it fails with the following message: `make: msgfmt: Command not found`
|
||||
[1.2.](#1_2) When I try to compile sysstat, it fails and says it cannot find some include files.
|
||||
[1.3.](#1_3) I don't understand why sysstat displays the time sometimes as `HH:MM:SS` and sometimes as `HH:MM:SS AM/PM`...
|
||||
[1.4.](#1_4) What are the units actually used by sysstat commands?
|
||||
|
||||
**[2. Questions related to sar, sadc and sadf](#sar)**
|
||||
|
||||
[2.1.](#2_1) The sar command complains with the following message: `Invalid system activity file: ...`
|
||||
[2.2.](#2_2) The sar command complains with the following message: `Cannot append data to that file (...)`
|
||||
[2.3.](#2_3) The sar command complains with the following message: `Inconsistent input data`
|
||||
[2.4.](#2_4) I get the following error message when I try to run sar: `Cannot open /var/log/sa/sa30: No such file or directory`
|
||||
[2.5.](#2_5) Are sar daily data files fully compatible with Sun Solaris format sar files?
|
||||
[2.6.](#2_6) The `Average:` results from the sar command are just rubbish...
|
||||
[2.7.](#2_7) My database (e.g. MySQL) doesn't appear to understand the time zone displayed by 'sadf -d'...
|
||||
[2.8.](#2_8) I tried to use options -s and -e with sadf. Unfortunately, I have nothing displayed at all / the output doesn't match that of sar.
|
||||
[2.9.](#2_9) I cannot see all my disks when I use the sar -d command...
|
||||
[2.10.](#2_10) Do you know a tool which can graphically plot the data collected by sar?
|
||||
[2.11.](#2_11) When I launch sadc, I get the error message: `flock: Resource temporarily unavailable`
|
||||
[2.12.](#2_12) How should I run sysstat / sar so that I get a reading for `00:00:00`?
|
||||
[2.13.](#2_13) The sar command complains with the following message: `Requested activities not available in file ...`
|
||||
[2.14.](#2_14) Does sar need a lot of resources to run?
|
||||
[2.15.](#2_15) Are the measurements gathered by sadc cumulative or instantaneous?
|
||||
[2.16.](#2_16) Some fields are always displayed as `0.00` when I use the `sar -d` command.
|
||||
[2.17.](#2_17) The sar command complains with the following message: `Requested activities not available`
|
||||
[2.18.](#2_18) How can I keep sar data for more than one month?
|
||||
[2.19.](#2_19) How can I load sar data into an Oracle database for performance analysis and capacity planning?
|
||||
[2.20.](#2_20) The sar command displays some weird output values...
|
||||
[2.21.](#2_21) What happened to sar's options -h, -H, -x and -X?
|
||||
[2.22.](#2_22) What is the exact meaning of the `count` parameter for sar and sadc?
|
||||
[2.23.](#2_23) Why doesn't sar deal with sub-second sampling/monitoring?
|
||||
[2.24.](#2_24) Is it possible to make sadc save only some specific activities in my binary daily data files?
|
||||
[2.25.](#2_25) The sar and/or sadf command complain(s) with the following message: `End of system activity file unexpected`
|
||||
|
||||
**[3. Questions related to iostat](#iostat)**
|
||||
|
||||
[3.1.](#3_1) I can't see all my disks when I use the iostat command...
|
||||
[3.2.](#3_2) iostat -x doesn't report disk I/O statistics...
|
||||
[3.3.](#3_3) Why can't iostat display extended statistics for partitions with 2.6.x kernels?
|
||||
[3.4.](#3_4) I don't understand the output of iostat. It doesn't match what I expect it to be...
|
||||
[3.5.](#3_5) Why values displayed by iostat are so different in the first report from those displayed in subsequent ones?
|
||||
[3.6.](#3_6) iostat -x displays huge numbers for some fields...
|
||||
|
||||
**[4. Questions related to pidstat](#pidstat)**
|
||||
|
||||
[4.1.](#4_1) pidstat -d doesn't report task I/O statistics...
|
||||
[4.2.](#4_2) The pidstat command complains with the following message: `Requested activities not available`
|
||||
[4.3.](#4_3) pidstat doesn't display statistics for process (task) _xyz_...
|
||||
[4.4.](#4_4) I noticed that the total CPU utilization for threads running on an individual CPU can exceed 100%...
|
||||
|
||||
---
|
||||
|
||||
### 1. General questions<a name="general"></a>
|
||||
|
||||
1.1.<a name="1_1"></a> When I compile sysstat, it fails with the following message:
|
||||
```
|
||||
make: msgfmt: Command not found
|
||||
make: ***[locales] Error 127
|
||||
```
|
||||
A: The **msgfmt** command belongs to the GNU gettext package.
|
||||
If you don't have it on your system, just configure sysstat with NLS disabled like this:
|
||||
```
|
||||
$ ./configure --disable-nls
|
||||
```
|
||||
or answer 'y' (for "yes") to the question
|
||||
```
|
||||
Disable National Language Support (NLS)? (y/n) [--disable-nls]
|
||||
```
|
||||
if you use the Interactive Configuration script (_iconfig_),
|
||||
then compile sysstat as usual (make ; make install).
|
||||
|
||||
Please read the _README-nls_ file included in sysstat source package to learn
|
||||
some more about National Language Support.
|
||||
|
||||
---
|
||||
1.2.<a name="1_2"></a> When I try to compile sysstat, it fails and says it cannot find some include files:
|
||||
```
|
||||
In file included from /usr/include/bits/errno.h:25,
|
||||
from /usr/include/errno.h:36,
|
||||
from common.c:26:
|
||||
/usr/include/linux/errno.h:4: asm/errno.h: No such file or directory
|
||||
<SNIP>
|
||||
common.c: In function `get_kb_shift':
|
||||
common.c:180: `PAGE_SIZE' undeclared (first use in this function)
|
||||
common.c:178: warning: `size' might be used uninitialized in this function
|
||||
make: *** [common.o] Error 1
|
||||
```
|
||||
A: Make sure that you have the Linux kernel sources installed in
|
||||
`/usr/src/linux`. Also make sure that the symbolic link exists in the
|
||||
`/usr/src/linux/include` directory and points to the right architecture, e.g.:
|
||||
```
|
||||
# ll /usr/src/linux/include/asm
|
||||
lrwxrwxrwx 1 root root 8 May 5 18:31 /usr/src/linux/include/asm -> asm-i386
|
||||
```
|
||||
In fact, only the Linux kernel headers should be necessary to be able to compile sysstat.
|
||||
|
||||
---
|
||||
1.3.<a name="1_3"></a> I don't understand why sysstat displays the time sometimes as `HH:MM:SS` and sometimes as `HH:MM:SS AM/PM`...
|
||||
|
||||
A: The time format used by sysstat tools depends on the locale of your system.
|
||||
The locale is defined by several environment variables, among which the **LANG**
|
||||
variable is perhaps the most widely used. See the following example:
|
||||
```
|
||||
$ export LANG=en_US
|
||||
$ sar
|
||||
Linux 2.4.9 (brooks.seringas.fr) 07/20/04
|
||||
|
||||
04:32:11 PM LINUX RESTART
|
||||
|
||||
05:00:00 PM CPU %user %nice %system %iowait %idle
|
||||
05:10:00 PM all 0.24 0.00 89.64 0.00 10.12
|
||||
Average: all 0.24 0.00 89.64 0.00 10.12
|
||||
|
||||
$ export LANG=fr_FR
|
||||
$ sar
|
||||
Linux 2.4.9 (brooks.seringas.fr) 20.07.2004
|
||||
|
||||
16:32:11 LINUX RESTART
|
||||
|
||||
17:00:00 CPU %user %nice %system %iowait %idle
|
||||
17:10:00 all 0,24 0,00 89,64 0,00 10,12
|
||||
Moyenne: all 0,24 0,00 89,64 0,00 10,12
|
||||
```
|
||||
As you can notice, the time format but also the date, the decimal point, and
|
||||
even some words (like "Average") have changed according to the specified locale.
|
||||
|
||||
---
|
||||
|
||||
1.4.<a name="1_4"></a> What are the units actually used by sysstat commands?
|
||||
|
||||
|
||||
A: Although sysstat commands use the following abbreviations: kB, MB, etc.
|
||||
as part of the metrics names (e.g. kB_read/s, wkB/s, or even sometimes with a
|
||||
lower 'b': kbmemfree, kbavail...), and the manual pages speak of kilobytes,
|
||||
megabytes, etc., we always actually refer to kibibytes (kiB), mebibytes (MiB),...
|
||||
A kibibyte is equal to 1024 bytes, and a mebibyte is equal to 1024 kibibytes.
|
||||
Metrics names have been defined many years ago. We don't modify them to avoid
|
||||
breaking third-party programs parsing sysstat commands' output.
|
||||
|
||||
---
|
||||
### 2. Questions related to sar, sadc and sadf<a name="sar"></a>
|
||||
|
||||
2.1.<a name="2_1"></a> The sar command complains with the following message:
|
||||
```
|
||||
Invalid system activity file: ...
|
||||
```
|
||||
A: You are trying to use a file which is not a system activity file, or whose
|
||||
format is no longer compatible with that of files created by current version of sar.
|
||||
If you were trying to use the standard system activity files located in the
|
||||
`/var/log/sa` directory then the solution is easy: just log in as root and
|
||||
remove by hand all the files located in the `/var/log/sa` directory:
|
||||
```
|
||||
# rm /var/log/sa/sa??
|
||||
```
|
||||
If you are using sysstat 11.1.1 and later, you can also use the sadf command
|
||||
to convert an old system activity binary datafile (version 9.1.6 and later) to
|
||||
current up-to-date format. Use the following syntax:
|
||||
```
|
||||
$ sadf -c old_datafile > new_datafile
|
||||
```
|
||||
Note: Starting with sysstat version 8.1.1 and later, it is possible to
|
||||
know which version of sar or sadc has been used to create a data file.
|
||||
Just enter the following command:
|
||||
```
|
||||
$ sadf -H /your/datafile | grep sysstat
|
||||
File created using sar/sadc from sysstat version 8.1.7
|
||||
```
|
||||
|
||||
---
|
||||
2.2.<a name="2_2"></a> The sar command complains with the following message:
|
||||
```
|
||||
Cannot append data to that file (...)
|
||||
```
|
||||
A: The internal structure of the data file does not allow sar to append
|
||||
data to it. The data file may come from another machine, or the components
|
||||
of the current box, such as the number of processors, may have changed.
|
||||
Use another data file, or delete the current daily data file, and try again.
|
||||
With sysstat version 10.1.3 and later, it is now possible to append data
|
||||
to a data file even if the number of processors has changed. But first,
|
||||
you have to make the data file aware of this change by inserting a restart
|
||||
mark (this is typically done when sadc is called at system restart). You
|
||||
can then append data to the data file as usual.
|
||||
|
||||
---
|
||||
2.3.<a name="2_3"></a> The sar command complains with the following message:
|
||||
```
|
||||
Inconsistent input data
|
||||
```
|
||||
A: This error message means that sadc (the system activity data collector that
|
||||
sar is using) is not consistent with the sar command. In most cases this is
|
||||
because the sar and sadc commands do not belong to the same release of the
|
||||
sysstat package. Remember that sar may search for sadc in predefined
|
||||
directories (`/usr/local/lib/sa`, `/usr/lib/sa`, ...) before looking in the
|
||||
current directory!
|
||||
With sysstat version 11.1.5 and later, enter `sar --sadc`
|
||||
to determine which data collector is called by sar.
|
||||
|
||||
---
|
||||
2.4.<a name="2_4"></a> I get the following error message when I try to run sar:
|
||||
```
|
||||
Cannot open /var/log/sa/sa30: No such file or directory
|
||||
```
|
||||
A: Please read the sar(1) manual page! Daily data files are created by default
|
||||
in the `/var/log/sa` directory using the data collector (sadc) or using
|
||||
option -o with sar. Once they are created, sar can display statistics
|
||||
saved in those files.
|
||||
But sar can also display statistics collected "on the fly": Just enter
|
||||
the proper options on the command line to indicate which statistics are
|
||||
to be displayed, and also specify `interval` and `count` numbers, e.g.:
|
||||
```
|
||||
# sar 2 5 --> will report CPU utilization every two seconds, five times.
|
||||
# sar -n DEV 3 --> will report network device utilization every 3 seconds, in an infinite loop.
|
||||
```
|
||||
|
||||
---
|
||||
2.5.<a name="2_5"></a> Are sar daily data files fully compatible with Sun Solaris format
|
||||
sar files?
|
||||
|
||||
|
||||
A: No, the format of the binary data files created by sysstat's sar command
|
||||
is not compatible with formats from other Unixes, because it contains
|
||||
data which are closely linked to Linux.
|
||||
For the same reason, sysstat cannot work on platforms other than Linux...
|
||||
|
||||
---
|
||||
2.6.<a name="2_6"></a> The `Average:` results from the sar command are just rubbish, e.g.:
|
||||
```
|
||||
11:00:00 AM CPU %user %nice %system %idle
|
||||
11:10:00 AM all 0.54 0.00 0.89 98.57
|
||||
11:20:01 AM all 3.02 8.05 22.85 66.08
|
||||
11:30:01 AM all 8.15 0.00 2.31 89.54
|
||||
11:40:01 AM all 8.03 0.00 2.42 89.55
|
||||
11:50:01 AM all 16.04 0.00 2.81 81.16
|
||||
12:00:00 PM all 21.11 0.00 3.23 75.66
|
||||
03:40:01 PM all 100.01 100.01 100.01 0.00
|
||||
04:40:00 PM all 100.00 0.00 100.00 0.00
|
||||
04:50:00 PM all 5.87 0.00 1.26 92.87
|
||||
05:00:00 PM all 4.70 0.00 1.48 93.82
|
||||
05:10:00 PM all 4.93 0.00 1.29 93.78
|
||||
Average: all 100.22 100.20 100.13 0.00
|
||||
```
|
||||
A: Your sar command was not installed properly. Whenever your computer
|
||||
is restarted (as it is the case here between `12:00:00 PM` and `03:40:01 PM`),
|
||||
the `sysstat` shell script must be called by the system, so that the
|
||||
LINUX RESTART message can be inserted into the daily data file, indicating
|
||||
that the relevant kernel counters have been reinitialized...
|
||||
You can install the `sysstat` script by hand in the relevant startup
|
||||
directory, or you can ask sysstat to do it for you during configuration
|
||||
stage by entering:
|
||||
```
|
||||
$ ./configure --enable-install-cron
|
||||
```
|
||||
Or you can answer 'y' to the question:
|
||||
```
|
||||
Set crontab to start sar automatically? (y/n) [--enable-install-cron]
|
||||
```
|
||||
if you use the Interactive Configuration script (iconfig).
|
||||
Then compile sysstat as usual and run 'make install' as the last stage.
|
||||
|
||||
---
|
||||
2.7.<a name="2_7"></a> My database (e.g. MySQL) doesn't appear to understand the time zone
|
||||
displayed by 'sadf -d'...
|
||||
|
||||
|
||||
A: The format includes the timezone detail in the output. This is to make
|
||||
sure it is communicated clearly that UTC is how the data is always
|
||||
converted and printed. Moreover we don't depend on the TZ environment
|
||||
variable and we don't have some data converted to a different timezone
|
||||
for any reason, known or unknown.
|
||||
When you deal with raw accounting data you always want it in UTC.
|
||||
Of course, you want it to all be the same when loading into a database.
|
||||
If your database can't deal with timezones, you should write a short script
|
||||
to strip the "UTC" characters from the data being loaded into the database.
|
||||
|
||||
---
|
||||
2.8.<a name="2_8"></a> I tried to use options -s and -e with sadf. Unfortunately, I have
|
||||
nothing displayed at all / the output doesn't match that of sar.
|
||||
|
||||
|
||||
A: The way how options -s and -e are interpreted has changed with sysstat's
|
||||
versions.
|
||||
First if you don't have any data displayed by sadf, this is because no data
|
||||
belong to the specified time interval! Up to sysstat version 12.1.4, the
|
||||
time specified with options -s and -e was always considered as being given
|
||||
in local time to be consistent with sar's default output. Yet sadf displays
|
||||
its timestamps in UTC (Coordinated Universal Time) by default (and in local
|
||||
time with option -T). This could lead to some misunderstandings, as if sadf's
|
||||
options -s and -e didn't work properly.
|
||||
So with sysstat version 12.1.5, the time specified with options -s and -e
|
||||
is now consistent with the timestamps displayed by sadf (either in UTC by
|
||||
default or in local time with option -T), even if the output doesn't match
|
||||
that of sar.
|
||||
|
||||
---
|
||||
2.9.<a name="2_9"></a> I cannot see all my disks when I use the sar -d command...
|
||||
|
||||
|
||||
A: See question "I can't see all my disks when I use the iostat command" below.
|
||||
|
||||
---
|
||||
2.10.<a name="2_10"></a> Do you know a tool which can graphically plot the data collected by sar?
|
||||
|
||||
|
||||
A: You can now draw graphs with sysstat's standard tools!
|
||||
SVG (Scalable Vector Graphics) is a new output format that has been added to
|
||||
sadf in sysstat version 11.3.1. Read sadf(1) manual page to learn some more
|
||||
about this new format.
|
||||
There are other tools lying around on the internet that you can use to draw
|
||||
some graphs. I haven't tested all of them and there must still be some
|
||||
way for improvement... First, some of them are included in the sysstat
|
||||
package although they are no longer maintained: isag (a Perl script) or
|
||||
sargraph (a shell script).
|
||||
You can also find: kSar (a Java application capable of visualizing a sar file
|
||||
with static graphs), sarjitsu (a more sophisticated application producing
|
||||
dynamic visualizations based on Grafana), sarvant, sar2gp, loadgraph,
|
||||
SysStat Charts, sarplot...
|
||||
[rrd.cgi](http://haroon.easi.utoronto.ca/rrd/scripts/) is a perl front-end for
|
||||
rrdtool and can be used to make some graphs (see a demo [here](http://haroon.easi.utoronto.ca/perl/rrd.cgi/sar_stats/)).
|
||||
[sysstat_mail_report](https://github.com/desbma/sysstat_mail_report) is a script
|
||||
that automatically generates and sends an email report every day/week/month
|
||||
with graphs generated from sysstat data.
|
||||
I've also heard of commercial tools which use sysstat: PerfMan comes to mind,
|
||||
among others.
|
||||
|
||||
---
|
||||
2.11.<a name="2_11"></a> When I launch sadc, I get the error message:
|
||||
```
|
||||
flock: Resource temporarily unavailable
|
||||
```
|
||||
A: You are launching sadc using -L option. With this option, sadc tries to
|
||||
get an exclusive lock on the output file. The above error message indicates
|
||||
that another sadc process was running and had already locked the same output
|
||||
file. Stop all sadc instances and try again.
|
||||
|
||||
---
|
||||
2.12.<a name="2_12"></a> I have sysstat setup to run via cron:
|
||||
```
|
||||
0 * * * * /usr/local/lib/sa/sa1 600 6
|
||||
```
|
||||
so that I get an activity report every 10 minutes.
|
||||
When I use sar to get my output, there is no reading for `00:00:00`. This
|
||||
means that at midnight every night there is a spike, or dip, in the graphs.
|
||||
How should I run sysstat / sar so that I get a reading for `00:00:00`?
|
||||
|
||||
|
||||
A: Sysstat does get its data at midnight, but two data samples are needed to
|
||||
display the values.
|
||||
When there is a "file rotation" (beginning of a new day), sadc writes its data
|
||||
at the end of the previous daily data file (`/var/log/sa/sa<DD>`) **and** at the
|
||||
beginning of the new one (`/var/log/sa/sa<DD+1>`). Please note that '-' must be
|
||||
used to specify the output file for sadc to be able to detect such a file
|
||||
rotation. So a crontab like the following one should enable you to get the
|
||||
data for midnight at the end of each daily data file:
|
||||
```
|
||||
# Activity reports every 10 minutes from 01:00:00 to 22:50:00
|
||||
0 1-22 * * * /usr/local/lib/sa/sa1 600 6
|
||||
# Activity reports every 10 minutes from 23:00:00 to 00:00:00
|
||||
# Reporting until 00:00:00 ensures that a file rotation will be detected
|
||||
# by sadc
|
||||
0 23 * * * /usr/local/lib/sa/sa1 600 7
|
||||
# Activity reports every 10 minutes from 00:10:00 to 00:50:00
|
||||
10 0 * * * /usr/local/lib/sa/sa1 600 5
|
||||
```
|
||||
Another possible crontab would be:
|
||||
```
|
||||
*/10 1-22 * * * /usr/lib/sa/sa1 1 1
|
||||
0,10,20,30,40 23 * * * /usr/lib/sa/sa1 1 1
|
||||
50 23 * * * /usr/lib/sa/sa1 600 2
|
||||
10,20,30,40,50 0 * * * /usr/lib/sa/sa1 1 1
|
||||
```
|
||||
Things are much easier with recent sysstat versions (12.5.1 and later): You simply have to run
|
||||
sa1 with its option `--rotate` shortly after midnight to add a statistics record to the system
|
||||
activity daily data file of the previous day. So your full crontab could be:
|
||||
```
|
||||
# Rotate file at midnight
|
||||
0 0 * * * /usr/lib/sa/sa1 --rotate
|
||||
# Run system activity accounting tool every 10 minutes
|
||||
0,10,20,30,40,50 * * * * /usr/lib/sa/sa1 1 1
|
||||
# Generate a text summary of previous day process accounting at 00:07
|
||||
7 0 * * * /usr/lib/sa/sa2 -A
|
||||
```
|
||||
|
||||
---
|
||||
2.13.<a name="2_13"></a> The sar command complains with the following message:
|
||||
```
|
||||
Requested activities not available in file ...
|
||||
```
|
||||
A: This error message means that you are trying to extract non-existent activities
|
||||
from the data file. Usually sadc reads all the available activities from the
|
||||
system and stores them in the data file. However, to prevent data files from
|
||||
taking too much space on disk, some activities must be explicitly set on the
|
||||
command line to be read by sadc.
|
||||
To tell sadc that an optional activity should be collected, use switch -S
|
||||
followed by the keyword corresponding to that activity (see sadc(8) manual page).
|
||||
As of this writing, optional activities are: interrupts, disks, SNMP, IPv6 and
|
||||
power management statistics.
|
||||
IMPORTANT NOTE: The list of activities that are saved in a file can no longer
|
||||
be modified once the file has been created. So it is important to use the proper
|
||||
options the first time sadc is called (whether via a crontab, a script like
|
||||
sa1 or even the script used to insert a RESTART message when the machine is
|
||||
rebooted).
|
||||
NB: If the sar command complains with the error message:
|
||||
```
|
||||
Requested activities not available
|
||||
```
|
||||
(without mentioning `in file`), then see question 2.17 below.
|
||||
|
||||
---
|
||||
2.14.<a name="2_14"></a> Does sar need a lot of resources to run?
|
||||
|
||||
|
||||
A: No, sar doesn't need a lot of CPU to run, nor does it make your system slow,
|
||||
contrary to what some people think. In the first place, it only runs every ten
|
||||
minutes by default. Secondly, when it does run, it is over and done very
|
||||
quickly. Try:
|
||||
```
|
||||
$ time /usr/lib/sa/sa1
|
||||
```
|
||||
to verify that for yourself.
|
||||
Nor do you have to be concerned about using up all your disk space.
|
||||
sar will use a few hundred kilobytes for a whole day's worth of data, and it
|
||||
normally only stores one week worth (this can be configured via the HISTORY
|
||||
variable in the `/etc/sysconfig/sysstat` file). It is entirely self limiting.
|
||||
Moreover, you can ask sar to compress its datafiles older than a certain
|
||||
number of days: see the COMPRESSAFTER parameter in the `/etc/sysconfig/sysstat`
|
||||
configuration file.
|
||||
|
||||
---
|
||||
2.15.<a name="2_15"></a> Are the measurements gathered by sadc cumulative or instantaneous values?
|
||||
|
||||
|
||||
A: Each counter maintained by the kernel is cumulative since system boot. As a
|
||||
consequence the measurements gathered by sadc are cumulative values.
|
||||
Moreover all per-second statistics displayed by sar are average values on the
|
||||
given time interval. So the value for counter foo at time T is calculated as:
|
||||
```
|
||||
foo/s = [foo(T) - foo(T-dt)] / dt
|
||||
```
|
||||
where dt is the interval given on the command line.
|
||||
|
||||
---
|
||||
2.16.<a name="2_16"></a> Some fields are always displayed as 0.00 when I use the sar -d
|
||||
command.
|
||||
|
||||
|
||||
A: See question 3.2 below.
|
||||
|
||||
---
|
||||
2.17.<a name="2_17"></a> The sar command complains with the following message:
|
||||
```
|
||||
Requested activities not available
|
||||
```
|
||||
A: This error message means that you are trying to display activities that the
|
||||
kernel itself is unable to provide.
|
||||
When this error message is displayed while trying to save the data into an
|
||||
existing file (`sar -o datafile ...`), this may also be because the target
|
||||
file cannot accept the requested activities. In this case, just try to use
|
||||
another file or create a new one. See also question 2.13 above.
|
||||
|
||||
---
|
||||
2.18.<a name="2_18"></a> How can I keep sar data for more than one month?
|
||||
|
||||
|
||||
A: By default sar saves its data in the standard system activity data file,
|
||||
the `/var/log/sa/saDD` file, where DD is the current day in the month.
|
||||
To prevent sar from overwriting any existing files, just set the variable
|
||||
HISTORY in `/etc/sysconfig/sysstat` to the number of days during which data
|
||||
must be kept. When this variable has a value greater than 28, sa1 script
|
||||
uses a month-by-month directory structure; datafiles are named `YYYYMM/saDD`
|
||||
and the script maintains links to these datafiles to mimic the standard
|
||||
sar datafile structure. However please note that pre-existing datafiles
|
||||
will be deleted as links will be created and replace them.
|
||||
Beginning with sysstat version 11.0.0, this tree of directories is no
|
||||
longer created. When HISTORY has a value greater than 28, sa1 now calls
|
||||
sadc with option -D set, telling it to use `saYYYYMMDD` instead of `saDD`
|
||||
as the name for the standard system activity daily data files, where
|
||||
YYYY stands for the current year, MM for the current month and DD for
|
||||
the current day. All these files are saved in the same directory
|
||||
(`/var/log/sa` by default).
|
||||
|
||||
---
|
||||
2.19.<a name="2_19"></a> How can I load sar data into an Oracle database for performance
|
||||
analysis and capacity planning?
|
||||
|
||||
|
||||
A: The simplest way for that is to use sadf (a command included in sysstat
|
||||
package) with its option -d. It displays sar data in a format that can
|
||||
easily be ingested by a relational database system (fields are separated
|
||||
by a semicolon). It should then be easy for a tool like SQL*Loader to
|
||||
load the data into the Oracle database.
|
||||
|
||||
---
|
||||
2.20.<a name="2_20"></a> The sar command displays some weird CPU values, e.g.:
|
||||
```
|
||||
10:50:01 AM CPU %user %nice %system %iowait %idle
|
||||
11:00:01 AM all 90.90 0.00 5.17 3.93 0.00
|
||||
11:00:01 AM 0 39.40 0.00 2.37 2.07 56.17
|
||||
11:00:01 AM 1 29.71 0.00 1.73 1.17 67.39
|
||||
11:00:01 AM 2 42.69 0.00 2.34 1.11 53.85
|
||||
11:00:01 AM 3 26.24 0.00 1.41 1.61 70.74
|
||||
...
|
||||
```
|
||||
A: Sysstat may have met an overflow condition while reading CPU usage from
|
||||
your /proc/stat file. This condition is all the more likely to happen as
|
||||
your machine uptime is high and/or there are many processors.
|
||||
Sysstat up to version 5.0.6 uses 32-bit integer variables to store CPU usage.
|
||||
Then, beginning with version 5.1.1, sysstat has shifted to 64-bit variables,
|
||||
which has fixed the problem. So try to upgrade your version of sysstat to
|
||||
the latest stable release and check that the problem has gone.
|
||||
Also see question 2.6 above.
|
||||
|
||||
---
|
||||
2.21.<a name="2_21"></a> What happened to sar's options -h, -H, -x and -X?
|
||||
|
||||
|
||||
A: These old options have been removed from sar because new commands have been
|
||||
made available. You should now use the sadf command instead of sar -h or
|
||||
sar -H, and the pidstat command instead of sar -x or sar -X. Please read
|
||||
their manual page to learn some more about their respective options.
|
||||
|
||||
---
|
||||
2.22.<a name="2_22"></a> What is the exact meaning of the `count` parameter for sar and sadc?
|
||||
|
||||
|
||||
A: For sadc, `count` is the number of data samples collected.
|
||||
For sar, `count` is the number of records to display (a record contains
|
||||
the average values for counters over the given time interval - See 2.15).
|
||||
|
||||
|
||||
Starting with an empty file `datafile`:
|
||||
```
|
||||
sadc datafile 1 6 will write 6 data samples to datafile.
|
||||
sar -f datafile 1 6 6 is invalid because there are only 5 intervals.
|
||||
```
|
||||
Based on the `count` value entered for sadc the "valid" `count` values for
|
||||
sar are 1 through 5. Any value greater than 5 for sar will give the
|
||||
same output as 5 in this example. So entering `sar -f datafile 1 2000`
|
||||
for a file populated with the output of `sadc 1 6 datafile` will give the
|
||||
same output as `sar -f datafile 1 5`. Note that it all depends on the number
|
||||
of data samples pre-existing in the data file. If the file is empty
|
||||
when first running sadc then the above is true.
|
||||
|
||||
---
|
||||
2.23.<a name="2_23"></a> Why doesn't sar deal with sub-second sampling/monitoring?
|
||||
|
||||
|
||||
A: There are two reasons for sar to not handle sub-second intervals:
|
||||
|
||||
|
||||
1) This is not sar's purpose. sar has been created to give the
|
||||
sys admin a global overview of its machine daily utilization so
|
||||
that when a problem happens, he has a benchmark and can compare
|
||||
the statistics gathered by sar with those saved before. For that
|
||||
reason an interval of 10 minutes (which is the default for sar) is
|
||||
quite appropriate.
|
||||
|
||||
|
||||
2) Because this is just a dumb idea to try to gather a huge amount
|
||||
of data on a sub-second interval basis (and sar really collects
|
||||
a lot of data). This can be resource-consuming and you are all the
|
||||
more prone to have an influence on the data you are retrieving as
|
||||
the interval of time is small.
|
||||
|
||||
---
|
||||
2.24.<a name="2_24"></a> Is it possible to make sadc save only some specific activities
|
||||
in my binary daily data files?
|
||||
|
||||
|
||||
A: sadc's option -S followed by one or more keywords (DISK, SNMP...)
|
||||
can already be used to specify which optional activities are to be
|
||||
collected. Without this option, sadc collects a default set of
|
||||
activities (CPU activity, memory activity, network activity, etc.)
|
||||
Yet it is actually possible to specify explicitly which activities
|
||||
should be collected by sadc! You have to use sadc's option -S
|
||||
followed by the report name corresponding to the activity you want
|
||||
to collect (enter "sar --help" to know the formal report names
|
||||
used by sadc).
|
||||
Example: To tell sadc to collect only temperature sensors activity
|
||||
in addition to the default set of activities, enter:
|
||||
|
||||
```
|
||||
sadc -S A_PWR_TEMP (...)
|
||||
```
|
||||
|
||||
followed by the other classic options (interval, count, filename...)
|
||||
Now assume you want to collect temperature sensors activity **without**
|
||||
the other activities collected by default,
|
||||
add the special report name A_NULL to the list passed to sadc, e.g.:
|
||||
```
|
||||
sadc -S A_NULL,A_PWR_TEMP (...)
|
||||
```
|
||||
Of course you can enter as many report names as you want to collect
|
||||
different activities.
|
||||
Last you can exclude a specific activity from a list by prefixing its
|
||||
report name with a dash. For example, to collect all possible activities
|
||||
**except** statistics for interrupts, enter:
|
||||
```
|
||||
sadc -S XALL,-A_IRQ (...)
|
||||
```
|
||||
This way you can tell sadc to collect only the desired activities.
|
||||
|
||||
---
|
||||
2.25.<a name="2_25"></a> The sar and/or sadf command complain(s) with the following message:
|
||||
```
|
||||
End of system activity file unexpected
|
||||
```
|
||||
A: sadc, the data collector, was unable to write all its data to the
|
||||
system activity data file (`/var/log/sa/saDD` by default).
|
||||
This is probably because there was no space left on the device where
|
||||
the data file is located.
|
||||
Make sure there is enough free space on the device. Sometimes it seems
|
||||
there is enough free space but there may be some jobs run by crontab
|
||||
(particularly during the night) that can temporarily consume all of
|
||||
your free space, making sadc fail.
|
||||
|
||||
Another reason could be linked to the system activity daily data file
|
||||
being corrupted. This could possibly happen when several instances of
|
||||
sadc are trying to update the same data file, especially around midnight
|
||||
when making a file rotation. See question 2.12 to know how to make such
|
||||
a file rotation properly.
|
||||
|
||||
Last this issue can also be triggered when the system is rebooted forcibly
|
||||
without data in cache being written to disk. You can use switch -f with sadc
|
||||
to make sure data are written to disk immediately. Of course sync'ing each
|
||||
data sample to disk implies a (probably slight) performance penalty.
|
||||
|
||||
---
|
||||
### 3. Questions related to iostat<a name="iostat"></a>
|
||||
|
||||
3.1.<a name="3_1"></a> I can't see all my disks when I use the iostat command...
|
||||
|
||||
|
||||
A: Yes. This is a kernel limit. Old kernels (2.2.x for instance) used to
|
||||
maintain stats for the first four devices.
|
||||
The accounting code has changed in 2.4 kernels, and the result may (or
|
||||
may not) be better for your system. Indeed, Linux 2.4 maintains the stats
|
||||
in a two dimensional array, with a maximum of 16 devices (DK_MAX_DISK
|
||||
in the kernel sources). Moreover, if the device major number exceeds
|
||||
DK_MAX_MAJOR (whose value also defaults to 16 in the kernel sources),
|
||||
then stats for this device will not be collected.
|
||||
So, a solution may be simply to change the values of these limits in
|
||||
linux/include/linux/kernel_stat.h and recompile your kernel.
|
||||
You should no longer have any problem with post 2.5 kernels, since
|
||||
statistics are maintained by the kernel for all the devices.
|
||||
In the particular case of iostat, also be sure to use the ALL keyword
|
||||
on the command line to display statistical information relating to
|
||||
every device, including those that are defined but have never been used
|
||||
by the system.
|
||||
|
||||
---
|
||||
3.2.<a name="3_2"></a> iostat -x doesn't report disk I/O statistics...
|
||||
|
||||
|
||||
A: For `iostat -x` to be able to report extended disk I/O statistics,
|
||||
it is better to use a recent version of the Linux kernel (2.6.x).
|
||||
Indeed, iostat tries to read data from the `/proc/diskstats` file or
|
||||
from the sysfs filesystem for that.
|
||||
But iostat may also be able to display extended statistics with
|
||||
older kernels (e.g. 2.4.x) providing that all the necessary
|
||||
statistical information is available in the /proc/partitions file,
|
||||
which requires that a patch be applied to the kernel (this is
|
||||
often done on kernels included in various distros). In recent 2.4.x
|
||||
kernels, the /proc/partitions file has all the necessary data
|
||||
providing that the kernel has been compiled with CONFIG_BLK_STATS=y.
|
||||
|
||||
---
|
||||
3.3.<a name="3_3"></a> Why can't iostat display extended statistics for partitions with
|
||||
some 2.6.x kernels?
|
||||
|
||||
|
||||
A: Because the kernel maintains these stats only for devices, and not for
|
||||
partitions! Here is an excerpt from the document iostats.txt included in
|
||||
the kernel source documentation:
|
||||
```
|
||||
There were significant changes between 2.4 and 2.6 in the I/O subsystem.
|
||||
As a result, some statistic information disappeared. The translation from
|
||||
a disk address relative to a partition to the disk address relative to
|
||||
the host disk happens much earlier. All merges and timings now happen
|
||||
at the disk level rather than at both the disk and partition level as
|
||||
in 2.4. Consequently, you'll see a different statistics output on 2.6 for
|
||||
partitions from that for disks.
|
||||
```
|
||||
Extended I/O statistics for partitions are available again with kernels
|
||||
2.6.25 and later.
|
||||
|
||||
---
|
||||
3.4.<a name="3_4"></a> I don't understand the output of iostat. It doesn't match what I expect it
|
||||
to be...
|
||||
|
||||
|
||||
A: By default iostat displays I/O activity in blocks per second. With old
|
||||
kernels (i.e. older than 2.4.x) a block is of indeterminate size and therefore
|
||||
the displayed values are not useful.
|
||||
With recent kernels (kernels 2.4 and later), iostat is now able to get disk
|
||||
activities from the kernel expressed in a number of sectors. If you take a
|
||||
look at the kernel code, the sector size is actually allowed to vary although
|
||||
I have never seen anything other than 512 bytes.
|
||||
|
||||
---
|
||||
3.5.<a name="3_5"></a> Why values displayed by iostat are so different in the first report
|
||||
from those displayed in subsequent ones?
|
||||
|
||||
|
||||
A: Probably because, as written in the manual page, the first report generated
|
||||
by iostat concerns the time since system startup, whereas subsequent ones
|
||||
cover only the time since the previous report (that is to say, the interval
|
||||
of time entered on the command line).
|
||||
|
||||
---
|
||||
3.6.<a name="3_6"></a> iostat -x displays huge numbers for some fields...
|
||||
|
||||
|
||||
A: Because of a Linux kernel bug, iostat -x may display huge I/O response times
|
||||
(svctm) and a bandwidth utilization (%util) of 100% for some devices. Indeed
|
||||
these devices have a value for the field #9 (beginning after the device name)
|
||||
in `/proc/{partitions,diskstats}` which is always different from 0, and even
|
||||
negative sometimes. Yet this field should go to zero, since it gives the
|
||||
number of I/Os currently in progress (it is incremented as requests are
|
||||
submitted, and decremented as they finish).
|
||||
To (temporarily) fix the problem, you should reboot your system to reset the
|
||||
counters in `/proc/{partitions,diskstats}`.
|
||||
|
||||
---
|
||||
### 4. Questions related to pidstat<a name="pidstat"></a>
|
||||
|
||||
4.1.<a name="4_1"></a> pidstat -d doesn't report task I/O statistics...
|
||||
|
||||
|
||||
A: For pidstat -d to be able to report I/O statistics for tasks, you need
|
||||
a recent Linux kernel (2.6.20 or later) with the option
|
||||
CONFIG_TASK_IO_ACCOUNTING compiled in.
|
||||
|
||||
---
|
||||
4.2.<a name="4_2"></a> The pidstat command complains with the following message:
|
||||
```
|
||||
Requested activities not available
|
||||
```
|
||||
A: This message is displayed when the pidstat command is unable to display
|
||||
the statistics you have requested. This may happen when you try to display
|
||||
statistics for child processes (option -T CHILD) because all options of
|
||||
pidstat don't necessarily work for child processes. Read the manual page
|
||||
to know which statistics are available for child processes.
|
||||
|
||||
---
|
||||
4.3.<a name="4_3"></a> pidstat doesn't display statistics for process (task) _xyz_...
|
||||
|
||||
|
||||
A: This must be because pidstat only displays statistics for active tasks
|
||||
by default. If you don't use option -p on the command line, then pidstat
|
||||
will display only tasks with non-zero statistics. For example, `pidstat -u`
|
||||
will display only tasks that have actually used some CPU resources since
|
||||
system startup. You should enter `pidstat -u -p ALL` to make sure that all
|
||||
the processes are listed in the report.
|
||||
|
||||
---
|
||||
4.4.<a name="4_4"></a> I noticed that the total CPU utilization for threads running on
|
||||
an individual CPU can exceed 100%...
|
||||
|
||||
|
||||
A: The CPU number displayed by pidstat is the CPU to which the task is attached
|
||||
when the statistics are actually displayed. This doesn't mean that the task
|
||||
has spent its whole interval of time attached to it. Hence the CPU ressource
|
||||
used by a thread on an interval of time as displayed by pidstat may have
|
||||
concerned several processors.
|
||||
|
||||
---
|
||||
Sebastien Godard (sysstat at orange dot fr) is the author and the current
|
||||
maintainer of this package.
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
will cause the specified gcc to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
|
@ -0,0 +1,884 @@
|
|||
# Makefile to build sysstat commands
|
||||
# (C) 1999-2021 Sebastien GODARD (sysstat <at> orange.fr)
|
||||
|
||||
# Version and package name
|
||||
VERSION = @PACKAGE_VERSION@
|
||||
PACKAGE = @PACKAGE_NAME@
|
||||
# Needed by docdir
|
||||
PACKAGE_TARNAME = $(PACKAGE)-$(VERSION)
|
||||
|
||||
# Compiler to use
|
||||
CC = @CC@
|
||||
|
||||
# Other commands
|
||||
CHMOD = @CHMOD@
|
||||
CHOWN = @CHOWN@
|
||||
LN_S = @LN_S@
|
||||
AR = @AR@
|
||||
# Full path to prevent from using aliases
|
||||
CP = @PATH_CP@
|
||||
|
||||
CHKCONFIG = @PATH_CHKCONFIG@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_BIN = @INSTALL_BIN@
|
||||
|
||||
ifndef HAVE_SENSORS
|
||||
HAVE_SENSORS = @HAVE_SENSORS@
|
||||
endif
|
||||
LFSENSORS =
|
||||
DFSENSORS =
|
||||
ifeq ($(HAVE_SENSORS),y)
|
||||
LFSENSORS = @LFSENSORS@
|
||||
DFSENSORS = @DFSENSORS@
|
||||
endif
|
||||
ifndef HAVE_SENSORS32
|
||||
HAVE_SENSORS32 = @HAVE_SENSORS32@
|
||||
endif
|
||||
LFSENSORS32 =
|
||||
DFSENSORS32 =
|
||||
ifeq ($(HAVE_SENSORS32),y)
|
||||
LFSENSORS32 = @LFSENSORS32@
|
||||
DFSENSORS32 = @DFSENSORS32@
|
||||
endif
|
||||
|
||||
HAVE_PCP = @HAVE_PCP@
|
||||
LFPCP =
|
||||
DFPCP =
|
||||
ifeq ($(HAVE_PCP),y)
|
||||
LFPCP = @LFPCP@
|
||||
DFPCP = @DFPCP@
|
||||
endif
|
||||
|
||||
# Directories
|
||||
ifndef PREFIX
|
||||
PREFIX = @prefix@
|
||||
endif
|
||||
ifndef DESTDIR
|
||||
DESTDIR = $(RPM_BUILD_ROOT)
|
||||
endif
|
||||
# These two variables are needed by other ones (eg bindir)
|
||||
prefix = $(PREFIX)
|
||||
exec_prefix = @exec_prefix@
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
ifndef SA_LIB_DIR
|
||||
SA_LIB_DIR = @SA_LIB_DIR@
|
||||
endif
|
||||
SADC_PATH = $(SA_LIB_DIR)/sadc
|
||||
ifndef SA_DIR
|
||||
SA_DIR = @SA_DIR@
|
||||
endif
|
||||
BIN_DIR = @bindir@
|
||||
|
||||
ifndef MAN_DIR
|
||||
# With recent versions of autoconf, mandir defaults to ${datarootdir}/man
|
||||
# (i.e. $prefix/share/man)
|
||||
MAN_DIR = @mandir@
|
||||
endif
|
||||
MAN1_DIR = $(MAN_DIR)/man1
|
||||
MAN5_DIR = $(MAN_DIR)/man5
|
||||
MAN8_DIR = $(MAN_DIR)/man8
|
||||
|
||||
ifndef DOC_DIR
|
||||
DOC_DIR = @docdir@
|
||||
endif
|
||||
|
||||
NLS_DIR = $(PREFIX)/share/locale
|
||||
|
||||
ifndef SYSCONFIG_DIR
|
||||
SYSCONFIG_DIR = @SYSCONFIG_DIR@
|
||||
endif
|
||||
ifndef SYSCONFIG_FILE
|
||||
SYSCONFIG_FILE = @SYSCONFIG_FILE@
|
||||
endif
|
||||
|
||||
# Compiler flags
|
||||
ifndef CFLAGS
|
||||
CFLAGS = @CFLAGS@
|
||||
endif
|
||||
CFLAGS += -Wall -Wstrict-prototypes -pipe -O2
|
||||
|
||||
ifndef DFLAGS
|
||||
DFLAGS = @DFLAGS@
|
||||
endif
|
||||
DFLAGS += -DSA_DIR=\"$(SA_DIR)\" -DSADC_PATH=\"$(SADC_PATH)\"
|
||||
DFLAGS += $(DFSENSORS) $(DFSENSORS32)
|
||||
DFLAGS += $(DFPCP)
|
||||
ifdef TFLAGS
|
||||
DFLAGS += $(TFLAGS)
|
||||
endif
|
||||
|
||||
ifndef LFLAGS
|
||||
LFLAGS = @STRIP@ @LDFLAGS@
|
||||
endif
|
||||
|
||||
# Commands
|
||||
ifndef MSGFMT
|
||||
MSGFMT = @MSGFMT@
|
||||
endif
|
||||
ifndef XGETTEXT
|
||||
XGETTEXT = @XGETTEXT@
|
||||
endif
|
||||
ifndef MSGMERGE
|
||||
MSGMERGE = @MSGMERGE@
|
||||
endif
|
||||
ifndef ZIP
|
||||
ZIP = @ZIP@
|
||||
endif
|
||||
|
||||
# Settings
|
||||
SYSMACROS = @SYSMACROS@
|
||||
ifeq ($(SYSMACROS),y)
|
||||
DFLAGS += -DHAVE_SYS_SYSMACROS_H
|
||||
endif
|
||||
LINUX_SCHED = @LINUX_SCHED@
|
||||
ifeq ($(LINUX_SCHED),y)
|
||||
DFLAGS += -DHAVE_LINUX_SCHED_H
|
||||
endif
|
||||
PCP_IMPL = @PCP_IMPL@
|
||||
ifeq ($(PCP_IMPL),y)
|
||||
DFLAGS += -DHAVE_PCP_IMPL_H
|
||||
endif
|
||||
SYSPARAM = @SYSPARAM@
|
||||
ifeq ($(SYSPARAM),y)
|
||||
DFLAGS += -DHAVE_SYS_PARAM_H
|
||||
endif
|
||||
|
||||
ifndef TGLIB32
|
||||
TGLIB32 = @TGLIB32@
|
||||
endif
|
||||
|
||||
ifndef NLS
|
||||
NLS = @NLS@
|
||||
endif
|
||||
LFLAGS += @LFINTL@
|
||||
ifeq ($(NLS),y)
|
||||
REQUIRE_NLS = -DUSE_NLS -DPACKAGE=\"$(PACKAGE)\" -DLOCALEDIR=\"$(NLS_DIR)\"
|
||||
endif
|
||||
ifdef REQUIRE_NLS
|
||||
DFLAGS += $(REQUIRE_NLS)
|
||||
endif
|
||||
|
||||
ifndef LTO
|
||||
LTO = @LTO@
|
||||
endif
|
||||
ifndef GCC_AR
|
||||
GCC_AR = @GCC_AR@
|
||||
endif
|
||||
ifeq ($(LTO),y)
|
||||
AR = $(GCC_AR)
|
||||
CFLAGS += -flto
|
||||
LD = gcc
|
||||
LDFLAGS += $(CFLAGS)
|
||||
endif
|
||||
|
||||
ifndef INSTALL_CRON
|
||||
INSTALL_CRON = @INSTALL_CRON@
|
||||
endif
|
||||
ifndef CRON_OWNER
|
||||
CRON_OWNER = @CRON_OWNER@
|
||||
endif
|
||||
|
||||
MAN_GROUP = @MAN_GROUP@
|
||||
ifndef IGNORE_FILE_ATTRIBUTES
|
||||
IGNORE_FILE_ATTRIBUTES = @IGNORE_FILE_ATTRIBUTES@
|
||||
endif
|
||||
ifeq ($(IGNORE_FILE_ATTRIBUTES),y)
|
||||
MANGRPARG =
|
||||
else
|
||||
MANGRPARG = -g $(MAN_GROUP)
|
||||
endif
|
||||
ifndef CLEAN_SA_DIR
|
||||
CLEAN_SA_DIR = @CLEAN_SA_DIR@
|
||||
endif
|
||||
ifndef COMPRESS_MANPG
|
||||
COMPRESS_MANPG = @COMPRESS_MANPG@
|
||||
endif
|
||||
ifndef INSTALL_DOC
|
||||
INSTALL_DOC = @INSTALL_DOC@
|
||||
endif
|
||||
ifndef COPY_ONLY
|
||||
COPY_ONLY = @COPY_ONLY@
|
||||
endif
|
||||
|
||||
# Systemd
|
||||
SYSTEMCTL = @SYSTEMCTL@
|
||||
SYSTEMD_UNIT_DIR = @SYSTEMD_UNIT_DIR@
|
||||
SYSTEMD_SLEEP_DIR = @SYSTEMD_SLEEP_DIR@
|
||||
|
||||
ifndef USE_CROND
|
||||
USE_CROND = @USE_CROND@
|
||||
endif
|
||||
ifeq ($(USE_CROND),y)
|
||||
SYSTEMD_UNIT_DIR =
|
||||
endif
|
||||
|
||||
# Run-command directories
|
||||
ifndef RC_DIR
|
||||
RC_DIR = @RC_DIR@
|
||||
endif
|
||||
RC0_DIR = $(RC_DIR)/rc0.d
|
||||
RC1_DIR = $(RC_DIR)/rc1.d
|
||||
RC2_DIR = $(RC_DIR)/rc2.d
|
||||
RC3_DIR = $(RC_DIR)/rc3.d
|
||||
RC4_DIR = $(RC_DIR)/rc4.d
|
||||
RC5_DIR = $(RC_DIR)/rc5.d
|
||||
RC6_DIR = $(RC_DIR)/rc6.d
|
||||
ifndef INIT_DIR
|
||||
INIT_DIR = @INIT_DIR@
|
||||
endif
|
||||
ifndef INITD_DIR
|
||||
INITD_DIR = @INITD_DIR@
|
||||
endif
|
||||
|
||||
SOURCE_CODE= $(wildcard *.c *.h)
|
||||
|
||||
NLSPO= $(wildcard nls/*.po)
|
||||
NLSGMO= $(NLSPO:.po=.gmo)
|
||||
NLSPOT= $(NLSPO:.po=.pot)
|
||||
|
||||
%.gmo: %.po
|
||||
$(MSGFMT) -o $@ $<
|
||||
|
||||
%.pot: %.po
|
||||
$(MSGMERGE) -U $< nls/sysstat.pot
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
% : %.o
|
||||
$(CC) -o $@ $(CFLAGS) $^ $(LFLAGS)
|
||||
|
||||
all: sadc sar sadf iostat tapestat mpstat pidstat cifsiostat locales
|
||||
|
||||
common_light.o: common.c version.h common.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADC $(DFLAGS) $<
|
||||
|
||||
common.o: common.c version.h common.h
|
||||
|
||||
systest.o: systest.c systest.h
|
||||
|
||||
sa_common_light.o: sa_common.c version.h sa.h common.h rd_stats.h rd_sensors.h ioconf.h sysconfig.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADC $(DFLAGS) $<
|
||||
|
||||
sa_common.o: sa_common.c version.h sa.h common.h rd_stats.h rd_sensors.h ioconf.h sysconfig.h
|
||||
|
||||
ioconf.o: ioconf.c ioconf.h common.h sysconfig.h
|
||||
|
||||
act_sadc.o: activity.c sa.h common.h rd_stats.h rd_sensors.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADC $(DFLAGS) $<
|
||||
|
||||
act_sar.o: activity.c sa.h common.h rd_stats.h rd_sensors.h pr_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SAR $(DFLAGS) $<
|
||||
|
||||
act_sadf.o: activity.c sa.h common.h rd_stats.h rd_sensors.h rndr_stats.h xml_stats.h json_stats.h svg_stats.h raw_stats.h pcp_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADF $(DFLAGS) $<
|
||||
|
||||
rd_stats.o: rd_stats.c common.h rd_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADC $(DFLAGS) $<
|
||||
|
||||
rd_stats_light.o: rd_stats.c common.h rd_stats.h ioconf.h sysconfig.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
count.o: count.c common.h rd_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADC $(DFLAGS) $<
|
||||
|
||||
count_light.o: count.c common.h rd_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
rd_sensors.o: rd_sensors.c common.h rd_sensors.h rd_stats.h
|
||||
|
||||
pr_stats.o: pr_stats.c sa.h common.h rd_stats.h rd_sensors.h ioconf.h sysconfig.h pr_stats.h
|
||||
|
||||
rndr_stats.o: rndr_stats.c sa.h common.h rd_stats.h rd_sensors.h ioconf.h sysconfig.h rndr_stats.h
|
||||
|
||||
xml_stats.o: xml_stats.c sa.h common.h rd_stats.h rd_sensors.h ioconf.h sysconfig.h xml_stats.h
|
||||
|
||||
json_stats.o: json_stats.c sa.h common.h rd_stats.h rd_sensors.h ioconf.h sysconfig.h json_stats.h
|
||||
|
||||
svg_stats.o: svg_stats.c sa.h common.h rd_stats.h rd_sensors.h ioconf.h sysconfig.h svg_stats.h
|
||||
|
||||
raw_stats.o: raw_stats.c sa.h common.h rd_stats.h rd_sensors.h ioconf.h sysconfig.h raw_stats.h
|
||||
|
||||
pcp_stats.o: pcp_stats.c sa.h pcp_stats.h
|
||||
|
||||
sa_wrap.o: sa_wrap.c sa.h common.h rd_stats.h count.h rd_sensors.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADC $(DFLAGS) $<
|
||||
|
||||
format_sadf.o: format.c sadf.h sa.h common.h rd_stats.h rd_sensors.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADF $(DFLAGS) $<
|
||||
|
||||
format_sar.o: format.c sa.h common.h rd_stats.h rd_sensors.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SAR $(DFLAGS) $<
|
||||
|
||||
pcp_def_metrics.o: pcp_def_metrics.c
|
||||
|
||||
sadf_misc.o: sadf_misc.c sadf.h pcp_def_metrics.h sa.h common.h rd_stats.h rd_sensors.h
|
||||
|
||||
sa_conv.o: sa_conv.c version.h sadf.h sa.h common.h rd_stats.h rd_sensors.h sa_conv.h
|
||||
|
||||
# Explicit rules needed to prevent possible file corruption
|
||||
# when using parallel execution.
|
||||
libsyscom.a: common.o ioconf.o systest.o
|
||||
$(AR) rvs $@ $?
|
||||
|
||||
# Ditto
|
||||
librdstats.a: rd_stats.o count.o
|
||||
$(AR) rvs $@ $?
|
||||
|
||||
librdstats_light.a: rd_stats_light.o count_light.o
|
||||
$(AR) rvs $@ $?
|
||||
|
||||
# librdsensors.a: librdsensors.a(rd_sensors.o)
|
||||
librdsensors.a: rd_sensors.o
|
||||
$(AR) rvs $@ $?
|
||||
|
||||
sadc.o: sadc.c sa.h version.h common.h rd_stats.h rd_sensors.h
|
||||
|
||||
sadc: LFLAGS += $(LFSENSORS)
|
||||
|
||||
sadc: sadc.o act_sadc.o sa_wrap.o sa_common_light.o common_light.o systest.o librdstats.a librdsensors.a libsyscom.a
|
||||
|
||||
sar.o: sar.c sa.h version.h common.h rd_stats.h rd_sensors.h
|
||||
|
||||
sar: sar.o act_sar.o format_sar.o sa_common.o pr_stats.o librdstats_light.a libsyscom.a
|
||||
|
||||
sadf.o: sadf.c sadf.h version.h sa.h common.h rd_stats.h rd_sensors.h
|
||||
|
||||
sadf: LFLAGS += $(LFPCP)
|
||||
|
||||
sadf: sadf.o act_sadf.o format_sadf.o sadf_misc.o pcp_def_metrics.o sa_conv.o rndr_stats.o xml_stats.o json_stats.o svg_stats.o raw_stats.o pcp_stats.o sa_common.o librdstats_light.a libsyscom.a
|
||||
|
||||
iostat.o: iostat.c iostat.h version.h common.h ioconf.h sysconfig.h rd_stats.h count.h
|
||||
|
||||
iostat: iostat.o librdstats_light.a libsyscom.a
|
||||
|
||||
tapestat.o: tapestat.c tapestat.h version.h common.h count.h rd_stats.h
|
||||
|
||||
tapestat: tapestat.o librdstats_light.a libsyscom.a
|
||||
|
||||
pidstat.o: pidstat.c pidstat.h version.h common.h rd_stats.h count.h
|
||||
|
||||
pidstat: pidstat.o librdstats_light.a libsyscom.a
|
||||
|
||||
mpstat.o: mpstat.c mpstat.h version.h common.h rd_stats.h count.h
|
||||
|
||||
mpstat: mpstat.o librdstats_light.a libsyscom.a
|
||||
|
||||
cifsiostat.o: cifsiostat.c cifsiostat.h count.h rd_stats.h version.h common.h
|
||||
|
||||
cifsiostat: cifsiostat.o librdstats_light.a libsyscom.a
|
||||
|
||||
# inisar: Old sar version
|
||||
|
||||
tests/ini/sa_common.o: tests/ini/sa_common.c tests/ini/iniversion.h tests/ini/sa.h tests/ini/common.h tests/ini/rd_stats.h tests/ini/rd_sensors.h tests/ini/ioconf.h tests/ini/inisysconfig.h
|
||||
|
||||
tests/ini/act_sar.o: tests/ini/activity.c tests/ini/sa.h tests/ini/common.h tests/ini/rd_stats.h tests/ini/rd_sensors.h tests/ini/pr_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SAR $(DFLAGS) $<
|
||||
|
||||
tests/ini/rd_stats_light.o: tests/ini/rd_stats.c tests/ini/common.h tests/ini/rd_stats.h tests/ini/ioconf.h tests/ini/inisysconfig.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
tests/ini/count_light.o: tests/ini/count.c tests/ini/common.h tests/ini/rd_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
tests/ini/libsyscom.a: tests/ini/common.o tests/ini/ioconf.o
|
||||
$(AR) rvs $@ $?
|
||||
|
||||
tests/ini/format_sar.o: tests/ini/format.c tests/ini/sa.h tests/ini/common.h tests/ini/rd_stats.h tests/ini/rd_sensors.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SAR $(DFLAGS) $<
|
||||
|
||||
tests/ini/pr_stats.o: tests/ini/pr_stats.c tests/ini/sa.h tests/ini/common.h tests/ini/rd_stats.h tests/ini/rd_sensors.h tests/ini/ioconf.h tests/ini/inisysconfig.h tests/ini/pr_stats.h
|
||||
|
||||
tests/ini/librdstats_light.a: tests/ini/rd_stats_light.o tests/ini/count_light.o
|
||||
$(AR) rvs $@ $?
|
||||
|
||||
tests/ini/inisar.o: tests/ini/inisar.c tests/ini/sa.h tests/ini/iniversion.h tests/ini/common.h tests/ini/rd_stats.h tests/ini/rd_sensors.h
|
||||
|
||||
tests/ini/inisar: tests/ini/inisar.o tests/ini/act_sar.o tests/ini/format_sar.o tests/ini/sa_common.o tests/ini/pr_stats.o tests/ini/librdstats_light.a tests/ini/libsyscom.a
|
||||
|
||||
# sar32/sadc32: 32-bit versions of sar/sadc
|
||||
tests/32bits/sadc32.o: sadc.c sa.h version.h common.h rd_stats.h rd_sensors.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
tests/32bits/sar32.o: sar.c sa.h version.h common.h rd_stats.h rd_sensors.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
tests/32bits/act_sadc32.o: activity.c sa.h common.h rd_stats.h rd_sensors.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADC $(DFLAGS) $<
|
||||
|
||||
tests/32bits/act_sar32.o: activity.c sa.h common.h rd_stats.h rd_sensors.h pr_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SAR $(DFLAGS) $<
|
||||
|
||||
tests/32bits/sa_wrap32.o: sa_wrap.c sa.h common.h rd_stats.h count.h rd_sensors.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADC $(DFLAGS) $<
|
||||
|
||||
tests/32bits/sa_common_light32.o: sa_common.c version.h sa.h common.h rd_stats.h rd_sensors.h ioconf.h sysconfig.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADC $(DFLAGS) $<
|
||||
|
||||
tests/32bits/sa_common32.o: sa_common.c version.h sa.h common.h rd_stats.h rd_sensors.h ioconf.h sysconfig.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
tests/32bits/common_light32.o: common.c version.h common.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADC $(DFLAGS) $<
|
||||
|
||||
tests/32bits/systest32.o: systest.c systest.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
tests/32bits/libsyscom32.a: tests/32bits/common32.o tests/32bits/ioconf32.o tests/32bits/systest32.o
|
||||
$(AR) rvs $@ $?
|
||||
|
||||
tests/32bits/librdstats32.a: tests/32bits/rd_stats32.o tests/32bits/count32.o
|
||||
$(AR) rvs $@ $?
|
||||
|
||||
tests/32bits/librdstats_light32.a: tests/32bits/rd_stats_light32.o tests/32bits/count_light32.o
|
||||
$(AR) rvs $@ $?
|
||||
|
||||
tests/32bits/librdsensors32.a: tests/32bits/rd_sensors32.o
|
||||
$(AR) rvs $@ $?
|
||||
|
||||
tests/32bits/rd_stats32.o: rd_stats.c common.h rd_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADC $(DFLAGS) $<
|
||||
|
||||
tests/32bits/rd_stats_light32.o: rd_stats.c common.h rd_stats.h ioconf.h sysconfig.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
tests/32bits/count32.o: count.c common.h rd_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADC $(DFLAGS) $<
|
||||
|
||||
tests/32bits/count_light32.o: count.c common.h rd_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
tests/32bits/format_sar32.o: format.c sa.h common.h rd_stats.h rd_sensors.h
|
||||
$(CC) -o $@ -c $(CFLAGS) -DSOURCE_SAR $(DFLAGS) $<
|
||||
|
||||
tests/32bits/pr_stats32.o: pr_stats.c sa.h common.h rd_stats.h rd_sensors.h ioconf.h sysconfig.h pr_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
tests/32bits/common32.o: common.c version.h common.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
tests/32bits/ioconf32.o: ioconf.c ioconf.h common.h sysconfig.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
tests/32bits/rd_sensors32.o: rd_sensors.c common.h rd_sensors.h rd_stats.h
|
||||
$(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
|
||||
|
||||
tests/32bits/sadc32: LFLAGS += $(LFSENSORS32)
|
||||
|
||||
tests/32bits/sadc32: tests/32bits/sadc32.o tests/32bits/act_sadc32.o tests/32bits/sa_wrap32.o tests/32bits/sa_common_light32.o tests/32bits/common_light32.o tests/32bits/systest32.o tests/32bits/librdstats32.a tests/32bits/librdsensors32.a
|
||||
|
||||
tests/32bits/sar32: tests/32bits/sar32.o tests/32bits/act_sar32.o tests/32bits/format_sar32.o tests/32bits/sa_common32.o tests/32bits/pr_stats32.o tests/32bits/librdstats_light32.a tests/32bits/libsyscom32.a
|
||||
|
||||
ifdef REQUIRE_NLS
|
||||
locales: $(NLSGMO)
|
||||
else
|
||||
locales:
|
||||
endif
|
||||
|
||||
nls/sysstat.pot: $(wildcard *.c)
|
||||
$(XGETTEXT) -o $@ -k_ --msgid-bugs-address="sysstat <at> orange.fr" $^
|
||||
|
||||
# Phony targets
|
||||
.PHONY: clean distclean install install_base install_all uninstall copyyear \
|
||||
uninstall_base uninstall_all dist bdist xdist gitdist squeeze simtest extratest
|
||||
|
||||
install_man: man/sadc.8 man/sar.1 man/sadf.1 man/sa1.8 man/sa2.8 man/sysstat.5
|
||||
ifeq ($(INSTALL_DOC),y)
|
||||
mkdir -p $(DESTDIR)$(MAN1_DIR)
|
||||
mkdir -p $(DESTDIR)$(MAN5_DIR)
|
||||
mkdir -p $(DESTDIR)$(MAN8_DIR)
|
||||
rm -f $(DESTDIR)$(MAN8_DIR)/sa1.8*
|
||||
$(INSTALL_DATA) $(MANGRPARG) man/sa1.8 $(DESTDIR)$(MAN8_DIR)
|
||||
rm -f $(DESTDIR)$(MAN8_DIR)/sa2.8*
|
||||
$(INSTALL_DATA) $(MANGRPARG) man/sa2.8 $(DESTDIR)$(MAN8_DIR)
|
||||
rm -f $(DESTDIR)$(MAN8_DIR)/sadc.8*
|
||||
$(INSTALL_DATA) $(MANGRPARG) man/sadc.8 $(DESTDIR)$(MAN8_DIR)
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/sar.1*
|
||||
$(INSTALL_DATA) $(MANGRPARG) man/sar.1 $(DESTDIR)$(MAN1_DIR)
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/sadf.1*
|
||||
$(INSTALL_DATA) $(MANGRPARG) man/sadf.1 $(DESTDIR)$(MAN1_DIR)
|
||||
rm -f $(DESTDIR)$(MAN5_DIR)/sysstat.5*
|
||||
$(INSTALL_DATA) $(MANGRPARG) man/sysstat.5 $(DESTDIR)$(MAN5_DIR)
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/iostat.1*
|
||||
$(INSTALL_DATA) $(MANGRPARG) man/iostat.1 $(DESTDIR)$(MAN1_DIR)
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/tapestat.1*
|
||||
$(INSTALL_DATA) $(MANGRPARG) man/tapestat.1 $(DESTDIR)$(MAN1_DIR)
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/mpstat.1*
|
||||
$(INSTALL_DATA) $(MANGRPARG) man/mpstat.1 $(DESTDIR)$(MAN1_DIR)
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/pidstat.1*
|
||||
$(INSTALL_DATA) $(MANGRPARG) man/pidstat.1 $(DESTDIR)$(MAN1_DIR)
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/cifsiostat.1*
|
||||
$(INSTALL_DATA) $(MANGRPARG) man/cifsiostat.1 $(DESTDIR)$(MAN1_DIR)
|
||||
ifeq ($(COMPRESS_MANPG),y)
|
||||
$(ZIP) $(DESTDIR)$(MAN8_DIR)/sa1.8
|
||||
$(ZIP) $(DESTDIR)$(MAN8_DIR)/sa2.8
|
||||
$(ZIP) $(DESTDIR)$(MAN8_DIR)/sadc.8
|
||||
$(ZIP) $(DESTDIR)$(MAN1_DIR)/sar.1
|
||||
$(ZIP) $(DESTDIR)$(MAN1_DIR)/sadf.1
|
||||
$(ZIP) $(DESTDIR)$(MAN5_DIR)/sysstat.5
|
||||
$(ZIP) $(DESTDIR)$(MAN1_DIR)/iostat.1
|
||||
$(ZIP) $(DESTDIR)$(MAN1_DIR)/tapestat.1
|
||||
$(ZIP) $(DESTDIR)$(MAN1_DIR)/mpstat.1
|
||||
$(ZIP) $(DESTDIR)$(MAN1_DIR)/pidstat.1
|
||||
$(ZIP) $(DESTDIR)$(MAN1_DIR)/cifsiostat.1
|
||||
endif
|
||||
endif
|
||||
|
||||
squeeze:
|
||||
catalogs="$(SOURCE_CODE)"; \
|
||||
for c in $$catalogs; do \
|
||||
echo "Squeezing file: $$c"; \
|
||||
sed 's/[\t ]*$$//g' $$c > squeeze.tmp; \
|
||||
mv squeeze.tmp $$c; \
|
||||
done
|
||||
|
||||
# Update Makefile.in by hand - Restore mode for iconfig.
|
||||
copyyear:
|
||||
catalogs="$(SOURCE_CODE) iconfig README.md sa1.in sa2.in sysconfig.in sysstat.in version.in"; \
|
||||
for c in $$catalogs; do \
|
||||
echo "Updating file: $$c"; \
|
||||
sed 's/-2021/-2022/g' $$c > copyyear.tmp; \
|
||||
mv copyyear.tmp $$c; \
|
||||
done
|
||||
|
||||
install_nls: locales
|
||||
ifdef REQUIRE_NLS
|
||||
catalogs='$(NLSGMO)'; \
|
||||
for c in $$catalogs; do \
|
||||
c=`basename $$c`; \
|
||||
c=`echo $$c | sed 's/\.gmo$$//'`; \
|
||||
mkdir -p $(DESTDIR)$(NLS_DIR)/$$c/LC_MESSAGES; \
|
||||
echo "NLS: Installing $$c file..." ; \
|
||||
$(INSTALL_DATA) nls/$$c.gmo $(DESTDIR)$(NLS_DIR)/$$c/LC_MESSAGES/$(PACKAGE).mo; \
|
||||
done
|
||||
endif
|
||||
|
||||
install_base: all sa1 sa2 sysstat.sysconfig install_man install_nls
|
||||
mkdir -p $(DESTDIR)$(SA_LIB_DIR)
|
||||
mkdir -p $(DESTDIR)$(SA_DIR)
|
||||
ifeq ($(CLEAN_SA_DIR),y)
|
||||
find $(DESTDIR)$(SA_DIR) -type f | grep -E "/sar?[0-9]{2,8}(\.(Z|gz|bz2|xz|lz|lzo))?$$" | xargs rm -f
|
||||
find $(DESTDIR)$(SA_DIR) -type f | grep -E "/sar?[0-9]{2,8}$$" | xargs rm -f
|
||||
endif
|
||||
mkdir -p $(DESTDIR)$(BIN_DIR)
|
||||
mkdir -p $(DESTDIR)$(DOC_DIR)
|
||||
mkdir -p $(DESTDIR)$(SYSCONFIG_DIR)
|
||||
$(INSTALL_BIN) sa1 $(DESTDIR)$(SA_LIB_DIR)
|
||||
$(INSTALL_BIN) sa2 $(DESTDIR)$(SA_LIB_DIR)
|
||||
$(INSTALL_BIN) sadc $(DESTDIR)$(SA_LIB_DIR)
|
||||
$(INSTALL_BIN) sar $(DESTDIR)$(BIN_DIR)
|
||||
$(INSTALL_BIN) sadf $(DESTDIR)$(BIN_DIR)
|
||||
$(INSTALL_BIN) iostat $(DESTDIR)$(BIN_DIR)
|
||||
$(INSTALL_BIN) tapestat $(DESTDIR)$(BIN_DIR)
|
||||
$(INSTALL_BIN) mpstat $(DESTDIR)$(BIN_DIR)
|
||||
$(INSTALL_BIN) pidstat $(DESTDIR)$(BIN_DIR)
|
||||
$(INSTALL_BIN) cifsiostat $(DESTDIR)$(BIN_DIR)
|
||||
$(INSTALL_DATA) sysstat.ioconf $(DESTDIR)$(SYSCONFIG_DIR)
|
||||
$(INSTALL_DATA) sysstat.sysconfig $(DESTDIR)$(SYSCONFIG_DIR)/$(SYSCONFIG_FILE)
|
||||
ifeq ($(INSTALL_DOC),y)
|
||||
$(INSTALL_DATA) CHANGES $(DESTDIR)$(DOC_DIR)
|
||||
$(INSTALL_DATA) COPYING $(DESTDIR)$(DOC_DIR)
|
||||
$(INSTALL_DATA) CREDITS $(DESTDIR)$(DOC_DIR)
|
||||
$(INSTALL_DATA) README.md $(DESTDIR)$(DOC_DIR)
|
||||
$(INSTALL_DATA) FAQ.md $(DESTDIR)$(DOC_DIR)
|
||||
$(INSTALL_DATA) *.lsm $(DESTDIR)$(DOC_DIR)
|
||||
endif
|
||||
|
||||
ifdef SYSTEMD_UNIT_DIR
|
||||
install_all: install_base cron/sysstat-collect.service cron/sysstat-collect.timer \
|
||||
cron/sysstat.sleep cron/sysstat-summary.service cron/sysstat-summary.timer
|
||||
else
|
||||
install_all: install_base cron/crontab sysstat \
|
||||
cron/sysstat.crond cron/sysstat.cron.daily cron/sysstat.cron.hourly
|
||||
endif
|
||||
|
||||
ifneq ($(IGNORE_FILE_ATTRIBUTES),y)
|
||||
$(CHOWN) $(CRON_OWNER) $(DESTDIR)$(SA_DIR)
|
||||
endif
|
||||
ifdef SYSTEMD_UNIT_DIR
|
||||
mkdir -p $(DESTDIR)$(SYSTEMD_UNIT_DIR)
|
||||
else
|
||||
if [ -d /etc/cron.d ]; then \
|
||||
mkdir -p $(DESTDIR)/etc/cron.d; \
|
||||
elif [ -d /etc/cron.hourly -a -d /etc/cron.daily ]; then \
|
||||
mkdir -p $(DESTDIR)/etc/cron.hourly $(DESTDIR)/etc/cron.daily; \
|
||||
fi
|
||||
if [ -d $(INIT_DIR) ]; then \
|
||||
mkdir -p $(DESTDIR)$(INIT_DIR); \
|
||||
elif [ -d $(RC_DIR) ]; then \
|
||||
mkdir -p $(DESTDIR)$(RC_DIR); \
|
||||
fi
|
||||
endif
|
||||
|
||||
ifdef SYSTEMD_SLEEP_DIR
|
||||
mkdir -p $(DESTDIR)$(SYSTEMD_SLEEP_DIR)
|
||||
endif
|
||||
|
||||
if [ -z "$(SYSTEMD_UNIT_DIR)" -o ! -d "$(DESTDIR)$(SYSTEMD_UNIT_DIR)" ]; then \
|
||||
if [ -d $(DESTDIR)/etc/cron.d ]; then \
|
||||
$(INSTALL_DATA) cron/sysstat.crond $(DESTDIR)/etc/cron.d/sysstat; \
|
||||
elif [ -d $(DESTDIR)/etc/cron.hourly -a -d $(DESTDIR)/etc/cron.daily ]; then \
|
||||
$(INSTALL_BIN) cron/sysstat.cron.hourly $(DESTDIR)/etc/cron.hourly/sysstat; \
|
||||
$(INSTALL_BIN) cron/sysstat.cron.daily $(DESTDIR)/etc/cron.daily/sysstat; \
|
||||
fi \
|
||||
fi
|
||||
ifeq ($(COPY_ONLY),n)
|
||||
if [ \( -z "$(SYSTEMD_UNIT_DIR)" -o ! -d "$(DESTDIR)$(SYSTEMD_UNIT_DIR)" \) -a ! -d $(DESTDIR)/etc/cron.d ]; then \
|
||||
if [ ! -d $(DESTDIR)/etc/cron.hourly -o ! -d $(DESTDIR)/etc/cron.daily ]; then \
|
||||
su $(CRON_OWNER) -c "crontab -l > /tmp/crontab-$(CRON_OWNER).save"; \
|
||||
$(CP) -a /tmp/crontab-$(CRON_OWNER).save ./crontab-$(CRON_OWNER).`date '+%Y%m%d.%H%M%S'`.save; \
|
||||
echo "USER'S PREVIOUS CRONTAB SAVED IN CURRENT DIRECTORY (USING .save SUFFIX)."; \
|
||||
su $(CRON_OWNER) -c "crontab cron/crontab"; \
|
||||
fi \
|
||||
fi
|
||||
endif
|
||||
if [ -n "$(SYSTEMD_UNIT_DIR)" -a -d "$(DESTDIR)$(SYSTEMD_UNIT_DIR)" ]; then \
|
||||
$(INSTALL_DATA) sysstat.service $(DESTDIR)$(SYSTEMD_UNIT_DIR); \
|
||||
$(INSTALL_DATA) cron/sysstat-collect.service $(DESTDIR)$(SYSTEMD_UNIT_DIR); \
|
||||
$(INSTALL_DATA) cron/sysstat-collect.timer $(DESTDIR)$(SYSTEMD_UNIT_DIR); \
|
||||
$(INSTALL_DATA) cron/sysstat-summary.service $(DESTDIR)$(SYSTEMD_UNIT_DIR); \
|
||||
$(INSTALL_DATA) cron/sysstat-summary.timer $(DESTDIR)$(SYSTEMD_UNIT_DIR); \
|
||||
elif [ -d $(DESTDIR)$(INIT_DIR) ]; then \
|
||||
$(INSTALL_BIN) sysstat $(DESTDIR)$(INIT_DIR)/sysstat; \
|
||||
if [ "$(COPY_ONLY)" = "n" ]; then \
|
||||
if [ -x "$(CHKCONFIG)" ]; then \
|
||||
cd $(DESTDIR)$(INIT_DIR) && $(CHKCONFIG) --add sysstat; \
|
||||
else \
|
||||
[ -d $(DESTDIR)$(RC2_DIR) ] || mkdir -p $(DESTDIR)$(RC2_DIR); \
|
||||
[ -d $(DESTDIR)$(RC3_DIR) ] || mkdir -p $(DESTDIR)$(RC3_DIR); \
|
||||
[ -d $(DESTDIR)$(RC5_DIR) ] || mkdir -p $(DESTDIR)$(RC5_DIR); \
|
||||
cd $(DESTDIR)$(RC2_DIR) && $(LN_S) -f ../$(INITD_DIR)/sysstat S01sysstat; \
|
||||
cd $(DESTDIR)$(RC3_DIR) && $(LN_S) -f ../$(INITD_DIR)/sysstat S01sysstat; \
|
||||
cd $(DESTDIR)$(RC5_DIR) && $(LN_S) -f ../$(INITD_DIR)/sysstat S01sysstat; \
|
||||
fi \
|
||||
fi \
|
||||
elif [ -d $(DESTDIR)$(RC_DIR) ]; then \
|
||||
$(INSTALL_BIN) sysstat $(DESTDIR)$(RC_DIR)/rc.sysstat; \
|
||||
if [ "$(COPY_ONLY)" = "n" ]; then \
|
||||
if [ -x "$(CHKCONFIG)" ]; then \
|
||||
cd $(DESTDIR)$(RC_DIR) && $(CHKCONFIG) --add rc.sysstat; \
|
||||
else \
|
||||
[ -d $(DESTDIR)$(RC2_DIR) ] || mkdir -p $(DESTDIR)$(RC2_DIR); \
|
||||
[ -d $(DESTDIR)$(RC3_DIR) ] || mkdir -p $(DESTDIR)$(RC3_DIR); \
|
||||
[ -d $(DESTDIR)$(RC5_DIR) ] || mkdir -p $(DESTDIR)$(RC5_DIR); \
|
||||
cd $(DESTDIR)$(RC2_DIR) && $(LN_S) -f ../rc.sysstat S01sysstat; \
|
||||
cd $(DESTDIR)$(RC3_DIR) && $(LN_S) -f ../rc.sysstat S01sysstat; \
|
||||
cd $(DESTDIR)$(RC5_DIR) && $(LN_S) -f ../rc.sysstat S01sysstat; \
|
||||
fi \
|
||||
fi \
|
||||
fi
|
||||
if [ -n "$(SYSTEMD_UNIT_DIR)" -a -n "$(SYSTEMD_SLEEP_DIR)" -a -d "$(DESTDIR)$(SYSTEMD_SLEEP_DIR)" ]; then \
|
||||
$(INSTALL_BIN) cron/sysstat.sleep $(DESTDIR)$(SYSTEMD_SLEEP_DIR); \
|
||||
fi
|
||||
|
||||
ifeq ($(COPY_ONLY),n)
|
||||
if [ -n "$(SYSTEMD_UNIT_DIR)" -a -x "$(SYSTEMCTL)" ]; then \
|
||||
$(SYSTEMCTL) enable sysstat.service; \
|
||||
fi
|
||||
endif
|
||||
|
||||
uninstall_man:
|
||||
ifeq ($(INSTALL_DOC),y)
|
||||
rm -f $(DESTDIR)$(MAN8_DIR)/sadc.8*
|
||||
rm -f $(DESTDIR)$(MAN8_DIR)/sa1.8*
|
||||
rm -f $(DESTDIR)$(MAN8_DIR)/sa2.8*
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/sar.1*
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/sadf.1*
|
||||
rm -f $(DESTDIR)$(MAN5_DIR)/sysstat.5*
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/iostat.1*
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/tapestat.1*
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/mpstat.1*
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/pidstat.1*
|
||||
rm -f $(DESTDIR)$(MAN1_DIR)/cifsiostat.1*
|
||||
endif
|
||||
|
||||
uninstall_nls:
|
||||
ifdef REQUIRE_NLS
|
||||
-catalogs='$(NLSGMO)'; \
|
||||
for c in $$catalogs; do \
|
||||
c=`basename $$c`; \
|
||||
c=`echo $$c | sed 's/\.gmo$$//'`; \
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/locale/$$c/LC_MESSAGES/$(PACKAGE).mo; \
|
||||
rmdir --ignore-fail-on-non-empty $(DESTDIR)$(PREFIX)/share/locale/$$c/LC_MESSAGES 2>/dev/null; \
|
||||
rmdir --ignore-fail-on-non-empty $(DESTDIR)$(PREFIX)/share/locale/$$c 2>/dev/null; \
|
||||
done
|
||||
endif
|
||||
|
||||
uninstall_base: uninstall_man uninstall_nls
|
||||
rm -f $(DESTDIR)$(SA_LIB_DIR)/sadc
|
||||
rm -f $(DESTDIR)$(SA_LIB_DIR)/sa1
|
||||
rm -f $(DESTDIR)$(SA_LIB_DIR)/sa2
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/sar
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/sadf
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/iostat
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/tapestat
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/mpstat
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/pidstat
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/cifsiostat
|
||||
-rmdir --ignore-fail-on-non-empty $(DESTDIR)$(SA_LIB_DIR)
|
||||
-rmdir --ignore-fail-on-non-empty $(DESTDIR)$(SA_DIR)/[0-9]?????
|
||||
-rmdir --ignore-fail-on-non-empty $(DESTDIR)$(SA_DIR)
|
||||
# No need to keep sysstat scripts, config files and links since
|
||||
# the binaries have been deleted.
|
||||
rm -f $(DESTDIR)$(INIT_DIR)/sysstat
|
||||
rm -f $(DESTDIR)$(RC_DIR)/rc.sysstat
|
||||
rm -f $(DESTDIR)$(SYSCONFIG_DIR)/$(SYSCONFIG_FILE)
|
||||
rm -f $(DESTDIR)$(SYSCONFIG_DIR)/sysstat.ioconf
|
||||
rm -f $(DESTDIR)$(RC2_DIR)/S??sysstat
|
||||
rm -f $(DESTDIR)$(RC2_DIR)/S??rc.sysstat
|
||||
rm -f $(DESTDIR)$(RC3_DIR)/S??sysstat
|
||||
rm -f $(DESTDIR)$(RC3_DIR)/S??rc.sysstat
|
||||
rm -f $(DESTDIR)$(RC5_DIR)/S??sysstat
|
||||
rm -f $(DESTDIR)$(RC5_DIR)/S??rc.sysstat
|
||||
# Delete possible kill entries installed by chkconfig
|
||||
rm -f $(DESTDIR)$(RC0_DIR)/K??sysstat
|
||||
rm -f $(DESTDIR)$(RC0_DIR)/K??rc.sysstat
|
||||
rm -f $(DESTDIR)$(RC1_DIR)/K??sysstat
|
||||
rm -f $(DESTDIR)$(RC1_DIR)/K??rc.sysstat
|
||||
rm -f $(DESTDIR)$(RC4_DIR)/K??sysstat
|
||||
rm -f $(DESTDIR)$(RC4_DIR)/K??rc.sysstat
|
||||
rm -f $(DESTDIR)$(RC6_DIR)/K??sysstat
|
||||
rm -f $(DESTDIR)$(RC6_DIR)/K??rc.sysstat
|
||||
# Vixie cron entries also can be safely deleted here
|
||||
rm -f $(DESTDIR)/etc/cron.d/sysstat
|
||||
# Id. for Slackware cron entries
|
||||
rm -f $(DESTDIR)/etc/cron.hourly/sysstat
|
||||
rm -f $(DESTDIR)/etc/cron.daily/sysstat
|
||||
ifeq ($(INSTALL_DOC),y)
|
||||
rm -f $(DESTDIR)$(DOC_DIR)/*
|
||||
-rmdir $(DESTDIR)$(DOC_DIR)
|
||||
endif
|
||||
@echo "Please ignore the errors above, if any."
|
||||
|
||||
uninstall_all: uninstall_base
|
||||
ifeq ($(COPY_ONLY),n)
|
||||
-if [ -z "$(SYSTEMD_UNIT_DIR)" -o ! -d "$(DESTDIR)$(SYSTEMD_UNIT_DIR)" ]; then \
|
||||
su $(CRON_OWNER) -c "crontab -l > /tmp/crontab-$(CRON_OWNER).old" ; \
|
||||
$(CP) -a /tmp/crontab-$(CRON_OWNER).old ./crontab-$(CRON_OWNER).`date '+%Y%m%d.%H%M%S'`.old ; \
|
||||
echo "USER'S CRONTAB SAVED IN CURRENT DIRECTORY (USING .old SUFFIX)." ; \
|
||||
su $(CRON_OWNER) -c "crontab -r" ; \
|
||||
fi
|
||||
-if [ -n "$(SYSTEMD_UNIT_DIR)" -a -x "$(SYSTEMCTL)" ]; then \
|
||||
$(SYSTEMCTL) disable sysstat.service; \
|
||||
fi
|
||||
endif
|
||||
if [ -n "$(SYSTEMD_UNIT_DIR)" -a -d "$(DESTDIR)$(SYSTEMD_UNIT_DIR)" ]; then \
|
||||
rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/sysstat.service; \
|
||||
rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/sysstat-collect.service; \
|
||||
rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/sysstat-collect.timer; \
|
||||
rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/sysstat-summary.service; \
|
||||
rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/sysstat-summary.timer; \
|
||||
fi
|
||||
if [ -n "$(SYSTEMD_UNIT_DIR)" -a -n "$(SYSTEMD_SLEEP_DIR)" -a -d "$(DESTDIR)$(SYSTEMD_SLEEP_DIR)" ]; then \
|
||||
rm -f $(DESTDIR)$(SYSTEMD_SLEEP_DIR)/sysstat.sleep; \
|
||||
fi
|
||||
|
||||
ifeq ($(INSTALL_CRON),y)
|
||||
uninstall: uninstall_all
|
||||
else
|
||||
uninstall: uninstall_base
|
||||
endif
|
||||
|
||||
ifeq ($(INSTALL_CRON),y)
|
||||
install: install_all
|
||||
else
|
||||
install: install_base
|
||||
endif
|
||||
|
||||
ifdef REQUIRE_NLS
|
||||
po-files: nls/sysstat.pot $(NLSPOT)
|
||||
else
|
||||
po-files:
|
||||
endif
|
||||
|
||||
TESTDIR="tests"
|
||||
TESTRUN="/bin/sh"
|
||||
TESTLIST:=$(shell ls $(TESTDIR) | grep -E '^[0-9]+$$' | sort -n)
|
||||
EXTRADIR="tests/extra"
|
||||
EXTRALIST:=$(shell ls $(EXTRADIR) | grep -E '^[0-9]+$$' | sort -n)
|
||||
|
||||
testcomp: tests/ini/inisar sa32bit
|
||||
|
||||
ifeq ($(TGLIB32),yes)
|
||||
sa32bit: DFLAGS += -DARCH32
|
||||
|
||||
sa32bit: CFLAGS += -m32
|
||||
|
||||
sa32bit: tests/32bits/sadc32 tests/32bits/sar32
|
||||
else
|
||||
sa32bit:
|
||||
endif
|
||||
|
||||
unit:
|
||||
@echo $(X) 2>&1
|
||||
@cat $(TESTDIR)/$(X) | $(TESTRUN)
|
||||
|
||||
extraunit:
|
||||
@echo $(X) 2>&1
|
||||
@cat $(EXTRADIR)/$(X) | $(TESTRUN)
|
||||
|
||||
# Use "do_test" script to make the following targets
|
||||
simtest: DFLAGS += -DTEST
|
||||
|
||||
simtest: all testcomp
|
||||
@$(foreach x, $(TESTLIST), $(MAKE) X=$x unit || exit;)
|
||||
rm -f tests/root
|
||||
ln -s root1 tests/root
|
||||
@echo Simulation tests: Success!
|
||||
|
||||
extratest: DFLAGS += -DTEST
|
||||
|
||||
extratest: all
|
||||
@$(foreach x, $(EXTRALIST), $(MAKE) X=$x extraunit || exit;)
|
||||
rm -f tests/root
|
||||
ln -s root1 tests/root
|
||||
@echo Extra simulation tests: Success!
|
||||
|
||||
clean:
|
||||
rm -f sadc sar sadf iostat tapestat mpstat pidstat cifsiostat *.o *.a core TAGS tests/*.tmp tests/extra/*.tmp
|
||||
rm -f nfsiostat* man/nfsiostat*
|
||||
rm -f tests/sa[0123]*
|
||||
rm -f tests/root
|
||||
ln -s root1 tests/root
|
||||
rm -f tests/ini/inisar tests/32bits/sadc32 tests/32bits/sar32
|
||||
rm -f tests/ini/*.o tests/ini/*.a tests/ini/core tests/pcpar.* tests/extra/pcpar-ssr.*
|
||||
rm -f tests/32bits/*.o tests/32bits/*.a tests/32bits/core
|
||||
find nls -name "*.gmo" -exec rm -f {} \;
|
||||
|
||||
almost-distclean: clean nls/sysstat.pot
|
||||
rm -f sa1 sa2 sysstat cron/crontab version.h sysconfig.h
|
||||
rm -f sysstat.sysconfig cron/sysstat.crond cron/sysstat.cron.daily sysstat.service
|
||||
rm -f cron/sysstat-collect.service cron/sysstat-collect.timer
|
||||
rm -f cron/sysstat-summary.service cron/sysstat-summary.timer cron/sysstat.sleep
|
||||
rm -f cron/sysstat.cron.hourly cron/sysstat.crond.sample cron/sysstat.crond.sample.in
|
||||
rm -f man/sa1.8 man/sa2.8 man/sadc.8 man/sadf.1 man/sar.1 man/iostat.1 man/sysstat.5
|
||||
rm -f tests/variables tests/data
|
||||
rm -f man/cifsiostat.1
|
||||
rm -f *.log config.status
|
||||
rm -rf autom4te.cache
|
||||
rm -f *.save *.old .*.swp data
|
||||
find . -name "*~" -exec rm -f {} \;
|
||||
|
||||
distclean: almost-distclean
|
||||
rm -f Makefile
|
||||
|
||||
maintainer-clean: distclean
|
||||
rm -f configure
|
||||
|
||||
dist: almost-distclean
|
||||
cd .. && (tar --exclude=Makefile --exclude=.git -cvf - sysstat-$(VERSION) | gzip -v9 > sysstat-$(VERSION).tar.gz)
|
||||
|
||||
bdist: almost-distclean
|
||||
cd .. && (tar --exclude=Makefile --exclude=.git -cvf - sysstat-$(VERSION) | bzip2 > sysstat-$(VERSION).tar.bz2)
|
||||
|
||||
xdist: almost-distclean
|
||||
cd .. && (tar --exclude=Makefile --exclude=.git -cvf - sysstat-$(VERSION) | xz > sysstat-$(VERSION).tar.xz)
|
||||
|
||||
gitdist: almost-distclean
|
||||
cd .. && (tar --exclude=Makefile -cvf - sysstat-$(VERSION) | bzip2 > sysstat-$(VERSION)-git.tar.bz2)
|
||||
|
||||
tags:
|
||||
etags ./*.[hc]
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
## sysstat - System performance tools for the Linux operating system
|
||||
[![Coverity Scan Build Status](https://scan.coverity.com/projects/4040/badge.svg)](https://scan.coverity.com/projects/sysstat-sysstat)
|
||||
[![Build Status](https://travis-ci.org/sysstat/sysstat.svg?branch=master)](https://travis-ci.org/sysstat/sysstat)
|
||||
[![Code Quality: Cpp](https://img.shields.io/lgtm/grade/cpp/g/sysstat/sysstat.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/sysstat/sysstat/context:cpp)
|
||||
[![Total Alerts](https://img.shields.io/lgtm/alerts/g/sysstat/sysstat.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/sysstat/sysstat/alerts)
|
||||
[![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=45U6F9R73ESFQ)
|
||||
|
||||
(C) 1999-2022 Sebastien GODARD (sysstat (at) orange (dot) fr)
|
||||
|
||||
### Introduction
|
||||
|
||||
The sysstat package contains various utilities, common to many commercial Unixes, to monitor system performance and usage activity:
|
||||
|
||||
* **iostat** reports CPU statistics and input/output statistics for block devices and partitions.
|
||||
* **mpstat** reports individual or combined processor related statistics.
|
||||
* **pidstat** reports statistics for Linux tasks (processes) : I/O, CPU, memory, etc.
|
||||
* **tapestat** reports statistics for tape drives connected to the system.
|
||||
* **cifsiostat** reports CIFS statistics.
|
||||
|
||||
Sysstat also contains tools you can schedule via cron or systemd to collect and historize performance and activity data:
|
||||
|
||||
* **sar** collects, reports and saves system activity information (see below a list of metrics collected by sar).
|
||||
* **sadc** is the system activity data collector, used as a backend for sar.
|
||||
* **sa1** collects and stores binary data in the system activity daily data file. It is a front end to sadc designed to be run from cron or systemd.
|
||||
* **sa2** writes a summarized daily activity report. It is a front end to sar designed to be run from cron or systemd.
|
||||
* **sadf** displays data collected by sar in multiple formats (CSV, XML, JSON, etc.) and can be used for data exchange with other programs. This command can also be used to draw graphs for the various activities collected by sar using SVG (Scalable Vector Graphics) format.
|
||||
|
||||
Default sampling interval is 10 minutes but this can be changed of course (it can be as small as 1 second).
|
||||
|
||||
#### System statistics collected by sar:
|
||||
- Input / Output and transfer rate statistics (global, per device, per partition and per network filesystem)
|
||||
- CPU statistics (global and per CPU), including support for virtualization architectures
|
||||
- Memory, hugepages and swap space utilization statistics
|
||||
- Virtual memory, paging and fault statistics
|
||||
- Process creation activity
|
||||
- Interrupt statistics (global, per CPU and per interrupt, including potential APIC interrupt sources, hardware and software interrupts)
|
||||
- Extensive network statistics: network interface activity (number of packets and kB received and transmitted per second, etc.) including failures from network devices; network traffic statistics for IP, TCP, ICMP and UDP protocols based on SNMPv2 standards; support for IPv6-related protocols
|
||||
- Fibre Channel traffic statistics
|
||||
- Software-based network processing (softnet) statistics
|
||||
- NFS server and client activity
|
||||
- Sockets statistics
|
||||
- Run queue and system load statistics
|
||||
- Kernel internal tables utilization statistics
|
||||
- Swapping statistics
|
||||
- TTY devices activity
|
||||
- Power management statistics (instantaneous and average CPU clock frequency, fans speed, devices temperature, voltage inputs)
|
||||
- USB devices plugged into the system
|
||||
- Filesystems utilization (inodes and blocks)
|
||||
- Pressure-Stall Information statistics
|
||||
|
||||
#### Sysstat key features:
|
||||
- Display average statistics values at the end of the reports.
|
||||
- On-the-fly detection of new devices (disks, network interfaces, etc.) that are created or registered dynamically.
|
||||
- Support for UP and SMP machines, including machines with hyperthreaded or multi-core processors.
|
||||
- Support for hotplug CPUs (it detects automagically processors that are disabled or enabled on the fly) and tickless CPUs.
|
||||
- Works on many different architectures, whether 32- or 64-bit.
|
||||
- Needs very little CPU time to run (written in C).
|
||||
- System statistics collected by sar/sadc can be saved in a file for future inspection. You can configure the length of data history to keep. There is no limit for this history length but the available space on your storage device.
|
||||
- System statistics collected by sar/sadc can be exported in various different formats (CSV, XML, JSON, SVG, etc.). DTD and XML Schema documents are included in sysstat package. JSON output format is also available for mpstat and iostat commands.
|
||||
- iostat can display statistics for devices managed by drivers in userspace like spdk.
|
||||
- Smart color output for easier statistics reading.
|
||||
|
||||
![Smart color output](images/color_output.png)
|
||||
- Internationalization support (sysstat has been translated into numerous different languages). Sysstat is now part of the [Translation Project](http://translationproject.org/).
|
||||
- Sysstat commands can automatically select the unit used to display sizes for easier reading (see option `--human`):
|
||||
|
||||
![Sample iostat output](images/iostat.png)
|
||||
|
||||
- Graphs can be generated (SVG format - Scalable Vector Graphics) and displayed in your favorite web browser. See some sample screenshots below:
|
||||
|
||||
![Fancy sysstat graph](images/cpugraph.jpg)
|
||||
|
||||
![Fancy sysstat graph](images/tcgraph.png)
|
||||
|
||||
![Fancy sysstat graph](images/loadavg-svg.png)
|
||||
|
||||
|
||||
Sysstat is Open Source / Free Software, and is freely available under the GNU General Public License, version 2.
|
||||
The latest version of sysstat can always be found on my web site at:
|
||||
|
||||
[http://pagesperso-orange.fr/sebastien.godard/](http://pagesperso-orange.fr/sebastien.godard/)
|
||||
|
||||
See the CHANGES file to know the new features/improvements/bug fixes added
|
||||
in this release of sysstat.
|
||||
Sysstat development can be tracked on [GitHub](https://github.com/sysstat/sysstat).
|
||||
|
||||
### Installation
|
||||
|
||||
#### Install from RHEL/Fedora/CentOS
|
||||
|
||||
Enter:
|
||||
|
||||
```
|
||||
$ sudo yum install sysstat
|
||||
```
|
||||
|
||||
CentOS and Fedora systems call the collector process using a cron job in /etc/cron.d and it's enabled by default.
|
||||
On recent versions, systemd is used instead of cron. You may need to enable and start the sysstat service:
|
||||
|
||||
```
|
||||
$ sudo systemctl enable --now sysstat
|
||||
```
|
||||
|
||||
#### Install from Ubuntu
|
||||
|
||||
Enter:
|
||||
|
||||
```
|
||||
$ sudo apt-get install sysstat
|
||||
```
|
||||
|
||||
Then enable data collecting:
|
||||
|
||||
```
|
||||
$ sudo vi /etc/default/sysstat
|
||||
change ENABLED="false" to ENABLED="true"
|
||||
save the file
|
||||
```
|
||||
|
||||
Last, restart the sysstat service:
|
||||
|
||||
```
|
||||
$ sudo service sysstat restart
|
||||
```
|
||||
|
||||
#### Install from sources
|
||||
|
||||
Clone sysstat public repository with:
|
||||
|
||||
```
|
||||
$ git clone git://github.com/sysstat/sysstat
|
||||
```
|
||||
|
||||
Then configure sysstat for your system:
|
||||
|
||||
```
|
||||
$ cd sysstat
|
||||
$ ./configure
|
||||
```
|
||||
|
||||
You can set several variables and parameters on the command line. For example you
|
||||
can enter the following option to activate data collecting (either using cron or systemd):
|
||||
|
||||
```
|
||||
$ ./configure --enable-install-cron
|
||||
```
|
||||
|
||||
Enter `./configure --help` to display all possible options.
|
||||
Note: There is another way to configure sysstat instead of entering `./configure`:
|
||||
This is the **Interactive Configuration script** (_iconfig_) which will ask you
|
||||
for the value of the main sysstat variables and parameters.
|
||||
Enter `./iconfig` then answer the questions or enter Return to accept
|
||||
the (sane) default values. For yes/no questions, answer 'y' or 'n'
|
||||
(without the quotes): It is case sensitive! You can also enter '?' to get
|
||||
a help message that will explain the meaning of each variable or parameter.
|
||||
|
||||
Compile and install:
|
||||
|
||||
```
|
||||
$ make
|
||||
$ sudo make install
|
||||
```
|
||||
|
||||
### Feedback welcome!
|
||||
|
||||
Please use the BUG_REPORT template file to report a bug: It contains important data
|
||||
that should be provided for this.
|
||||
Please also remember to read the FAQ that comes with sysstat or is available
|
||||
from the Wiki page on GitHub.
|
||||
|
||||
Opening an issue or a pull request on GitHub is the preferred way to report a bug or submit a patch.
|
||||
Patches and suggestions for improvements are always welcome!
|
||||
|
||||
### Support sysstat!
|
||||
|
||||
If you are reading this README file then you are probably about to use the sysstat tools
|
||||
to help you monitor your system and maybe troubleshoot some performance issues. Good choice.
|
||||
Sysstat is made for you. Moreover sysstat is free software and always will be.
|
||||
|
||||
Yet have you ever considered making a donation to sysstat, regardless of how much your
|
||||
contribution is? This in turn would encourage me to keep up the work as good as it can be...
|
||||
Oh, and it would certainly also help me explain to my wife why I spend so much time in front
|
||||
of my computer instead of taking care of the household ;-)
|
||||
|
||||
Click on the "Donate PayPal" button above at the beginning of this file.
|
||||
You can also make a donation [from my web page](http://pagesperso-orange.fr/sebastien.godard/).
|
||||
|
||||
Enjoy!
|
||||
|
||||
--
|
||||
|
||||
Sebastien GODARD - sysstat (at) orange (dot) fr
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,20 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Ask a question and return the answer
|
||||
|
||||
QUESTION=$1
|
||||
PARM=$2
|
||||
TEXT_FILE=$3
|
||||
while :; do
|
||||
echo -n "${QUESTION} [${PARM}] " >/dev/tty
|
||||
read ANSWER
|
||||
if [ "${ANSWER}" = "" ]; then
|
||||
break
|
||||
elif [ "${ANSWER}" = "?" ]; then
|
||||
cat build/${TEXT_FILE} >/dev/tty
|
||||
else
|
||||
echo ${ANSWER}
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
Answer y if you want to remove existing daily data files from
|
||||
system activity directory that were created by a previous
|
||||
version of sysstat.
|
||||
Removing those files may be compulsory if they have been created
|
||||
with a format which is no longer compatible with that of current
|
||||
sysstat version.
|
||||
Default answer is n (files are not deleted).
|
||||
You can still remove them by hand afterwards if sar yields the
|
||||
following error: "Invalid system activity file".
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
Answer y if you want sadc to collect all possible activities. This is
|
||||
equivalent to passing option "-S XALL" to sadc, and as a consequence
|
||||
all optional activities are collected (read sadc(8) manual page to
|
||||
knwow which activities are optional).
|
||||
Default answer is n: Optional activities are NOT collected to prevent
|
||||
data files from growing too large.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
Sysstat manual pages are compressed by default (using xz, bzip2 or gzip program)
|
||||
when they are installed.
|
||||
Answer y if you don't want them to be compressed.
|
||||
Default answer is n here (manual pages will be compressed).
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
To prevent sar daily datafiles from taking to much space on disk, you can
|
||||
ask the sa2 shell script to compress them (using gzip or bzip2) after a
|
||||
certain amount of time.
|
||||
Answer here the number of days after which datafiles are to be compressed
|
||||
(default value is 10 days).
|
||||
Note that this parameter is saved in the /etc/sysconfig/sysstat file.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
This is the directory where sysstat configuration files will
|
||||
be installed. Default location is /etc/sysconfig. The directory
|
||||
will be automatically created during installation stage if
|
||||
necessary. Press Enter to accept this default location.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
This is the name of the main sysstat configuration file which
|
||||
contains the values of various environment variables.
|
||||
Default configuration file name is "sysstat".
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
Answer y to make sure that installing sysstat on your machine
|
||||
only results on files being copied to destinations directories
|
||||
and nothing else (like activating a service) is done.
|
||||
This option is interesting for those creating a sysstat package
|
||||
for example. Indeed some distributions want to install files
|
||||
into $DESTDIR before actually installing them into the root
|
||||
directory. If the distribution uses systemd (a system management
|
||||
daemon written for Linux), the sysstat service should not be
|
||||
activated in this case before files are actually copied into
|
||||
the root directory.
|
||||
But for most of you wanting sysstat to be properly installed
|
||||
when you enter "make install", just answer n here (this is the
|
||||
default answer).
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
You may enter here the sampling interval (in minutes) that the configuration
|
||||
script will use to customize the crontab.
|
||||
Default value is 10. This means that sadc (the system activity data collector
|
||||
called by sar) will take a snapshot of the system counters every 10 minutes.
|
||||
Other reasonable values could be 5, 15 or 20 minutes.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
This is the user the crontab will belong to. Be careful that sysstat may
|
||||
need to replace his original crontab (after having saved it in sysstat
|
||||
directory) if you use an old version of cron (i.e. if /etc/cron.d directory
|
||||
doesn't exist).
|
||||
Default user is root here.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
Answer y to include debug information in some sysstat's commands.
|
||||
This is usually unneeded, so you can safely answer n.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
Tell sa2 script to wait for a random delay in the indicated range before
|
||||
running. This delay is expressed in seconds, and is aimed at preventing
|
||||
a massive I/O burst at the same time on VM sharing the same storage area.
|
||||
Default value is 0, meaning that sa2 will generate reports files immediately.
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
The sa2 shell script creates daily reports, saved in /var/log/sa directory
|
||||
(default location).
|
||||
It also removes daily data files and reports which are older than a number
|
||||
of days. This number defaults to 7 (one week of data history). If the
|
||||
number is greater than 28 then the script uses a tree of log directories
|
||||
under /var/log/sa.
|
||||
Answer here the number of days during which a daily data file or a report
|
||||
should be kept.
|
||||
Note that this parameter is saved in the /etc/sysconfig/sysstat file.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
Here again, don't bother too much with that. When set, this parameter prevents
|
||||
the installation process from setting the attributes (eg. user, group...) of
|
||||
files being installed.
|
||||
For example, when this parameter is used, the contents of the man_group variable
|
||||
won't be taken into account, the installation process won't try to set the
|
||||
user and group attributes of the /var/log/sa directory...
|
||||
This parameter is only used by some distros to package sysstat.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
Answer y if you want to automate sar reporting. In this case, a crontab will
|
||||
be created to periodically start the data collector. System activity daily
|
||||
data files will then be created in the /var/log/sa directory.
|
||||
You can find various crontab templates in sysstat directory. By default
|
||||
sysstat will try to use sysstat.crond template and install it in the
|
||||
/etc/cron.d directory.
|
||||
Default answer is n here.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
Answer y if you don't want to install sysstat's documentation files.
|
||||
Those are primarily manual pages for sysstat's commands. They also
|
||||
include a few other files like the FAQ or README files.
|
||||
Default answer is n here (documentation files ARE installed).
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
Link Time Optimization (LTO) gives the compiler the opportunity to optimize
|
||||
as a single module all the different compilation units that make up a single
|
||||
executable. The downside is an increased compile time.
|
||||
Answer y to compile sysstat commands with link time optimizations.
|
||||
The default answer is n (no).
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
This is the group name that will be used for each manual page file saved on
|
||||
your disk.
|
||||
Don't bother too much with this. The default answer ("man" if it exists)
|
||||
should be OK.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
NLS stands for National Language Support.
|
||||
With NLS enabled, the sysstat utilities will behave in accordance with your
|
||||
current locale. Sysstat messages will be translated into the language specified
|
||||
by the LANG environment variable, among other.
|
||||
Read the nls/README-nls file for more information.
|
||||
So you should not disable NLS support by default.
|
||||
Note that NLS needs the GNU gettext package to work.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
Answering y here disables PCP (Performance Co-Pilot) support.
|
||||
sadf command will then not be able to export its data into a PCP compliant format.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
This is the base directory used for installation.
|
||||
System administrators would rather install software that are added to
|
||||
an already existing system into /usr/local, since /usr is sometimes
|
||||
mounted read-only.
|
||||
/usr/local is the default answer here.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
This is the directory where sysstat's startup scripts and links
|
||||
will be installed. The usual location is /etc/rc.d.
|
||||
Note that if this directory doesn't exist, startup scripts and
|
||||
links won't be installed.
|
||||
Just press Enter to let configure guess the proper value.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
This is the directory where daily data files will be stored.
|
||||
Those files contain statistics reported by the sar command.
|
||||
The usual location is /var/log/sa. The directory will be
|
||||
automatically created during installation stage if necessary.
|
||||
Just press Enter to accept this usual location.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
This is the directory where sadc, the system activity data
|
||||
collector called by sar, will be located (usually PREFIX/lib/sa).
|
||||
sa1 and sa2 shell scripts will also be saved in that directory.
|
||||
Letting ./configure guess the proper location for them should be a safe bet.
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
Options to be passed to sadc. This is typically used to tell sadc
|
||||
which optional activities should be collected.
|
||||
A possible answer here could be for example "-S DISK,POWER" (without
|
||||
the quotation marks) to tell sadc to collect data for block devices
|
||||
and power management statistics. Read sadc(8) manual page to know
|
||||
all the possible options accepted by sadc.
|
||||
You can also skip this question by pressing only the return key. In
|
||||
this case, sadc will collect only standard activities.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
Answering y here disables sensors support. Sysstat commands
|
||||
will not be linked against sensors library even if this library
|
||||
is installed on your system.
|
||||
Without sensors support, some statistics related to power management
|
||||
will not be available (fan speed, device temperature, etc.)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
Answer y if you don't want binaries to be stripped.
|
||||
This will result in commands being slightly bigger but may be
|
||||
necessary for debugging purposes.
|
||||
Default answer is n here (binaries will be stripped).
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
By default sysstat uses systemd if available to start
|
||||
the sa1 (the data collector) and sa2 scripts periodically.
|
||||
Answer y if you want to use the standard cron daemon instead.
|
||||
Default answer is n (no).
|
||||
|
|
@ -0,0 +1,626 @@
|
|||
/*
|
||||
* cifsiostat: Report I/O statistics for CIFS filesystems.
|
||||
* Copyright (C) 2010 Red Hat, Inc. All Rights Reserved
|
||||
* Written by Ivana Varekova <varekova@redhat.com>
|
||||
*
|
||||
***************************************************************************
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
|
||||
* for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "cifsiostat.h"
|
||||
#include "rd_stats.h"
|
||||
#include "count.h"
|
||||
|
||||
#ifdef USE_NLS
|
||||
#include <locale.h>
|
||||
#include <libintl.h>
|
||||
#define _(string) gettext(string)
|
||||
#else
|
||||
#define _(string) (string)
|
||||
#endif
|
||||
|
||||
#ifdef USE_SCCSID
|
||||
#define SCCSID "@(#)sysstat-" VERSION ": " __FILE__ " compiled " __DATE__ " " __TIME__
|
||||
char *sccsid(void) { return (SCCSID); }
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
void int_handler(int n) { return; }
|
||||
#endif
|
||||
|
||||
unsigned long long uptime_cs[2] = {0, 0};
|
||||
struct io_cifs *cifs_list = NULL;
|
||||
|
||||
int cpu_nr = 0; /* Nb of processors on the machine */
|
||||
int flags = 0; /* Flag for common options and system state */
|
||||
int dplaces_nr = -1; /* Number of decimal places */
|
||||
|
||||
long interval = 0;
|
||||
char timestamp[TIMESTAMP_LEN];
|
||||
|
||||
struct sigaction alrm_act;
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Print usage and exit.
|
||||
*
|
||||
* IN:
|
||||
* @progname Name of sysstat command.
|
||||
***************************************************************************
|
||||
*/
|
||||
void usage(char *progname)
|
||||
{
|
||||
fprintf(stderr, _("Usage: %s [ options ] [ <interval> [ <count> ] ]\n"),
|
||||
progname);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, _("Options are:\n"
|
||||
"[ --dec={ 0 | 1 | 2 } ] [ --human ] [ --pretty ]\n"
|
||||
"[ -h ] [ -k | -m ] [ -t ] [ -V ] [ --debuginfo ]\n"));
|
||||
#else
|
||||
fprintf(stderr, _("Options are:\n"
|
||||
"[ --dec={ 0 | 1 | 2 } ] [ --human ] [ --pretty ]\n"
|
||||
"[ -h ] [ -k | -m ] [ -t ] [ -V ]\n"));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* SIGALRM signal handler.
|
||||
*
|
||||
* IN:
|
||||
* @sig Signal number.
|
||||
***************************************************************************
|
||||
*/
|
||||
void alarm_handler(int sig)
|
||||
{
|
||||
alarm(interval);
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Set every cifs entry to nonexistent status.
|
||||
*
|
||||
* IN:
|
||||
* @clist Pointer on the start of the linked list.
|
||||
***************************************************************************
|
||||
*/
|
||||
void set_cifs_nonexistent(struct io_cifs *clist)
|
||||
{
|
||||
while (clist != NULL) {
|
||||
clist->exist = FALSE;
|
||||
clist = clist->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Check if a cifs filesystem is present in the list, and add it if requested.
|
||||
*
|
||||
* IN:
|
||||
* @clist Address of pointer on the start of the linked list.
|
||||
* @name cifs name.
|
||||
*
|
||||
* RETURNS:
|
||||
* Pointer on the io_cifs structure in the list where the cifs is located
|
||||
* (whether it was already in the list or if it has been added).
|
||||
* NULL if the cifs name is too long or if the cifs doesn't exist and we
|
||||
* don't want to add it.
|
||||
***************************************************************************
|
||||
*/
|
||||
struct io_cifs *add_list_cifs(struct io_cifs **clist, char *name)
|
||||
{
|
||||
struct io_cifs *c, *cs;
|
||||
int i;
|
||||
|
||||
if (strnlen(name, MAX_NAME_LEN) == MAX_NAME_LEN)
|
||||
/* cifs name is too long */
|
||||
return NULL;
|
||||
|
||||
while (*clist != NULL) {
|
||||
|
||||
c = *clist;
|
||||
if ((i = strcmp(c->name, name)) == 0) {
|
||||
/* cifs found in list */
|
||||
c->exist = TRUE;
|
||||
return c;
|
||||
}
|
||||
if (i > 0)
|
||||
/*
|
||||
* If no group defined and we don't use /proc/diskstats,
|
||||
* insert current device in alphabetical order.
|
||||
* NB: Using /proc/diskstats ("iostat -p ALL") is a bit better than
|
||||
* using alphabetical order because sda10 comes after sda9...
|
||||
*/
|
||||
break;
|
||||
|
||||
clist = &(c->next);
|
||||
}
|
||||
|
||||
/* cifs not found */
|
||||
cs = *clist;
|
||||
|
||||
/* Add cifs to the list */
|
||||
if ((*clist = (struct io_cifs *) malloc(IO_CIFS_SIZE)) == NULL) {
|
||||
perror("malloc");
|
||||
exit(4);
|
||||
}
|
||||
memset(*clist, 0, IO_CIFS_SIZE);
|
||||
|
||||
c = *clist;
|
||||
for (i = 0; i < 2; i++) {
|
||||
if ((c->cifs_stats[i] = (struct cifs_st *) malloc(CIFS_ST_SIZE)) == NULL) {
|
||||
perror("malloc");
|
||||
exit(4);
|
||||
}
|
||||
memset(c->cifs_stats[i], 0, CIFS_ST_SIZE);
|
||||
}
|
||||
strncpy(c->name, name, sizeof(c->name));
|
||||
c->name[sizeof(c->name) - 1] = '\0';
|
||||
c->exist = TRUE;
|
||||
c->next = cs;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Read CIFS-mount directories stats from /proc/fs/cifs/Stats.
|
||||
*
|
||||
* IN:
|
||||
* @curr Index in array for current sample statistics.
|
||||
***************************************************************************
|
||||
*/
|
||||
void read_cifs_stat(int curr)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[256];
|
||||
char aux[32];
|
||||
int start = 0;
|
||||
long long unsigned aux_open;
|
||||
long long unsigned all_open = 0;
|
||||
char cifs_name[MAX_NAME_LEN];
|
||||
char name_tmp[MAX_NAME_LEN];
|
||||
struct cifs_st scifs;
|
||||
struct io_cifs *ci;
|
||||
|
||||
if ((fp = fopen(CIFSSTATS, "r")) == NULL)
|
||||
return;
|
||||
|
||||
sprintf(aux, "%%*d) %%%ds",
|
||||
MAX_NAME_LEN < 200 ? MAX_NAME_LEN - 1 : 200);
|
||||
|
||||
memset(&scifs, 0, CIFS_ST_SIZE);
|
||||
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
|
||||
/* Read CIFS directory name */
|
||||
if (isdigit((unsigned char) line[0]) && sscanf(line, aux , name_tmp) == 1) {
|
||||
if (start) {
|
||||
scifs.fopens = all_open;
|
||||
ci = add_list_cifs(&cifs_list, cifs_name);
|
||||
if (ci != NULL) {
|
||||
*ci->cifs_stats[curr] = scifs;
|
||||
}
|
||||
all_open = 0;
|
||||
}
|
||||
else {
|
||||
start = 1;
|
||||
}
|
||||
strncpy(cifs_name, name_tmp, sizeof(cifs_name));
|
||||
cifs_name[sizeof(cifs_name) - 1] = '\0';
|
||||
memset(&scifs, 0, CIFS_ST_SIZE);
|
||||
}
|
||||
else {
|
||||
if (!strncmp(line, "Reads:", 6)) {
|
||||
/*
|
||||
* SMB1 format: Reads: %llu Bytes: %llu
|
||||
* SMB2 format: Reads: %llu sent %llu failed
|
||||
* If this is SMB2 format then only the first variable (rd_ops) will be set.
|
||||
*/
|
||||
sscanf(line, "Reads: %llu Bytes: %llu", &scifs.rd_ops, &scifs.rd_bytes);
|
||||
}
|
||||
else if (!strncmp(line, "Bytes read:", 11)) {
|
||||
sscanf(line, "Bytes read: %llu Bytes written: %llu",
|
||||
&scifs.rd_bytes, &scifs.wr_bytes);
|
||||
}
|
||||
else if (!strncmp(line, "Writes:", 7)) {
|
||||
/*
|
||||
* SMB1 format: Writes: %llu Bytes: %llu
|
||||
* SMB2 format: Writes: %llu sent %llu failed
|
||||
* If this is SMB2 format then only the first variable (wr_ops) will be set.
|
||||
*/
|
||||
sscanf(line, "Writes: %llu Bytes: %llu", &scifs.wr_ops, &scifs.wr_bytes);
|
||||
}
|
||||
else if (!strncmp(line, "Opens:", 6)) {
|
||||
sscanf(line, "Opens: %llu Closes:%llu Deletes: %llu",
|
||||
&aux_open, &scifs.fcloses, &scifs.fdeletes);
|
||||
all_open += aux_open;
|
||||
}
|
||||
else if (!strncmp(line, "Posix Opens:", 12)) {
|
||||
sscanf(line, "Posix Opens: %llu", &aux_open);
|
||||
all_open += aux_open;
|
||||
}
|
||||
else if (!strncmp(line, "Open files:", 11)) {
|
||||
sscanf(line, "Open files: %llu total (local), %llu",
|
||||
&all_open, &aux_open);
|
||||
all_open += aux_open;
|
||||
}
|
||||
else if (!strncmp(line, "Closes:", 7)) {
|
||||
sscanf(line, "Closes: %llu", &scifs.fcloses);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (start) {
|
||||
scifs.fopens = all_open;
|
||||
ci = add_list_cifs(&cifs_list, cifs_name);
|
||||
if (ci != NULL) {
|
||||
*ci->cifs_stats[curr] = scifs;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Display CIFS stats header.
|
||||
*
|
||||
* OUT:
|
||||
* @fctr Conversion factor.
|
||||
***************************************************************************
|
||||
*/
|
||||
void write_cifs_stat_header(int *fctr)
|
||||
{
|
||||
if (!DISPLAY_PRETTY(flags)) {
|
||||
printf("Filesystem ");
|
||||
}
|
||||
if (DISPLAY_KILOBYTES(flags)) {
|
||||
printf(" rkB/s wkB/s");
|
||||
*fctr = 1024;
|
||||
}
|
||||
else if (DISPLAY_MEGABYTES(flags)) {
|
||||
printf(" rMB/s wMB/s");
|
||||
*fctr = 1024 * 1024;
|
||||
}
|
||||
else {
|
||||
printf(" rB/s wB/s");
|
||||
*fctr = 1;
|
||||
}
|
||||
printf(" rops/s wops/s fo/s fc/s fd/s");
|
||||
if (DISPLAY_PRETTY(flags)) {
|
||||
printf(" Filesystem");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Write CIFS stats read from /proc/fs/cifs/Stats.
|
||||
*
|
||||
* IN:
|
||||
* @curr Index in array for current sample statistics.
|
||||
* @itv Interval of time (in 1/100th of a second).
|
||||
* @fctr Conversion factor.
|
||||
* @clist Pointer on the linked list where the cifs is saved.
|
||||
* @ioi Current sample statistics.
|
||||
* @ioj Previous sample statistics.
|
||||
***************************************************************************
|
||||
*/
|
||||
void write_cifs_stat(int curr, unsigned long long itv, int fctr,
|
||||
struct io_cifs *clist, struct cifs_st *ioni,
|
||||
struct cifs_st *ionj)
|
||||
{
|
||||
double rbytes, wbytes;
|
||||
|
||||
if (!DISPLAY_PRETTY(flags)) {
|
||||
cprintf_in(IS_STR, "%-22s", clist->name, 0);
|
||||
}
|
||||
|
||||
/* rB/s wB/s fo/s fc/s fd/s*/
|
||||
rbytes = S_VALUE(ionj->rd_bytes, ioni->rd_bytes, itv);
|
||||
wbytes = S_VALUE(ionj->wr_bytes, ioni->wr_bytes, itv);
|
||||
if (!DISPLAY_UNIT(flags)) {
|
||||
rbytes /= fctr;
|
||||
wbytes /= fctr;
|
||||
}
|
||||
cprintf_f(DISPLAY_UNIT(flags) ? UNIT_BYTE : NO_UNIT, 2, 12, 2,
|
||||
rbytes, wbytes);
|
||||
cprintf_f(NO_UNIT, 2, 9, 2,
|
||||
S_VALUE(ionj->rd_ops, ioni->rd_ops, itv),
|
||||
S_VALUE(ionj->wr_ops, ioni->wr_ops, itv));
|
||||
cprintf_f(NO_UNIT, 3, 12, 2,
|
||||
S_VALUE(ionj->fopens, ioni->fopens, itv),
|
||||
S_VALUE(ionj->fcloses, ioni->fcloses, itv),
|
||||
S_VALUE(ionj->fdeletes, ioni->fdeletes, itv));
|
||||
if (DISPLAY_PRETTY(flags)) {
|
||||
cprintf_in(IS_STR, " %s", clist->name, 0);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Print everything now (stats and uptime).
|
||||
*
|
||||
* IN:
|
||||
* @curr Index in array for current sample statistics.
|
||||
* @rectime Current date and time.
|
||||
***************************************************************************
|
||||
*/
|
||||
void write_stats(int curr, struct tm *rectime)
|
||||
{
|
||||
int fctr = 1;
|
||||
unsigned long long itv;
|
||||
struct io_cifs *clist;
|
||||
struct cifs_st *ioni, *ionj;
|
||||
|
||||
/* Test stdout */
|
||||
TEST_STDOUT(STDOUT_FILENO);
|
||||
|
||||
/* Print time stamp */
|
||||
if (DISPLAY_TIMESTAMP(flags)) {
|
||||
if (DISPLAY_ISO(flags)) {
|
||||
strftime(timestamp, sizeof(timestamp), "%FT%T%z", rectime);
|
||||
}
|
||||
else {
|
||||
strftime(timestamp, sizeof(timestamp), "%x %X", rectime);
|
||||
}
|
||||
printf("%s\n", timestamp);
|
||||
#ifdef DEBUG
|
||||
if (DISPLAY_DEBUG(flags)) {
|
||||
fprintf(stderr, "%s\n", timestamp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Interval of time, reduced to one processor */
|
||||
itv = get_interval(uptime_cs[!curr], uptime_cs[curr]);
|
||||
|
||||
/* Display CIFS stats header */
|
||||
write_cifs_stat_header(&fctr);
|
||||
|
||||
for (clist = cifs_list; clist != NULL; clist = clist->next) {
|
||||
|
||||
if (!clist->exist)
|
||||
/* Current cifs non existent */
|
||||
continue;
|
||||
|
||||
ioni = clist->cifs_stats[curr];
|
||||
ionj = clist->cifs_stats[!curr];
|
||||
|
||||
#ifdef DEBUG
|
||||
if (DISPLAY_DEBUG(flags)) {
|
||||
/* Debug output */
|
||||
fprintf(stderr, "name=%s itv=%llu fctr=%d ioni{ rd_bytes=%llu "
|
||||
"wr_bytes=%llu rd_ops=%llu wr_ops=%llu fopens=%llu "
|
||||
"fcloses=%llu fdeletes=%llu}\n",
|
||||
clist->name, itv, fctr,
|
||||
ioni->rd_bytes, ioni->wr_bytes,
|
||||
ioni->rd_ops, ioni->wr_ops,
|
||||
ioni->fopens, ioni->fcloses,
|
||||
ioni->fdeletes);
|
||||
}
|
||||
#endif
|
||||
write_cifs_stat(curr, itv, fctr, clist, ioni, ionj);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Main loop: Read stats from the relevant sources and display them.
|
||||
*
|
||||
* IN:
|
||||
* @count Number of lines of stats to print.
|
||||
* @rectime Current date and time.
|
||||
***************************************************************************
|
||||
*/
|
||||
void rw_io_stat_loop(long int count, struct tm *rectime)
|
||||
{
|
||||
int curr = 1;
|
||||
|
||||
/* Set a handler for SIGALRM */
|
||||
memset(&alrm_act, 0, sizeof(alrm_act));
|
||||
alrm_act.sa_handler = alarm_handler;
|
||||
sigaction(SIGALRM, &alrm_act, NULL);
|
||||
alarm(interval);
|
||||
|
||||
do {
|
||||
/* Every device is potentially nonexistent */
|
||||
set_cifs_nonexistent(cifs_list);
|
||||
|
||||
/* Read system uptime in 1/100th of a second */
|
||||
read_uptime(&(uptime_cs[curr]));
|
||||
|
||||
/* Read CIFS stats */
|
||||
read_cifs_stat(curr);
|
||||
|
||||
/* Get time */
|
||||
get_localtime(rectime, 0);
|
||||
|
||||
/* Print results */
|
||||
write_stats(curr, rectime);
|
||||
|
||||
if (count > 0) {
|
||||
count--;
|
||||
}
|
||||
|
||||
if (count) {
|
||||
curr ^= 1;
|
||||
__pause();
|
||||
}
|
||||
}
|
||||
while (count);
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Main entry to the cifsiostat program.
|
||||
***************************************************************************
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int it = 0;
|
||||
int opt = 1;
|
||||
int i;
|
||||
long count = 1;
|
||||
struct utsname header;
|
||||
struct tm rectime;
|
||||
|
||||
#ifdef USE_NLS
|
||||
/* Init National Language Support */
|
||||
init_nls();
|
||||
#endif
|
||||
|
||||
/* Init color strings */
|
||||
init_colors();
|
||||
|
||||
/* Process args... */
|
||||
while (opt < argc) {
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!strcmp(argv[opt], "--debuginfo")) {
|
||||
flags |= I_D_DEBUG;
|
||||
opt++;
|
||||
} else
|
||||
#endif
|
||||
|
||||
if (!strcmp(argv[opt], "--human")) {
|
||||
flags |= I_D_UNIT;
|
||||
opt++;
|
||||
}
|
||||
|
||||
else if (!strcmp(argv[opt], "--pretty")) {
|
||||
/* Display an easy-to-read CIFS report */
|
||||
flags |= I_D_PRETTY;
|
||||
opt++;
|
||||
}
|
||||
|
||||
else if (!strncmp(argv[opt], "--dec=", 6) && (strlen(argv[opt]) == 7)) {
|
||||
/* Get number of decimal places */
|
||||
dplaces_nr = atoi(argv[opt] + 6);
|
||||
if ((dplaces_nr < 0) || (dplaces_nr > 2)) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
opt++;
|
||||
}
|
||||
|
||||
else if (!strncmp(argv[opt], "-", 1)) {
|
||||
for (i = 1; *(argv[opt] + i); i++) {
|
||||
|
||||
switch (*(argv[opt] + i)) {
|
||||
|
||||
case 'h':
|
||||
/* Option -h is equivalent to --pretty --human */
|
||||
flags |= I_D_PRETTY + I_D_UNIT;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
if (DISPLAY_MEGABYTES(flags)) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
/* Display stats in kB/s */
|
||||
flags |= I_D_KILOBYTES;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (DISPLAY_KILOBYTES(flags)) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
/* Display stats in MB/s */
|
||||
flags |= I_D_MEGABYTES;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
/* Display timestamp */
|
||||
flags |= I_D_TIMESTAMP;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
/* Print version number and exit */
|
||||
print_version();
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
opt++;
|
||||
}
|
||||
|
||||
else if (!it) {
|
||||
interval = atol(argv[opt++]);
|
||||
if (interval < 0) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
count = -1;
|
||||
it = 1;
|
||||
}
|
||||
|
||||
else if (it > 0) {
|
||||
count = atol(argv[opt++]);
|
||||
if ((count < 1) || !interval) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
it = -1;
|
||||
}
|
||||
else {
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!interval) {
|
||||
count = 1;
|
||||
}
|
||||
|
||||
/* How many processors on this machine? */
|
||||
cpu_nr = get_cpu_nr(~0, FALSE);
|
||||
|
||||
get_localtime(&rectime, 0);
|
||||
|
||||
/*
|
||||
* Don't buffer data if redirected to a pipe.
|
||||
* Note: With musl-c, the behavior of this function is undefined except
|
||||
* when it is the first operation on the stream.
|
||||
*/
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
/* Get system name, release number and hostname */
|
||||
__uname(&header);
|
||||
if (print_gal_header(&rectime, header.sysname, header.release,
|
||||
header.nodename, header.machine, cpu_nr,
|
||||
PLAIN_OUTPUT)) {
|
||||
flags |= I_D_ISO;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* Main loop */
|
||||
rw_io_stat_loop(count, &rectime);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* cifsiostat: Report CIFS statistics
|
||||
* Copyright (C) 2010 Red Hat, Inc. All Rights Reserved
|
||||
* Written by Ivana Varekova <varekova@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef _CIFSIOSTAT_H
|
||||
#define _CIFSIOSTAT_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define CIFSSTATS PRE "/proc/fs/cifs/Stats"
|
||||
|
||||
/* I_: cifsiostat - D_: Display - F_: Flag */
|
||||
#define I_D_TIMESTAMP 0x001
|
||||
#define I_D_KILOBYTES 0x002
|
||||
#define I_D_MEGABYTES 0x004
|
||||
#define I_D_ISO 0x008
|
||||
#define I_D_PRETTY 0x010
|
||||
#define I_D_DEBUG 0x020
|
||||
#define I_D_UNIT 0x040
|
||||
|
||||
#define DISPLAY_TIMESTAMP(m) (((m) & I_D_TIMESTAMP) == I_D_TIMESTAMP)
|
||||
#define DISPLAY_KILOBYTES(m) (((m) & I_D_KILOBYTES) == I_D_KILOBYTES)
|
||||
#define DISPLAY_MEGABYTES(m) (((m) & I_D_MEGABYTES) == I_D_MEGABYTES)
|
||||
#define DISPLAY_ISO(m) (((m) & I_D_ISO) == I_D_ISO)
|
||||
#define DISPLAY_PRETTY(m) (((m) & I_D_PRETTY) == I_D_PRETTY)
|
||||
#define DISPLAY_DEBUG(m) (((m) & I_D_DEBUG) == I_D_DEBUG)
|
||||
#define DISPLAY_UNIT(m) (((m) & I_D_UNIT) == I_D_UNIT)
|
||||
|
||||
struct cifs_st {
|
||||
unsigned long long rd_bytes __attribute__ ((aligned (8)));
|
||||
unsigned long long wr_bytes __attribute__ ((packed));
|
||||
unsigned long long rd_ops __attribute__ ((packed));
|
||||
unsigned long long wr_ops __attribute__ ((packed));
|
||||
unsigned long long fopens __attribute__ ((packed));
|
||||
unsigned long long fcloses __attribute__ ((packed));
|
||||
unsigned long long fdeletes __attribute__ ((packed));
|
||||
};
|
||||
|
||||
#define CIFS_ST_SIZE (sizeof(struct cifs_st))
|
||||
|
||||
struct io_cifs {
|
||||
char name[MAX_NAME_LEN];
|
||||
int exist;
|
||||
struct cifs_st *cifs_stats[2];
|
||||
struct io_cifs *next;
|
||||
};
|
||||
|
||||
#define IO_CIFS_SIZE (sizeof(struct io_cifs))
|
||||
|
||||
#endif /* _CIFSIOSTAT_H */
|
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
* sysstat: System performance tools for Linux
|
||||
* (C) 1999-2022 by Sebastien Godard (sysstat <at> orange.fr)
|
||||
*/
|
||||
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
/* Maximum length of sensors device name */
|
||||
#define MAX_SENSORS_DEV_LEN 20
|
||||
|
||||
#include <time.h>
|
||||
#include <sched.h> /* For __CPU_SETSIZE */
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include "systest.h"
|
||||
|
||||
#ifdef HAVE_SYS_SYSMACROS_H
|
||||
/* Needed on some non-glibc environments */
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Various keywords and constants
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define PLAIN_OUTPUT 0
|
||||
|
||||
#define DISP_HDR 1
|
||||
|
||||
/* Index in units array (see common.c) */
|
||||
#define NO_UNIT -1
|
||||
#define UNIT_SECTOR 0
|
||||
#define UNIT_BYTE 1
|
||||
#define UNIT_KILOBYTE 2
|
||||
|
||||
#define NR_UNITS 8
|
||||
|
||||
/* Timestamp buffer length */
|
||||
#define TIMESTAMP_LEN 64
|
||||
|
||||
/* Number of seconds per day */
|
||||
#define SEC_PER_DAY 3600 * 24
|
||||
|
||||
/* Maximum number of CPUs */
|
||||
#if defined(__CPU_SETSIZE) && __CPU_SETSIZE > 8192
|
||||
#define NR_CPUS __CPU_SETSIZE
|
||||
#else
|
||||
#define NR_CPUS 8192
|
||||
#endif
|
||||
|
||||
/* Maximum number of interrupts */
|
||||
#define NR_IRQS 4096
|
||||
|
||||
/* Size of /proc/interrupts line, CPU data excluded */
|
||||
#define INTERRUPTS_LINE 128
|
||||
|
||||
/* Keywords */
|
||||
#define K_ISO "ISO"
|
||||
#define K_ALL "ALL"
|
||||
#define K_LOWERALL "all"
|
||||
#define K_LOWERSUM "sum"
|
||||
#define K_UTC "UTC"
|
||||
#define K_JSON "JSON"
|
||||
|
||||
/* Files */
|
||||
#define __DISKSTATS "diskstats"
|
||||
#define __BLOCK "block"
|
||||
#define __DEV_BLOCK "dev/block"
|
||||
#define SLASH_SYS PRE "/sys"
|
||||
#define SLASH_DEV PRE "/dev/"
|
||||
#define STAT PRE "/proc/stat"
|
||||
#define UPTIME PRE "/proc/uptime"
|
||||
#define DISKSTATS PRE "/proc/" __DISKSTATS
|
||||
#define INTERRUPTS PRE "/proc/interrupts"
|
||||
#define MEMINFO PRE "/proc/meminfo"
|
||||
#define SYSFS_BLOCK SLASH_SYS "/" __BLOCK
|
||||
#define SYSFS_DEV_BLOCK SLASH_SYS "/" __DEV_BLOCK
|
||||
#define SYSFS_DEVCPU PRE "/sys/devices/system/cpu"
|
||||
#define SYSFS_TIME_IN_STATE "cpufreq/stats/time_in_state"
|
||||
#define S_STAT "stat"
|
||||
#define DEVMAP_DIR PRE "/dev/mapper"
|
||||
#define DEVICES PRE "/proc/devices"
|
||||
#define SYSFS_USBDEV PRE "/sys/bus/usb/devices"
|
||||
#define DEV_DISK_BY PRE "/dev/disk/by"
|
||||
#define DEV_DISK_BY_ID PRE "/dev/disk/by-id"
|
||||
#define SYSFS_IDVENDOR "idVendor"
|
||||
#define SYSFS_IDPRODUCT "idProduct"
|
||||
#define SYSFS_BMAXPOWER "bMaxPower"
|
||||
#define SYSFS_MANUFACTURER "manufacturer"
|
||||
#define SYSFS_PRODUCT "product"
|
||||
#define SYSFS_FCHOST PRE "/sys/class/fc_host"
|
||||
|
||||
#define MAX_FILE_LEN 512
|
||||
#define MAX_PF_NAME 1024
|
||||
#define MAX_NAME_LEN 128
|
||||
|
||||
#define IGNORE_VIRTUAL_DEVICES FALSE
|
||||
#define ACCEPT_VIRTUAL_DEVICES TRUE
|
||||
|
||||
/* Environment variables */
|
||||
#define ENV_TIME_FMT "S_TIME_FORMAT"
|
||||
#define ENV_TIME_DEFTM "S_TIME_DEF_TIME"
|
||||
#define ENV_COLORS "S_COLORS"
|
||||
#define ENV_COLORS_SGR "S_COLORS_SGR"
|
||||
|
||||
#define C_NEVER "never"
|
||||
#define C_ALWAYS "always"
|
||||
|
||||
#define DIGITS "0123456789"
|
||||
#define XDIGITS "0123456789-"
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Macro functions definitions.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Macro used to define activity bitmap size.
|
||||
* All those bitmaps have an additional bit used for global activity
|
||||
* (eg. CPU "all" or total number of interrupts). That's why we do "(m) + 1".
|
||||
*/
|
||||
#define BITMAP_SIZE(m) ((((m) + 1) >> 3) + 1)
|
||||
|
||||
/* Allocate and init structure */
|
||||
#define SREALLOC(S, TYPE, SIZE) do { \
|
||||
TYPE *_p_ = S; \
|
||||
if ((SIZE) != 0) { \
|
||||
if ((S = (TYPE *) realloc(S, (SIZE))) == NULL) { \
|
||||
perror("realloc"); \
|
||||
exit(4); \
|
||||
} \
|
||||
/* If the ptr was null, then it's a malloc() */ \
|
||||
if (!_p_) { \
|
||||
memset(S, 0, (SIZE)); \
|
||||
} \
|
||||
} \
|
||||
if (!S) { \
|
||||
/* Should never happen */ \
|
||||
fprintf(stderr, "srealloc\n"); \
|
||||
exit(4); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Macros used to display statistics values.
|
||||
*
|
||||
*/
|
||||
/* With S_VALUE macro, the interval of time (@p) is given in 1/100th of a second */
|
||||
#define S_VALUE(m,n,p) (((double) ((n) - (m))) / (p) * 100)
|
||||
/* Define SP_VALUE() to normalize to % */
|
||||
#define SP_VALUE(m,n,p) (((double) ((n) - (m))) / (p) * 100)
|
||||
|
||||
/*
|
||||
* Under very special circumstances, STDOUT may become unavailable.
|
||||
* This is what we try to guess here.
|
||||
*/
|
||||
#define TEST_STDOUT(_fd_) do { \
|
||||
if (write(_fd_, "", 0) == -1) { \
|
||||
perror("stdout"); \
|
||||
exit(6); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define MINIMUM(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#define PANIC(m) sysstat_panic(__FUNCTION__, m)
|
||||
|
||||
/* Number of ticks per second */
|
||||
#define HZ hz
|
||||
extern unsigned long hz;
|
||||
|
||||
/* Number of bit shifts to convert pages to kB */
|
||||
extern unsigned int kb_shift;
|
||||
|
||||
/*
|
||||
* kB <-> number of pages.
|
||||
* Page size depends on machine architecture (4 kB, 8 kB, 16 kB, 64 kB...)
|
||||
*/
|
||||
#define KB_TO_PG(k) ((k) >> kb_shift)
|
||||
#define PG_TO_KB(k) ((k) << kb_shift)
|
||||
|
||||
/* Type of persistent device names used in sar and iostat */
|
||||
extern char persistent_name_type[MAX_FILE_LEN];
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Colors definitions
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#define C_LIGHT_RED "\e[31;22m"
|
||||
#define C_BOLD_RED "\e[31;1m"
|
||||
#define C_LIGHT_GREEN "\e[32;22m"
|
||||
#define C_LIGHT_YELLOW "\e[33;22m"
|
||||
#define C_BOLD_MAGENTA "\e[35;1m"
|
||||
#define C_BOLD_BLUE "\e[34;1m"
|
||||
#define C_LIGHT_BLUE "\e[34;22m"
|
||||
#define C_NORMAL "\e[0m"
|
||||
|
||||
#define PERCENT_LIMIT_HIGH 75.0
|
||||
#define PERCENT_LIMIT_LOW 50.0
|
||||
|
||||
#define MAX_SGR_LEN 16
|
||||
|
||||
#define IS_INT 0
|
||||
#define IS_STR 1
|
||||
#define IS_RESTART 2
|
||||
#define IS_DEBUG IS_RESTART
|
||||
#define IS_COMMENT 3
|
||||
#define IS_ZERO 4
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Structures definitions
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/* Structure used for extended disk statistics */
|
||||
struct ext_disk_stats {
|
||||
double util;
|
||||
double await;
|
||||
double arqsz;
|
||||
};
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Functions prototypes
|
||||
***************************************************************************
|
||||
*/
|
||||
void print_version
|
||||
(void);
|
||||
void get_HZ
|
||||
(void);
|
||||
void get_kb_shift
|
||||
(void);
|
||||
time_t get_localtime
|
||||
(struct tm *, int);
|
||||
time_t get_time
|
||||
(struct tm *, int);
|
||||
void init_nls
|
||||
(void);
|
||||
int is_device
|
||||
(char *, char *, int);
|
||||
void sysstat_panic
|
||||
(const char *, int);
|
||||
int extract_wwnid
|
||||
(char *, unsigned long long *, unsigned int *);
|
||||
int get_wwnid_from_pretty
|
||||
(char *, unsigned long long *, unsigned int *);
|
||||
int check_dir
|
||||
(char *);
|
||||
void check_overflow
|
||||
(unsigned int, unsigned int, unsigned int);
|
||||
|
||||
#ifndef SOURCE_SADC
|
||||
int count_bits
|
||||
(void *, int);
|
||||
int count_csvalues
|
||||
(int, char **);
|
||||
void cprintf_f
|
||||
(int, int, int, int, ...);
|
||||
void cprintf_in
|
||||
(int, char *, char *, int);
|
||||
void cprintf_pc
|
||||
(int, int, int, int, ...);
|
||||
void cprintf_s
|
||||
(int, char *, char *);
|
||||
void cprintf_u64
|
||||
(int, int, int, ...);
|
||||
void cprintf_x
|
||||
(int, int, ...);
|
||||
char *device_name
|
||||
(char *);
|
||||
char *get_device_name
|
||||
(unsigned int, unsigned int, unsigned long long [],
|
||||
unsigned int, unsigned int, unsigned int, unsigned int, char *);
|
||||
unsigned int get_devmap_major
|
||||
(void);
|
||||
unsigned long long get_interval
|
||||
(unsigned long long, unsigned long long);
|
||||
char *get_persistent_name_from_pretty
|
||||
(char *);
|
||||
char *get_persistent_type_dir
|
||||
(char *);
|
||||
char *get_pretty_name_from_persistent
|
||||
(char *);
|
||||
int get_sysfs_dev_nr
|
||||
(int);
|
||||
int get_win_height
|
||||
(void);
|
||||
void init_colors
|
||||
(void);
|
||||
double ll_sp_value
|
||||
(unsigned long long, unsigned long long, unsigned long long);
|
||||
int is_iso_time_fmt
|
||||
(void);
|
||||
int parse_range_values
|
||||
(char *t, int, int *, int *);
|
||||
int parse_values
|
||||
(char *, unsigned char[], int, const char *);
|
||||
int print_gal_header
|
||||
(struct tm *, char *, char *, char *, char *, int, int);
|
||||
int set_report_date
|
||||
(struct tm *, char[], int);
|
||||
char *strtolower
|
||||
(char *);
|
||||
void xprintf
|
||||
(int, const char *, ...);
|
||||
void xprintf0
|
||||
(int, const char *, ...);
|
||||
|
||||
#endif /* SOURCE_SADC undefined */
|
||||
#endif /* _COMMON_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,807 @@
|
|||
# configure.in
|
||||
#
|
||||
# (C) 2007 - Ivana Varekova <varekova@redhat.com>
|
||||
# Modified by Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
||||
# Initialization of $PACKAGE_VERSION and $PACKAGE_NAME variables
|
||||
AC_INIT(sysstat, 12.6.1)
|
||||
|
||||
# Ensure that a recent enough version of Autoconf is being used
|
||||
AC_PREREQ(2.53)
|
||||
|
||||
# Check whether the configure script is in the right dir
|
||||
AC_CONFIG_SRCDIR(ioconf.h)
|
||||
|
||||
# Check programs
|
||||
echo .
|
||||
echo Check programs:
|
||||
echo .
|
||||
|
||||
AC_PROG_CC
|
||||
AC_GNU_SOURCE
|
||||
AC_PROG_LN_S
|
||||
|
||||
DFLAGS=""
|
||||
|
||||
AC_CHECK_PROG(CHMOD, chmod, chmod)
|
||||
AC_CHECK_PROG(CHOWN, chown, chown)
|
||||
AC_CHECK_PROG(AR, ar, ar)
|
||||
AC_CHECK_PROG(INSTALL, install, install)
|
||||
AC_CHECK_PROG(MSGFMT, msgfmt, msgfmt)
|
||||
AC_CHECK_PROG(XGETTEXT, xgettext, xgettext)
|
||||
AC_CHECK_PROG(MSGMERGE, msgmerge, msgmerge)
|
||||
AC_CHECK_PROG(VER_XML, xmllint, xmllint)
|
||||
AC_CHECK_PROGS(VER_JSON, json_verify json_pp, true)
|
||||
AC_CHECK_PROGS(ZIP, xz bzip2 gzip, gzip)
|
||||
INSTALL_DATA="\${INSTALL} -m 644"
|
||||
AC_SUBST(INSTALL_DATA)
|
||||
INSTALL_BIN="\${INSTALL} -m 755"
|
||||
AC_SUBST(INSTALL_BIN)
|
||||
|
||||
AC_SUBST(VER_JSON)
|
||||
AC_SUBST(VER_XML)
|
||||
|
||||
AC_PATH_PROG(PATH_CP, cp)
|
||||
AC_PATH_PROG(PATH_CHKCONFIG, chkconfig)
|
||||
|
||||
# Check for systemd
|
||||
AC_CHECK_PROG(PKG_CONFIG, pkg-config, pkg-config)
|
||||
AC_PATH_PROG(SYSTEMCTL, systemctl)
|
||||
AC_ARG_WITH([systemdsystemunitdir],
|
||||
AS_HELP_STRING([--with-systemdsystemunitdir=DIR],[Directory for systemd service files]),
|
||||
[], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
|
||||
if test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ; then
|
||||
AC_SUBST([SYSTEMD_UNIT_DIR], [$with_systemdsystemunitdir])
|
||||
fi
|
||||
AC_ARG_WITH([systemdsleepdir],
|
||||
AS_HELP_STRING([--with-systemdsleepdir=DIR],[Directory for systemd suspend/resume scripts]),
|
||||
[], [with_systemdsleepdir=$($PKG_CONFIG --variable=systemdsleepdir systemd)])
|
||||
if test -n "$with_systemdsleepdir" -a "x$with_systemdsleepdir" != xno ; then
|
||||
AC_SUBST([SYSTEMD_SLEEP_DIR], [$with_systemdsleepdir])
|
||||
fi
|
||||
|
||||
# Check libraries
|
||||
|
||||
# Check header files
|
||||
echo .
|
||||
echo Check header files:
|
||||
echo .
|
||||
HAVE_LIBINTL_H=
|
||||
HAVE_LOCALE_H=
|
||||
HAVE_SYS_SYSMACROS_H=
|
||||
HAVE_SYS_PARAM_H=
|
||||
AC_CHECK_HEADERS(ctype.h)
|
||||
AC_CHECK_HEADERS(errno.h)
|
||||
AC_CHECK_HEADERS(libintl.h, HAVE_LIBINTL_H=1)
|
||||
AC_CHECK_HEADERS(locale.h, HAVE_LOCALE_H=1)
|
||||
AC_CHECK_HEADERS(linux/sched.h, HAVE_LINUX_SCHED_H=1)
|
||||
AC_CHECK_HEADERS(net/if.h)
|
||||
AC_CHECK_HEADERS(regex.h)
|
||||
AC_CHECK_HEADERS(signal.h)
|
||||
AC_CHECK_HEADERS(stdio.h)
|
||||
AC_CHECK_HEADERS(stdint.h)
|
||||
AC_CHECK_HEADERS(fcntl.h)
|
||||
AC_CHECK_HEADERS(inttypes.h)
|
||||
AC_CHECK_HEADERS(libgen.h)
|
||||
AC_CHECK_HEADERS(pwd.h)
|
||||
AC_CHECK_HEADERS(time.h)
|
||||
AC_CHECK_HEADERS(unistd.h)
|
||||
AC_CHECK_HEADERS(pcp/pmapi.h, HAVE_PCP_PMAPI_H=1)
|
||||
AC_CHECK_HEADERS(pcp/impl.h, HAVE_PCP_IMPL_H=1)
|
||||
AC_CHECK_HEADERS(sys/time.h)
|
||||
AC_CHECK_HEADERS(sys/statvfs.h)
|
||||
AC_CHECK_HEADERS(sys/types.h)
|
||||
AC_CHECK_HEADERS(sys/file.h)
|
||||
AC_CHECK_HEADERS(sys/ioctl.h)
|
||||
AC_CHECK_HEADERS(sys/param.h, HAVE_SYS_PARAM_H=1)
|
||||
AC_CHECK_HEADERS(sys/stat.h)
|
||||
AC_CHECK_HEADERS(sys/sysmacros.h, HAVE_SYS_SYSMACROS_H=1)
|
||||
AC_CHECK_HEADERS(sys/utsname.h)
|
||||
|
||||
echo .
|
||||
echo Check typedefs, structures and compiler characteristics:
|
||||
echo .
|
||||
AC_TYPE_SIGNAL
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_OFF_T
|
||||
|
||||
echo .
|
||||
echo Check library functions:
|
||||
echo .
|
||||
AC_CHECK_FUNCS(strchr)
|
||||
AC_CHECK_FUNCS(strcspn)
|
||||
AC_CHECK_FUNCS(strspn)
|
||||
AC_CHECK_FUNCS(strstr)
|
||||
|
||||
# Should we check for PCP support?
|
||||
AC_MSG_CHECKING(for PCP support)
|
||||
AC_ARG_ENABLE(pcp,
|
||||
AC_HELP_STRING([--disable-pcp],
|
||||
[disable PCP support]),
|
||||
PCP=$enableval,PCP=yes)
|
||||
if test $PCP != "yes"; then
|
||||
HAVE_PCP="n"
|
||||
else
|
||||
HAVE_PCP="y"
|
||||
fi
|
||||
|
||||
if test ! $HAVE_PCP_PMAPI_H; then
|
||||
HAVE_PCP="n"
|
||||
PCP=no
|
||||
fi
|
||||
AC_MSG_RESULT($PCP)
|
||||
|
||||
# Check for PCP libraries
|
||||
LFPCP=""
|
||||
DFPCP=""
|
||||
if test $HAVE_PCP = "y"; then
|
||||
PCP=no
|
||||
AC_CHECK_LIB(pcp, pmGetVersion, LFPCP="-lpcp -lpcp_import", HAVE_PCP="n")
|
||||
AC_MSG_CHECKING(for PCP libraries)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <pcp/pmapi.h>
|
||||
#include <pcp/import.h>]],
|
||||
[[pmiEnd();]])],PCP=yes; DFPCP="-DHAVE_PCP", HAVE_PCP="n"; PCP=no)
|
||||
AC_MSG_RESULT($PCP)
|
||||
fi
|
||||
AC_SUBST(HAVE_PCP)
|
||||
AC_SUBST(LFPCP)
|
||||
AC_SUBST(DFPCP)
|
||||
|
||||
if test $HAVE_PCP_IMPL_H; then
|
||||
PCP_IMPL="y"
|
||||
else
|
||||
PCP_IMPL="n"
|
||||
fi
|
||||
AC_SUBST(PCP_IMPL)
|
||||
|
||||
# Should we check for lm_sensors?
|
||||
AC_MSG_CHECKING(for sensors support)
|
||||
AC_ARG_ENABLE(sensors,
|
||||
AC_HELP_STRING([--disable-sensors],
|
||||
[disable sensors support]),
|
||||
SENSORS=$enableval,SENSORS=yes)
|
||||
if test $SENSORS != "yes"; then
|
||||
SENSORS_SUPPORT="n"
|
||||
else
|
||||
SENSORS_SUPPORT="y"
|
||||
fi
|
||||
AC_MSG_RESULT($SENSORS)
|
||||
|
||||
# Check for lm_sensors library
|
||||
LFSENSORS=""
|
||||
DFSENSORS=""
|
||||
HAVE_SENSORS="n"
|
||||
if test $SENSORS_SUPPORT = "y"; then
|
||||
SENSORS=no
|
||||
AC_CHECK_LIB(sensors, sensors_get_detected_chips, LFSENSORS="-lsensors", HAVE_SENSORS="n")
|
||||
AC_MSG_CHECKING(for sensors library)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sensors/sensors.h>
|
||||
#include <sensors/error.h>]],
|
||||
[[sensors_cleanup();]])], SENSORS=yes; HAVE_SENSORS="y"; DFSENSORS="-DHAVE_SENSORS", HAVE_SENSORS="n"; SENSORS=no)
|
||||
AC_MSG_RESULT($SENSORS)
|
||||
fi
|
||||
AC_SUBST(HAVE_SENSORS)
|
||||
AC_SUBST(LFSENSORS)
|
||||
AC_SUBST(DFSENSORS)
|
||||
|
||||
# Check for 32-bit version of lm_sensors library
|
||||
LFSENSORS32=""
|
||||
DFSENSORS32=""
|
||||
HAVE_SENSORS32="n"
|
||||
if test $SENSORS_SUPPORT = "y"; then
|
||||
CFLAGS_SAVE=$CFLAGS
|
||||
CFLAGS+=" -m32"
|
||||
LDFLAGS_SAVE=$LDFLAGS
|
||||
LDFLAGS+=" -lsensors"
|
||||
SENSORS=no
|
||||
# Check for another function to avoid using cached result
|
||||
AC_CHECK_LIB(sensors, sensors_cleanup, LFSENSORS32="-lsensors", HAVE_SENSORS32="n")
|
||||
AC_MSG_CHECKING(for sensors 32-bit library)
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sensors/sensors.h>
|
||||
#include <sensors/error.h>]],
|
||||
[[sensors_cleanup();]])], SENSORS=yes; HAVE_SENSORS32="y"; DFSENSORS32="-DHAVE_SENSORS32", HAVE_SENSORS32="n"; SENSORS=no)
|
||||
AC_MSG_RESULT($SENSORS)
|
||||
CFLAGS=$CFLAGS_SAVE
|
||||
LDFLAGS=$LDFLAGS_SAVE
|
||||
fi
|
||||
AC_SUBST(HAVE_SENSORS32)
|
||||
AC_SUBST(LFSENSORS32)
|
||||
AC_SUBST(DFSENSORS32)
|
||||
|
||||
# Check for 32-bit system libraries
|
||||
TGLIB32=no
|
||||
CFLAGS_SAVE=$CFLAGS
|
||||
CFLAGS+=" -m32"
|
||||
AC_MSG_CHECKING(for 32-bit system libraries)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]],
|
||||
[[printf("%d\n", sizeof(long));]])],TGLIB32=yes, TGLIB32=no)
|
||||
AC_MSG_RESULT($TGLIB32)
|
||||
CFLAGS=$CFLAGS_SAVE
|
||||
AC_SUBST(TGLIB32)
|
||||
|
||||
echo .
|
||||
echo Check system services:
|
||||
echo .
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
echo .
|
||||
echo Check configuration:
|
||||
echo .
|
||||
# Check arguments used
|
||||
#
|
||||
# Optional Features:
|
||||
# --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
||||
# --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||
# --disable-largefile omit support for large files
|
||||
# --disable-nls disable National Language Support
|
||||
# --disable-file-attr don't set attributes on files being installed
|
||||
# --enable-install-cron tell sysstat to install cron scripts
|
||||
# --collect-all tell sadc to collect all possible data
|
||||
# --enable-clean-sa-dir clean system activity directory
|
||||
# --disable-compress-manpg do not compress manual pages when installed
|
||||
# --enable-debuginfo enable debug output (--debuginfo option)
|
||||
# --disable-documentation do not install documentation (man pages...)
|
||||
# --disable-sensors do not link against libsensors even if available
|
||||
# --disable-pcp do not link against PCP libraries even if available
|
||||
# --disable-stripping do not strip object files
|
||||
# --enable-copy-only only copy files when installing sysstat
|
||||
# --enable-use-crond use standard cron daemon
|
||||
# --enable-lto compile with Link Time Optimizations
|
||||
#
|
||||
# Some influential environment variables:
|
||||
# rcdir directory where startup scripts are installed
|
||||
# sa_lib_dir sadc, sa1 and sa2 directory
|
||||
# sa_dir system activity daily datafiles directory
|
||||
# sar_dir sar binary location. Used only in sa2 shell script
|
||||
# conf_dir sysstat configuration directory (default is /etc/sysconfig)
|
||||
# conf_file sysstat configuration file (default is sysstat)
|
||||
# history number of daily datafiles to keep (default value is 7)
|
||||
# delay_range maximum delay (in seconds) to wait before sa2 script generates its reports
|
||||
# compressafter number of days after which datafiles are compressed
|
||||
# man_group group for man pages
|
||||
# cron_owner crontab owner
|
||||
# cron_interval crontab sampling interval
|
||||
# sadc_options options to be passed to sadc
|
||||
#
|
||||
# Fine tuning the installation directories:
|
||||
# --mandir=DIR man documentation directory [PREFIX/man]
|
||||
# --docdir=DIR other documentation directory [PREFIX/share/doc]
|
||||
#
|
||||
# Installation directories:
|
||||
# --prefix=PREFIX install architecture-independent files in PREFIX
|
||||
# [/usr/local]
|
||||
# --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
|
||||
# [PREFIX]
|
||||
|
||||
# Set directories
|
||||
if test -d /etc/init.d && test ! -L /etc/init.d; then
|
||||
if test -d /etc/init.d/rc2.d; then
|
||||
RC_DIR=/etc/init.d
|
||||
INITD_DIR=.
|
||||
else
|
||||
RC_DIR=/etc
|
||||
INITD_DIR=init.d
|
||||
fi
|
||||
INIT_DIR=/etc/init.d
|
||||
elif test -d /sbin/init.d; then
|
||||
RC_DIR=/sbin/init.d
|
||||
INIT_DIR=/sbin/init.d
|
||||
INITD_DIR=.
|
||||
else
|
||||
RC_DIR=/etc/rc.d
|
||||
INIT_DIR=/etc/rc.d/init.d
|
||||
INITD_DIR=init.d
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(run-commands directory)
|
||||
AC_ARG_VAR([rcdir],[run-commands directory])
|
||||
if test x$rcdir != x""; then
|
||||
# Override previous rc directories values
|
||||
RC_DIR=$rcdir
|
||||
INIT_DIR=$rcdir/init.d
|
||||
INITD_DIR=init.d
|
||||
fi
|
||||
AC_MSG_RESULT($RC_DIR)
|
||||
if test ! -d $RC_DIR; then
|
||||
echo "INFO: Directory ${RC_DIR} doesn't exist."
|
||||
echo "INFO: Startup scripts won't be installed."
|
||||
fi
|
||||
|
||||
AC_SUBST(RC_DIR)
|
||||
AC_SUBST(INIT_DIR)
|
||||
AC_SUBST(INITD_DIR)
|
||||
|
||||
if test $HAVE_SYS_SYSMACROS_H; then
|
||||
SYSMACROS="y"
|
||||
else
|
||||
SYSMACROS="n"
|
||||
fi
|
||||
AC_SUBST(SYSMACROS)
|
||||
|
||||
if test $HAVE_LINUX_SCHED_H; then
|
||||
LINUX_SCHED="y"
|
||||
else
|
||||
LINUX_SCHED="n"
|
||||
fi
|
||||
AC_SUBST(LINUX_SCHED)
|
||||
|
||||
if test $HAVE_SYS_PARAM_H; then
|
||||
SYSPARAM="y"
|
||||
else
|
||||
SYSPARAM="n"
|
||||
fi
|
||||
AC_SUBST(SYSPARAM)
|
||||
|
||||
# Set sadc directory
|
||||
if test $prefix != "NONE"; then
|
||||
AuxPrefix=$prefix
|
||||
else
|
||||
AuxPrefix=/usr/local
|
||||
fi
|
||||
|
||||
SADC_DIR=$AuxPrefix/lib
|
||||
if test -d $AuxPrefix/lib64; then
|
||||
# Verify that this OS is really 64 bit
|
||||
BITS=$(getconf LONG_BIT 2>/dev/null)
|
||||
if test $? = 0; then
|
||||
if test $BITS = 64; then
|
||||
SADC_DIR=$AuxPrefix/lib64
|
||||
fi
|
||||
else
|
||||
# Fallback: look for lm (long mode) flag to know if CPU is 64 bit
|
||||
grep " lm " /proc/cpuinfo >/dev/null 2>&1
|
||||
if test $? = 0; then
|
||||
SADC_DIR=$AuxPrefix/lib64
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(sadc directory)
|
||||
AC_ARG_VAR([sa_lib_dir],[sadc directory])
|
||||
if test x$sa_lib_dir != x""; then
|
||||
SA_LIB_DIR=$sa_lib_dir
|
||||
else
|
||||
SA_LIB_DIR=$SADC_DIR/sa
|
||||
fi
|
||||
AC_MSG_RESULT($SA_LIB_DIR)
|
||||
if test ! -d $SA_LIB_DIR; then
|
||||
echo "INFO: Directory ${SA_LIB_DIR} will be created during installation stage."
|
||||
fi
|
||||
AC_SUBST(SA_LIB_DIR)
|
||||
|
||||
# Set system activity directory
|
||||
AC_MSG_CHECKING(system activity directory)
|
||||
AC_ARG_VAR([sa_dir],[system activity directory])
|
||||
if test x$sa_dir != x""; then
|
||||
SA_DIR=$sa_dir
|
||||
else
|
||||
SA_DIR=/var/log/sa
|
||||
fi
|
||||
AC_MSG_RESULT($SA_DIR)
|
||||
if test ! -d $SA_DIR; then
|
||||
echo "INFO: Directory ${SA_DIR} will be created during installation stage."
|
||||
fi
|
||||
AC_SUBST(SA_DIR)
|
||||
|
||||
# sar binary location. Used only in sa2 shell script
|
||||
AC_MSG_CHECKING(sar directory)
|
||||
AC_ARG_VAR([sar_dir],[sar directory])
|
||||
if test x$sar_dir != x""; then
|
||||
SAR_DIR=$sar_dir
|
||||
else
|
||||
SAR_DIR=
|
||||
fi
|
||||
AC_MSG_RESULT($SAR_DIR)
|
||||
AC_SUBST(SAR_DIR)
|
||||
|
||||
# Set configuration directory
|
||||
AC_MSG_CHECKING(sysstat configuration directory)
|
||||
AC_ARG_VAR([conf_dir],[sysstat configuration directory])
|
||||
if test x$conf_dir != x""; then
|
||||
SYSCONFIG_DIR=$conf_dir
|
||||
else
|
||||
SYSCONFIG_DIR=/etc/sysconfig
|
||||
fi
|
||||
AC_MSG_RESULT($SYSCONFIG_DIR)
|
||||
if test ! -d $SYSCONFIG_DIR; then
|
||||
echo "INFO: Directory ${SYSCONFIG_DIR} will be created during installation stage."
|
||||
fi
|
||||
AC_SUBST(SYSCONFIG_DIR)
|
||||
|
||||
# Set configuration directory
|
||||
AC_MSG_CHECKING(sysstat configuration file)
|
||||
AC_ARG_VAR([conf_file],[sysstat configuration file])
|
||||
if test x$conf_file != x""; then
|
||||
SYSCONFIG_FILE=$conf_file
|
||||
else
|
||||
SYSCONFIG_FILE=sysstat
|
||||
fi
|
||||
AC_MSG_RESULT($SYSCONFIG_FILE)
|
||||
AC_SUBST(SYSCONFIG_FILE)
|
||||
|
||||
# National Language Support
|
||||
AC_MSG_CHECKING(National Language Support)
|
||||
AC_ARG_ENABLE(nls,
|
||||
AC_HELP_STRING([--disable-nls],
|
||||
[disable National Language Support]),
|
||||
AUX_NLS=$enableval,AUX_NLS=yes)
|
||||
if test $AUX_NLS != "no" && test $HAVE_LIBINTL_H && test $HAVE_LOCALE_H; then
|
||||
AUX_NLS="yes"
|
||||
NLS="y"
|
||||
else
|
||||
AUX_NLS="no"
|
||||
NLS="n"
|
||||
fi
|
||||
AC_MSG_RESULT($AUX_NLS)
|
||||
AC_CHECK_LIB(intl, gettext, LFINTL="-lintl")
|
||||
AC_SUBST(LFINTL)
|
||||
LACKING_GETTEXT="n"
|
||||
if test $AUX_NLS = "yes" && test x$MSGFMT != x"msgfmt"; then
|
||||
echo "WARNING: msgfmt command not found!"
|
||||
LACKING_GETTEXT="y"
|
||||
fi
|
||||
if test $AUX_NLS = "yes" && test x$XGETTEXT != x"xgettext"; then
|
||||
echo "WARNING: xgettext command not found!"
|
||||
LACKING_GETTEXT="y"
|
||||
fi
|
||||
if test $AUX_NLS = "yes" && test x$MSGMERGE != x"msgmerge"; then
|
||||
echo "WARNING: msgmerge command not found!"
|
||||
LACKING_GETTEXT="y"
|
||||
fi
|
||||
if test $NLS = "y" && test $LACKING_GETTEXT = "y"; then
|
||||
echo "WARNING: Disabling NLS"
|
||||
NLS="n"
|
||||
fi
|
||||
AC_SUBST(NLS)
|
||||
|
||||
# Link Time Optimization
|
||||
AC_MSG_CHECKING(Link Time Optimization support)
|
||||
AC_ARG_ENABLE(lto,
|
||||
AC_HELP_STRING([--enable-lto],
|
||||
[enable Link Time Optimization]),
|
||||
AUX_LTO=$enableval,AUX_LTO=no)
|
||||
AC_MSG_RESULT($AUX_LTO)
|
||||
LTO="n"
|
||||
if test $AUX_LTO = "yes"; then
|
||||
AC_CHECK_PROG(GCC_AR, gcc-ar, gcc-ar)
|
||||
if test x$GCC_AR != x"gcc-ar"; then
|
||||
echo "WARNING: gcc-ar command not found! Disabling LTO support"
|
||||
AUX_LTO="no"
|
||||
else
|
||||
LTO="y"
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(LTO)
|
||||
|
||||
# Data history to keep by sa2
|
||||
AC_MSG_CHECKING(number of daily data files to keep)
|
||||
AC_ARG_VAR([history],[number of daily data files to keep (default value is 7)])
|
||||
if test x$history = x""; then
|
||||
HISTORY=7
|
||||
else
|
||||
HISTORY=$history
|
||||
fi
|
||||
AC_MSG_RESULT($HISTORY)
|
||||
AC_SUBST(HISTORY)
|
||||
|
||||
# Number of days after which datafiles are compressed
|
||||
AC_MSG_CHECKING(number of days after which data files are compressed)
|
||||
AC_ARG_VAR([compressafter],[number of days after which data files are compressed (default value is 10)])
|
||||
if test x$compressafter = x""; then
|
||||
COMPRESSAFTER=10
|
||||
else
|
||||
COMPRESSAFTER=$compressafter
|
||||
fi
|
||||
AC_MSG_RESULT($COMPRESSAFTER)
|
||||
AC_SUBST(COMPRESSAFTER)
|
||||
|
||||
# Random delay to wait before sa2 script runs
|
||||
AC_MSG_CHECKING(random delay to wait before sa2 script runs)
|
||||
AC_ARG_VAR([delay_range],[maximum delay (in seconds) to wait before sa2 script generates its reports])
|
||||
if test x$delay_range = x""; then
|
||||
DELAY_RANGE=0
|
||||
else
|
||||
DELAY_RANGE=$delay_range
|
||||
fi
|
||||
AC_MSG_RESULT($DELAY_RANGE)
|
||||
AC_SUBST(DELAY_RANGE)
|
||||
|
||||
# Manual page group
|
||||
grep ^man: /etc/group >/dev/null 2>&1
|
||||
if test $? = 0; then
|
||||
GRP=man
|
||||
else
|
||||
GRP=root
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(group for manual pages)
|
||||
AC_ARG_VAR([man_group],[group for manual pages])
|
||||
if test x$man_group = x""; then
|
||||
MAN_GROUP=$GRP
|
||||
AC_MSG_RESULT($MAN_GROUP)
|
||||
else
|
||||
grep ^$man_group: /etc/group >/dev/null 2>&1
|
||||
if test $? = 1; then
|
||||
MAN_GROUP=$GRP
|
||||
AC_MSG_RESULT($MAN_GROUP)
|
||||
echo "WARNING: Group ${man_group} not found: Using ${GRP} instead"
|
||||
else
|
||||
MAN_GROUP=$man_group
|
||||
AC_MSG_RESULT($MAN_GROUP)
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(MAN_GROUP)
|
||||
|
||||
# Don't set attributes on files being installed?
|
||||
AC_MSG_CHECKING(whether attributes should not be set on files being installed)
|
||||
AC_ARG_ENABLE(file-attr,
|
||||
AC_HELP_STRING([--disable-file-attr],
|
||||
[do not set attributes on files being installed]),
|
||||
AUX_IMG=$enableval,AUX_IMG=yes)
|
||||
if test $AUX_IMG != "no"; then
|
||||
IGNORE_FILE_ATTRIBUTES=n
|
||||
AUX_IMG=no
|
||||
else
|
||||
IGNORE_FILE_ATTRIBUTES=y
|
||||
AUX_IMG=yes
|
||||
fi
|
||||
AC_MSG_RESULT($AUX_IMG)
|
||||
AC_SUBST(IGNORE_FILE_ATTRIBUTES)
|
||||
|
||||
# Compress manual pages?
|
||||
AC_MSG_CHECKING(whether manual pages should be compressed)
|
||||
AC_ARG_ENABLE(compress-manpg,
|
||||
AC_HELP_STRING([--disable-compress-manpg],
|
||||
[do not compress sysstat manual pages]),
|
||||
AUX_MPG=$enableval,AUX_MPG=yes)
|
||||
if test $AUX_MPG != "yes"; then
|
||||
COMPRESS_MANPG=n
|
||||
else
|
||||
COMPRESS_MANPG=y
|
||||
fi
|
||||
AC_MSG_RESULT($AUX_MPG)
|
||||
AC_SUBST(COMPRESS_MANPG)
|
||||
|
||||
# Check whether sa directory should be cleaned
|
||||
AC_MSG_CHECKING(whether system activity directory should be cleaned)
|
||||
AC_ARG_ENABLE(clean-sa-dir,
|
||||
AC_HELP_STRING([--enable-clean-sa-dir],
|
||||
[clean system activity directory]),
|
||||
AUX_CSD=$enableval,AUX_CSD=no)
|
||||
if test $AUX_CSD != "yes"; then
|
||||
CLEAN_SA_DIR=n
|
||||
AUX_CSD=no
|
||||
else
|
||||
CLEAN_SA_DIR=y
|
||||
fi
|
||||
AC_MSG_RESULT($AUX_CSD)
|
||||
AC_SUBST(CLEAN_SA_DIR)
|
||||
|
||||
# Start crontab
|
||||
AC_MSG_CHECKING(whether cron should start sar automatically)
|
||||
AC_ARG_ENABLE(install-cron,
|
||||
AC_HELP_STRING([--enable-install-cron],
|
||||
[install a crontab to start sar]),
|
||||
INSTALL_CRON=$enableval,INSTALL_CRON=n)
|
||||
if test $INSTALL_CRON != "yes"; then
|
||||
INSTALL_CRON=n
|
||||
AUX_CRON=no
|
||||
else
|
||||
INSTALL_CRON=y
|
||||
AUX_CRON=yes
|
||||
fi
|
||||
AC_MSG_RESULT($AUX_CRON)
|
||||
AC_SUBST(INSTALL_CRON)
|
||||
|
||||
# Crontab owner
|
||||
CUSR="root"
|
||||
if test $INSTALL_CRON = "y"; then
|
||||
AC_MSG_CHECKING(crontab owner)
|
||||
AC_ARG_VAR([cron_owner],[crontab owner])
|
||||
if test x$cron_owner = x""; then
|
||||
CRON_OWNER=$CUSR
|
||||
AC_MSG_RESULT($CRON_OWNER)
|
||||
else
|
||||
grep ^$cron_owner: /etc/passwd >/dev/null 2>&1
|
||||
if test $? = 1; then
|
||||
CRON_OWNER=$CUSR;
|
||||
AC_MSG_RESULT($CRON_OWNER)
|
||||
echo "WARNING: User ${cron_owner} not found: Using ${CUSR} instead."
|
||||
else
|
||||
CRON_OWNER=$cron_owner
|
||||
AC_MSG_RESULT($CRON_OWNER)
|
||||
fi
|
||||
fi
|
||||
echo "INFO: Crontab for ${CRON_OWNER} will be saved in current directory if necessary"
|
||||
if test $CRON_OWNER = "root"; then
|
||||
SU_C_OWNER=""
|
||||
QUOTE=""
|
||||
REM_CHOWN="# REM_CHOWN"
|
||||
else
|
||||
SU_C_OWNER="su $CRON_OWNER -c "
|
||||
QUOTE=\"
|
||||
# " (ignore this line)
|
||||
REM_CHOWN=$CHOWN
|
||||
fi
|
||||
|
||||
# Check whether we should use the standard cron daemon
|
||||
AC_MSG_CHECKING(whether we should use the standard cron daemon)
|
||||
AC_ARG_ENABLE(use-crond,
|
||||
AC_HELP_STRING([--enable-use-crond],
|
||||
[use standard cron daemon]),
|
||||
UCROND=$enableval,UCROND=no)
|
||||
if test $UCROND != "yes"; then
|
||||
USE_CROND=n
|
||||
UCROND=no
|
||||
else
|
||||
USE_CROND=y
|
||||
fi
|
||||
AC_MSG_RESULT($UCROND)
|
||||
AC_SUBST(USE_CROND)
|
||||
|
||||
# Crontab interval
|
||||
AC_MSG_CHECKING(crontab interval)
|
||||
AC_ARG_VAR([cron_interval],[crontab interval])
|
||||
if test x$cron_interval = x""; then
|
||||
CRON_INTERVAL=10
|
||||
else
|
||||
CRON_INTERVAL=$cron_interval
|
||||
fi
|
||||
AC_MSG_RESULT($CRON_INTERVAL)
|
||||
CRON_INTERVAL_SEC=`expr ${CRON_INTERVAL} \* 60`
|
||||
CRON_COUNT=`expr 60 / ${CRON_INTERVAL}`
|
||||
|
||||
# Check whether sadc should collect all possible activities
|
||||
AC_MSG_CHECKING(whether sadc should collect all possible activities)
|
||||
AC_ARG_ENABLE(collect-all,
|
||||
AC_HELP_STRING([--enable-collect-all],
|
||||
[collect all possible activities]),
|
||||
COLLECT_ALL=$enableval,COLLECT_ALL=n)
|
||||
if test $COLLECT_ALL != "yes"; then
|
||||
COLLECT_ALL=""
|
||||
AUX_COLL=no
|
||||
else
|
||||
COLLECT_ALL="-S XALL"
|
||||
AUX_COLL=yes
|
||||
fi
|
||||
AC_MSG_RESULT($AUX_COLL)
|
||||
|
||||
AC_MSG_CHECKING(options to be passed to sadc)
|
||||
AC_ARG_VAR([sadc_options],[options to be passed to sadc])
|
||||
if test x"$sadc_options" != x""; then
|
||||
SADC_OPT="$sadc_options"
|
||||
else
|
||||
SADC_OPT=
|
||||
fi
|
||||
AC_MSG_RESULT($SADC_OPT)
|
||||
AC_SUBST(SADC_OPT)
|
||||
|
||||
# Check whether files should only be copied
|
||||
AC_MSG_CHECKING(whether files should only be copied)
|
||||
AC_ARG_ENABLE(copy-only,
|
||||
AC_HELP_STRING([--enable-copy-only],
|
||||
[only copy files when installing]),
|
||||
OCOPY=$enableval,OCOPY=no)
|
||||
if test $OCOPY != "yes"; then
|
||||
COPY_ONLY=n
|
||||
OCOPY=no
|
||||
else
|
||||
COPY_ONLY=y
|
||||
fi
|
||||
AC_MSG_RESULT($OCOPY)
|
||||
AC_SUBST(COPY_ONLY)
|
||||
|
||||
else
|
||||
CRON_OWNER="root"
|
||||
SU_C_OWNER=""
|
||||
QUOTE=""
|
||||
REM_CHOWN="# REM_CHOWN"
|
||||
CRON_INTERVAL=10
|
||||
CRON_INTERVAL_SEC=600
|
||||
CRON_COUNT=6
|
||||
COLLECT_ALL=""
|
||||
fi
|
||||
AC_SUBST(CRON_OWNER)
|
||||
AC_SUBST(SU_C_OWNER)
|
||||
AC_SUBST(CRON_INTERVAL)
|
||||
AC_SUBST(CRON_INTERVAL_SEC)
|
||||
AC_SUBST(CRON_COUNT)
|
||||
AC_SUBST(QUOTE)
|
||||
AC_SUBST(REM_CHOWN)
|
||||
AC_SUBST(COLLECT_ALL)
|
||||
|
||||
# Check whether documentation should be installed
|
||||
AC_MSG_CHECKING(whether documentation should be installed)
|
||||
AC_ARG_ENABLE(documentation,
|
||||
AC_HELP_STRING([--disable-documentation],
|
||||
[do not install documentation]),
|
||||
AUX_DOC=$enableval,AUX_DOC=yes)
|
||||
if test $AUX_DOC != "no"; then
|
||||
AUX_DOC="yes"
|
||||
INSTALL_DOC="y"
|
||||
else
|
||||
AUX_DOC="no"
|
||||
INSTALL_DOC="n"
|
||||
fi
|
||||
AC_MSG_RESULT($AUX_DOC)
|
||||
AC_SUBST(INSTALL_DOC)
|
||||
|
||||
# Set directory for installing manual pages (see comment in Makefile)
|
||||
AC_SUBST(mandir)
|
||||
|
||||
# Check whether debug mode should be activated
|
||||
AC_MSG_CHECKING(whether debug mode should be activated)
|
||||
AC_ARG_ENABLE(debuginfo,
|
||||
AC_HELP_STRING([--enable-debuginfo],
|
||||
[enable debug output (--debuginfo option)]),
|
||||
WITH_DEBUG=yes ; DFLAGS="$DFLAGS -DDEBUG" , WITH_DEBUG=no)
|
||||
AC_MSG_RESULT($WITH_DEBUG)
|
||||
AC_SUBST(DFLAGS)
|
||||
AC_SUBST(WITH_DEBUG)
|
||||
|
||||
# Check whether object files should be stripped
|
||||
AC_MSG_CHECKING(whether object files should be stripped)
|
||||
AC_ARG_ENABLE(stripping,
|
||||
AC_HELP_STRING([--disable-stripping],
|
||||
[do not strip object files]),
|
||||
AUX_STRIP=$enableval,AUX_STRIP=yes)
|
||||
if test $AUX_STRIP != "no"; then
|
||||
AUX_STRIP="yes"
|
||||
STRIP="-s"
|
||||
else
|
||||
AUX_STRIP="no"
|
||||
STRIP=
|
||||
fi
|
||||
AC_MSG_RESULT($AUX_STRIP)
|
||||
AC_SUBST(STRIP)
|
||||
|
||||
# Create files
|
||||
echo .
|
||||
echo Now create files:
|
||||
echo .
|
||||
AC_CONFIG_FILES([sa1], [chmod +x sa1]) # Permissions must be changed
|
||||
AC_CONFIG_FILES([sa2], [chmod +x sa2]) # Permissions must be changed
|
||||
AC_CONFIG_FILES([cron/crontab:cron/crontab.sample]) # File must be renamed
|
||||
AC_CONFIG_FILES([sysstat.sysconfig])
|
||||
AC_CONFIG_FILES([version.h:version.in]) # File must be renamed
|
||||
AC_CONFIG_FILES([sysconfig.h:sysconfig.in]) # File must be renamed
|
||||
AC_CONFIG_FILES([cron/sysstat.cron.daily])
|
||||
AC_CONFIG_FILES([cron/sysstat.cron.hourly])
|
||||
AC_CONFIG_FILES([cron/sysstat.crond])
|
||||
AC_CONFIG_FILES([cron/sysstat.crond.sample.in:cron/sysstat.crond.in], [sed s/^/#/ cron/sysstat.crond.sample.in > cron/sysstat.crond.sample])
|
||||
AC_CONFIG_FILES([sysstat], [chmod +x sysstat]) # Permissions must be changed
|
||||
AC_CONFIG_FILES([sysstat.service])
|
||||
AC_CONFIG_FILES([cron/sysstat-collect.service])
|
||||
AC_CONFIG_FILES([cron/sysstat-collect.timer])
|
||||
AC_CONFIG_FILES([cron/sysstat-summary.service])
|
||||
AC_CONFIG_FILES([cron/sysstat-summary.timer])
|
||||
AC_CONFIG_FILES([cron/sysstat.sleep], [chmod +x cron/sysstat.sleep]) # Permissions must be changed
|
||||
AC_CONFIG_FILES([man/sa1.8:man/sa1.in]) # File must be renamed
|
||||
AC_CONFIG_FILES([man/sa2.8:man/sa2.in]) # File must be renamed
|
||||
AC_CONFIG_FILES([man/sadc.8:man/sadc.in]) # File must be renamed
|
||||
AC_CONFIG_FILES([man/sadf.1:man/sadf.in]) # File must be renamed
|
||||
AC_CONFIG_FILES([man/sar.1:man/sar.in]) # File must be renamed
|
||||
AC_CONFIG_FILES([man/sysstat.5:man/sysstat.in]) # File must be renamed
|
||||
AC_CONFIG_FILES([man/iostat.1:man/iostat.in]) # File must be renamed
|
||||
AC_CONFIG_FILES([man/cifsiostat.1:man/cifsiostat.in]) # File must be renamed
|
||||
AC_CONFIG_FILES([tests/variables])
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
|
||||
echo "
|
||||
Sysstat version: $PACKAGE_VERSION
|
||||
Installation prefix: $prefix
|
||||
rc directory: ${RC_DIR}
|
||||
Init directory: ${INIT_DIR}"
|
||||
if test "$UCROND" != "yes"; then
|
||||
echo " Systemd unit dir: ${with_systemdsystemunitdir}"
|
||||
echo " Systemd sleep dir: ${with_systemdsleepdir}"
|
||||
else
|
||||
echo " Use standard cron daemon"
|
||||
fi
|
||||
echo " Configuration file: ${SYSCONFIG_DIR}/${SYSCONFIG_FILE}
|
||||
Man pages directory: $mandir
|
||||
Compiler: $CC
|
||||
Compiler flags: $CFLAGS
|
||||
Linker flags: $LDFLAGS
|
||||
"
|
|
@ -0,0 +1,8 @@
|
|||
This is the directory where you can find various programs related to sysstat.
|
||||
Please don't ask me any questions about them. Send your comments and/or
|
||||
bug reports to their respective authors.
|
||||
|
||||
Thx.
|
||||
--
|
||||
Sébastien Godard (sysstat <at> orange.fr)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Lance W. Shelton
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
irqstat
|
||||
=======
|
||||
|
||||
A better way to watch /proc/interrupts, designed for NUMA systems with many processors.
|
||||
|
||||
Contributed by Lance Shelton <lance.shelton@sandisk.com>
|
||||
|
|
@ -0,0 +1,396 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2015 Lance W. Shelton
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
"""
|
||||
A better way to watch /proc/interrupts, especially on large NUMA machines with
|
||||
so many CPUs that /proc/interrupts is wider than the screen. Press '0'-'9'
|
||||
for node views, 't' for node totals
|
||||
"""
|
||||
|
||||
__version__ = '1.0.1-pre'
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tty
|
||||
import termios
|
||||
import time
|
||||
from time import sleep
|
||||
import subprocess
|
||||
from optparse import OptionParser
|
||||
import thread
|
||||
import threading
|
||||
|
||||
KEYEVENT = threading.Event()
|
||||
|
||||
|
||||
def gen_numa(numafile):
|
||||
"""Generate NUMA info"""
|
||||
cpunodes = {}
|
||||
numacores = {}
|
||||
err_str = ""
|
||||
|
||||
try:
|
||||
if not numafile:
|
||||
temp = subprocess.Popen(['numactl', '--hardware'],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
(output, error) = temp.communicate()
|
||||
temp.wait()
|
||||
|
||||
if error:
|
||||
print("NUMACTL ERROR:")
|
||||
print(error)
|
||||
exit(1)
|
||||
else:
|
||||
numa_file = open(numafile, 'r')
|
||||
output = numa_file.read()
|
||||
numa_file.close()
|
||||
|
||||
output = output.split("\n")
|
||||
for line in output:
|
||||
arr = line.split()
|
||||
if len(arr) < 3:
|
||||
continue
|
||||
if arr[0] == "node" and arr[2] == "cpus:":
|
||||
node = arr[1]
|
||||
numacores[node] = arr[3:]
|
||||
for core in arr[3:]:
|
||||
cpunodes[core] = node
|
||||
continue
|
||||
return numacores, cpunodes
|
||||
except (OSError, IOError) as err:
|
||||
if err.errno == 2: # No such file or directory
|
||||
if numafile:
|
||||
err_str = " (does '" + numafile + "' exist?)"
|
||||
else:
|
||||
err_str = err.strerror + " (is numactl installed?)"
|
||||
print("ERROR: " + err.strerror + err_str)
|
||||
exit(1)
|
||||
|
||||
# input character, passed between threads
|
||||
INCHAR = ''
|
||||
|
||||
|
||||
def wait_for_input():
|
||||
"""Get a single character of input, validate"""
|
||||
global INCHAR
|
||||
|
||||
acceptable_keys = ['0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '0', 't']
|
||||
while True:
|
||||
key = sys.stdin.read(1)
|
||||
|
||||
# simple just to exit on any invalid input
|
||||
if not key in acceptable_keys:
|
||||
thread.interrupt_main()
|
||||
|
||||
# set the new input and notify the main thread
|
||||
INCHAR = key
|
||||
KEYEVENT.set()
|
||||
|
||||
|
||||
def filter_found(name, filter_list):
|
||||
"""Check if IRQ name matches anything in the filter list"""
|
||||
for filt in filter_list:
|
||||
if filt in name:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def display_itop(batch, seconds, rowcnt, iterations, sort, totals, dispnode,
|
||||
zero, filters, file1, file2, overall, numafile):
|
||||
"""Main I/O loop"""
|
||||
irqs = {}
|
||||
cpunodes = {}
|
||||
numacores = {}
|
||||
loops = 0
|
||||
width = len('NODEXX')
|
||||
|
||||
if not file1 and batch:
|
||||
print("Running in batch mode")
|
||||
elif not file1:
|
||||
print("interactive commands -- "
|
||||
"t: view totals, 0-9: view node, any other key: quit\r")
|
||||
|
||||
if file1:
|
||||
intr_filename = file1
|
||||
else:
|
||||
intr_filename = '/proc/interrupts'
|
||||
|
||||
while True:
|
||||
# Grab the new display type at a time when nothing is in flux
|
||||
if KEYEVENT.isSet():
|
||||
KEYEVENT.clear()
|
||||
dispnode = INCHAR if INCHAR in numacores else '-1'
|
||||
|
||||
with open(intr_filename, 'r') as intr_file:
|
||||
header = intr_file.readline()
|
||||
cpus = []
|
||||
for name in header.split():
|
||||
num = name[3:]
|
||||
cpus.append(num)
|
||||
|
||||
# Only query the numa information when something is missing.
|
||||
# This is effectively the first time and when any disabled CPUs
|
||||
# are enabled
|
||||
if not num in cpunodes:
|
||||
numacores, cpunodes = gen_numa(numafile)
|
||||
|
||||
for line in intr_file.readlines():
|
||||
vals = line.split()
|
||||
irqnum = vals[0].rstrip(':')
|
||||
|
||||
# Optionally exclude rows that are not an IRQ number
|
||||
if totals is None:
|
||||
try:
|
||||
num = int(irqnum)
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
irq = {}
|
||||
irq['cpus'] = [int(x) for x in vals[1:len(cpus)+1]]
|
||||
irq['oldcpus'] = (irqs[irqnum]['cpus'] if irqnum in irqs
|
||||
else [0] * len(cpus))
|
||||
irq['name'] = ' '.join(vals[len(cpus)+1:])
|
||||
irq['oldsum'] = irqs[irqnum]['sum'] if irqnum in irqs else 0
|
||||
irq['sum'] = sum(irq['cpus'])
|
||||
irq['num'] = irqnum
|
||||
|
||||
for node in numacores:
|
||||
oldkey = 'oldsum' + node
|
||||
key = 'sum' + node
|
||||
irq[oldkey] = (irqs[irqnum][key] if irqnum in irqs
|
||||
and key in irqs[irqnum] else 0)
|
||||
irq[key] = 0
|
||||
|
||||
for idx, val in enumerate(irq['cpus']):
|
||||
key = 'sum' + cpunodes[cpus[idx]]
|
||||
irq[key] = irq[key] + val if key in irq else val
|
||||
|
||||
# save old
|
||||
irqs[irqnum] = irq
|
||||
|
||||
def sort_func(val):
|
||||
"""Sort output"""
|
||||
sortnum = -1
|
||||
try:
|
||||
sortnum = int(sort)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if sortnum >= 0:
|
||||
for node in numacores:
|
||||
if sortnum == int(node):
|
||||
return val['sum' + node] - val['oldsum' + node]
|
||||
if sort == 't':
|
||||
return val['sum'] - val['oldsum']
|
||||
if sort == 'i':
|
||||
if val['num'].isdigit():
|
||||
return int(val['num'])
|
||||
return sys.maxsize
|
||||
if sort == 'n':
|
||||
return val['name']
|
||||
raise Exception('Invalid sort type {}'.format(sort))
|
||||
|
||||
# reverse sort all IRQ count sorts
|
||||
rev = sort not in ['i', 'n']
|
||||
rows = sorted(irqs.values(), key=sort_func, reverse=rev)
|
||||
|
||||
# determine the width required for the count field
|
||||
for idx, irq in enumerate(rows):
|
||||
width = max(width, len(str(irq['sum'] - irq['oldsum'])))
|
||||
|
||||
if overall and loops > 0:
|
||||
print("" + '\r')
|
||||
if not file1 and (overall or loops > 0):
|
||||
print(time.ctime() + '\r')
|
||||
print("IRQs / " + str(seconds) + " second(s)" + '\r')
|
||||
fmtstr = ('IRQ# %' + str(width) + 's') % 'TOTAL'
|
||||
|
||||
# node view header
|
||||
if int(dispnode) >= 0:
|
||||
node = 'NODE%s' % dispnode
|
||||
fmtstr += (' %' + str(width) + 's ') % node
|
||||
for idx, val in enumerate(irq['cpus']):
|
||||
if cpunodes[cpus[idx]] == dispnode:
|
||||
cpu = 'CPU%s' % cpus[idx]
|
||||
fmtstr += (' %' + str(width) + 's ') % cpu
|
||||
# top view header
|
||||
else:
|
||||
for node in sorted(numacores):
|
||||
node = 'NODE%s' % node
|
||||
fmtstr += (' %' + str(width) + 's ') % node
|
||||
|
||||
fmtstr += ' NAME'
|
||||
if overall or loops > 0:
|
||||
print(fmtstr + '\r')
|
||||
|
||||
displayed_rows = 0
|
||||
for idx, irq in enumerate(rows):
|
||||
if filters and not filter_found(irq['name'], filters):
|
||||
continue
|
||||
|
||||
total = irq['sum'] - irq['oldsum']
|
||||
if zero and not total:
|
||||
continue
|
||||
|
||||
# IRQ# TOTAL
|
||||
fmtstr = ('%4s %' + str(width) + 'd') % (irq['num'], total)
|
||||
|
||||
# node view
|
||||
if int(dispnode) >= 0:
|
||||
oldnodesum = 'oldsum' + dispnode
|
||||
nodesum = 'sum' + dispnode
|
||||
nodecnt = irq[nodesum] - irq[oldnodesum]
|
||||
if zero and not nodecnt:
|
||||
continue
|
||||
fmtstr += (' %' + str(width) + 's ') % str(nodecnt)
|
||||
for cpu, val in enumerate(irq['cpus']):
|
||||
if cpunodes[cpus[cpu]] == dispnode:
|
||||
fmtstr += ((' %' + str(width) + 's ') %
|
||||
str(irq['cpus'][cpu] - irq['oldcpus'][cpu]))
|
||||
|
||||
# top view
|
||||
else:
|
||||
for node in sorted(numacores):
|
||||
oldnodesum = 'oldsum' + node
|
||||
nodesum = 'sum' + node
|
||||
nodecnt = irq[nodesum] - irq[oldnodesum]
|
||||
fmtstr += ((' %' + str(width) + 's ') % str(nodecnt))
|
||||
fmtstr += ' ' + irq['name']
|
||||
if overall or loops > 0:
|
||||
print(fmtstr + '\r')
|
||||
displayed_rows += 1
|
||||
if displayed_rows == rowcnt:
|
||||
break
|
||||
|
||||
# Update field widths after the first iteration. Data changes
|
||||
# significantly between the all-time stats and the interval stats, so
|
||||
# this compresses the fields quite a bit. Updating every iteration
|
||||
# is too jumpy.
|
||||
if loops == 0:
|
||||
width = len('NODEXX')
|
||||
|
||||
loops += 1
|
||||
if loops == iterations:
|
||||
break
|
||||
|
||||
if file2 and loops == 1:
|
||||
intr_filename = file2
|
||||
continue
|
||||
|
||||
# thread.interrupt_main() does not seem to interrupt a sleep, so break
|
||||
# it into tenth-of-a-second sleeps to improve user response time on exit
|
||||
for _ in range(0, seconds * 10):
|
||||
sleep(.1)
|
||||
|
||||
|
||||
def main(args):
|
||||
"""Parse arguments, call main loop"""
|
||||
|
||||
parser = OptionParser(description=__doc__)
|
||||
parser.add_option("-b", "--batch", action="store_true",
|
||||
help="run under batch mode")
|
||||
parser.add_option("-i", "--iterations", default='-1',
|
||||
help="iterations to run")
|
||||
parser.add_option("-n", "--node", default='-1',
|
||||
help="view a single node")
|
||||
parser.add_option("-r", "--rows", default='10',
|
||||
help="rows to display (default 10)")
|
||||
parser.add_option("-s", "--sort", default='t',
|
||||
help="column to sort on ('t':total, 'n': name, "
|
||||
"'i':IRQ number, '1':node1, etc) (default: 't')")
|
||||
parser.add_option("-t", "--time", default='5',
|
||||
help="update interval in seconds")
|
||||
parser.add_option("-z", "--zero", action="store_true",
|
||||
help="exclude inactive IRQs")
|
||||
parser.add_option("-v", "--version", action="store_true",
|
||||
help="get version")
|
||||
parser.add_option("--filter", default="",
|
||||
help="filter IRQs based on name matching comma "
|
||||
"separated filters")
|
||||
parser.add_option("--totals", action="store_true",
|
||||
help="include total rows")
|
||||
parser.add_option("-f", "--file1", default="",
|
||||
help="read a file instead of /proc/interrupts")
|
||||
parser.add_option("-F", "--file2", default="",
|
||||
help="no monitoring. Compare the samples from two files "
|
||||
"instead")
|
||||
parser.add_option("-O", "--overall", action="store_true",
|
||||
help="print all-time stats at the beginning")
|
||||
parser.add_option("-N", "--numafile", default="",
|
||||
help="read the NUMA info from a file, instead of "
|
||||
"calling numactl")
|
||||
|
||||
options = parser.parse_args(args)[0]
|
||||
|
||||
if options.version:
|
||||
print __version__
|
||||
return 0
|
||||
|
||||
if options.filter:
|
||||
options.filter = options.filter.split(',')
|
||||
else:
|
||||
options.filter = []
|
||||
|
||||
# If file is specified, no iterations
|
||||
if options.file1:
|
||||
options.iterations = 1
|
||||
options.batch = True
|
||||
|
||||
if options.file2:
|
||||
if not options.file1:
|
||||
print("ERROR: --file2 requires --file1")
|
||||
return -1
|
||||
options.iterations = 2
|
||||
|
||||
if options.file1 and not options.file2:
|
||||
options.overall = True
|
||||
|
||||
# Set the terminal to unbuffered, to catch a single keypress
|
||||
if not options.batch:
|
||||
out = sys.stdin.fileno()
|
||||
old_settings = termios.tcgetattr(out)
|
||||
tty.setraw(sys.stdin.fileno())
|
||||
|
||||
# input thread
|
||||
thread.start_new_thread(wait_for_input, tuple())
|
||||
else:
|
||||
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
|
||||
|
||||
try:
|
||||
display_itop(options.batch, int(options.time), int(options.rows),
|
||||
int(options.iterations), options.sort, options.totals,
|
||||
options.node, options.zero, options.filter, options.file1,
|
||||
options.file2, options.overall, options.numafile)
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
pass
|
||||
finally:
|
||||
if not options.batch:
|
||||
termios.tcsetattr(out, termios.TCSADRAIN, old_settings)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv))
|
|
@ -0,0 +1,10 @@
|
|||
[MESSAGES CONTROL]
|
||||
disable=too-many-arguments,
|
||||
too-many-locals,
|
||||
too-many-branches,
|
||||
too-many-statements,
|
||||
global-statement,
|
||||
superfluous-parens # https://docs.python.org/3.0/whatsnew/3.0.html#print-is-a-function
|
||||
|
||||
[REPORTS]
|
||||
reports=no
|
|
@ -0,0 +1,411 @@
|
|||
#!/usr/bin/perl
|
||||
# irqtop
|
||||
#
|
||||
# by Robert Elliott, HP
|
||||
# contributed to the sysstat project
|
||||
#
|
||||
#########################################################################
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#########################################################################
|
||||
#
|
||||
# Monitor differences in /proc/interrupts and /proc/softirqs
|
||||
# per CPU, along with CPU statistics
|
||||
#
|
||||
# Usage: irqtop [interval]
|
||||
#
|
||||
# Displays interrupts that have occurred since this program
|
||||
# began, filtering those that have always been zeros.
|
||||
#
|
||||
# TODO features:
|
||||
# * increase column widths automatically
|
||||
# * add an all-CPU column
|
||||
# * add option to choose between
|
||||
# - online CPUs
|
||||
# - just the all-CPU column
|
||||
# - select CPUs (e.g., ranges like in smp_affinity_list)
|
||||
# * automatically determine interrupts to total (e.g.
|
||||
# all mpt3sas or hpsaN interrupts) based on them having
|
||||
# common prefixes in their names or common names
|
||||
#
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
|
||||
my $myname = "irqtop";
|
||||
my $myversion = "0.2";
|
||||
|
||||
sub print_usage {
|
||||
print "Usage: $myname [interval] [-V | --version] [-h | --help]\n\n";
|
||||
print " [internal] time in seconds between updates (default: 1 second)\n";
|
||||
print " [-V | --version] display version number\n";
|
||||
print " [-h | --help] display usage\n\n";
|
||||
print "Use Control-C to exit\n";
|
||||
}
|
||||
|
||||
#my $mpstat = "../sysstat/mpstat";
|
||||
my $mpstat = "mpstat";
|
||||
|
||||
# calculate total interrupt stats for this list
|
||||
#my @track_list = ();
|
||||
my @track_list = ("eth", "hpsa1", "hpsa2", "mpt3sas");
|
||||
|
||||
# exclude these from per-vector display (e.g., eth while studying storage)
|
||||
# still included in totals if also in track_list
|
||||
#my @exclude_list = ();
|
||||
my @exclude_list = ("eth");
|
||||
|
||||
my $interval = 1; # default interval in seconds
|
||||
|
||||
# hashes of arrays
|
||||
# key is the interrupt number or name (e.g., 95 or TIMER)
|
||||
# array is the interrupt counts and the description on the right
|
||||
my %current;
|
||||
my %delta; # hold the deltas between collection and printing
|
||||
|
||||
# hash of values
|
||||
my %ever_changed; # indicates if this row ever changed
|
||||
my %track_interrupts; # number of each type
|
||||
|
||||
my $online_cpus; # as seen by process_hardirq, used to filter columns in softirq
|
||||
|
||||
# return 1 to exclude, 0 to not
|
||||
sub is_excluded {
|
||||
my ($line) = @_;
|
||||
|
||||
foreach (@exclude_list) {
|
||||
return 1 if ($line =~ /$_/);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# convert affinity_list bitmask (64-bit binary) into numbered list
|
||||
# Example: 5800a000f -> "0-3,17,19,31-32,34"
|
||||
# used for parsing /proc/irq/NN/affinity_hint
|
||||
sub bitmask_to_list {
|
||||
my ($bitmask) = @_;
|
||||
my $inrange;
|
||||
my $rangelist;
|
||||
my $rangenew;
|
||||
my $lowcpu;
|
||||
my $highcpu;
|
||||
|
||||
for (my $i = 0; $i < 63; $i++) {
|
||||
if (!$inrange && $bitmask & 1) {
|
||||
$inrange = 1;
|
||||
$lowcpu = $i;
|
||||
$highcpu = $i;
|
||||
} elsif ($inrange && $bitmask & 1) {
|
||||
$highcpu = $i;
|
||||
} elsif ($inrange && !($bitmask & 1)) {
|
||||
$inrange = 0;
|
||||
if ($lowcpu == $highcpu) {
|
||||
$rangenew = "$lowcpu";
|
||||
} else {
|
||||
$rangenew = "$lowcpu-$highcpu";
|
||||
}
|
||||
|
||||
if ($rangelist) {
|
||||
$rangelist = "$rangelist,$rangenew";
|
||||
} else {
|
||||
$rangelist = "$rangenew";
|
||||
}
|
||||
}
|
||||
|
||||
$bitmask = $bitmask >> 1;
|
||||
}
|
||||
if ($inrange) {
|
||||
$rangelist = "$rangelist,$lowcpu-$highcpu";
|
||||
}
|
||||
if (!$rangelist) {
|
||||
$rangelist = "none";
|
||||
}
|
||||
return $rangelist;
|
||||
}
|
||||
|
||||
# process /proc/interrupts
|
||||
# argument:
|
||||
# 0 do not display - use the first time to not display values since reboot
|
||||
# 1 display - use on all subsequent calls
|
||||
sub collect_hardirqs {
|
||||
my ($firstpass) = @_;
|
||||
|
||||
open HARDIRQFILE, "/proc/interrupts" or die "Cannot open $_";
|
||||
|
||||
foreach (@track_list) {
|
||||
$track_interrupts{$_} = 0;
|
||||
}
|
||||
|
||||
# /proc/interrupts lists only online cpus
|
||||
# first line contains CPUnn headers for each column
|
||||
# CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 CPU8 CPU9 CPU10 CPU11
|
||||
$_ = <HARDIRQFILE>;
|
||||
my @cpulist = split;
|
||||
$online_cpus = $#cpulist + 1; # hardirqs are a source of online_cpus
|
||||
|
||||
# remaining lines contain vector number: per-cpu counts, interrupt type, device
|
||||
# or vector name, per-CPU counts, interrupt type, description
|
||||
while (<HARDIRQFILE>) {
|
||||
my @values = split;
|
||||
my $irqname = $values[0];
|
||||
my $cpu;
|
||||
my $line = $_;
|
||||
|
||||
for ($cpu = 0; $cpu < $online_cpus; $cpu++) {
|
||||
$delta{$irqname}[$cpu] = $values[$cpu + 1] - $current{$irqname}[$cpu];
|
||||
$current{$irqname}[$cpu] = $values[$cpu + 1];
|
||||
|
||||
# if this is not the first pass,
|
||||
# keep track of whether the values have changed
|
||||
if ($delta{$irqname}[$cpu] && !$firstpass && !is_excluded($line)) {
|
||||
$ever_changed{$irqname} = 1;
|
||||
}
|
||||
|
||||
foreach (@track_list) {
|
||||
if ($line =~ /$_/) {
|
||||
$track_interrupts{$_} += $delta{$irqname}[$cpu];
|
||||
}
|
||||
}
|
||||
}
|
||||
# capture the rest of the line (interrupt type, handlers)
|
||||
# these are not really per-cpu values, but continue storing
|
||||
# each word in %current since it's convenient
|
||||
for (; $cpu < $#values + 1; $cpu++ ) {
|
||||
$current{$irqname}[$cpu] = $values[$cpu + 1];
|
||||
}
|
||||
}
|
||||
close HARDIRQFILE;
|
||||
|
||||
}
|
||||
|
||||
# process /proc/softirqs
|
||||
# argument:
|
||||
# 0 do not display - use the first time to not display values since reboot
|
||||
# 1 display - use on all subsequent calls
|
||||
sub collect_softirqs {
|
||||
my ($firstpass) = @_;
|
||||
|
||||
open SOFTIRQFILE, "/proc/softirqs" or die "Cannot open $_";
|
||||
|
||||
# /proc/softirqs includes all possible cpus, not all online cpus
|
||||
# this function ignores all those extra cpus
|
||||
# first line contains CPUnn headers for each column
|
||||
# CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 CPU8 CPU9 CPU10 CPU11
|
||||
$_ = <SOFTIRQFILE>;
|
||||
my @cpulist = split; # discard the first line
|
||||
|
||||
# remaining lines contain
|
||||
# vector number: per-cpu counts, interrupt type, device
|
||||
# or vector name: per-cpu counts, interrupt type, description
|
||||
while (<SOFTIRQFILE>) {
|
||||
my @values = split;
|
||||
my $irqname = $values[0];
|
||||
my $line = $_;
|
||||
|
||||
# just remember the values for online cpus, not offline cpus
|
||||
for (my $cpu = 0; $cpu < $online_cpus; $cpu++) {
|
||||
$delta{$irqname}[$cpu] = $values[$cpu + 1] - $current{$irqname}[$cpu];
|
||||
$current{$irqname}[$cpu] = $values[$cpu + 1];
|
||||
if ($delta{$irqname}[$cpu] && !$firstpass && !is_excluded($line)) {
|
||||
$ever_changed{$irqname} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
close SOFTIRQFILE;
|
||||
}
|
||||
|
||||
# print the CPU0 CPU1 CPU2... header line for the online cpus
|
||||
sub print_cpulist {
|
||||
for (my $cpu = 0; $cpu < $online_cpus; $cpu++) {
|
||||
my $cpustring;
|
||||
$cpustring = sprintf("CPU%d", $cpu);
|
||||
printf("%6s ", $cpustring);
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
# print hardirqs and softirqs from %delta that have ever %changed
|
||||
sub print_irqs {
|
||||
|
||||
# header line
|
||||
printf("%13s ", "--- IRQs ---");
|
||||
# print_cpulist(); # uncomment if print_mpstat is not used, since that prints the header line
|
||||
print "\n";
|
||||
|
||||
foreach (sort keys %delta) {
|
||||
my $irqname = $_;
|
||||
# if any values have ever changed for an interrupt, print the delta values
|
||||
if ($ever_changed{$irqname}) {
|
||||
# match the width of softirq names 12 characters plus :
|
||||
printf("%13s ", $irqname);
|
||||
my $cpu;
|
||||
for ($cpu = 0; $cpu < $online_cpus; $cpu++) {
|
||||
printf("%6d ", $delta{$irqname}[$cpu]);
|
||||
}
|
||||
# print the rest of the line (interrupt type, handlers)
|
||||
for (; $cpu < @{$current{$irqname}} + 1; $cpu++ ) {
|
||||
print "$current{$irqname}[$cpu] ";
|
||||
}
|
||||
|
||||
# print the irq smp affinity list, if any
|
||||
my $irqname_nocolon = $irqname;
|
||||
$irqname_nocolon =~ s/://;
|
||||
|
||||
if (!($irqname =~ /[A-Z]/)) {
|
||||
my $affinity_hint_file = "/proc/irq/$irqname_nocolon/affinity_hint";
|
||||
if (-e $affinity_hint_file) {
|
||||
open IRQAFF, "<$affinity_hint_file";
|
||||
my $affhint = <IRQAFF>;
|
||||
close IRQAFF;
|
||||
chomp $affhint;
|
||||
my ($affhigh,$afflow) = $affhint =~ /(.*),(.*)/;
|
||||
my $aff = hex $affhigh << 32 | hex $afflow;
|
||||
printf("hint=%s,", bitmask_to_list($aff));
|
||||
} else {
|
||||
print "hint=none,";
|
||||
}
|
||||
my $smp_affinity_list_file = "/proc/irq/$irqname_nocolon/smp_affinity_list";
|
||||
if (-e $smp_affinity_list_file) {
|
||||
open IRQAFF, "<$smp_affinity_list_file";
|
||||
my $afflist = <IRQAFF>;
|
||||
close IRQAFF;
|
||||
chomp $afflist;
|
||||
print "aff=$afflist";
|
||||
} else {
|
||||
print "aff=none";
|
||||
}
|
||||
}
|
||||
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
|
||||
# print summary of selected sets of interrupts
|
||||
foreach (@track_list) {
|
||||
printf("%12s: total=%-7d, average=%-7d; total/s=%-7d, average/s=%-7d\n",
|
||||
$_,
|
||||
$track_interrupts{$_},
|
||||
$track_interrupts{$_} / $online_cpus,
|
||||
$track_interrupts{$_} / $interval,
|
||||
$track_interrupts{$_} / $interval / $online_cpus);
|
||||
}
|
||||
}
|
||||
|
||||
# collect interesting CPU statistics from mpstat
|
||||
# %usr, %sys, %iowait, %idle, %irq, %soft
|
||||
# mpstat displays:
|
||||
# 06:14:48 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
|
||||
# plain "mpstat" shows averages since boot, which is not useful
|
||||
# so, use the interval option based on the first argument to this function,
|
||||
# which also causes this function to incur the delay.
|
||||
# per-cpu arrays of value strings
|
||||
my @usr;
|
||||
my @sys;
|
||||
my @irq;
|
||||
my @soft;
|
||||
my @iowait;
|
||||
my @idle;
|
||||
|
||||
sub collect_mpstat {
|
||||
my ($delay) = @_;
|
||||
|
||||
open MPSTATFILE, "$mpstat -P ON -u $delay 1 |" or sleep($delay);
|
||||
while (<MPSTATFILE>) {
|
||||
if (/CPU/ || /all/ || /^$/ || /Average/) {
|
||||
next;
|
||||
}
|
||||
my ($time, $ampm, $cpu, $usr, $nice, $sys, $iowait, $irq, $soft, $steal, $guest, $idle) = split;
|
||||
$usr[$cpu] = $usr;
|
||||
$sys[$cpu] = $sys;
|
||||
$irq[$cpu] = $irq;
|
||||
$soft[$cpu] = $soft;
|
||||
$iowait[$cpu] = $iowait;
|
||||
$idle[$cpu] = $idle;
|
||||
$online_cpus = $cpu + 1; # mpstat is a source for # online CPUs
|
||||
}
|
||||
close MPSTATFILE;
|
||||
}
|
||||
|
||||
# print the interesting CPU statistics from mpstat
|
||||
# collected in collect_mpstat()
|
||||
sub print_mpstat {
|
||||
|
||||
# header line
|
||||
printf("%13s ", "CPU usage:");
|
||||
print_cpulist();
|
||||
|
||||
printf("%13s ", "\%usr:");
|
||||
for (my $cpu = 0; $cpu < $online_cpus; $cpu++) {
|
||||
printf("%6s ", $usr[$cpu]);
|
||||
}
|
||||
print "\n";
|
||||
printf("%13s ", "\%sys:");
|
||||
for (my $cpu = 0; $cpu < $online_cpus; $cpu++) {
|
||||
printf("%6s ", $sys[$cpu]);
|
||||
}
|
||||
print "\n";
|
||||
printf("%13s ", "\%irq:");
|
||||
for (my $cpu = 0; $cpu < $online_cpus; $cpu++) {
|
||||
printf("%6s ", $irq[$cpu]);
|
||||
}
|
||||
print "\n";
|
||||
printf("%13s ", "\%soft:");
|
||||
for (my $cpu = 0; $cpu < $online_cpus; $cpu++) {
|
||||
printf("%6s ", $soft[$cpu]);
|
||||
}
|
||||
print "\n";
|
||||
printf("%13s ", "\%iowait idle:"); # clarify that iowait is really idle time
|
||||
for (my $cpu = 0; $cpu < $online_cpus; $cpu++) {
|
||||
printf("%6s ", $iowait[$cpu]);
|
||||
}
|
||||
print "\n";
|
||||
printf("%13s ", "\%idle:");
|
||||
for (my $cpu = 0; $cpu < $online_cpus; $cpu++) {
|
||||
printf("%6s ", $idle[$cpu]);
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
#
|
||||
# start of program
|
||||
#
|
||||
foreach (@ARGV) {
|
||||
if (/--version/ || /-V/) {
|
||||
print "$myname version $myversion\n";
|
||||
exit;
|
||||
} elsif (/--help/ || /-h/) {
|
||||
print_usage();
|
||||
exit;
|
||||
} elsif (!/[a-z]/) {
|
||||
# assume an all-numeric argument is the interval
|
||||
$interval = $_;
|
||||
}
|
||||
print "Collecting CPU and interrupt activity for $interval seconds between updates\n";
|
||||
}
|
||||
|
||||
# remember the clear screen characters to avoid system() during run time
|
||||
my $clearscreen = `clear`;
|
||||
collect_hardirqs(1);
|
||||
collect_softirqs(1);
|
||||
while (1) {
|
||||
collect_hardirqs(0);
|
||||
collect_softirqs(0);
|
||||
collect_mpstat($interval);
|
||||
my $datestring = localtime();
|
||||
print "${clearscreen}$myname $datestring interval: $interval s\n";
|
||||
print_mpstat();
|
||||
print_irqs();
|
||||
|
||||
# if collect_mpstat(), which delays, is commented out, sleep here
|
||||
# sleep($interval);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
README file for the isag - Interactive System Activity Graph - command.
|
||||
|
||||
isag is a command that enables you to plot data stored in a daily data file
|
||||
by a previous sar run.
|
||||
isag needs a recent version of Tcl/Tk installed, together with the
|
||||
gnuplot plotting program.
|
||||
|
||||
isag is (C) 2000,2001 by David Doubrava <linux_monitor@volny.cz>.
|
||||
Send bug reports to <linux_monitor@volny.cz>.
|
||||
|
||||
Note that the path to daily data files is hard coded in isag and
|
||||
its value is "/var/log/sa".
|
||||
Also isag assumes that sar is installed in /usr/bin directory.
|
||||
Update isag script if sar is located elsewhere.
|
||||
|
||||
--
|
||||
Sebastien Godard (sysstat <at> wanadoo.fr)
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,201 @@
|
|||
.\" Automatically generated by Pod::Man version 1.02
|
||||
.\" Mon Mar 22 20:19:18 2004
|
||||
.\"
|
||||
.\" Standard preamble:
|
||||
.\" ======================================================================
|
||||
.de Sh \" Subsection heading
|
||||
.br
|
||||
.if t .Sp
|
||||
.ne 5
|
||||
.PP
|
||||
\fB\\$1\fR
|
||||
.PP
|
||||
..
|
||||
.de Sp \" Vertical space (when we can't use .PP)
|
||||
.if t .sp .5v
|
||||
.if n .sp
|
||||
..
|
||||
.de Ip \" List item
|
||||
.br
|
||||
.ie \\n(.$>=3 .ne \\$3
|
||||
.el .ne 3
|
||||
.IP "\\$1" \\$2
|
||||
..
|
||||
.de Vb \" Begin verbatim text
|
||||
.ft CW
|
||||
.nf
|
||||
.ne \\$1
|
||||
..
|
||||
.de Ve \" End verbatim text
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.\" Set up some character translations and predefined strings. \*(-- will
|
||||
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
||||
.\" double quote, and \*(R" will give a right double quote. | will give a
|
||||
.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used
|
||||
.\" to do unbreakable dashes and therefore won't be available. \*(C` and
|
||||
.\" \*(C' expand to `' in nroff, nothing in troff, for use with C<>
|
||||
.\".tr \(*W-|\(bv\*(Tr
|
||||
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
||||
.ie n \{\
|
||||
. ds -- \(*W-
|
||||
. ds PI pi
|
||||
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
||||
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
||||
. ds L" ""
|
||||
. ds R" ""
|
||||
. ds C` `
|
||||
. ds C' '
|
||||
'br\}
|
||||
.el\{\
|
||||
. ds -- \|\(em\|
|
||||
. ds PI \(*p
|
||||
. ds L" ``
|
||||
. ds R" ''
|
||||
'br\}
|
||||
.\"
|
||||
.\" If the F register is turned on, we'll generate index entries on stderr
|
||||
.\" for titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and
|
||||
.\" index entries marked with X<> in POD. Of course, you'll have to process
|
||||
.\" the output yourself in some meaningful fashion.
|
||||
.if \nF \{\
|
||||
. de IX
|
||||
. tm Index:\\$1\t\\n%\t"\\$2"
|
||||
. .
|
||||
. nr % 0
|
||||
. rr F
|
||||
.\}
|
||||
.\"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it
|
||||
.\" makes way too many mistakes in technical documents.
|
||||
.hy 0
|
||||
.if n .na
|
||||
.\"
|
||||
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
|
||||
.\" Fear. Run. Save yourself. No user-serviceable parts.
|
||||
.bd B 3
|
||||
. \" fudge factors for nroff and troff
|
||||
.if n \{\
|
||||
. ds #H 0
|
||||
. ds #V .8m
|
||||
. ds #F .3m
|
||||
. ds #[ \f1
|
||||
. ds #] \fP
|
||||
.\}
|
||||
.if t \{\
|
||||
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
|
||||
. ds #V .6m
|
||||
. ds #F 0
|
||||
. ds #[ \&
|
||||
. ds #] \&
|
||||
.\}
|
||||
. \" simple accents for nroff and troff
|
||||
.if n \{\
|
||||
. ds ' \&
|
||||
. ds ` \&
|
||||
. ds ^ \&
|
||||
. ds , \&
|
||||
. ds ~ ~
|
||||
. ds /
|
||||
.\}
|
||||
.if t \{\
|
||||
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
|
||||
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
|
||||
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
|
||||
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
|
||||
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
|
||||
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
|
||||
.\}
|
||||
. \" troff and (daisy-wheel) nroff accents
|
||||
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
|
||||
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
|
||||
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
|
||||
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
|
||||
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
|
||||
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
|
||||
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
|
||||
.ds ae a\h'-(\w'a'u*4/10)'e
|
||||
.ds Ae A\h'-(\w'A'u*4/10)'E
|
||||
. \" corrections for vroff
|
||||
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
|
||||
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
|
||||
. \" for low resolution devices (crt and lpr)
|
||||
.if \n(.H>23 .if \n(.V>19 \
|
||||
\{\
|
||||
. ds : e
|
||||
. ds 8 ss
|
||||
. ds o a
|
||||
. ds d- d\h'-1'\(ga
|
||||
. ds D- D\h'-1'\(hy
|
||||
. ds th \o'bp'
|
||||
. ds Th \o'LP'
|
||||
. ds ae ae
|
||||
. ds Ae AE
|
||||
.\}
|
||||
.rm #[ #] #H #V #F C
|
||||
.\" ======================================================================
|
||||
.\"
|
||||
.IX Title "ISAG 1"
|
||||
.TH ISAG 1 "0.81.0" "March 2004" "System Activity Grapher"
|
||||
.UC
|
||||
.SH "NAME"
|
||||
isag \- Interactive System Activity Grapher
|
||||
.SH "SYNOPSIS"
|
||||
.IX Header "SYNOPSIS"
|
||||
isag [\-p datafiles_path] [\-c config_file] [\-ght gr_height] [\-gwd gr_width]
|
||||
.SH "DESCRIPTION"
|
||||
.IX Header "DESCRIPTION"
|
||||
The \fIisag\fR command graphically displays the system activity data stored
|
||||
in a binary data file by a previous \fIsar\fR run. The \fIisag\fR command invokes
|
||||
\&\fIsar\fR to extract the data to be plotted.
|
||||
.PP
|
||||
The data are processed using \fIsar\fR command and slightly transformed
|
||||
to tabular format, and then this format is visualized using \fIgnuplot\fR
|
||||
program.
|
||||
.SH "OPTIONS"
|
||||
.IX Header "OPTIONS"
|
||||
.Ip "\-p datafiles_path" 4
|
||||
.IX Item "-p datafiles_path"
|
||||
Specify the pathname where are located the daily data files.
|
||||
Default path is: \fI/var/log/sa\fR
|
||||
.Ip "\-c config_file" 4
|
||||
.IX Item "-c config_file"
|
||||
Specify the configuration file used by the \fIisag\fR command.
|
||||
The contents of this file may depend on \fIisag\fR version number.
|
||||
Default config file is: \fI$HOME/.isag.cfg\fR.
|
||||
.Ip "\-ght gr_height" 4
|
||||
.IX Item "-ght gr_height"
|
||||
Specify the height of the chart area.
|
||||
Default value is: \fI400\fR.
|
||||
.Ip "\-gwd gr_width" 4
|
||||
.IX Item "-gwd gr_width"
|
||||
Specify the width of the chart area.
|
||||
Default value is: \fI720\fR.
|
||||
.SH "CONFIG FILE"
|
||||
.IX Header "CONFIG FILE"
|
||||
As mentioned above there is a config file. There are stored following values:
|
||||
.Ip "last showed graph" 2
|
||||
.IX Item "last showed graph"
|
||||
.Ip "y limits for each kind of graph" 2
|
||||
.IX Item "y limits for each kind of graph"
|
||||
.PP
|
||||
It seems useful, because new run doesn't need new settings to obtain same scale.
|
||||
.SH "PREREQUSITIES"
|
||||
.IX Header "PREREQUSITIES"
|
||||
Here is list of prerequsities including versioning and built-in features.
|
||||
.Ip "Tcl/Tk"
|
||||
.IX Item "Tcl/Tk"
|
||||
Version 8.0 or newer.
|
||||
.Ip "gnuplot"
|
||||
.IX Item "gnuplot"
|
||||
Gnuplot must have a \fBtkcanvas\fR display.
|
||||
.SH "AUTHOR"
|
||||
.IX Header "AUTHOR"
|
||||
D. Doubrava 2000, 2002 e-mail:\ linux_monitor(at)volny(dot)cz
|
||||
.PP
|
||||
\&\s-1HTTP\s0 Site: http://www.volny.cz/linux_monitor/isag/index.html
|
||||
.SH "SEE ALSO"
|
||||
.IX Header "SEE ALSO"
|
||||
\&\fBsar\fR (1), \fBsadc\fR (8).
|
|
@ -0,0 +1,529 @@
|
|||
#!/bin/bash
|
||||
# sargraph - a simple sketch on how to generate graphs from sadf XML output
|
||||
# by Lans.Carstensen@dreamworks.com <Lans Carstensen>
|
||||
|
||||
# Our dependencies - bail out if they are not found
|
||||
|
||||
set -e
|
||||
ZENITY=`which zenity`
|
||||
XSLTPROC=`which xsltproc`
|
||||
SADF=`which sadf`
|
||||
GNUPLOT=`which gnuplot`
|
||||
MKTEMP=`which mktemp`
|
||||
FIND=`which find`
|
||||
SORT=`which sort`
|
||||
CUT=`which cut`
|
||||
GZIP=`which gzip`
|
||||
set +e
|
||||
|
||||
# Default for --sa-dir
|
||||
SA_DIR="/var/log/sa"
|
||||
|
||||
SA_REGEX='/sa[0-9][0-9]+(\.(gz|bz2|xz|lz|lzo))?$'
|
||||
|
||||
|
||||
######### OPTION PARSING ###########
|
||||
set -e
|
||||
|
||||
parsed_opts=`getopt -o "" -l sa-dir: -- "$@"`
|
||||
eval set -- "$parsed_opts"
|
||||
|
||||
DONE=no
|
||||
while [ $DONE != yes ]
|
||||
do
|
||||
case $1 in
|
||||
--sa-dir)
|
||||
shift
|
||||
SA_DIR="$1"
|
||||
;;
|
||||
--)
|
||||
# End of options
|
||||
DONE=yes
|
||||
;;
|
||||
*)
|
||||
echo Unexpected argument: $1
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
shift # should shift the last arg or '--' if DONE=yes
|
||||
done
|
||||
|
||||
set +e
|
||||
####################################
|
||||
|
||||
|
||||
# sar / sysstat DTD is published here:
|
||||
# http://pagesperso-orange.fr/sebastien.godard/sysstat.dtd
|
||||
# compare against output of "sadf -x"
|
||||
# and pull apart data into gnuplot tabular data files
|
||||
|
||||
# Subroutines
|
||||
|
||||
# Graph for "sar -u"
|
||||
|
||||
cpu_xslt() {
|
||||
# Create the XSLT transform to make a GNUplot data file out of "sar -u" type data
|
||||
# test with "sadf -x | xsltproc <file containing stuff below> -
|
||||
cat > $1 <<EOF
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:strip-space elements="*"/>
|
||||
<xsl:template match="/sysstat/host/statistics">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:for-each select="timestamp">
|
||||
<xsl:value-of select="@time"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./cpu-load/cpu[@number='all']/@user"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./cpu-load/cpu[@number='all']/@nice"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./cpu-load/cpu[@number='all']/@system"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./cpu-load/cpu[@number='all']/@iowait"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./cpu-load/cpu[@number='all']/@steal"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
EOF
|
||||
}
|
||||
|
||||
cpu_gnuplot() {
|
||||
# Create the GNUplot rendering file, largely based on "isag" Tk script from sysstat package
|
||||
#set yrange [0:100]
|
||||
cat > $1 <<EOF
|
||||
set term x11
|
||||
set title "sar -u"
|
||||
set ylabel "Percent"
|
||||
set timefmt "%H:%M:%S"
|
||||
set xdata time
|
||||
set format x "%H:%M"
|
||||
plot "$2" using 1:2 t "%user" with line, "$2" using 1:3 t "%nice" with line, "$2" using 1:4 t "%system" with line, "$2" using 1:5 t "%iowait" with line, "$2" using 1:6 t "%steal" with line
|
||||
pause mouse
|
||||
EOF
|
||||
}
|
||||
|
||||
# To output to a file change the gnuplot routines to say something like:
|
||||
# set term svg
|
||||
# ...
|
||||
# set output "/tmp/test.svg"
|
||||
# plot ...
|
||||
|
||||
# Graph for "sar -q"
|
||||
|
||||
rq_xslt() {
|
||||
# Create the XSLT transform to make a GNUplot data file out of "sar -q" type data
|
||||
# test with "sadf -x | xsltproc <file containing stuff below> -
|
||||
cat > $1 <<EOF
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:strip-space elements="*"/>
|
||||
<xsl:template match="/sysstat/host/statistics">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:for-each select="timestamp">
|
||||
<xsl:value-of select="@time"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./queue/@runq-sz"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./queue/@plist-sz"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./queue/@ldavg-1"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./queue/@ldavg-5"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./queue/@ldavg-15"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
EOF
|
||||
}
|
||||
|
||||
rq_gnuplot() {
|
||||
cat > $1 <<EOF
|
||||
set term x11
|
||||
set title "sar -q"
|
||||
set ylabel ""
|
||||
set timefmt "%H:%M:%S"
|
||||
set xdata time
|
||||
set format x "%H:%M"
|
||||
plot "$2" using 1:2 t "runq-sz" with line, "$2" using 1:3 t "plist-sz" with line, "$2" using 1:4 t "ldavg-1" with line, "$2" using 1:5 t "ldavg-5" with line, "$2" using 1:6 t "ldavg-15" with line
|
||||
pause mouse
|
||||
EOF
|
||||
}
|
||||
|
||||
# Graph for "sar -q", but w/o the process list size
|
||||
|
||||
rqnoplistsz_xslt() {
|
||||
# Create the XSLT transform to make a GNUplot data file out of "sar -q" type data
|
||||
# test with "sadf -x | xsltproc <file containing stuff below> -
|
||||
cat > $1 <<EOF
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:strip-space elements="*"/>
|
||||
<xsl:template match="/sysstat/host/statistics">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:for-each select="timestamp">
|
||||
<xsl:value-of select="@time"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./queue/@runq-sz"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./queue/@ldavg-1"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./queue/@ldavg-5"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./queue/@ldavg-15"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
EOF
|
||||
}
|
||||
|
||||
rqnoplistsz_gnuplot() {
|
||||
cat > $1 <<EOF
|
||||
set term x11
|
||||
set title "sar -q"
|
||||
set ylabel ""
|
||||
set timefmt "%H:%M:%S"
|
||||
set xdata time
|
||||
set format x "%H:%M"
|
||||
plot "$2" using 1:2 t "runq-sz" with line, "$2" using 1:3 t "ldavg-1" with line, "$2" using 1:4 t "ldavg-5" with line, "$2" using 1:5 t "ldavg-15" with line
|
||||
pause mouse
|
||||
EOF
|
||||
}
|
||||
|
||||
# Graph for "sar -b"
|
||||
|
||||
io_xslt() {
|
||||
# Create the XSLT transform to make a GNUplot data file out of "sar -b" type data
|
||||
# test with "sadf -x | xsltproc <file containing stuff below> -
|
||||
cat > $1 <<EOF
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:strip-space elements="*"/>
|
||||
<xsl:template match="/sysstat/host/statistics">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:for-each select="timestamp">
|
||||
<xsl:value-of select="@time"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./io/tps"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./io/io-reads/@rtps"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./io/io-writes/@wtps"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./io/io-reads/@bread"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./io/io-writes/@bwrtn"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
EOF
|
||||
}
|
||||
|
||||
io_gnuplot() {
|
||||
cat > $1 <<EOF
|
||||
set term x11
|
||||
set title "sar -b"
|
||||
set ylabel "ops/s"
|
||||
set timefmt "%H:%M:%S"
|
||||
set xdata time
|
||||
set format x "%H:%M"
|
||||
plot "$2" using 1:2 t "rtps" with line, "$2" using 1:3 t "wtps" with line, "$2" using 1:4 t "bread/s" with line, "$2" using 1:5 t "bwrtn/s" with line
|
||||
pause mouse
|
||||
EOF
|
||||
}
|
||||
|
||||
# Graph for "sar -n NFS"
|
||||
|
||||
nfsclient_xslt() {
|
||||
# Create the XSLT transform to make a GNUplot data file out of "sar -n NFS" type data
|
||||
# test with "sadf -x | xsltproc <file containing stuff below> -
|
||||
cat > $1 <<EOF
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:strip-space elements="*"/>
|
||||
<xsl:template match="/sysstat/host/statistics">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:for-each select="timestamp">
|
||||
<xsl:value-of select="@time"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./network/net-nfs/@call"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./network/net-nfs/@retrans"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./network/net-nfs/@read"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./network/net-nfs/@write"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./network/net-nfs/@access"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./network/net-nfs/@getatt"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
EOF
|
||||
}
|
||||
|
||||
nfsclient_gnuplot() {
|
||||
cat > $1 <<EOF
|
||||
set term x11
|
||||
set title "sar -n NFS"
|
||||
set ylabel "ops/s"
|
||||
set timefmt "%H:%M:%S"
|
||||
set xdata time
|
||||
set format x "%H:%M"
|
||||
plot "$2" using 1:2 t "call/s" with line, "$2" using 1:3 t "retrans/s" with line, "$2" using 1:4 t "read/s" with line, "$2" using 1:5 t "write/s" with line, "$2" using 1:6 t "access/s" with line, "$2" using 1:7 t "getatt/s" with line
|
||||
pause mouse
|
||||
EOF
|
||||
}
|
||||
|
||||
# Graph for "sar -B"
|
||||
|
||||
paging_xslt() {
|
||||
# Create the XSLT transform to make a GNUplot data file out of "sar -B" type data
|
||||
# test with "sadf -x | xsltproc <file containing stuff below> -
|
||||
cat > $1 <<EOF
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:strip-space elements="*"/>
|
||||
<xsl:template match="/sysstat/host/statistics">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:for-each select="timestamp">
|
||||
<xsl:value-of select="@time"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./paging/@pgpgin"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./paging/@pgpgout"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./paging/@fault"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./paging/@majflt"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
EOF
|
||||
}
|
||||
|
||||
paging_gnuplot() {
|
||||
cat > $1 <<EOF
|
||||
set term x11
|
||||
set title "sar -B"
|
||||
set ylabel "pages/s"
|
||||
set timefmt "%H:%M:%S"
|
||||
set xdata time
|
||||
set format x "%H:%M"
|
||||
plot "$2" using 1:2 t "pgpgin/s" with line, "$2" using 1:3 t "pgpgout/s" with line, "$2" using 1:4 t "fault/s" with line, "$2" using 1:5 t "majflt/s" with line
|
||||
pause mouse
|
||||
EOF
|
||||
}
|
||||
|
||||
# Graph for "sar -r"
|
||||
|
||||
memuse_xslt() {
|
||||
# Create the XSLT transform to make a GNUplot data file out of "sar -r" type data
|
||||
# test with "sadf -x | xsltproc <file containing stuff below> -
|
||||
cat > $1 <<EOF
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:strip-space elements="*"/>
|
||||
<xsl:template match="/sysstat/host/statistics">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:for-each select="timestamp">
|
||||
<xsl:value-of select="@time"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./memory/memfree"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./memory/memused"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./memory/buffers"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./memory/cached"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./memory/swpfree"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./memory/swpused"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./memory/swpcad"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
EOF
|
||||
}
|
||||
|
||||
memuse_gnuplot() {
|
||||
cat > $1 <<EOF
|
||||
set term x11
|
||||
set title "sar -r"
|
||||
set ylabel "kB"
|
||||
set timefmt "%H:%M:%S"
|
||||
set xdata time
|
||||
set format x "%H:%M"
|
||||
plot "$2" using 1:2 t "kbmemfree" with line, "$2" using 1:3 t "kbmemused" with line, "$2" using 1:4 t "kbbuffers" with line, "$2" using 1:5 t "kbcached" with line, "$2" using 1:6 t "swpfree" with line, "$2" using 1:7 t "swpused" with line, "$2" using 1:8 t "swpcad" with line
|
||||
pause mouse
|
||||
EOF
|
||||
}
|
||||
|
||||
# Graph for "sar -S"
|
||||
|
||||
swapuse_xslt() {
|
||||
# Create the XSLT transform to make a GNUplot data file out of "sar -r" type data
|
||||
# test with "sadf -x | xsltproc <file containing stuff below> -
|
||||
cat > $1 <<EOF
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:strip-space elements="*"/>
|
||||
<xsl:template match="/sysstat/host/statistics">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:for-each select="timestamp">
|
||||
<xsl:value-of select="@time"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./memory/swpfree"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./memory/swpused"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="./memory/swpcad"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
EOF
|
||||
}
|
||||
|
||||
swapuse_gnuplot() {
|
||||
cat > $1 <<EOF
|
||||
set term x11
|
||||
set title "sar -S"
|
||||
set ylabel "kB"
|
||||
set timefmt "%H:%M:%S"
|
||||
set xdata time
|
||||
set format x "%H:%M"
|
||||
plot "$2" using 1:2 t "swpfree" with line, "$2" using 1:3 t "swpused" with line, "$2" using 1:4 t "swpcad" with line
|
||||
pause mouse
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
SA_FILES=`$FIND "$SA_DIR" -type f -printf '%T@,%p\n' \
|
||||
| grep -E "$SA_REGEX" | $SORT -n -r | $CUT -d, -f2`
|
||||
|
||||
# Main loop
|
||||
|
||||
DONE=no
|
||||
while [ $DONE != yes ]
|
||||
do
|
||||
|
||||
# Prompt for sa file
|
||||
|
||||
SA_FILE=`$ZENITY --list --text "Select data source" \
|
||||
--column "sa file" $SA_FILES`
|
||||
|
||||
if [ "$SA_FILE" == "" ]
|
||||
then
|
||||
exit
|
||||
fi
|
||||
|
||||
if echo $SA_FILE | grep '.gz$'
|
||||
then
|
||||
UNCOMPRESSED_SA_FILE=`mktemp`
|
||||
gzip -dc $SA_FILE > $UNCOMPRESSED_SA_FILE
|
||||
SA_FILE=$UNCOMPRESSED_SA_FILE
|
||||
fi
|
||||
|
||||
|
||||
# Prompt for graph
|
||||
|
||||
GRAPH=`$ZENITY --list --text "Select a graph" --column "Graph Type" "CPU" "Run Queue" "Run Queue w/o Process List Size" "IO Transfer Rate" "NFS Client" "Paging Stats" "Memory Utilization" "Memory Utilization (Swap)"`
|
||||
|
||||
case "$GRAPH" in
|
||||
"CPU")
|
||||
XSLTFILE=`mktemp`
|
||||
cpu_xslt $XSLTFILE
|
||||
DATAFILE=`mktemp`
|
||||
$SADF -t -x $SA_FILE -- -u | $XSLTPROC --novalid $XSLTFILE - > $DATAFILE
|
||||
GNUPLOTFILE=`mktemp`
|
||||
cpu_gnuplot $GNUPLOTFILE $DATAFILE
|
||||
$GNUPLOT $GNUPLOTFILE
|
||||
;;
|
||||
"Run Queue")
|
||||
XSLTFILE=`mktemp`
|
||||
rq_xslt $XSLTFILE
|
||||
DATAFILE=`mktemp`
|
||||
$SADF -t -x $SA_FILE -- -q | $XSLTPROC --novalid $XSLTFILE - > $DATAFILE
|
||||
GNUPLOTFILE=`mktemp`
|
||||
rq_gnuplot $GNUPLOTFILE $DATAFILE
|
||||
$GNUPLOT $GNUPLOTFILE
|
||||
;;
|
||||
"Run Queue w/o Process List Size")
|
||||
XSLTFILE=`mktemp`
|
||||
rqnoplistsz_xslt $XSLTFILE
|
||||
DATAFILE=`mktemp`
|
||||
$SADF -t -x $SA_FILE -- -q | $XSLTPROC --novalid $XSLTFILE - > $DATAFILE
|
||||
GNUPLOTFILE=`mktemp`
|
||||
rqnoplistsz_gnuplot $GNUPLOTFILE $DATAFILE
|
||||
$GNUPLOT $GNUPLOTFILE
|
||||
;;
|
||||
"IO Transfer Rate")
|
||||
XSLTFILE=`mktemp`
|
||||
io_xslt $XSLTFILE
|
||||
DATAFILE=`mktemp`
|
||||
$SADF -t -x $SA_FILE -- -b | $XSLTPROC --novalid $XSLTFILE - > $DATAFILE
|
||||
GNUPLOTFILE=`mktemp`
|
||||
io_gnuplot $GNUPLOTFILE $DATAFILE
|
||||
$GNUPLOT $GNUPLOTFILE
|
||||
;;
|
||||
"NFS Client")
|
||||
XSLTFILE=`mktemp`
|
||||
nfsclient_xslt $XSLTFILE
|
||||
DATAFILE=`mktemp`
|
||||
$SADF -t -x $SA_FILE -- -n NFS | $XSLTPROC --novalid $XSLTFILE - > $DATAFILE
|
||||
GNUPLOTFILE=`mktemp`
|
||||
nfsclient_gnuplot $GNUPLOTFILE $DATAFILE
|
||||
$GNUPLOT $GNUPLOTFILE
|
||||
;;
|
||||
"Paging Stats")
|
||||
XSLTFILE=`mktemp`
|
||||
paging_xslt $XSLTFILE
|
||||
DATAFILE=`mktemp`
|
||||
$SADF -t -x $SA_FILE -- -B | $XSLTPROC --novalid $XSLTFILE - > $DATAFILE
|
||||
GNUPLOTFILE=`mktemp`
|
||||
paging_gnuplot $GNUPLOTFILE $DATAFILE
|
||||
$GNUPLOT $GNUPLOTFILE
|
||||
;;
|
||||
"Memory Utilization")
|
||||
XSLTFILE=`mktemp`
|
||||
memuse_xslt $XSLTFILE
|
||||
DATAFILE=`mktemp`
|
||||
$SADF -t -x $SA_FILE -- -r | $XSLTPROC --novalid $XSLTFILE - > $DATAFILE
|
||||
GNUPLOTFILE=`mktemp`
|
||||
memuse_gnuplot $GNUPLOTFILE $DATAFILE
|
||||
$GNUPLOT $GNUPLOTFILE
|
||||
;;
|
||||
"Memory Utilization (Swap)")
|
||||
XSLTFILE=`mktemp`
|
||||
swapuse_xslt $XSLTFILE
|
||||
DATAFILE=`mktemp`
|
||||
$SADF -t -x $SA_FILE -- -S | $XSLTPROC --novalid $XSLTFILE - > $DATAFILE
|
||||
GNUPLOTFILE=`mktemp`
|
||||
swapuse_gnuplot $GNUPLOTFILE $DATAFILE
|
||||
$GNUPLOT $GNUPLOTFILE
|
||||
;;
|
||||
*)
|
||||
# If you click "Cancel", you end up here
|
||||
DONE=yes
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -f "$UNCOMPRESSED_SA_FILE" ] && rm $UNCOMPRESSED_SA_FILE
|
||||
[ -f "$GNUPLOTFILE" ] && rm $GNUPLOTFILE
|
||||
[ -f "$DATAFILE" ] && rm $DATAFILE
|
||||
[ -f "$XSLTFILE" ] && rm $XSLTFILE
|
||||
done
|
||||
|
||||
exit
|
||||
|
||||
# Local Variables:
|
||||
# sh-basic-offset: 4
|
||||
# indent-tabs-mode: nil
|
||||
# sh-indent-for-case-label: 0
|
||||
# sh-indent-for-case-alt: +
|
||||
# End:
|
|
@ -0,0 +1,294 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
# Our dependencies - bail out if they are not found
|
||||
SADF=`which sadf`
|
||||
GNUPLOT=`which gnuplot`
|
||||
|
||||
|
||||
# Default for --sa-file is today's file
|
||||
# (by default sadf will show today's logs)
|
||||
SA_FILE=""
|
||||
|
||||
# Default for --sa-dir
|
||||
SA_DIR="/var/log/sa"
|
||||
|
||||
# Default for --type
|
||||
GRAPH_TYPE=CPU
|
||||
|
||||
|
||||
GNUPLOT_TERMINAL="pngcairo font \"Sans,8\" size 640,320"
|
||||
SAFILES_REGEX='/sar?[0-9]{2,8}(\.(Z|gz|bz2|xz|lz|lzo))?$'
|
||||
GRAPH_TYPES="cpu,mem,io"
|
||||
|
||||
|
||||
print_usage()
|
||||
{
|
||||
echo "
|
||||
Usage
|
||||
sargraph2 [--type $GRAPH_TYPES] [--sa-file INFILE] [--output OUTFILE]
|
||||
|
||||
Examples
|
||||
|
||||
To plot CPU for today no arguments are needed:
|
||||
sargraph2
|
||||
To plot MEM for 20150330:
|
||||
sargraph2 --type mem --sa-file /var/log/sa/sa20150330.gz
|
||||
To plot I/O for 20150330 to a PNG file:
|
||||
sargraph2 --type io --sa-file /var/log/sa/sa20150330.gz --output io.png
|
||||
|
||||
"
|
||||
}
|
||||
|
||||
|
||||
######### OPTION PARSING ###########
|
||||
parsed_opts=`getopt -o "h" \
|
||||
-l help,sa-dir:,sa-file:,output:,type: \
|
||||
-- "$@"`
|
||||
eval set -- "$parsed_opts"
|
||||
|
||||
DONE=no
|
||||
while [ $DONE != yes ]
|
||||
do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
print_usage
|
||||
exit
|
||||
shift
|
||||
;;
|
||||
--sa-dir)
|
||||
shift
|
||||
SA_DIR="$1"
|
||||
;;
|
||||
--sa-file)
|
||||
shift
|
||||
SA_FILE="$1"
|
||||
;;
|
||||
--output)
|
||||
shift
|
||||
OUT_FILE="$1"
|
||||
;;
|
||||
--type)
|
||||
shift
|
||||
GRAPH_TYPE=`echo $1 | tr a-z A-Z`
|
||||
;;
|
||||
--)
|
||||
# End of options
|
||||
DONE=yes
|
||||
;;
|
||||
*)
|
||||
echo Unexpected argument: $1
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
shift # should shift the last arg or '--' if DONE=yes
|
||||
done
|
||||
####################################
|
||||
|
||||
|
||||
# Decompress a file to another, or just copy it if not compressed
|
||||
decompress_copy()
|
||||
{
|
||||
if [ x$# != x2 ]
|
||||
then
|
||||
echo "Function decompress_copy requires 2 arguments but got $#: $*"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -f "$1" ]
|
||||
then
|
||||
case "$1" in
|
||||
|
||||
*.Z) uncompress -c "$1" > "$2" ;;
|
||||
*.gz) gzip -dc "$1" > "$2" ;;
|
||||
*.bz2) bzip2 -dc "$1" > "$2" ;;
|
||||
*.xz) xz -dc "$1" > "$2" ;;
|
||||
*.lz) lzip -dc "$1" > "$2" ;;
|
||||
*.lzo) lzop -dc "$1" > "$2" ;;
|
||||
|
||||
*) cp "$1" "$2" ;;
|
||||
|
||||
esac
|
||||
else
|
||||
echo "$1: file not found" 1>&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
# TODO send systemd patch
|
||||
#soupermouf;60;2015-04-01 04:24:00;-1;5.77;0.00;2.10;0.63;0.00;91.50
|
||||
#soupermouf;26846;2015-04-01 11:51:26;-1;0.00;0.00;0.00;0.00;0.00;0.00
|
||||
#soupermouf;60;2015-04-01 11:52:26;-1;7.11;0.01;2.69;68.44;0.00;21.75
|
||||
|
||||
cpu_gnuplot() # %iowait,%user,%nice,%system,%steal
|
||||
{
|
||||
# First make sure that the columns are where we expect them to be
|
||||
HEADER=`grep -Ev ';LINUX-RESTART|;COM' $2 | head -1 | cut -d ';' -f 5-10`
|
||||
EXPECTED="%user;%nice;%system;%iowait;%steal;%idle"
|
||||
if [ "$HEADER" != "$EXPECTED" ]
|
||||
then
|
||||
echo "Headers not in right order: $HEADER" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat > $1 <<EOF
|
||||
set title "sar -u"
|
||||
set xdata time
|
||||
set format x "%H:%M"
|
||||
set ylabel "Percentage"
|
||||
set yrange [0:100]
|
||||
set timefmt "%Y-%m-%d %H:%M:%S"
|
||||
set datafile separator ";"
|
||||
plot \
|
||||
"$2" using 3:(\$9+\$7+\$6+\$5+\$8) title "%iowait" with filledcurves x1 linecolor rgb "light-gray", \
|
||||
"$2" using 3:(\$9+\$7+\$6+\$5) title "%user" with filledcurves x1 linecolor rgb "dark-green", \
|
||||
"$2" using 3:(\$9+\$7+\$6) title "%nice" with filledcurves x1 linecolor rgb "greenyellow", \
|
||||
"$2" using 3:(\$9+\$7) title "%system" with filledcurves x1 linecolor rgb "red", \
|
||||
"$2" using 3:(\$9) title "%steal" with filledcurves x1 linecolor rgb "purple"
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
mem_gnuplot() # free,used,buffers,cached / %commit,%swpused
|
||||
{
|
||||
# First make sure that the columns are where we expect them to be
|
||||
HEADER=`grep -Ev ';LINUX-RESTART|;COM' $2 | head -1 | cut -d ';' -f 4-10`
|
||||
EXPECTED="kbmemfree;kbmemused;%memused;kbbuffers;kbcached;kbcommit;%commit"
|
||||
if [ "$HEADER" != "$EXPECTED" ]
|
||||
then
|
||||
echo "Headers not in right order: $HEADER" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
HEADER=`grep -Ev ';LINUX-RESTART|;COM' $3 | head -1 | cut -d ';' -f 4-6`
|
||||
EXPECTED="kbswpfree;kbswpused;%swpused"
|
||||
if [ "$HEADER" != "$EXPECTED" ]
|
||||
then
|
||||
echo "Headers not in right order: $HEADER" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat > $1 <<EOF
|
||||
set title "sar -r"
|
||||
set xdata time
|
||||
set format x "%H:%M"
|
||||
set ylabel "Memory Usage in MB"
|
||||
set yrange [0:]
|
||||
set y2label "Percentage"
|
||||
set y2range [0:]
|
||||
set y2tics
|
||||
set timefmt "%Y-%m-%d %H:%M:%S"
|
||||
set datafile separator ";"
|
||||
set key on bottom center opaque
|
||||
plot \
|
||||
"$2" using 3:((\$5+\$4)/1024) title "free" with filledcurves x1 linecolor rgb "light-gray", \
|
||||
"$2" using 3:((\$5)/1024) title "cached" with filledcurves x1 linecolor rgb "dark-green", \
|
||||
"$2" using 3:((\$5-\$8)/1024) title "buffers" with filledcurves x1 linecolor rgb "greenyellow", \
|
||||
"$2" using 3:((\$5-\$8-\$7)/1024) title "used" with filledcurves x1 linecolor rgb "red", \
|
||||
\
|
||||
"$2" using 3:(\$10) title "%commit" with lines linecolor rgb "blue" linewidth 2 axes x1y2, \
|
||||
"$3" using 3:(\$6) title "%swpused" with lines linecolor rgb "dark-magenta" linewidth 2 axes x1y2
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
io_gnuplot() # %KBr/s,KBw/s / rIOPS,wIOPS
|
||||
{
|
||||
# First make sure that the columns are where we expect them to be
|
||||
HEADER=`grep -Ev ';LINUX-RESTART|;COM' $2 | head -1 | cut -d ';' -f 4-8`
|
||||
EXPECTED="tps;rtps;wtps;bread/s;bwrtn/s"
|
||||
if [ "$HEADER" != "$EXPECTED" ]
|
||||
then
|
||||
echo "Headers not in right order: $HEADER" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat > $1 <<EOF
|
||||
set title "sar -b"
|
||||
set xdata time
|
||||
set format x "%H:%M"
|
||||
set ylabel "MB/s"
|
||||
set yrange [0:]
|
||||
set y2label "IOPS"
|
||||
set y2range [0:]
|
||||
set y2tics
|
||||
set timefmt "%Y-%m-%d %H:%M:%S"
|
||||
set datafile separator ";"
|
||||
plot \
|
||||
"$2" using 3:((\$8+\$7)/2/1024) title "rMB/s" with filledcurves x1 linecolor rgb "dark-green", \
|
||||
"$2" using 3:((\$8)/2/1024) title "wMB/s" with filledcurves x1 linecolor rgb "dark-red", \
|
||||
\
|
||||
"$2" using 3:(\$4) title "rIOPS" with lines linecolor rgb "light-green" linewidth 2 axes x1y2, \
|
||||
"$2" using 3:(\$6) title "wIOPS" with lines linecolor rgb "light-red" linewidth 2 axes x1y2
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if [ x"$OUT_FILE" = x ]
|
||||
then
|
||||
# no --output passed, INTERACTIVE mode
|
||||
GNUPLOT_OPTS="-persist"
|
||||
else
|
||||
GNUPLOT_OPTS="-e 'set terminal $GNUPLOT_TERMINAL; set output \"$OUT_FILE\"'"
|
||||
fi
|
||||
|
||||
if [ x"$SA_FILE" != x ]
|
||||
then
|
||||
# Decompress the SA file if it's compressed
|
||||
PLAIN_SA_FILE=`mktemp`
|
||||
decompress_copy "$SA_FILE" $PLAIN_SA_FILE
|
||||
else
|
||||
# If the user passed no parameter
|
||||
PLAIN_SA_FILE=""
|
||||
fi
|
||||
unset SA_FILE
|
||||
|
||||
DATAFILE=`mktemp`
|
||||
DATAFILE2=`mktemp`
|
||||
GNUPLOTFILE=`mktemp`
|
||||
|
||||
case "$GRAPH_TYPE" in
|
||||
"CPU")
|
||||
$SADF -t -d -C $PLAIN_SA_FILE -- -u > $DATAFILE
|
||||
cpu_gnuplot $GNUPLOTFILE $DATAFILE
|
||||
;;
|
||||
"MEM")
|
||||
$SADF -t -d -C $PLAIN_SA_FILE -- -r > $DATAFILE
|
||||
$SADF -t -d -C $PLAIN_SA_FILE -- -S > $DATAFILE2
|
||||
mem_gnuplot $GNUPLOTFILE $DATAFILE $DATAFILE2
|
||||
;;
|
||||
"IO")
|
||||
$SADF -t -d -C $PLAIN_SA_FILE -- -b > $DATAFILE
|
||||
io_gnuplot $GNUPLOTFILE $DATAFILE
|
||||
;;
|
||||
*)
|
||||
echo "Unknown graph type, supported types are: $GRAPH_TYPES" 1>&2
|
||||
exit 1
|
||||
esac
|
||||
|
||||
eval $GNUPLOT $GNUPLOT_OPTS $GNUPLOTFILE
|
||||
|
||||
|
||||
[ -f "$PLAIN_SA_FILE" ] && rm $PLAIN_SA_FILE
|
||||
[ -f "$GNUPLOTFILE" ] && rm $GNUPLOTFILE
|
||||
[ -f "$DATAFILE" ] && rm $DATAFILE
|
||||
[ -f "$DATAFILE2" ] && rm $DATAFILE2
|
||||
|
||||
|
||||
exit
|
||||
|
||||
|
||||
# Local Variables:
|
||||
# sh-basic-offset: 4
|
||||
# indent-tabs-mode: nil
|
||||
# sh-indent-for-case-label: 0
|
||||
# sh-indent-for-case-alt: +
|
||||
# End:
|
|
@ -0,0 +1,537 @@
|
|||
/*
|
||||
* count.c: Count items for which statistics will be collected.
|
||||
* (C) 1999-2022 by Sebastien GODARD (sysstat <at> orange.fr)
|
||||
*
|
||||
***************************************************************************
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
|
||||
* for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA *
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "rd_stats.h"
|
||||
|
||||
#ifdef USE_NLS
|
||||
#include <locale.h>
|
||||
#include <libintl.h>
|
||||
#define _(string) gettext(string)
|
||||
#else
|
||||
#define _(string) (string)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Count number of processors in /sys.
|
||||
*
|
||||
* IN:
|
||||
* @highest If set to TRUE, then look for the highest processor number.
|
||||
* This is used when eg. the machine has 4 CPU numbered 0, 1, 4
|
||||
* and 5. In this case, this procedure will return 6.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of processors (online and offline).
|
||||
* A value of 0 means that /sys was not mounted.
|
||||
* A value of N (!=0) means N processor(s) (cpu0 .. cpu(N-1)).
|
||||
***************************************************************************
|
||||
*/
|
||||
int get_sys_cpu_nr(int highest)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *drd;
|
||||
struct stat buf;
|
||||
char line[MAX_PF_NAME];
|
||||
int num_proc, proc_nr = -1;
|
||||
|
||||
/* Open relevant /sys directory */
|
||||
if ((dir = opendir(SYSFS_DEVCPU)) == NULL)
|
||||
return 0;
|
||||
|
||||
/* Get current file entry */
|
||||
while ((drd = readdir(dir)) != NULL) {
|
||||
|
||||
if (!strncmp(drd->d_name, "cpu", 3) && isdigit(drd->d_name[3])) {
|
||||
snprintf(line, sizeof(line), "%s/%s", SYSFS_DEVCPU, drd->d_name);
|
||||
line[sizeof(line) - 1] = '\0';
|
||||
if (stat(line, &buf) < 0)
|
||||
continue;
|
||||
if (S_ISDIR(buf.st_mode)) {
|
||||
if (highest) {
|
||||
sscanf(drd->d_name + 3, "%d", &num_proc);
|
||||
if (num_proc > proc_nr) {
|
||||
proc_nr = num_proc;
|
||||
}
|
||||
}
|
||||
else {
|
||||
proc_nr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Close directory */
|
||||
closedir(dir);
|
||||
|
||||
return (proc_nr + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Count number of processors in /proc/stat.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of processors. The returned value is greater than or equal to the
|
||||
* number of online processors.
|
||||
* A value of 0 means one processor and non SMP kernel.
|
||||
* A value of N (!=0) means N processor(s) (0 .. N-1) with SMP kernel.
|
||||
***************************************************************************
|
||||
*/
|
||||
int get_proc_cpu_nr(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[16];
|
||||
int num_proc, proc_nr = -1;
|
||||
|
||||
if ((fp = fopen(STAT, "r")) == NULL) {
|
||||
fprintf(stderr, _("Cannot open %s: %s\n"), STAT, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
|
||||
if (strncmp(line, "cpu ", 4) && !strncmp(line, "cpu", 3)) {
|
||||
sscanf(line + 3, "%d", &num_proc);
|
||||
if (num_proc > proc_nr) {
|
||||
proc_nr = num_proc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
proc_nr++;
|
||||
return proc_nr;
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Count the number of processors on the machine, or look for the
|
||||
* highest processor number.
|
||||
* Try to use /sys for that, or /proc/stat if /sys doesn't exist.
|
||||
*
|
||||
* IN:
|
||||
* @max_nr_cpus Maximum number of proc that sysstat can handle.
|
||||
* @highest If set to TRUE, then look for the highest processor number.
|
||||
* This is used when eg. the machine has 4 CPU numbered 0, 1, 4
|
||||
* and 5. In this case, this procedure will return 6.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of processors.
|
||||
* 0: one proc and non SMP kernel.
|
||||
* 1: one proc and SMP kernel (NB: On SMP machines where all the CPUs but
|
||||
* one have been disabled, we get the total number of proc since we use
|
||||
* /sys to count them).
|
||||
* 2: two proc...
|
||||
*
|
||||
* USED BY:
|
||||
* sadc, cifsiostat, iostat, mpstat, pidstat, tapestat
|
||||
***************************************************************************
|
||||
*/
|
||||
__nr_t get_cpu_nr(unsigned int max_nr_cpus, int highest)
|
||||
{
|
||||
__nr_t cpu_nr;
|
||||
|
||||
if ((cpu_nr = get_sys_cpu_nr(highest)) == 0) {
|
||||
/* /sys may be not mounted. Use /proc/stat instead */
|
||||
cpu_nr = get_proc_cpu_nr();
|
||||
}
|
||||
|
||||
if (cpu_nr > max_nr_cpus) {
|
||||
fprintf(stderr, _("Cannot handle so many processors!\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return cpu_nr;
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Find number of interrupts available per processor (use
|
||||
* /proc/interrupts file or /proc/softirqs).
|
||||
*
|
||||
* IN:
|
||||
* @file /proc file to read (interrupts or softirqs).
|
||||
* @max_nr_irqcpu Maximum number of interrupts per processor that
|
||||
* sadc can handle.
|
||||
* @cpu_nr Number of processors.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of interrupts per processor.
|
||||
*
|
||||
* USED BY:
|
||||
* sadc, mpstat
|
||||
***************************************************************************
|
||||
*/
|
||||
__nr_t get_irqcpu_nr(char *file, int max_nr_irqcpu, int cpu_nr)
|
||||
{
|
||||
FILE *fp;
|
||||
char *line = NULL;
|
||||
__nr_t irq = 0;
|
||||
int p;
|
||||
|
||||
if ((fp = fopen(file, "r")) == NULL)
|
||||
return 0; /* No interrupts file */
|
||||
|
||||
SREALLOC(line, char, INTERRUPTS_LINE + 11 * cpu_nr);
|
||||
|
||||
while ((fgets(line, INTERRUPTS_LINE + 11 * cpu_nr , fp) != NULL) &&
|
||||
(irq < max_nr_irqcpu)) {
|
||||
|
||||
p = strcspn(line, ":");
|
||||
if ((p > 0) && (p < 16)) {
|
||||
irq++;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
free(line);
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
#ifdef SOURCE_SADC
|
||||
/*---------------- BEGIN: FUNCTIONS USED BY SADC ONLY ---------------------*/
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Find number of devices and partitions available in /proc/diskstats.
|
||||
*
|
||||
* IN:
|
||||
* @count_part Set to TRUE if devices _and_ partitions are to be
|
||||
* counted.
|
||||
* @only_used_dev When counting devices, set to TRUE if only devices
|
||||
* with non zero stats must be counted.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of devices (and partitions).
|
||||
***************************************************************************
|
||||
*/
|
||||
__nr_t get_diskstats_dev_nr(int count_part, int only_used_dev)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[256];
|
||||
char dev_name[MAX_NAME_LEN];
|
||||
__nr_t dev = 0;
|
||||
int i;
|
||||
unsigned long rd_ios, wr_ios;
|
||||
|
||||
if ((fp = fopen(DISKSTATS, "r")) == NULL)
|
||||
/* File non-existent */
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Counting devices and partitions is simply a matter of counting
|
||||
* the number of lines...
|
||||
*/
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
|
||||
if (!count_part) {
|
||||
i = sscanf(line, "%*d %*d %s %lu %*u %*u %*u %lu",
|
||||
dev_name, &rd_ios, &wr_ios);
|
||||
if ((i == 2) || !is_device(SLASH_SYS, dev_name, ACCEPT_VIRTUAL_DEVICES))
|
||||
/* It was a partition and not a device */
|
||||
continue;
|
||||
if (only_used_dev && !rd_ios && !wr_ios)
|
||||
/* Unused device */
|
||||
continue;
|
||||
}
|
||||
dev++;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Find number of serial lines that support tx/rx accounting
|
||||
* in /proc/tty/driver/serial file.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of serial lines supporting tx/rx accouting.
|
||||
***************************************************************************
|
||||
*/
|
||||
__nr_t get_serial_nr(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[256];
|
||||
__nr_t sl = 0;
|
||||
|
||||
if ((fp = fopen(SERIAL, "r")) == NULL)
|
||||
return 0; /* No SERIAL file */
|
||||
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
/*
|
||||
* tx/rx statistics are always present,
|
||||
* except when serial line is unknown.
|
||||
*/
|
||||
if (strstr(line, "tx:") != NULL) {
|
||||
sl++;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return sl;
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Find number of interfaces (network devices) that are in /proc/net/dev
|
||||
* file.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of network interfaces.
|
||||
***************************************************************************
|
||||
*/
|
||||
__nr_t get_iface_nr(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[128];
|
||||
__nr_t iface = 0;
|
||||
|
||||
if ((fp = fopen(NET_DEV, "r")) == NULL)
|
||||
return 0; /* No network device file */
|
||||
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
if (strchr(line, ':')) {
|
||||
iface++;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return iface;
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Get number of devices in /proc/diskstats.
|
||||
*
|
||||
* IN:
|
||||
* @f Non zero (true) if disks *and* partitions should be counted, and
|
||||
* zero (false) if only disks must be counted.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of devices.
|
||||
***************************************************************************
|
||||
*/
|
||||
__nr_t get_disk_nr(unsigned int f)
|
||||
{
|
||||
__nr_t disk_nr;
|
||||
|
||||
/*
|
||||
* Partitions are taken into account by sar -d only with
|
||||
* kernels 2.6.25 and later.
|
||||
*/
|
||||
disk_nr = get_diskstats_dev_nr(f, CNT_USED_DEV);
|
||||
|
||||
return disk_nr;
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Count number of possible frequencies for CPU#0.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of frequencies.
|
||||
***************************************************************************
|
||||
*/
|
||||
__nr_t get_freq_nr(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char filename[MAX_PF_NAME];
|
||||
char line[128];
|
||||
__nr_t freq = 0;
|
||||
|
||||
snprintf(filename, MAX_PF_NAME, "%s/cpu0/%s",
|
||||
SYSFS_DEVCPU, SYSFS_TIME_IN_STATE);
|
||||
if ((fp = fopen(filename, "r")) == NULL)
|
||||
return 0; /* No time_in_state file for CPU#0 */
|
||||
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
freq++;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Count number of USB devices in /sys/bus/usb/devices.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of USB devices plugged into the system.
|
||||
* Don't count USB root hubs.
|
||||
* Return -1 if directory doesn't exist in sysfs.
|
||||
***************************************************************************
|
||||
*/
|
||||
__nr_t get_usb_nr(void)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *drd;
|
||||
__nr_t usb = 0;
|
||||
|
||||
/* Open relevant /sys directory */
|
||||
if ((dir = opendir(SYSFS_USBDEV)) == NULL)
|
||||
return -1;
|
||||
|
||||
/* Get current file entry */
|
||||
while ((drd = readdir(dir)) != NULL) {
|
||||
|
||||
if (isdigit(drd->d_name[0]) && !strchr(drd->d_name, ':')) {
|
||||
usb++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close directory */
|
||||
closedir(dir);
|
||||
|
||||
return usb;
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Find number of filesystems in /etc/mtab. Pseudo-filesystems are ignored.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of filesystems.
|
||||
***************************************************************************
|
||||
*/
|
||||
__nr_t get_filesystem_nr(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[512], fs_name[MAX_FS_LEN], mountp[256], type[128];
|
||||
char *pos = 0, *pos2 = 0;
|
||||
__nr_t fs = 0;
|
||||
int skip = 0, skip_next = 0;
|
||||
struct statvfs buf;
|
||||
|
||||
if ((fp = fopen(MTAB, "r")) == NULL)
|
||||
/* File non-existent */
|
||||
return 0;
|
||||
|
||||
/* Get current filesystem */
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
/*
|
||||
* Ignore line if the preceding line did not contain '\n'.
|
||||
* (Some very long lines may be found for instance when
|
||||
* overlay2 filesystem with docker is used).
|
||||
*/
|
||||
skip = skip_next;
|
||||
skip_next = (strchr(line, '\n') == NULL);
|
||||
if (skip)
|
||||
continue;
|
||||
|
||||
if (line[0] == '/') {
|
||||
/* Find field separator position */
|
||||
pos = strchr(line, ' ');
|
||||
if (pos == NULL)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Find second field separator position,
|
||||
* read filesystem type,
|
||||
* if filesystem type is autofs, skip it
|
||||
*/
|
||||
pos2 = strchr(pos + 1, ' ');
|
||||
if (pos2 == NULL)
|
||||
continue;
|
||||
|
||||
sscanf(pos2 + 1, "%127s", type);
|
||||
if (strcmp(type, "autofs") == 0)
|
||||
continue;
|
||||
|
||||
/* Read filesystem name and mount point */
|
||||
sscanf(line, "%127s", fs_name);
|
||||
sscanf(pos + 1, "%255s", mountp);
|
||||
|
||||
/* Replace octal codes */
|
||||
oct2chr(mountp);
|
||||
|
||||
/* Check that total size is not zero */
|
||||
if (__statvfs(mountp, &buf) < 0)
|
||||
continue;
|
||||
|
||||
if (buf.f_blocks) {
|
||||
fs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return fs;
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Find number of fibre channel hosts in /sys/class/fc_host/.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of FC hosts.
|
||||
* Return -1 if directory doesn't exist in sysfs.
|
||||
***************************************************************************
|
||||
*/
|
||||
__nr_t get_fchost_nr(void)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *drd;
|
||||
__nr_t fc = 0;
|
||||
|
||||
if ((dir = opendir(SYSFS_FCHOST)) == NULL) {
|
||||
/* Directory non-existent */
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((drd = readdir(dir)) != NULL) {
|
||||
|
||||
if (!strncmp(drd->d_name, "host", 4)) {
|
||||
fc++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close directory */
|
||||
closedir(dir);
|
||||
|
||||
return fc;
|
||||
}
|
||||
|
||||
/*------------------ END: FUNCTIONS USED BY SADC ONLY ---------------------*/
|
||||
#endif /* SOURCE_SADC */
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* count.h: Include file used to count items for which
|
||||
* statistics will be collected.
|
||||
* (C) 1999-2022 by Sebastien Godard (sysstat <at> orange.fr)
|
||||
*/
|
||||
|
||||
#ifndef _COUNT_H
|
||||
#define _COUNT_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Prototypes for functions used to count number of items.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
__nr_t get_cpu_nr
|
||||
(unsigned int, int);
|
||||
__nr_t get_irqcpu_nr
|
||||
(char *, int, int);
|
||||
__nr_t get_diskstats_dev_nr
|
||||
(int, int);
|
||||
__nr_t get_serial_nr
|
||||
(void);
|
||||
__nr_t get_iface_nr
|
||||
(void);
|
||||
__nr_t get_disk_nr
|
||||
(unsigned int);
|
||||
__nr_t get_freq_nr
|
||||
(void);
|
||||
__nr_t get_usb_nr
|
||||
(void);
|
||||
__nr_t get_filesystem_nr
|
||||
(void);
|
||||
__nr_t get_fchost_nr
|
||||
(void);
|
||||
|
||||
#endif /* _COUNT_H */
|
Binary file not shown.
|
@ -0,0 +1,19 @@
|
|||
# Crontab sample for root or adm
|
||||
# Please update this crontab with the proper location
|
||||
# for sa1 and sa2 shell scripts (replace @SA_LIB_DIR@ with
|
||||
# /usr/lib/sa for example).
|
||||
#
|
||||
# 8am-7pm activity reports every 20 minutes during weekdays.
|
||||
# 0 8-18 * * 1-5 @SA_LIB_DIR@/sa1 1200 3
|
||||
# activity reports every @CRON_INTERVAL@ minutes everyday.
|
||||
0 * * * * @SA_LIB_DIR@/sa1 @CRON_INTERVAL_SEC@ @CRON_COUNT@
|
||||
#
|
||||
# Activity reports every an hour on Saturday and Sunday.
|
||||
# 0 * * * 0,6 @SA_LIB_DIR@/sa1
|
||||
#
|
||||
# 7pm-8am activity reports every an hour during weekdays.
|
||||
# 0 19-7 * * 1-5 @SA_LIB_DIR@/sa1
|
||||
#
|
||||
# Previous day summary prepared at 00:07.
|
||||
# 7 0 * * 1-5 @SA_LIB_DIR@/sa2 -A
|
||||
7 0 * * * @SA_LIB_DIR@/sa2 -A
|
|
@ -0,0 +1,17 @@
|
|||
# @SYSTEMD_UNIT_DIR@/sysstat-collect.service
|
||||
# (C) 2014 Tomasz Torcz <tomek@pipebreaker.pl>
|
||||
#
|
||||
# @PACKAGE_NAME@-@PACKAGE_VERSION@ systemd unit file:
|
||||
# Collects system activity data
|
||||
# Activated by sysstat-collect.timer unit
|
||||
|
||||
[Unit]
|
||||
Description=system activity accounting tool
|
||||
Documentation=man:sa1(8)
|
||||
After=sysstat.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=@CRON_OWNER@
|
||||
ExecStart=@SA_LIB_DIR@/sa1 1 1
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# @SYSTEMD_UNIT_DIR@/sysstat-collect.timer
|
||||
# (C) 2014 Tomasz Torcz <tomek@pipebreaker.pl>
|
||||
#
|
||||
# @PACKAGE_NAME@-@PACKAGE_VERSION@ systemd unit file:
|
||||
# Activates activity collector every @CRON_INTERVAL@ minutes
|
||||
|
||||
[Unit]
|
||||
Description=Run system activity accounting tool every @CRON_INTERVAL@ minutes
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*:00/@CRON_INTERVAL@
|
||||
|
||||
[Install]
|
||||
WantedBy=sysstat.service
|
|
@ -0,0 +1,15 @@
|
|||
# @SYSTEMD_UNIT_DIR@/sysstat-summary.service
|
||||
# (C) 2014 Tomasz Torcz <tomek@pipebreaker.pl>
|
||||
#
|
||||
# @PACKAGE_NAME@-@PACKAGE_VERSION@ systemd unit file:
|
||||
# Generates daily summary of process accounting
|
||||
|
||||
[Unit]
|
||||
Description=Generate a daily summary of process accounting
|
||||
Documentation=man:sa2(8)
|
||||
After=sysstat.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=@CRON_OWNER@
|
||||
ExecStart=@SA_LIB_DIR@/sa2 -A
|
|
@ -0,0 +1,15 @@
|
|||
# @SYSTEMD_UNIT_DIR@/sysstat-summary.timer
|
||||
# (C) 2014 Tomasz Torcz <tomek@pipebreaker.pl>
|
||||
#
|
||||
# @PACKAGE_NAME@-@PACKAGE_VERSION@ systemd unit file:
|
||||
# Triggers daily summary generation.
|
||||
# Activates sysstat-summary.service
|
||||
|
||||
[Unit]
|
||||
Description=Generate summary of yesterday's process accounting
|
||||
|
||||
[Timer]
|
||||
OnCalendar=00:07:00
|
||||
|
||||
[Install]
|
||||
WantedBy=sysstat.service
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
# Generate a daily summary of process accounting. Since this will probably
|
||||
# get kicked off in the morning, it would probably be better to run against
|
||||
# the previous days data.
|
||||
@SA_LIB_DIR@/sa2 -A
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
# Run system activity accounting tool every @CRON_INTERVAL@ minutes
|
||||
@SA_LIB_DIR@/sa1 @CRON_INTERVAL_SEC@ @CRON_COUNT@
|
|
@ -0,0 +1,6 @@
|
|||
# Run system activity accounting tool every @CRON_INTERVAL@ minutes
|
||||
*/@CRON_INTERVAL@ * * * * @CRON_OWNER@ @SA_LIB_DIR@/sa1 1 1
|
||||
# 0 * * * * @CRON_OWNER@ @SA_LIB_DIR@/sa1 @CRON_INTERVAL_SEC@ @CRON_COUNT@
|
||||
# Generate a text summary of previous day process accounting at 00:07
|
||||
7 0 * * * @CRON_OWNER@ @SA_LIB_DIR@/sa2 -A
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
# sysstat suspend/resume hack
|
||||
# for systemd's @SYSTEMD_SLEEP_DIR@ directory
|
||||
# (C) 2020 Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
||||
# Insert a comment in current daily datafile
|
||||
@SA_LIB_DIR@/sa1 --sleep $*
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/sh
|
||||
if [ "$1" = "conf" ]
|
||||
then
|
||||
make distclean
|
||||
./configure sa_lib_dir=. sar_dir=. conf_dir=. conf_file=sysstat.sysconfig sa_dir=tests --enable-debuginfo
|
||||
elif [ "$1" = "conflto" ]
|
||||
then
|
||||
make distclean
|
||||
./configure sa_lib_dir=. sar_dir=. conf_dir=. conf_file=sysstat.sysconfig sa_dir=tests --enable-debuginfo --enable-lto
|
||||
elif [ "$1" = "comp" ]
|
||||
then
|
||||
make TFLAGS="-DTEST"
|
||||
else
|
||||
make distclean
|
||||
./configure sa_lib_dir=. sar_dir=. conf_dir=. conf_file=sysstat.sysconfig sa_dir=tests --enable-debuginfo && make TFLAGS="-DTEST" && make simtest
|
||||
fi
|
||||
if [ "$?" = "0" -a "$1" = "all" ]
|
||||
then
|
||||
make extratest && make distclean && ./configure --disable-nls --disable-sensors --disable-pcp sa_lib_dir=. sar_dir=. conf_dir=. conf_file=sysstat.sysconfig sa_dir=tests --enable-debuginfo && make TFLAGS="-DTEST" && echo "EXTRA TESTS: Success!"
|
||||
fi
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* format.c: Output format definitions for sadf and sar
|
||||
* (C) 2011-2022 by Sebastien GODARD (sysstat <at> orange.fr)
|
||||
*
|
||||
***************************************************************************
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
|
||||
* for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA *
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef SOURCE_SADF
|
||||
#include "sadf.h"
|
||||
#endif
|
||||
|
||||
#ifdef SOURCE_SAR
|
||||
#include "sa.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Definitions of output formats.
|
||||
* See sadf.h file for format structure definition.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef SOURCE_SADF
|
||||
/*
|
||||
* Display only datafile header.
|
||||
*/
|
||||
struct report_format hdr_fmt = {
|
||||
.id = F_HEADER_OUTPUT,
|
||||
.options = FO_HEADER_ONLY,
|
||||
.f_header = print_hdr_header,
|
||||
.f_statistics = NULL,
|
||||
.f_timestamp = NULL,
|
||||
.f_restart = NULL,
|
||||
.f_comment = NULL,
|
||||
.f_display = NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Database friendly format.
|
||||
*/
|
||||
struct report_format db_fmt = {
|
||||
.id = F_DB_OUTPUT,
|
||||
.options = FO_LOCAL_TIME + FO_HORIZONTALLY +
|
||||
FO_SEC_EPOCH + FO_FIELD_LIST,
|
||||
.f_header = NULL,
|
||||
.f_statistics = NULL,
|
||||
.f_timestamp = print_db_timestamp,
|
||||
.f_restart = print_db_restart,
|
||||
.f_comment = print_db_comment,
|
||||
.f_display = logic2_display_loop
|
||||
};
|
||||
|
||||
/*
|
||||
* Format easily handled by pattern processing commands like awk.
|
||||
*/
|
||||
struct report_format ppc_fmt = {
|
||||
.id = F_PPC_OUTPUT,
|
||||
.options = FO_LOCAL_TIME + FO_SEC_EPOCH,
|
||||
.f_header = NULL,
|
||||
.f_statistics = NULL,
|
||||
.f_timestamp = print_ppc_timestamp,
|
||||
.f_restart = print_ppc_restart,
|
||||
.f_comment = print_ppc_comment,
|
||||
.f_display = logic2_display_loop
|
||||
};
|
||||
|
||||
/*
|
||||
* XML output.
|
||||
*/
|
||||
struct report_format xml_fmt = {
|
||||
.id = F_XML_OUTPUT,
|
||||
.options = FO_HEADER_ONLY + FO_LOCAL_TIME + FO_TEST_MARKUP,
|
||||
.f_header = print_xml_header,
|
||||
.f_statistics = print_xml_statistics,
|
||||
.f_timestamp = print_xml_timestamp,
|
||||
.f_restart = print_xml_restart,
|
||||
.f_comment = print_xml_comment,
|
||||
.f_display = logic1_display_loop
|
||||
};
|
||||
|
||||
/*
|
||||
* JSON output.
|
||||
*/
|
||||
struct report_format json_fmt = {
|
||||
.id = F_JSON_OUTPUT,
|
||||
.options = FO_HEADER_ONLY + FO_LOCAL_TIME + FO_TEST_MARKUP +
|
||||
FO_LC_NUMERIC_C,
|
||||
.f_header = print_json_header,
|
||||
.f_statistics = print_json_statistics,
|
||||
.f_timestamp = print_json_timestamp,
|
||||
.f_restart = print_json_restart,
|
||||
.f_comment = print_json_comment,
|
||||
.f_display = logic1_display_loop
|
||||
};
|
||||
|
||||
/*
|
||||
* Convert an old datafile to up-to-date format.
|
||||
*/
|
||||
struct report_format conv_fmt = {
|
||||
.id = F_CONV_OUTPUT,
|
||||
.options = 0,
|
||||
.f_header = NULL,
|
||||
.f_statistics = NULL,
|
||||
.f_timestamp = NULL,
|
||||
.f_restart = NULL,
|
||||
.f_comment = NULL,
|
||||
.f_display = NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* SVG output.
|
||||
*/
|
||||
struct report_format svg_fmt = {
|
||||
.id = F_SVG_OUTPUT,
|
||||
.options = FO_HEADER_ONLY + FO_LOCAL_TIME + FO_NO_TRUE_TIME +
|
||||
FO_LC_NUMERIC_C,
|
||||
.f_header = print_svg_header,
|
||||
.f_statistics = NULL,
|
||||
.f_timestamp = NULL,
|
||||
.f_restart = NULL,
|
||||
.f_comment = NULL,
|
||||
.f_display = svg_display_loop
|
||||
};
|
||||
|
||||
/*
|
||||
* Raw output.
|
||||
*/
|
||||
struct report_format raw_fmt = {
|
||||
.id = F_RAW_OUTPUT,
|
||||
.options = FO_LOCAL_TIME + FO_SEC_EPOCH,
|
||||
.f_header = NULL,
|
||||
.f_statistics = NULL,
|
||||
.f_timestamp = print_raw_timestamp,
|
||||
.f_restart = print_raw_restart,
|
||||
.f_comment = print_raw_comment,
|
||||
.f_display = logic2_display_loop
|
||||
};
|
||||
|
||||
/*
|
||||
* PCP output.
|
||||
*/
|
||||
struct report_format pcp_fmt = {
|
||||
.id = F_PCP_OUTPUT,
|
||||
.options = FO_HEADER_ONLY + FO_LOCAL_TIME + FO_NO_TRUE_TIME +
|
||||
FO_ITEM_LIST + FO_FULL_ORDER,
|
||||
.f_header = print_pcp_header,
|
||||
.f_statistics = print_pcp_statistics,
|
||||
.f_timestamp = print_pcp_timestamp,
|
||||
.f_restart = print_pcp_restart,
|
||||
.f_comment = print_pcp_comment,
|
||||
.f_display = logic1_display_loop
|
||||
};
|
||||
|
||||
/*
|
||||
* Array of output formats.
|
||||
*/
|
||||
struct report_format *fmt[NR_FMT] = {
|
||||
&hdr_fmt,
|
||||
&db_fmt,
|
||||
&ppc_fmt,
|
||||
&xml_fmt,
|
||||
&json_fmt,
|
||||
&conv_fmt,
|
||||
&svg_fmt,
|
||||
&raw_fmt,
|
||||
&pcp_fmt
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef SOURCE_SAR
|
||||
/*
|
||||
* Special output format for sar.
|
||||
* Used only for functions to display special
|
||||
* (RESTART and COMMENT) records.
|
||||
*/
|
||||
struct report_format sar_fmt = {
|
||||
.id = F_SAR_OUTPUT,
|
||||
.options = 0,
|
||||
.f_header = NULL,
|
||||
.f_statistics = NULL,
|
||||
.f_timestamp = NULL,
|
||||
.f_restart = print_sar_restart,
|
||||
.f_comment = print_sar_comment
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,253 @@
|
|||
#!/bin/sh
|
||||
#@(#) Configuration script for sysstat
|
||||
# (C) 2000-2022 Sebastien GODARD (sysstat <at> orange.fr)
|
||||
|
||||
ASK="sh build/Ask.sh"
|
||||
|
||||
echo ; echo
|
||||
echo Welcome to sysstat\'s Interactive Configuration script!
|
||||
echo
|
||||
echo This script enables you to set the parameters value used by ./configure.
|
||||
echo Please enter the value for the parameters listed below.
|
||||
echo Press Return to tell ./configure to use the default value or to try to guess the proper one.
|
||||
echo "Default value for yes/no questions is no (parameter is NOT set)."
|
||||
echo You can enter a ? to display a help message at any time...
|
||||
echo
|
||||
|
||||
# Syntax: Ask <QUESTION> <PARM> <TEXT_FILE>
|
||||
|
||||
# Installation directory
|
||||
PREFIX=`${ASK} 'Installation directory:' "--prefix" "prefix"`
|
||||
if [ "${PREFIX}" != "" ]; then
|
||||
PREFIX="--prefix=${PREFIX} "
|
||||
fi
|
||||
|
||||
# sadc directory
|
||||
SA_LIB_DIR=`${ASK} 'sadc directory:' "sa_lib_dir" "sa_lib_dir"`
|
||||
if [ "${SA_LIB_DIR}" != "" ]; then
|
||||
SA_LIB_DIR="sa_lib_dir=${SA_LIB_DIR} "
|
||||
fi
|
||||
|
||||
# System Activity directory
|
||||
SA_DIR=`${ASK} 'System activity directory:' "sa_dir" "sa_dir"`
|
||||
if [ "${SA_DIR}" != "" ]; then
|
||||
SA_DIR="sa_dir=${SA_DIR} "
|
||||
fi
|
||||
|
||||
# sysstat configuration directory
|
||||
SYSCONFIG_DIR=`${ASK} 'sysstat configuration directory:' "conf_dir" "conf_dir"`
|
||||
if [ "${SYSCONFIG_DIR}" != "" ]; then
|
||||
SYSCONFIG_DIR="conf_dir=${SYSCONFIG_DIR} "
|
||||
fi
|
||||
|
||||
# sysstat configuration file
|
||||
SYSCONFIG_FILE=`${ASK} 'sysstat configuration file:' "conf_file" "conf_file"`
|
||||
if [ "${SYSCONFIG_FILE}" != "" ]; then
|
||||
SYSCONFIG_FILE="conf_file=${SYSCONFIG_FILE} "
|
||||
fi
|
||||
|
||||
# Clean sa directory
|
||||
CLEAN_SA_DIR=`${ASK} 'Clean system activity directory? (y/n)' "--enable-clean-sa-dir" "clean-sa-dir"`
|
||||
if [ "${CLEAN_SA_DIR}" = "y" ]; then
|
||||
CLEAN_SA_DIR="--enable-clean-sa-dir "
|
||||
else
|
||||
CLEAN_SA_DIR=""
|
||||
echo "Parameter --enable-clean-sa-dir is NOT set"
|
||||
fi
|
||||
|
||||
# National Language Support
|
||||
NLS=`${ASK} 'Disable National Language Support (NLS)? (y/n)' "--disable-nls" "nls"`
|
||||
if [ "${NLS}" = "y" ]; then
|
||||
NLS="--disable-nls "
|
||||
else
|
||||
NLS=""
|
||||
echo "Parameter --disable-nls is NOT set"
|
||||
fi
|
||||
|
||||
# Link Time Optimization support
|
||||
LTO=`${ASK} 'Compile with Link Time Optimizations (LTO)? (y/n)' "--enable-lto" "lto"`
|
||||
if [ "${LTO}" = "y" ]; then
|
||||
LTO="--enable-lto "
|
||||
else
|
||||
LTO=""
|
||||
echo "Parameter --enable-lto is NOT set"
|
||||
fi
|
||||
|
||||
# Sensors support
|
||||
SENSORS=`${ASK} 'Disable sensors support? (y/n)' "--disable-sensors" "sensors"`
|
||||
if [ "${SENSORS}" = "y" ]; then
|
||||
SENSORS="--disable-sensors "
|
||||
else
|
||||
SENSORS=""
|
||||
echo "Parameter --disable-sensors is NOT set"
|
||||
fi
|
||||
|
||||
# PCP support
|
||||
PCP=`${ASK} 'Disable PCP support? (y/n)' "--disable-pcp" "pcp"`
|
||||
if [ "${PCP}" = "y" ]; then
|
||||
PCP="--disable-pcp "
|
||||
else
|
||||
PCP=""
|
||||
echo "Parameter --disable-pcp is NOT set"
|
||||
fi
|
||||
|
||||
# Data history to keep by sa2
|
||||
HISTORY=`${ASK} 'Number of daily data files to keep:' "history" "history"`
|
||||
if [ "${HISTORY}" != "" ]; then
|
||||
HISTORY="history=${HISTORY} "
|
||||
fi
|
||||
|
||||
# Random delay before sa2 script generates its reports files
|
||||
DELAY_RANGE=`${ASK} 'Maximum delay in seconds to wait before sa2 script runs:' "delay_range" "delay_range"`
|
||||
if [ "${DELAY_RANGE}" != "" ]; then
|
||||
DELAY_RANGE="delay_range=${DELAY_RANGE} "
|
||||
fi
|
||||
|
||||
# Delay after which datafiles are to be compressed
|
||||
COMPRESSAFTER=`${ASK} 'Number of days after which sar datafiles must be compressed:' "compressafter" "compressafter"`
|
||||
if [ "${COMPRESSAFTER}" != "" ]; then
|
||||
COMPRESSAFTER="compressafter=${COMPRESSAFTER} "
|
||||
fi
|
||||
|
||||
# Manual page group
|
||||
MAN=`${ASK} 'Group for manual pages:' "man_group" "man_group"`
|
||||
if [ "${MAN}" != "" ]; then
|
||||
MAN="man_group=${MAN} "
|
||||
fi
|
||||
|
||||
# Don't set attributes on files being installed
|
||||
IGNORE_FILE_ATTR=`${ASK} 'Do not set attributes on files being installed? (y/n)' "--disable-file-attr" "ignore-file-attr"`
|
||||
if [ "${IGNORE_FILE_ATTR}" = "y" ]; then
|
||||
IGNORE_FILE_ATTR="--disable-file-attr "
|
||||
else
|
||||
IGNORE_FILE_ATTR=""
|
||||
echo "Parameter --disable-file-attr is NOT set"
|
||||
fi
|
||||
|
||||
# Crontab
|
||||
CRON=`${ASK} 'Set crontab to start sar automatically? (y/n)' "--enable-install-cron" "install-cron"`
|
||||
if [ "${CRON}" = "y" ]; then
|
||||
CRON="--enable-install-cron "
|
||||
else
|
||||
CRON=""
|
||||
echo "Parameter --enable-install-cron is NOT set"
|
||||
fi
|
||||
|
||||
if [ "${CRON}" != "" ];
|
||||
then
|
||||
CRON_OWNER=`${ASK} 'Crontab owner:' "cron_owner" "cron_owner"`
|
||||
if [ "${CRON_OWNER}" != "" ]; then
|
||||
CRON="${CRON}cron_owner=${CRON_OWNER} "
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${CRON}" != "" ];
|
||||
then
|
||||
USE_CROND=`${ASK} 'Use standard cron daemon? (y/n)' "--enable-use-crond" "use-crond"`
|
||||
if [ "${USE_CROND}" = "y" ]; then
|
||||
USE_CROND="--enable-use-crond "
|
||||
else
|
||||
USE_CROND=""
|
||||
echo "Parameter --enable-use-crond is NOT set"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${CRON}" != "" ];
|
||||
then
|
||||
CRON_INTERVAL=`${ASK} 'Crontab sampling interval (in minutes):' "cron_interval" "cron_interval"`
|
||||
if [ "${CRON_INTERVAL}" != "" ]; then
|
||||
CRON="${CRON}cron_interval=${CRON_INTERVAL} "
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${CRON}" != "" ];
|
||||
then
|
||||
COLL_ALL=`${ASK} 'Should sadc collect optional activities? (y/n)' "--enable-collect-all" "collect-all"`
|
||||
if [ "${COLL_ALL}" = "y" ]; then
|
||||
CRON="${CRON}--enable-collect-all "
|
||||
else
|
||||
echo "Parameter --enable-collect-all is NOT set"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${CRON}" != "" -a "${COLL_ALL}" != "y" ];
|
||||
then
|
||||
# Optional args for sadc
|
||||
SADC_OPT=`${ASK} 'Options to be passed to sadc:' "sadc_options" "sadc_options"`
|
||||
else
|
||||
SADC_OPT=
|
||||
fi
|
||||
|
||||
if [ "${CRON}" != "" ];
|
||||
then
|
||||
# rc directory
|
||||
RCDIR=`${ASK} 'rc directory:' "rcdir" "rcdir"`
|
||||
if [ "${RCDIR}" != "" ]; then
|
||||
RCDIR="rcdir=${RCDIR} "
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${CRON}" != "" ];
|
||||
then
|
||||
# Only copy files
|
||||
COPY_ONLY=`${ASK} 'Only copy files when installing sysstat? (y/n)' "--enable-copy-only" "copy-only"`
|
||||
if [ "${COPY_ONLY}" = "y" ]; then
|
||||
COPY_ONLY="--enable-copy-only "
|
||||
else
|
||||
COPY_ONLY=""
|
||||
echo "Parameter --enable-copy-only is NOT set"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Compress manual pages
|
||||
COMPRESSMANPG=`${ASK} 'Do not compress manual pages? (y/n)' "--disable-compress-manpg" "compress-manpg"`
|
||||
if [ "${COMPRESSMANPG}" = "y" ]; then
|
||||
COMPRESSMANPG="--disable-compress-manpg "
|
||||
else
|
||||
COMPRESSMANPG=""
|
||||
echo "Parameter --disable-compress-manpg is NOT set"
|
||||
fi
|
||||
|
||||
# Install documentation
|
||||
INSTALL_DOC=`${ASK} 'Skip documentation installation? (y/n)' "--disable-documentation" "install-doc"`
|
||||
if [ "${INSTALL_DOC}" = "y" ]; then
|
||||
INSTALL_DOC="--disable-documentation "
|
||||
else
|
||||
INSTALL_DOC=""
|
||||
echo "Parameter --disable-documentation is NOT set"
|
||||
fi
|
||||
|
||||
# Debug mode
|
||||
DEBUGINFO=`${ASK} 'Debug mode support? (y/n)' "--enable-debuginfo" "debuginfo"`
|
||||
if [ "${DEBUGINFO}" = "y" ]; then
|
||||
DEBUGINFO="--enable-debuginfo "
|
||||
else
|
||||
DEBUGINFO=""
|
||||
echo "Parameter --enable-debuginfo is NOT set"
|
||||
fi
|
||||
|
||||
# Strip object files
|
||||
STRIP=`${ASK} 'Do not strip object files? (y/n)' "--disable-stripping" "stripping"`
|
||||
if [ "${STRIP}" = "y" ]; then
|
||||
STRIP="--disable-stripping "
|
||||
else
|
||||
STRIP=""
|
||||
echo "Parameter --disable-stripping is NOT set"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo -n "./configure ${PREFIX}${SA_LIB_DIR}${SA_DIR}${SYSCONFIG_DIR}${SYSCONFIG_FILE} \
|
||||
${CLEAN_SA_DIR}${NLS}${LTO}${HISTORY}${DELAY_RANGE}${COMPRESSAFTER}${MAN}${IGNORE_FILE_ATTR} \
|
||||
${CRON}${USE_CROND}${RCDIR}"
|
||||
if [ "${SADC_OPT}" != "" ];
|
||||
then
|
||||
echo -n "sadc_options=\"${SADC_OPT}\""
|
||||
fi
|
||||
echo "${COMPRESSMANPG}${INSTALL_DOC}${DEBUGINFO}${SENSORS}${PCP}${STRIP}${COPY_ONLY}"
|
||||
echo
|
||||
|
||||
./configure ${PREFIX}${SA_LIB_DIR}${SA_DIR}${SYSCONFIG_DIR}${SYSCONFIG_FILE} \
|
||||
${CLEAN_SA_DIR}${NLS}${LTO} \
|
||||
${HISTORY}${DELAY_RANGE}${COMPRESSAFTER}${MAN}${IGNORE_FILE_ATTR}${CRON}${USE_CROND}${RCDIR} \
|
||||
sadc_options="${SADC_OPT}" ${COMPRESSMANPG}${INSTALL_DOC}${DEBUGINFO}${SENSORS} \
|
||||
${PCP}${STRIP}${COPY_ONLY}
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 63 KiB |
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
|
@ -0,0 +1,507 @@
|
|||
/*
|
||||
* ioconf: ioconf configuration file handling code
|
||||
* Original code (C) 2004 by Red Hat (Charlie Bennett <ccb@redhat.com>)
|
||||
*
|
||||
* Modified and maintained by Sebastien GODARD (sysstat <at> orange.fr)
|
||||
*
|
||||
***************************************************************************
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
|
||||
* for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "ioconf.h"
|
||||
#include "common.h"
|
||||
|
||||
#ifdef USE_NLS
|
||||
#include <locale.h>
|
||||
#include <libintl.h>
|
||||
#define _(string) gettext(string)
|
||||
#else
|
||||
#define _(string) (string)
|
||||
#endif
|
||||
|
||||
static unsigned int ioc_parsed = 0;
|
||||
static struct ioc_entry *ioconf[MAX_BLKDEV + 1];
|
||||
static unsigned int ioc_refnr[MAX_BLKDEV + 1];
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Free ioc_entry structures
|
||||
***************************************************************************
|
||||
*/
|
||||
static void ioc_free(void)
|
||||
{
|
||||
unsigned int i;
|
||||
struct ioc_entry **p;
|
||||
|
||||
/* Take out all of the references first */
|
||||
for (i = 0, p = ioconf; i < MAX_BLKDEV; ++i, ++p) {
|
||||
if ((*p == NULL) || ((*p)->live))
|
||||
continue;
|
||||
|
||||
if ((*p)->desc != (*p)->blkp->desc) {
|
||||
/* Not a shared description */
|
||||
free((*p)->desc);
|
||||
}
|
||||
free(*p);
|
||||
*p = NULL;
|
||||
}
|
||||
|
||||
/* Now the live ones */
|
||||
for (i = 0, p = ioconf; i < MAX_BLKDEV; ++i, ++p) {
|
||||
if (*p == NULL)
|
||||
continue;
|
||||
free((*p)->blkp);
|
||||
free(*p);
|
||||
*p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* ioc_conv - Turn a number into a string in radix <radix> using symbol
|
||||
* set (and ordering) syms. Use nozero to generate strings
|
||||
* in which the number system uses a single sym for the
|
||||
* radix value (not 2, like decimal) and adds a column only
|
||||
* at radix+1. If decimal were like this:
|
||||
*
|
||||
* (no zero) 1 2 3 4 5 6 7 8 9 0 11 12 13 14 15 16 17 18 19 10 ...
|
||||
***************************************************************************
|
||||
*/
|
||||
static char *ioc_conv(int radix, int nozero, const char *syms,
|
||||
unsigned int val)
|
||||
{
|
||||
static char out[17];
|
||||
char *p;
|
||||
int j;
|
||||
|
||||
*(p = out + 16) = '\0';
|
||||
|
||||
val += nozero;
|
||||
|
||||
if (val == 0) {
|
||||
if (!nozero) {
|
||||
*--p = '0';
|
||||
}
|
||||
return (p); /* Empty string if nozero radix gets val == 0 */
|
||||
}
|
||||
|
||||
while (val > 0) {
|
||||
|
||||
*--p = syms[j = val % radix];
|
||||
val /= radix;
|
||||
if (nozero && (j == 0)) {
|
||||
/* Comp for 10 in nozero bases */
|
||||
--val;
|
||||
}
|
||||
}
|
||||
return (p);
|
||||
}
|
||||
|
||||
char *ioc_ito10(unsigned int n)
|
||||
{
|
||||
return (ioc_conv(10, 0, DIGITS, n));
|
||||
}
|
||||
|
||||
char *ioc_ito26(unsigned int n)
|
||||
{
|
||||
return (ioc_conv(26, 1, "zabcdefghijklmnopqrstuvwxy", n));
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* ioc_init() - internalize the ioconf file
|
||||
*
|
||||
* given: void
|
||||
* does: parses IOCONF into ioconf, an array of ioc_entry *
|
||||
* Only entries having lines in IOCONF will have valid pointers
|
||||
* return: 1 on success
|
||||
* 0 on failure
|
||||
***************************************************************************
|
||||
*/
|
||||
int ioc_init(void)
|
||||
{
|
||||
FILE *fp;
|
||||
unsigned int i, major, indirect, count = 0;
|
||||
char buf[IOC_LINESIZ];
|
||||
char cfmt[IOC_FMTLEN];
|
||||
char dfmt[IOC_FMTLEN];
|
||||
char pfmt[IOC_FMTLEN];
|
||||
char desc[IOC_DESCLEN];
|
||||
struct ioc_entry *iocp = NULL;
|
||||
struct blk_config *blkp = NULL;
|
||||
char ioconf_name[64];
|
||||
|
||||
if ((fp = fopen(IOCONF, "r")) == NULL) {
|
||||
if ((fp = fopen(LOCAL_IOCONF, "r")) == NULL)
|
||||
return 0;
|
||||
strncpy(ioconf_name, LOCAL_IOCONF, sizeof(ioconf_name));
|
||||
}
|
||||
else {
|
||||
strncpy(ioconf_name, IOCONF, sizeof(ioconf_name));
|
||||
}
|
||||
ioconf_name[sizeof(ioconf_name) - 1] = '\0';
|
||||
|
||||
/* Init ioc_refnr array */
|
||||
memset(ioc_refnr, 0, sizeof(ioc_refnr));
|
||||
|
||||
while (fgets(buf, sizeof(buf) - 1, fp)) {
|
||||
|
||||
if ((*buf == '#') || (*buf == '\n'))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Preallocate some (probably) needed data structures
|
||||
*/
|
||||
IOC_ALLOC(blkp, struct blk_config, BLK_CONFIG_SIZE);
|
||||
IOC_ALLOC(iocp, struct ioc_entry, IOC_ENTRY_SIZE);
|
||||
memset(blkp, 0, BLK_CONFIG_SIZE);
|
||||
memset(iocp, 0, IOC_ENTRY_SIZE);
|
||||
|
||||
i = sscanf(buf, "%u:%u:%u:%s",
|
||||
&major, &indirect, &iocp->ctrlno, desc);
|
||||
|
||||
if (i != 4) {
|
||||
i = sscanf(buf, "%u:%u:%u",
|
||||
&major, &indirect, &iocp->ctrlno);
|
||||
}
|
||||
|
||||
if ((i == 3) || (i == 4)) {
|
||||
/* indirect record */
|
||||
if (indirect == 0) {
|
||||
/* conventional usage for unsupported device */
|
||||
continue;
|
||||
}
|
||||
if (indirect > MAX_BLKDEV) {
|
||||
fprintf(stderr, "%s: Indirect major #%u out of range\n",
|
||||
ioconf_name, indirect);
|
||||
continue;
|
||||
}
|
||||
if (major > MAX_BLKDEV) {
|
||||
fprintf(stderr, "%s: Major #%u out of range\n",
|
||||
ioconf_name, major);
|
||||
continue;
|
||||
}
|
||||
if (ioconf[indirect] == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s: Indirect record '%u:%u:%u:...'"
|
||||
" references not yet seen major %u\n",
|
||||
ioconf_name, major, indirect, iocp->ctrlno, major);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Cool. Point this device at its referent.
|
||||
* Skip last: (last field my be empty...)
|
||||
* if it was empty and : was in the sscanf spec
|
||||
* we'd only see 3 fields...
|
||||
*/
|
||||
if (i == 3) {
|
||||
/* reference the mothership */
|
||||
iocp->desc = ioconf[indirect]->blkp->desc;
|
||||
}
|
||||
else {
|
||||
IOC_ALLOC(iocp->desc, char, IOC_DESCLEN);
|
||||
memcpy(iocp->desc, desc, IOC_DESCLEN);
|
||||
}
|
||||
ioc_refnr[indirect]++;
|
||||
ioconf[major] = iocp;
|
||||
iocp->basemajor = indirect;
|
||||
iocp->blkp = ioconf[indirect]->blkp;
|
||||
iocp->live = 0;
|
||||
iocp = NULL;
|
||||
continue;
|
||||
/* all done with indirect record */
|
||||
}
|
||||
|
||||
/* maybe it's a full record? */
|
||||
|
||||
i = sscanf(buf, "%u:%[^:]:%[^:]:%u:%[^:]:%u:%[^:]:%u:%s",
|
||||
&major, blkp->name,
|
||||
cfmt, &iocp->ctrlno,
|
||||
dfmt, &blkp->dcount,
|
||||
pfmt, &blkp->pcount,
|
||||
desc);
|
||||
|
||||
if (i != 9) {
|
||||
fprintf(stderr, "%s: Malformed %u field record: %s\n",
|
||||
ioconf_name, i, buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* this is a full-fledged direct record */
|
||||
|
||||
if ((major == 0) || (major >= MAX_BLKDEV)) {
|
||||
fprintf(stderr, "%s: major #%u out of range\n",
|
||||
__FUNCTION__, major);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* is this an exception record? */
|
||||
if (*cfmt == 'x') {
|
||||
struct blk_config *xblkp;
|
||||
|
||||
/*
|
||||
* device has an aliased minor
|
||||
* for now we only support one exception per major
|
||||
* (catering to initrd: (1,250))
|
||||
*/
|
||||
if (ioconf[major] == NULL) {
|
||||
fprintf(stderr, "%s: type 'x' record for"
|
||||
" major #%u must follow the base record - ignored\n",
|
||||
ioconf_name, major);
|
||||
continue;
|
||||
}
|
||||
xblkp = ioconf[major]->blkp;
|
||||
|
||||
if (xblkp->ext) {
|
||||
/*
|
||||
* Enforce one minor exception per major policy
|
||||
* note: this applies to each major number and
|
||||
* all of it's indirect (short form) majors
|
||||
*/
|
||||
fprintf(stderr, "%s: duplicate 'x' record for"
|
||||
" major #%u - ignored\ninput line: %s\n",
|
||||
ioconf_name, major, buf);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Decorate the base major struct with the
|
||||
* exception info
|
||||
*/
|
||||
xblkp->ext_minor = iocp->ctrlno;
|
||||
strncpy(xblkp->ext_name, blkp->name, IOC_NAMELEN);
|
||||
xblkp->ext_name[IOC_NAMELEN - 1] = '\0';
|
||||
xblkp->ext = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Preformat the sprintf format strings for generating
|
||||
* c-d-p info in ioc_name()
|
||||
*/
|
||||
|
||||
/* basename of device + provided string + controller # */
|
||||
if (*cfmt == '*') {
|
||||
strncpy(blkp->cfmt, blkp->name, MINIMUM(sizeof(blkp->name), sizeof(blkp->cfmt) - 1));
|
||||
blkp->cfmt[sizeof(blkp->cfmt) - 1] = '\0';
|
||||
}
|
||||
else {
|
||||
sprintf(blkp->cfmt, "%s%s%%d", blkp->name, cfmt);
|
||||
++(blkp->ctrl_explicit);
|
||||
}
|
||||
|
||||
/* Disk */
|
||||
*blkp->dfmt = '\0';
|
||||
switch (*dfmt) {
|
||||
case 'a':
|
||||
blkp->cconv = ioc_ito26;
|
||||
strcpy(blkp->dfmt, "%s");
|
||||
break;
|
||||
|
||||
case '%':
|
||||
strncpy(blkp->dfmt, dfmt + 1, IOC_FMTLEN - 1);
|
||||
/* fallthrough to next case */
|
||||
case 'd':
|
||||
blkp->cconv = ioc_ito10;
|
||||
strcat(blkp->dfmt, "%s");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Partition */
|
||||
sprintf(blkp->pfmt, "%s%%d", (*pfmt == '*') ? "" : pfmt);
|
||||
|
||||
/*
|
||||
* We're good to go.
|
||||
* Stuff the ioc_entry and ref it.
|
||||
*/
|
||||
iocp->live = 1;
|
||||
iocp->blkp = blkp;
|
||||
iocp->desc = NULL;
|
||||
iocp->basemajor = major;
|
||||
ioconf[major] = iocp;
|
||||
memcpy(blkp->desc, desc, IOC_DESCLEN);
|
||||
blkp = NULL; iocp = NULL;
|
||||
++count;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
/*
|
||||
* These will become leaks if we ever 'continue'
|
||||
* after IOC_ALLOC( blkp->desc ... ).
|
||||
* Right now, we don't.
|
||||
*/
|
||||
free(blkp);
|
||||
free(iocp);
|
||||
|
||||
/* Indicate that ioconf file has been parsed */
|
||||
ioc_parsed = 1;
|
||||
|
||||
return (count);
|
||||
|
||||
free_and_return:
|
||||
/* Free pointers and return */
|
||||
fclose(fp);
|
||||
if (blkp) {
|
||||
free(blkp);
|
||||
}
|
||||
if (iocp) {
|
||||
free(iocp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* ioc_name() - Generate a name from a maj,min pair
|
||||
*
|
||||
* IN:
|
||||
* @major Device major number.
|
||||
* @minor Device minor number.
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns NULL if major or minor are out of range
|
||||
* otherwise returns a pointer to a static string containing
|
||||
* the generated name.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
char *ioc_name(unsigned int major, unsigned int minor)
|
||||
{
|
||||
static char name[IOC_DEVLEN];
|
||||
struct ioc_entry *p;
|
||||
int base, offset;
|
||||
|
||||
if ((major > MAX_BLKDEV) || (minor > IOC_MAXMINOR)) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (!ioc_parsed && !ioc_init())
|
||||
return (NULL);
|
||||
|
||||
p = ioconf[major];
|
||||
|
||||
/* Invalid major or minor numbers? */
|
||||
if ((p == NULL) || ((minor & 0xff) >= (p->blkp->dcount * p->blkp->pcount))) {
|
||||
/*
|
||||
* That minor test is only there for IDE-style devices
|
||||
* that have no minors over 128.
|
||||
*/
|
||||
strcpy(name, K_NODEV);
|
||||
return (name);
|
||||
}
|
||||
|
||||
/* Is this an extension record? */
|
||||
if (p->blkp->ext && (p->blkp->ext_minor == minor)) {
|
||||
strncpy(name, p->blkp->ext_name, sizeof(name));
|
||||
name[sizeof(name) - 1] = '\0';
|
||||
return (name);
|
||||
}
|
||||
|
||||
/* OK. we're doing an actual device name... */
|
||||
|
||||
/*
|
||||
* Assemble base + optional controller info
|
||||
* this is of course too clever by half
|
||||
* the parser has already cooked cfmt, dfmt to make this easy
|
||||
* (we parse once but may generate lots of names)
|
||||
*/
|
||||
base = p->ctrlno * p->blkp->dcount;
|
||||
if (minor >= 256) {
|
||||
base += p->blkp->dcount * (ioc_refnr[p->basemajor] + 1) * (minor >> 8);
|
||||
}
|
||||
|
||||
offset = (minor & 0xff) / p->blkp->pcount;
|
||||
if (!p->blkp->ctrl_explicit) {
|
||||
offset += base;
|
||||
}
|
||||
|
||||
/*
|
||||
* These sprintfs can't be coalesced because the first might
|
||||
* ignore its first arg
|
||||
*/
|
||||
sprintf(name, p->blkp->cfmt, p->ctrlno);
|
||||
sprintf(name + strlen(name), p->blkp->dfmt, p->blkp->cconv(offset));
|
||||
|
||||
if (!IS_WHOLE(major, minor)) {
|
||||
/*
|
||||
* Tack on partition info, format string cooked (curried?) by
|
||||
* the parser
|
||||
*/
|
||||
sprintf(name + strlen(name), p->blkp->pfmt, minor % p->blkp->pcount);
|
||||
}
|
||||
return (name);
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Transform device mapper name: Get the user assigned name of the logical
|
||||
* device instead of the internal device mapper numbering.
|
||||
*
|
||||
* IN:
|
||||
* @major Device major number.
|
||||
* @minor Device minor number.
|
||||
*
|
||||
* RETURNS:
|
||||
* Assigned name of the logical device.
|
||||
***************************************************************************
|
||||
*/
|
||||
char *transform_devmapname(unsigned int major, unsigned int minor)
|
||||
{
|
||||
DIR *dm_dir;
|
||||
struct dirent *dp;
|
||||
char filen[MAX_FILE_LEN];
|
||||
char *dm_name = NULL;
|
||||
static char name[MAX_NAME_LEN];
|
||||
struct stat aux;
|
||||
unsigned int dm_major, dm_minor;
|
||||
|
||||
if ((dm_dir = opendir(DEVMAP_DIR)) == NULL) {
|
||||
fprintf(stderr, _("Cannot open %s: %s\n"), DEVMAP_DIR, strerror(errno));
|
||||
exit(4);
|
||||
}
|
||||
|
||||
while ((dp = readdir(dm_dir)) != NULL) {
|
||||
/* For each file in DEVMAP_DIR */
|
||||
|
||||
snprintf(filen, sizeof(filen), "%s/%s", DEVMAP_DIR, dp->d_name);
|
||||
filen[sizeof(filen) - 1] = '\0';
|
||||
|
||||
if (__stat(filen, &aux) == 0) {
|
||||
/* Get its minor and major numbers */
|
||||
|
||||
dm_major = __major(aux.st_rdev);
|
||||
dm_minor = __minor(aux.st_rdev);
|
||||
|
||||
if ((dm_minor == minor) && (dm_major == major)) {
|
||||
strncpy(name, dp->d_name, sizeof(name));
|
||||
name[sizeof(name) - 1] = '\0';
|
||||
dm_name = name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dm_dir);
|
||||
|
||||
return dm_name;
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* ioconf: ioconf configuration file handling code
|
||||
* Original code (C) 2004 by Red Hat (Charlie Bennett <ccb@redhat.com>)
|
||||
*
|
||||
* Modified and maintained by Sebastien GODARD (sysstat <at> orange.fr)
|
||||
*/
|
||||
|
||||
#ifndef _IOCONF_H
|
||||
#define _IOCONF_H
|
||||
|
||||
#include "sysconfig.h"
|
||||
|
||||
#define IOC_NAMELEN 32
|
||||
#define IOC_DESCLEN 64
|
||||
#define IOC_DEVLEN 48
|
||||
#define IOC_LINESIZ 256
|
||||
#define IOC_FMTLEN 16
|
||||
#define IOC_XFMTLEN (IOC_FMTLEN + IOC_NAMELEN + 3)
|
||||
|
||||
#ifndef MINORBITS
|
||||
#define MINORBITS 20
|
||||
#endif
|
||||
#define IOC_MAXMINOR ((1U << MINORBITS) - 1)
|
||||
#ifndef MAX_BLKDEV
|
||||
/* #define MAX_BLKDEV ((1U << (32 - MINORBITS)) - 1) */
|
||||
/* Use a lower value since this value is used to allocate arrays statically in ioconf.c */
|
||||
#define MAX_BLKDEV 511
|
||||
#endif
|
||||
|
||||
#define K_NODEV "nodev"
|
||||
|
||||
#define IS_WHOLE(maj,min) ((min % ioconf[maj]->blkp->pcount) == 0)
|
||||
|
||||
/*
|
||||
* When is C going to get templates?
|
||||
*/
|
||||
#define IOC_ALLOC(P,TYPE,SIZE) \
|
||||
do { \
|
||||
if (P == NULL) { \
|
||||
P = (TYPE *) malloc(SIZE); \
|
||||
if (P == NULL) { \
|
||||
perror("malloc"); \
|
||||
ioc_free(); \
|
||||
goto free_and_return; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
/* That dummy while allows ';' on the line that invokes the macro... */
|
||||
|
||||
|
||||
struct blk_config {
|
||||
char name[IOC_NAMELEN]; /* device basename */
|
||||
char cfmt[IOC_XFMTLEN]; /* controller format string */
|
||||
char dfmt[IOC_FMTLEN]; /* disk format string */
|
||||
char pfmt[IOC_FMTLEN + 2]; /* partition format string */
|
||||
/* ctrlno is in the ioc_entry */
|
||||
unsigned int ctrl_explicit; /* use "cN" in name */
|
||||
unsigned int dcount; /* number of devices handled by this major */
|
||||
unsigned int pcount; /* partitions per device */
|
||||
char desc[IOC_DESCLEN];
|
||||
/* disk info unit # conversion function */
|
||||
char *(*cconv)(unsigned int);
|
||||
|
||||
/* extension properties (all this for initrd?) */
|
||||
char ext_name[IOC_NAMELEN];
|
||||
unsigned int ext; /* flag - this is an extension record */
|
||||
unsigned int ext_minor; /* which minor does this apply to */
|
||||
};
|
||||
|
||||
#define BLK_CONFIG_SIZE (sizeof(struct blk_config))
|
||||
|
||||
|
||||
struct ioc_entry {
|
||||
int live; /* is this a Direct entry? */
|
||||
unsigned int ctrlno; /* controller number */
|
||||
unsigned int basemajor; /* Major number of the template */
|
||||
char *desc; /* (dynamic) per-controller description */
|
||||
struct blk_config *blkp; /* the real info, may be a shared ref */
|
||||
};
|
||||
|
||||
#define IOC_ENTRY_SIZE (sizeof(struct ioc_entry))
|
||||
|
||||
|
||||
int ioc_iswhole
|
||||
(unsigned int, unsigned int);
|
||||
char *ioc_name
|
||||
(unsigned int, unsigned int);
|
||||
char *transform_devmapname
|
||||
(unsigned int, unsigned int);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* iostat: report CPU and I/O statistics
|
||||
* (C) 1999-2022 by Sebastien Godard (sysstat <at> orange.fr)
|
||||
*/
|
||||
|
||||
#ifndef _IOSTAT_H
|
||||
#define _IOSTAT_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* I_: iostat - D_: Display - F_: Flag */
|
||||
#define I_D_CPU 0x000001
|
||||
#define I_D_DISK 0x000002
|
||||
#define I_D_TIMESTAMP 0x000004
|
||||
#define I_D_EXTENDED 0x000008
|
||||
#define I_D_EVERYTHING 0x000010
|
||||
#define I_D_KILOBYTES 0x000020
|
||||
#define I_D_ALL_DIR 0x000040
|
||||
#define I_D_DEBUG 0x000080
|
||||
#define I_D_UNFILTERED 0x000100
|
||||
#define I_D_MEGABYTES 0x000200
|
||||
#define I_D_ALL_DEVICES 0x000400
|
||||
#define I_F_GROUP_DEFINED 0x000800
|
||||
#define I_D_PRETTY 0x001000
|
||||
#define I_D_PERSIST_NAME 0x002000
|
||||
#define I_D_OMIT_SINCE_BOOT 0x004000
|
||||
#define I_D_JSON_OUTPUT 0x008000
|
||||
#define I_D_DEVMAP_NAME 0x010000
|
||||
#define I_D_ISO 0x020000
|
||||
#define I_D_GROUP_TOTAL_ONLY 0x040000
|
||||
#define I_D_ZERO_OMIT 0x080000
|
||||
#define I_D_UNIT 0x100000
|
||||
#define I_D_SHORT_OUTPUT 0x200000
|
||||
#define I_D_COMPACT 0x400000
|
||||
|
||||
#define DISPLAY_CPU(m) (((m) & I_D_CPU) == I_D_CPU)
|
||||
#define DISPLAY_DISK(m) (((m) & I_D_DISK) == I_D_DISK)
|
||||
#define DISPLAY_TIMESTAMP(m) (((m) & I_D_TIMESTAMP) == I_D_TIMESTAMP)
|
||||
#define DISPLAY_EXTENDED(m) (((m) & I_D_EXTENDED) == I_D_EXTENDED)
|
||||
#define DISPLAY_EVERYTHING(m) (((m) & I_D_EVERYTHING) == I_D_EVERYTHING)
|
||||
#define DISPLAY_KILOBYTES(m) (((m) & I_D_KILOBYTES) == I_D_KILOBYTES)
|
||||
#define DISPLAY_MEGABYTES(m) (((m) & I_D_MEGABYTES) == I_D_MEGABYTES)
|
||||
#define DISPLAY_DEBUG(m) (((m) & I_D_DEBUG) == I_D_DEBUG)
|
||||
#define DISPLAY_UNFILTERED(m) (((m) & I_D_UNFILTERED) == I_D_UNFILTERED)
|
||||
#define DISPLAY_ALL_DEVICES(m) (((m) & I_D_ALL_DEVICES) == I_D_ALL_DEVICES)
|
||||
#define GROUP_DEFINED(m) (((m) & I_F_GROUP_DEFINED) == I_F_GROUP_DEFINED)
|
||||
#define DISPLAY_PRETTY(m) (((m) & I_D_PRETTY) == I_D_PRETTY)
|
||||
#define DISPLAY_PERSIST_NAME_I(m) (((m) & I_D_PERSIST_NAME) == I_D_PERSIST_NAME)
|
||||
#define DISPLAY_OMIT_SINCE_BOOT(m) (((m) & I_D_OMIT_SINCE_BOOT) == I_D_OMIT_SINCE_BOOT)
|
||||
#define DISPLAY_DEVMAP_NAME(m) (((m) & I_D_DEVMAP_NAME) == I_D_DEVMAP_NAME)
|
||||
#define DISPLAY_ISO(m) (((m) & I_D_ISO) == I_D_ISO)
|
||||
#define DISPLAY_GROUP_TOTAL_ONLY(m) (((m) & I_D_GROUP_TOTAL_ONLY) == I_D_GROUP_TOTAL_ONLY)
|
||||
#define DISPLAY_ZERO_OMIT(m) (((m) & I_D_ZERO_OMIT) == I_D_ZERO_OMIT)
|
||||
#define DISPLAY_JSON_OUTPUT(m) (((m) & I_D_JSON_OUTPUT) == I_D_JSON_OUTPUT)
|
||||
#define DISPLAY_UNIT(m) (((m) & I_D_UNIT) == I_D_UNIT)
|
||||
#define DISPLAY_SHORT_OUTPUT(m) (((m) & I_D_SHORT_OUTPUT) == I_D_SHORT_OUTPUT)
|
||||
#define USE_ALL_DIR(m) (((m) & I_D_ALL_DIR) == I_D_ALL_DIR)
|
||||
#define DISPLAY_COMPACT(m) (((m) & I_D_COMPACT) == I_D_COMPACT)
|
||||
|
||||
#define T_PART 0
|
||||
#define T_DEV 1
|
||||
#define T_PART_DEV 2
|
||||
#define T_GROUP 3
|
||||
|
||||
#define UKWN_MAJ_NR 0
|
||||
|
||||
/* Environment variable */
|
||||
#define ENV_POSIXLY_CORRECT "POSIXLY_CORRECT"
|
||||
|
||||
/*
|
||||
* Structures for I/O stats.
|
||||
* These are now dynamically allocated.
|
||||
*/
|
||||
struct io_stats {
|
||||
/* # of sectors read */
|
||||
unsigned long rd_sectors __attribute__ ((aligned (8)));
|
||||
/* # of sectors written */
|
||||
unsigned long wr_sectors __attribute__ ((packed));
|
||||
/* # of sectors discarded */
|
||||
unsigned long dc_sectors __attribute__ ((packed));
|
||||
/* # of read operations issued to the device */
|
||||
unsigned long rd_ios __attribute__ ((packed));
|
||||
/* # of read requests merged */
|
||||
unsigned long rd_merges __attribute__ ((packed));
|
||||
/* # of write operations issued to the device */
|
||||
unsigned long wr_ios __attribute__ ((packed));
|
||||
/* # of write requests merged */
|
||||
unsigned long wr_merges __attribute__ ((packed));
|
||||
/* # of discard operations issued to the device */
|
||||
unsigned long dc_ios __attribute__ ((packed));
|
||||
/* # of discard requests merged */
|
||||
unsigned long dc_merges __attribute__ ((packed));
|
||||
/* # of flush requests issued to the device */
|
||||
unsigned long fl_ios __attribute__ ((packed));
|
||||
/* Time of read requests in queue */
|
||||
unsigned int rd_ticks __attribute__ ((packed));
|
||||
/* Time of write requests in queue */
|
||||
unsigned int wr_ticks __attribute__ ((packed));
|
||||
/* Time of discard requests in queue */
|
||||
unsigned int dc_ticks __attribute__ ((packed));
|
||||
/* Time of flush requests in queue */
|
||||
unsigned int fl_ticks __attribute__ ((packed));
|
||||
/* # of I/Os in progress */
|
||||
unsigned int ios_pgr __attribute__ ((packed));
|
||||
/* # of ticks total (for this device) for I/O */
|
||||
unsigned int tot_ticks __attribute__ ((packed));
|
||||
/* # of ticks requests spent in queue */
|
||||
unsigned int rq_ticks __attribute__ ((packed));
|
||||
};
|
||||
|
||||
#define IO_STATS_SIZE (sizeof(struct io_stats))
|
||||
|
||||
struct io_device {
|
||||
char name[MAX_NAME_LEN];
|
||||
/*
|
||||
* 0: Not a whole device (T_PART)
|
||||
* 1: whole device (T_DEV)
|
||||
* 2: whole device and all its partitions to be read (T_PART_DEV)
|
||||
* 3+: group name (T_GROUP) (4 means 1 device in the group, 5 means 2 devices in the group, etc.)
|
||||
*/
|
||||
int dev_tp;
|
||||
/* TRUE if device exists in /proc/diskstats or /sys. Don't apply for groups. */
|
||||
int exist;
|
||||
/* major and minor numbers (not set for T_GROUP "devices") */
|
||||
int major;
|
||||
int minor;
|
||||
struct io_stats *dev_stats[2];
|
||||
struct io_device *next;
|
||||
};
|
||||
|
||||
struct ext_io_stats {
|
||||
/* r_await */
|
||||
double r_await;
|
||||
/* w_await */
|
||||
double w_await;
|
||||
/* d_await */
|
||||
double d_await;
|
||||
/* f_await */
|
||||
double f_await;
|
||||
/* rsec/s */
|
||||
double rsectors;
|
||||
/* wsec/s */
|
||||
double wsectors;
|
||||
/* dsec/s */
|
||||
double dsectors;
|
||||
/* sec/s */
|
||||
double sectors;
|
||||
/* %rrqm */
|
||||
double rrqm_pc;
|
||||
/* %wrqm */
|
||||
double wrqm_pc;
|
||||
/* %drqm */
|
||||
double drqm_pc;
|
||||
/* rareq-sz */
|
||||
double rarqsz;
|
||||
/* wareq-sz */
|
||||
double warqsz;
|
||||
/* dareq-sz */
|
||||
double darqsz;
|
||||
};
|
||||
|
||||
#endif /* _IOSTAT_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* json_stats.h: Include file used to display system statistics in JSON format.
|
||||
* (C) 1999-2022 by Sebastien Godard (sysstat <at> orange.fr)
|
||||
*/
|
||||
|
||||
#ifndef _JSON_STATS_H
|
||||
#define _JSON_STATS_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Prototypes for functions used to display system statistics in JSON.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/* Functions used to display statistics in JSON */
|
||||
__print_funct_t json_print_cpu_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_pcsw_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_irq_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_swap_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_paging_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_io_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_memory_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_ktables_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_queue_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_serial_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_disk_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_dev_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_edev_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_nfs_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_nfsd_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_sock_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_ip_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_eip_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_icmp_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_eicmp_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_tcp_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_etcp_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_udp_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_sock6_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_ip6_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_eip6_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_icmp6_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_eicmp6_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_net_udp6_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_pwr_cpufreq_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_pwr_fan_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_pwr_temp_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_pwr_in_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_huge_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_pwr_wghfreq_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_pwr_usb_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_filesystem_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_fchost_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_softnet_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_psicpu_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_psiio_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
__print_funct_t json_print_psimem_stats
|
||||
(struct activity *, int, int, unsigned long long);
|
||||
|
||||
#endif /* _JSON_STATS_H */
|
|
@ -0,0 +1,154 @@
|
|||
.\" cifsiostat manual page - (C) 2020 Sebastien Godard (sysstat <at> orange.fr)
|
||||
.TH CIFSIOSTAT 1 "JULY 2020" Linux "Linux User's Manual" -*- nroff -*-
|
||||
.SH NAME
|
||||
cifsiostat \- Report CIFS statistics.
|
||||
|
||||
.SH SYNOPSIS
|
||||
.ie 'yes'@WITH_DEBUG@' \{
|
||||
.B cifsiostat [ -h ] [ -k | -m ] [ -t ] [ -V ] [ --debuginfo ] [ --dec={ 0 | 1 | 2 } ] [ --human ] [ --pretty ] [
|
||||
.IB "interval " "[ " "count " "] ]"
|
||||
.\}
|
||||
.el \{
|
||||
.B cifsiostat [ -h ] [ -k | -m ] [ -t ] [ -V ] [ --dec={ 0 | 1 | 2 } ] [ --human ] [ --pretty ] [
|
||||
.IB "interval " "[ " "count " "] ]"
|
||||
.\}
|
||||
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B cifsiostat
|
||||
command displays statistics about read and write operations
|
||||
on CIFS filesystems.
|
||||
.PP
|
||||
.RI "The " "interval"
|
||||
parameter specifies the amount of time in seconds between
|
||||
each report. The first report contains statistics for the time since
|
||||
system startup (boot). Each subsequent report contains statistics
|
||||
collected during the interval since the previous report.
|
||||
A report consists of a CIFS header row followed by
|
||||
a line of statistics for each CIFS filesystem that is mounted.
|
||||
.RI "The " "count " "parameter can be specified in conjunction with the " "interval "
|
||||
.RI "parameter. If the " "count " "parameter is specified, the value of " "count "
|
||||
.RI "determines the number of reports generated at " "interval " "seconds apart. If the " "interval "
|
||||
.RI "parameter is specified without the " "count " "parameter, the "
|
||||
.BR "cifsiostat " "command generates reports continuously."
|
||||
|
||||
.SH REPORT
|
||||
The CIFS report provides statistics for each mounted CIFS filesystem.
|
||||
The report shows the following fields:
|
||||
|
||||
.IP Filesystem:
|
||||
This columns shows the mount point of the CIFS filesystem.
|
||||
.IP "rB/s (rkB/s, rMB/s)"
|
||||
Indicate the average number of bytes (kilobytes, megabytes) read per second.
|
||||
.IP "wB/s (wkB/s, wMB/s)"
|
||||
Indicate the average number of bytes (kilobytes, megabytes) written per second.
|
||||
.IP rop/s
|
||||
Indicate the number of 'read' operations that were issued to the filesystem
|
||||
per second.
|
||||
.IP wop/s
|
||||
Indicate the number of 'write' operations that were issued to the filesystem
|
||||
per second.
|
||||
.IP fo/s
|
||||
Indicate the number of open files per second.
|
||||
.IP fc/s
|
||||
Indicate the number of closed files per second.
|
||||
.IP fd/s
|
||||
Indicate the number of deleted files per second.
|
||||
|
||||
.SH OPTIONS
|
||||
.if 'yes'@WITH_DEBUG@' \{
|
||||
.TP
|
||||
.B --debuginfo
|
||||
Print debug output to stderr.
|
||||
.\}
|
||||
.TP
|
||||
.B --dec={ 0 | 1 | 2 }
|
||||
Specify the number of decimal places to use (0 to 2, default value is 2).
|
||||
.TP
|
||||
.B -h
|
||||
This option is equivalent to specifying
|
||||
.BR "--human --pretty" "."
|
||||
.TP
|
||||
.B --human
|
||||
Print sizes in human readable format (e.g. 1.0k, 1.2M, etc.)
|
||||
The units displayed with this option supersede any other default units (e.g.
|
||||
kilobytes, sectors...) associated with the metrics.
|
||||
.TP
|
||||
.B -k
|
||||
Display statistics in kilobytes per second.
|
||||
.TP
|
||||
.B -m
|
||||
Display statistics in megabytes per second.
|
||||
.TP
|
||||
.B --pretty
|
||||
Make the CIFS report easier to read by a human.
|
||||
.TP
|
||||
.B -t
|
||||
Print the time for each report displayed. The timestamp format may depend
|
||||
on the value of the
|
||||
.BR "S_TIME_FORMAT " "environment variable (see below)."
|
||||
.TP
|
||||
.B -V
|
||||
Print version number then exit.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
.RB "The " "cifsiostat " "command takes into account the following environment variables: "
|
||||
.TP
|
||||
.B S_COLORS
|
||||
By default statistics are displayed in color when the output is connected to a terminal.
|
||||
Use this variable to change the settings. Possible values for this variable are
|
||||
.BR "never" ", " "always " "or " "auto " "(the latter is equivalent to the default settings)."
|
||||
.br
|
||||
Please note that the color (being red, yellow, or some other color) used to display a value
|
||||
is not indicative of any kind of issue simply because of the color. It only indicates different
|
||||
ranges of values.
|
||||
.TP
|
||||
.B S_COLORS_SGR
|
||||
Specify the colors and other attributes used to display statistics on the terminal.
|
||||
Its value is a colon-separated list of capabilities that defaults to
|
||||
.BR "I=32;22:N=34;1:Z=34;22" "."
|
||||
Supported capabilities are:
|
||||
.RS
|
||||
.TP
|
||||
.B I=
|
||||
SGR substring for filesystem names.
|
||||
.TP
|
||||
.B N=
|
||||
SGR substring for non-zero statistics values.
|
||||
.TP
|
||||
.B Z=
|
||||
SGR substring for zero values.
|
||||
.RE
|
||||
.TP
|
||||
.B S_TIME_FORMAT
|
||||
If this variable exists and its value is
|
||||
.B ISO
|
||||
then the current locale will be ignored when printing the date in the report
|
||||
header. The
|
||||
.B cifsiostat
|
||||
command will use the ISO 8601 format (YYYY-MM-DD) instead.
|
||||
.RB "The timestamp displayed with option " "-t " "will also be compliant with ISO 8601 format."
|
||||
|
||||
.SH BUG
|
||||
.IR "/proc " "filesystem must be mounted for"
|
||||
.BR "cifsiostat " "to work."
|
||||
.PP
|
||||
.RB "Although " "cifsiostat"
|
||||
speaks of kilobytes (kB), megabytes (MB)..., it actually uses kibibytes (kiB), mebibytes (MiB)...
|
||||
A kibibyte is equal to 1024 bytes, and a mebibyte is equal to 1024 kibibytes.
|
||||
|
||||
.SH FILE
|
||||
.IR "/proc/fs/cifs/Stats " "contains CIFS statistics."
|
||||
|
||||
.SH AUTHORS
|
||||
Written by Ivana Varekova (varekova <at> redhat.com)
|
||||
.br
|
||||
Maintained by Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR "sar" "(1), " "pidstat" "(1), " "mpstat" "(1), " "vmstat" "(8), " "iostat" "(1),"
|
||||
.BR "tapestat" "(1), " "nfsiostat" "(1)"
|
||||
|
||||
.I https://github.com/sysstat/sysstat
|
||||
.br
|
||||
.I http://pagesperso-orange.fr/sebastien.godard/
|
|
@ -0,0 +1,477 @@
|
|||
.\" iostat manual page - (C) 1998-2020 Sebastien Godard (sysstat <at> orange.fr)
|
||||
.TH IOSTAT 1 "SEPTEMBER 2021" Linux "Linux User's Manual" -*- nroff -*-
|
||||
.SH NAME
|
||||
iostat \- Report Central Processing Unit (CPU) statistics and input/output
|
||||
statistics for devices and partitions.
|
||||
|
||||
.SH SYNOPSIS
|
||||
.ie 'yes'@WITH_DEBUG@' \{
|
||||
.B iostat [ -c ] [ -d ] [ -h ] [ -k | -m ] [ -N ] [ -s ] [ -t ] [ -V ] [ -x ] [ -y ] [ -z ]
|
||||
.BI "[ --compact ] [ --dec={ 0 | 1 | 2 } ] [ { -f | +f } " "directory" " ] [ -j { ID | LABEL | PATH | UUID | ... } ] "
|
||||
.BI "[ -o JSON ] [ [ -H ] -g " "group_name " "] [ --human ] [ --pretty ] [ -p [ " "device" "[,...] | ALL ] ] ["
|
||||
.IB "device " "[...] | ALL ] [ --debuginfo ] [ " "interval " "[ " "count " "] ] "
|
||||
.\}
|
||||
.el \{
|
||||
.B iostat [ -c ] [ -d ] [ -h ] [ -k | -m ] [ -N ] [ -s ] [ -t ] [ -V ] [ -x ] [ -y ] [ -z ]
|
||||
.BI "[ --compact ] [ --dec={ 0 | 1 | 2 } ] [ { -f | +f } " "directory" " ] [ -j { ID | LABEL | PATH | UUID | ... } ] "
|
||||
.BI "[ -o JSON ] [ [ -H ] -g " "group_name " "] [ --human ] [ --pretty ] [ -p [ " "device" "[,...] | ALL ] ] ["
|
||||
.IB "device " "[...] | ALL ] [ " "interval " "[ " "count " "] ]"
|
||||
.\}
|
||||
|
||||
.SH DESCRIPTION
|
||||
.RB "The " "iostat"
|
||||
command is used for monitoring system input/output device
|
||||
loading by observing the time the devices are active in relation
|
||||
to their average transfer rates. The
|
||||
.B iostat
|
||||
command generates reports
|
||||
that can be used to change system configuration to better balance
|
||||
the input/output load between physical disks.
|
||||
.PP
|
||||
The first report generated by the
|
||||
.B iostat
|
||||
command provides statistics
|
||||
concerning the time since the system was booted, unless the
|
||||
.B -y
|
||||
option is used (in this case, this first report is omitted).
|
||||
Each subsequent report
|
||||
covers the time since the previous report. All statistics are reported
|
||||
each time the
|
||||
.B iostat
|
||||
command is run. The report consists of a
|
||||
CPU header row followed by a row of
|
||||
CPU statistics. On
|
||||
multiprocessor systems, CPU statistics are calculated system-wide
|
||||
as averages among all processors. A device header row is displayed
|
||||
followed by a line of statistics for each device that is configured.
|
||||
.PP
|
||||
The
|
||||
.I interval
|
||||
parameter specifies the amount of time in seconds between
|
||||
each report. The
|
||||
.IR "count " "parameter can be specified in conjunction with the " "interval"
|
||||
.RI "parameter. If the " "count " "parameter is specified, the value of " "count"
|
||||
.RI "determines the number of reports generated at " "interval " "seconds apart. If the"
|
||||
.IR "interval " "parameter is specified without the " "count " "parameter, the"
|
||||
.B iostat
|
||||
command generates reports continuously.
|
||||
|
||||
.SH REPORTS
|
||||
The
|
||||
.B iostat
|
||||
command generates two types of reports, the CPU
|
||||
Utilization report and the Device Utilization report.
|
||||
|
||||
.IP "CPU Utilization Report"
|
||||
The first report generated by the
|
||||
.B iostat
|
||||
command is the CPU Utilization Report. For multiprocessor systems, the CPU values are
|
||||
global averages among all processors.
|
||||
The report has the following format:
|
||||
.RS
|
||||
.IP %user
|
||||
Show the percentage of CPU utilization that occurred while
|
||||
executing at the user level (application).
|
||||
.IP %nice
|
||||
Show the percentage of CPU utilization that occurred while
|
||||
executing at the user level with nice priority.
|
||||
.IP %system
|
||||
Show the percentage of CPU utilization that occurred while
|
||||
executing at the system level (kernel).
|
||||
.IP %iowait
|
||||
Show the percentage of time that the CPU or CPUs were idle during which
|
||||
the system had an outstanding disk I/O request.
|
||||
.IP %steal
|
||||
Show the percentage of time spent in involuntary wait by the virtual CPU
|
||||
or CPUs while the hypervisor was servicing another virtual processor.
|
||||
.IP %idle
|
||||
Show the percentage of time that the CPU or CPUs were idle and the system
|
||||
did not have an outstanding disk I/O request.
|
||||
.RE
|
||||
.PP
|
||||
.IP "Device Utilization Report"
|
||||
The second report generated by the
|
||||
.B iostat
|
||||
command is the Device Utilization Report.
|
||||
The device report provides statistics on a per physical device
|
||||
or partition basis. Block devices and partitions for which statistics are
|
||||
to be displayed may be entered on the command line.
|
||||
If no device nor partition is entered, then statistics are displayed
|
||||
for every device used by the system, and
|
||||
providing that the kernel maintains statistics for it.
|
||||
If the
|
||||
.B ALL
|
||||
keyword is given on the command line, then statistics are
|
||||
displayed for every device defined by the system, including those
|
||||
that have never been used.
|
||||
Transfer rates are shown in 1K blocks by default, unless the environment
|
||||
variable
|
||||
.B POSIXLY_CORRECT
|
||||
is set, in which case 512-byte blocks are used.
|
||||
The report may show the following fields, depending on the flags used (e.g.
|
||||
.BR "-x" ", " "-s " "and " "-k " "or " "-m" "):"
|
||||
.RS
|
||||
.IP Device:
|
||||
This column gives the device (or partition) name as listed in the
|
||||
.IR "/dev " "directory."
|
||||
.IP tps
|
||||
Indicate the number of transfers per second that were issued
|
||||
to the device. A transfer is an I/O request to the
|
||||
device. Multiple logical requests can be combined into a single I/O
|
||||
request to the device. A transfer is of indeterminate size.
|
||||
.IP "Blk_read/s (kB_read/s, MB_read/s)"
|
||||
Indicate the amount of data read from the device expressed in a number of
|
||||
blocks (kilobytes, megabytes) per second. Blocks are equivalent to sectors
|
||||
and therefore have a size of 512 bytes.
|
||||
.IP "Blk_wrtn/s (kB_wrtn/s, MB_wrtn/s)"
|
||||
Indicate the amount of data written to the device expressed in a number of
|
||||
blocks (kilobytes, megabytes) per second.
|
||||
.IP "Blk_dscd/s (kB_dscd/s, MB_dscd/s)"
|
||||
Indicate the amount of data discarded for the device expressed in a number of
|
||||
blocks (kilobytes, megabytes) per second.
|
||||
.IP "Blk_w+d/s (kB_w+d/s, MB_w+d/s)"
|
||||
Indicate the amount of data written to or discarded for the device expressed
|
||||
in a number of blocks (kilobytes, megabytes) per second.
|
||||
.IP "Blk_read (kB_read, MB_read)"
|
||||
The total number of blocks (kilobytes, megabytes) read.
|
||||
.IP "Blk_wrtn (kB_wrtn, MB_wrtn)"
|
||||
The total number of blocks (kilobytes, megabytes) written.
|
||||
.IP "Blk_dscd (kB_dscd, MB_dscd)"
|
||||
The total number of blocks (kilobytes, megabytes) discarded.
|
||||
.IP "Blk_w+d (kB_w+d, MB_w+d)"
|
||||
The total number of blocks (kilobytes, megabytes) written or discarded.
|
||||
.IP r/s
|
||||
The number (after merges) of read requests completed per second for the device.
|
||||
.IP w/s
|
||||
The number (after merges) of write requests completed per second for the device.
|
||||
.IP d/s
|
||||
The number (after merges) of discard requests completed per second for the device.
|
||||
.IP f/s
|
||||
The number (after merges) of flush requests completed per second for the device.
|
||||
This counts flush requests executed by disks. Flush requests are not tracked for partitions.
|
||||
Before being merged, flush operations are counted as writes.
|
||||
.IP "sec/s (kB/s, MB/s)"
|
||||
The number of sectors (kilobytes, megabytes) read from, written to or
|
||||
discarded for the device per second.
|
||||
.IP "rsec/s (rkB/s, rMB/s)"
|
||||
The number of sectors (kilobytes, megabytes) read from the device per second.
|
||||
.IP "wsec/s (wkB/s, wMB/s)"
|
||||
The number of sectors (kilobytes, megabytes) written to the device per second.
|
||||
.IP "dsec/s (dkB/s, dMB/s)"
|
||||
The number of sectors (kilobytes, megabytes) discarded for the device per second.
|
||||
.IP rqm/s
|
||||
The number of I/O requests merged per second that were queued to the device.
|
||||
.IP rrqm/s
|
||||
The number of read requests merged per second that were queued to the device.
|
||||
.IP wrqm/s
|
||||
The number of write requests merged per second that were queued to the device.
|
||||
.IP drqm/s
|
||||
The number of discard requests merged per second that were queued to the device.
|
||||
.IP %rrqm
|
||||
The percentage of read requests merged together before being sent to the device.
|
||||
.IP %wrqm
|
||||
The percentage of write requests merged together before being sent to the device.
|
||||
.IP %drqm
|
||||
The percentage of discard requests merged together before being sent to the device.
|
||||
.IP areq-sz
|
||||
The average size (in kilobytes) of the I/O requests that were issued to the device.
|
||||
.br
|
||||
Note: In previous versions, this field was known as avgrq-sz and was expressed in sectors.
|
||||
.IP rareq-sz
|
||||
The average size (in kilobytes) of the read requests that were issued to the device.
|
||||
.IP wareq-sz
|
||||
The average size (in kilobytes) of the write requests that were issued to the device.
|
||||
.IP dareq-sz
|
||||
The average size (in kilobytes) of the discard requests that were issued to the device.
|
||||
.IP await
|
||||
The average time (in milliseconds) for I/O requests issued to the device
|
||||
to be served. This includes the time spent by the requests in queue and
|
||||
the time spent servicing them.
|
||||
.IP r_await
|
||||
The average time (in milliseconds) for read requests issued to the device
|
||||
to be served. This includes the time spent by the requests in queue and
|
||||
the time spent servicing them.
|
||||
.IP w_await
|
||||
The average time (in milliseconds) for write requests issued to the device
|
||||
to be served. This includes the time spent by the requests in queue and
|
||||
the time spent servicing them.
|
||||
.IP d_await
|
||||
The average time (in milliseconds) for discard requests issued to the device
|
||||
to be served. This includes the time spent by the requests in queue and
|
||||
the time spent servicing them.
|
||||
.IP f_await
|
||||
The average time (in milliseconds) for flush requests issued to the device
|
||||
to be served.
|
||||
The block layer combines flush requests and executes at most one at a time.
|
||||
Thus flush operations could be twice as long: Wait for current flush request,
|
||||
then execute it, then wait for the next one.
|
||||
.IP aqu-sz
|
||||
The average queue length of the requests that were issued to the device.
|
||||
.br
|
||||
Note: In previous versions, this field was known as avgqu-sz.
|
||||
.IP %util
|
||||
Percentage of elapsed time during which I/O requests were issued to the device
|
||||
(bandwidth utilization for the device). Device saturation occurs when this
|
||||
value is close to 100% for devices serving requests serially.
|
||||
But for devices serving requests in parallel, such as RAID arrays and
|
||||
modern SSDs, this number does not reflect their performance limits.
|
||||
.RE
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -c
|
||||
Display the CPU utilization report.
|
||||
.TP
|
||||
.B --compact
|
||||
Don't break the Device Utilization Report into sub-reports so that all the metrics get displayed
|
||||
on a single line.
|
||||
.TP
|
||||
.B -d
|
||||
Display the device utilization report.
|
||||
.if 'yes'@WITH_DEBUG@' \{
|
||||
.TP
|
||||
.B --debuginfo
|
||||
Print debug output to stderr.
|
||||
.\}
|
||||
.TP
|
||||
.B --dec={ 0 | 1 | 2 }
|
||||
Specify the number of decimal places to use (0 to 2, default value is 2).
|
||||
.TP
|
||||
.BI "-f " "directory"
|
||||
.RE
|
||||
.BI "+f " "directory"
|
||||
.RS
|
||||
Specify an alternative directory for
|
||||
.B iostat
|
||||
to read devices statistics. Option
|
||||
.BR "-f " "tells " "iostat " "to use only the files located in the alternative directory, "
|
||||
whereas option
|
||||
.B +f
|
||||
tells it to use both the standard kernel files and the files located in the alternative directory
|
||||
to read device statistics.
|
||||
|
||||
.IR "directory" " is a directory containing files with statistics for devices managed in userspace."
|
||||
It may contain:
|
||||
|
||||
- a "diskstats" file whose format is compliant with that located in "/proc",
|
||||
.br
|
||||
- statistics for individual devices contained in files whose format is compliant with that of files located in
|
||||
"/sys".
|
||||
|
||||
In particular, the following files located in
|
||||
.I "directory"
|
||||
.RB "may be used by " "iostat" ":"
|
||||
|
||||
.IR "directory" "/block/" "device" "/stat"
|
||||
.br
|
||||
.IR "directory" "/block/" "device" "/" "partition" "/stat"
|
||||
|
||||
.IR "partition" " files must have an entry in " "directory" "/dev/block/ directory, e.g.:"
|
||||
|
||||
.IR "directory" "/dev/block/" "major" ":" "minor" " --> ../../block/" "device" "/" "partition"
|
||||
.RE
|
||||
.TP
|
||||
.BI "-g " "group_name " "{ " "device " "[...] | ALL }"
|
||||
Display statistics for a group of devices.
|
||||
The
|
||||
.B iostat
|
||||
command reports statistics for each individual device in the list
|
||||
then a line of global statistics for the group displayed as
|
||||
.I group_name
|
||||
and made up of all the devices in the list. The
|
||||
.B ALL
|
||||
keyword means that all the block devices defined by the system shall be
|
||||
included in the group.
|
||||
.TP
|
||||
.B -H
|
||||
This option must be used with option
|
||||
.B -g
|
||||
and indicates that only global
|
||||
statistics for the group are to be displayed, and not statistics for
|
||||
individual devices in the group.
|
||||
.TP
|
||||
.B -h
|
||||
This option is equivalent to specifying
|
||||
.BR "--human --pretty" "."
|
||||
.TP
|
||||
.B --human
|
||||
Print sizes in human readable format (e.g. 1.0k, 1.2M, etc.)
|
||||
The units displayed with this option supersede any other default units (e.g.
|
||||
kilobytes, sectors...) associated with the metrics.
|
||||
.TP
|
||||
.BI "-j { ID | LABEL | PATH | UUID | ... } [ " "device " "[...] | ALL ]"
|
||||
Display persistent device names. Keywords
|
||||
.BR "ID" ", " "LABEL" ", "
|
||||
etc. specify the type of the persistent name. These keywords are not limited,
|
||||
only prerequisite is that directory with required persistent names is present in
|
||||
.IR "/dev/disk" "."
|
||||
Optionally, multiple devices can be specified in the chosen persistent name type.
|
||||
Because persistent device names are usually long, option
|
||||
.B --pretty
|
||||
is implicitly set with this option.
|
||||
.TP
|
||||
.B -k
|
||||
Display statistics in kilobytes per second.
|
||||
.TP
|
||||
.B -m
|
||||
Display statistics in megabytes per second.
|
||||
.TP
|
||||
.B -N
|
||||
Display the registered device mapper names for any device mapper devices.
|
||||
Useful for viewing LVM2 statistics.
|
||||
.TP
|
||||
.B -o JSON
|
||||
Display the statistics in JSON (JavaScript Object Notation) format.
|
||||
JSON output field order is undefined, and new fields may be added
|
||||
in the future.
|
||||
.TP
|
||||
.BI "-p [ { " "device" "[,...] | ALL } ]"
|
||||
Display statistics for
|
||||
block devices and all their partitions that are used by the system.
|
||||
If a device name is entered on the command line, then statistics for it
|
||||
and all its partitions are displayed. Last, the
|
||||
.B ALL
|
||||
keyword indicates that statistics have to be displayed for all the block
|
||||
devices and partitions defined by the system, including those that have
|
||||
never been used. If option
|
||||
.B -j
|
||||
is defined before this option, devices entered on the command line can be
|
||||
specified with the chosen persistent name type.
|
||||
.TP
|
||||
.B --pretty
|
||||
Make the Device Utilization Report easier to read by a human.
|
||||
The device name will be printed on the right side. The report may also be broken
|
||||
into sub-reports if there are many metrics to display (use
|
||||
.B --compact
|
||||
option to prevent this).
|
||||
.TP
|
||||
.B -s
|
||||
Display a short (narrow) version of the report that should fit in 80
|
||||
characters wide screens.
|
||||
.TP
|
||||
.B -t
|
||||
Print the time for each report displayed. The timestamp format may depend
|
||||
on the value of the
|
||||
.BR "S_TIME_FORMAT " "environment variable (see below)."
|
||||
.TP
|
||||
.B -V
|
||||
Print version number then exit.
|
||||
.TP
|
||||
.B -x
|
||||
Display extended statistics.
|
||||
.TP
|
||||
.B -y
|
||||
Omit first report with statistics since system boot, if displaying
|
||||
multiple records at given interval.
|
||||
.TP
|
||||
.B -z
|
||||
Tell
|
||||
.B iostat
|
||||
to omit output for any devices for which there was no activity
|
||||
during the sample period.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
The
|
||||
.B iostat
|
||||
command takes into account the following environment variables:
|
||||
.TP
|
||||
.B POSIXLY_CORRECT
|
||||
When this variable is set, transfer rates are shown in 512-byte blocks instead
|
||||
of the default 1K blocks.
|
||||
.TP
|
||||
.B S_COLORS
|
||||
By default statistics are displayed in color when the output is connected to a terminal.
|
||||
Use this variable to change the settings. Possible values for this variable are
|
||||
.IR "never" ", " "always " "or " "auto"
|
||||
(the latter is equivalent to the default settings).
|
||||
.br
|
||||
Please note that the color (being red, yellow, or some other color) used to display a value
|
||||
is not indicative of any kind of issue simply because of the color. It only indicates different
|
||||
ranges of values.
|
||||
.TP
|
||||
.B S_COLORS_SGR
|
||||
Specify the colors and other attributes used to display statistics on the terminal.
|
||||
Its value is a colon-separated list of capabilities that defaults to
|
||||
.BR "H=31;1:I=32;22:M=35;1:N=34;1:Z=34;22" "."
|
||||
Supported capabilities are:
|
||||
.RS
|
||||
.TP
|
||||
.B H=
|
||||
SGR (Select Graphic Rendition) substring for percentage values greater than or equal to 75%.
|
||||
.TP
|
||||
.B I=
|
||||
SGR substring for device names.
|
||||
.TP
|
||||
.B M=
|
||||
SGR substring for percentage values in the range from 50% to 75%.
|
||||
.TP
|
||||
.B N=
|
||||
SGR substring for non-zero statistics values.
|
||||
.TP
|
||||
.B Z=
|
||||
SGR substring for zero values.
|
||||
.RE
|
||||
.TP
|
||||
.B S_TIME_FORMAT
|
||||
If this variable exists and its value is
|
||||
.B ISO
|
||||
then the current locale will be ignored when printing the date in the report
|
||||
header. The
|
||||
.B iostat
|
||||
command will use the ISO 8601 format (YYYY-MM-DD) instead.
|
||||
The timestamp displayed with option
|
||||
.B -t
|
||||
will also be compliant with ISO 8601 format.
|
||||
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B iostat
|
||||
Display a single history since boot report for all CPU and Devices.
|
||||
.TP
|
||||
.B iostat -d 2
|
||||
Display a continuous device report at two second intervals.
|
||||
.TP
|
||||
.B iostat -d 2 6
|
||||
Display six reports at two second intervals for all devices.
|
||||
.TP
|
||||
.B iostat -x sda sdb 2 6
|
||||
Display six reports of extended statistics at two second intervals for devices
|
||||
sda and sdb.
|
||||
.TP
|
||||
.B iostat -p sda 2 6
|
||||
Display six reports at two second intervals for device sda and all its
|
||||
partitions (sda1, etc.)
|
||||
|
||||
.SH BUGS
|
||||
.IR "/proc " "filesystem must be mounted for"
|
||||
.BR "iostat " "to work."
|
||||
.PP
|
||||
Kernels older than 2.6.x are no longer supported.
|
||||
.PP
|
||||
.RB "Although " "iostat"
|
||||
speaks of kilobytes (kB), megabytes (MB)..., it actually uses kibibytes (kiB), mebibytes (MiB)...
|
||||
A kibibyte is equal to 1024 bytes, and a mebibyte is equal to 1024 kibibytes.
|
||||
|
||||
.SH FILES
|
||||
.IR "/proc/stat " "contains system statistics."
|
||||
.br
|
||||
.IR "/proc/uptime " "contains system uptime."
|
||||
.br
|
||||
.IR "/proc/diskstats " "contains disks statistics."
|
||||
.br
|
||||
.IR "/sys " "contains statistics for block devices."
|
||||
.br
|
||||
.IR "/proc/self/mountstats " "contains statistics for network filesystems."
|
||||
.br
|
||||
.IR "/dev/disk " "contains persistent device names."
|
||||
|
||||
.SH AUTHOR
|
||||
Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR "sar" "(1), " "pidstat" "(1), " "mpstat" "(1), " "vmstat" "(8), " "tapestat" "(1), " "nfsiostat" "(1),"
|
||||
.BR "cifsiostat" "(1)"
|
||||
.PP
|
||||
.I https://github.com/sysstat/sysstat
|
||||
.br
|
||||
.I http://pagesperso-orange.fr/sebastien.godard/
|
|
@ -0,0 +1,241 @@
|
|||
.\" mpstat manual page - (C) 2000-2020 Sebastien Godard (sysstat <at> orange.fr)
|
||||
.TH MPSTAT 1 "AUGUST 2020" Linux "Linux User's Manual" -*- nroff -*-
|
||||
.SH NAME
|
||||
mpstat \- Report processors related statistics.
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B mpstat [ -A ] [ --dec={ 0 | 1 | 2 } ] [ -n ] [ -u ] [ -T ] [ -V ] [ -I {
|
||||
.IB "keyword" "[,...] | ALL } ] [ -N { " "node_list " "| ALL } ] [ -o JSON ] [ -P {"
|
||||
.IB "cpu_list " "| ALL } ] [ " "interval " "[ " "count " "] ]"
|
||||
|
||||
.SH DESCRIPTION
|
||||
.RB "The " "mpstat"
|
||||
command writes to standard output activities for each available processor,
|
||||
processor 0 being the first one.
|
||||
Global average activities among all processors are also reported.
|
||||
.RB "The " "mpstat"
|
||||
command can be used on both SMP and UP machines, but in the latter, only global
|
||||
average activities will be printed. If no activity has been selected, then the
|
||||
default report is the CPU utilization report.
|
||||
.PP
|
||||
.RI "The " "interval"
|
||||
parameter specifies the amount of time in seconds between each report.
|
||||
A value of 0 (or no parameters at all) indicates that processors statistics are
|
||||
to be reported for the time since system startup (boot). The
|
||||
.IR "count " "parameter can be specified in conjunction with the " "interval"
|
||||
parameter if this one is not set to zero. The value of
|
||||
.I count
|
||||
determines the number of reports generated at
|
||||
.IR "interval " "seconds apart. If the " "interval"
|
||||
parameter is specified without the
|
||||
.IR "count " "parameter, the"
|
||||
.B mpstat
|
||||
command generates reports continuously.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -A
|
||||
This option is equivalent to specifying
|
||||
.BR "-n -u -I ALL" "."
|
||||
This option also implies specifying
|
||||
.B "-N ALL -P ALL"
|
||||
unless these options are explicitly set on the command line.
|
||||
.TP
|
||||
.B --dec={ 0 | 1 | 2 }
|
||||
Specify the number of decimal places to use (0 to 2, default value is 2).
|
||||
.TP
|
||||
.BI "-I { " "keyword" "[,...] | ALL }"
|
||||
Report interrupts statistics.
|
||||
.RI "Possible " "keywords " "are"
|
||||
.BR "CPU" ", " "SCPU" ", and " "SUM" "."
|
||||
.PP
|
||||
.RS
|
||||
.RB "With the " "CPU"
|
||||
keyword, the number of each individual interrupt received per
|
||||
second by the CPU or CPUs is displayed. Interrupts are those listed in
|
||||
.IR "/proc/interrupts " "file."
|
||||
.PP
|
||||
.RB "With the " "SCPU"
|
||||
keyword, the number of each individual software interrupt received per
|
||||
second by the CPU or CPUs is displayed. This option works only
|
||||
with kernels 2.6.31 and later. Software interrupts are those listed in
|
||||
.IR "/proc/softirqs " "file."
|
||||
.PP
|
||||
.RB "With the " "SUM " "keyword, the " "mpstat"
|
||||
command reports the total number of interrupts per processor.
|
||||
The following values are displayed:
|
||||
|
||||
.IP CPU
|
||||
Processor number. The keyword
|
||||
.B all
|
||||
indicates that statistics are calculated as averages among all processors.
|
||||
|
||||
.IP intr/s
|
||||
Show the total number of interrupts received per second by
|
||||
the CPU or CPUs.
|
||||
.RE
|
||||
.IP
|
||||
.RB "The " "ALL"
|
||||
keyword is equivalent to specifying all the keywords above and
|
||||
therefore all the interrupts statistics are displayed.
|
||||
.TP
|
||||
.BI "-N { " "node_list " "| ALL }"
|
||||
Indicate the NUMA nodes for which statistics are to be reported.
|
||||
.I node_list
|
||||
is a list of comma-separated values or range of values (e.g.,
|
||||
.BR "0,2,4-7,12-" "). Note that node " "all"
|
||||
is the global average among all nodes. The
|
||||
.B ALL
|
||||
keyword indicates that statistics are to be reported for all nodes.
|
||||
.TP
|
||||
.B -n
|
||||
Report summary CPU statistics based on NUMA node placement. The following
|
||||
values are displayed:
|
||||
.RS
|
||||
.IP NODE
|
||||
Logical NUMA node number. The keyword
|
||||
.B all
|
||||
indicates that statistics are calculated as averages among all nodes.
|
||||
.RE
|
||||
.IP
|
||||
All the other fields are the same as those displayed with option
|
||||
.BR "-u " "(see below)."
|
||||
.TP
|
||||
.B -o JSON
|
||||
Display the statistics in JSON (JavaScript Object Notation) format.
|
||||
JSON output field order is undefined, and new fields may be added
|
||||
in the future.
|
||||
.TP
|
||||
.BI "-P { " "cpu_list " "| ALL }"
|
||||
Indicate the processors for which statistics are to be reported.
|
||||
.I cpu_list
|
||||
is a list of comma-separated values or range of values (e.g.,
|
||||
.BR "0,2,4-7,12-" ")."
|
||||
Note that processor 0 is the first processor, and processor
|
||||
.B all
|
||||
is the global average among all processors.
|
||||
.RB "The " "ALL"
|
||||
keyword indicates that statistics are to be reported for all processors.
|
||||
Offline processors are not displayed.
|
||||
.TP
|
||||
.B -T
|
||||
Display topology elements in the CPU report (see option
|
||||
.B -u
|
||||
below). The following elements are displayed:
|
||||
.RS
|
||||
.IP CORE
|
||||
Logical core number.
|
||||
.IP SOCK
|
||||
Logical socket number.
|
||||
.IP NODE
|
||||
Logical NUMA node number.
|
||||
.RE
|
||||
.TP
|
||||
.B -u
|
||||
Report CPU utilization. The following values are displayed:
|
||||
.RS
|
||||
.IP CPU
|
||||
Processor number. The keyword
|
||||
.I all
|
||||
indicates that statistics are calculated as averages among all processors.
|
||||
.IP %usr
|
||||
Show the percentage of CPU utilization that occurred while
|
||||
executing at the user level (application).
|
||||
.IP %nice
|
||||
Show the percentage of CPU utilization that occurred while
|
||||
executing at the user level with nice priority.
|
||||
.IP %sys
|
||||
Show the percentage of CPU utilization that occurred while
|
||||
executing at the system level (kernel). Note that this does not
|
||||
include time spent servicing hardware and software interrupts.
|
||||
.IP %iowait
|
||||
Show the percentage of time that the CPU or CPUs were idle during which
|
||||
the system had an outstanding disk I/O request.
|
||||
.IP %irq
|
||||
Show the percentage of time spent by the CPU or CPUs to service hardware interrupts.
|
||||
.IP %soft
|
||||
Show the percentage of time spent by the CPU or CPUs to service software interrupts.
|
||||
.IP %steal
|
||||
Show the percentage of time spent in involuntary wait by the virtual CPU
|
||||
or CPUs while the hypervisor was servicing another virtual processor.
|
||||
.IP %guest
|
||||
Show the percentage of time spent by the CPU or CPUs to run a virtual processor.
|
||||
.IP %gnice
|
||||
Show the percentage of time spent by the CPU or CPUs to run a niced guest.
|
||||
.IP %idle
|
||||
Show the percentage of time that the CPU or CPUs were idle and the system
|
||||
did not have an outstanding disk I/O request.
|
||||
.RE
|
||||
.TP
|
||||
.B -V
|
||||
Print version number then exit.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
.RB "The " "mpstat"
|
||||
command takes into account the following environment variable:
|
||||
.TP
|
||||
.B S_COLORS
|
||||
By default statistics are displayed in color when the output is connected to a terminal.
|
||||
Use this variable to change the settings. Possible values for this variable are
|
||||
.IR "never" ", " "always " "or " "auto"
|
||||
(the latter is equivalent to the default settings).
|
||||
.br
|
||||
Please note that the color (being red, yellow, or some other color) used to display a value
|
||||
is not indicative of any kind of issue simply because of the color. It only indicates different
|
||||
ranges of values.
|
||||
.TP
|
||||
.B S_COLORS_SGR
|
||||
Specify the colors and other attributes used to display statistics on the terminal.
|
||||
Its value is a colon-separated list of capabilities that defaults to
|
||||
.BR "H=31;1:I=32;22:M=35;1:N=34;1:Z=34;22" "."
|
||||
Supported capabilities are:
|
||||
.RS
|
||||
.TP
|
||||
.B H=
|
||||
SGR (Select Graphic Rendition) substring for percentage values greater than or equal to 75%.
|
||||
.TP
|
||||
.B I=
|
||||
SGR substring for CPU number.
|
||||
.TP
|
||||
.B M=
|
||||
SGR substring for percentage values in the range from 50% to 75%.
|
||||
.TP
|
||||
.B N=
|
||||
SGR substring for non-zero statistics values.
|
||||
.TP
|
||||
.B Z=
|
||||
SGR substring for zero values.
|
||||
.RE
|
||||
.TP
|
||||
.B S_TIME_FORMAT
|
||||
If this variable exists and its value is
|
||||
.BR ISO
|
||||
then the current locale will be ignored when printing the date in the report header.
|
||||
.RB "The " "mpstat"
|
||||
command will use the ISO 8601 format (YYYY-MM-DD) instead.
|
||||
The timestamp will also be compliant with ISO 8601 format.
|
||||
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B mpstat 2 5
|
||||
Display five reports of global statistics among all processors at two second intervals.
|
||||
.TP
|
||||
.B mpstat -P ALL 2 5
|
||||
Display five reports of statistics for all processors at two second intervals.
|
||||
|
||||
.SH BUGS
|
||||
.IR "/proc " "filesystem must be mounted for the"
|
||||
.BR "mpstat " "command to work."
|
||||
|
||||
.SH FILES
|
||||
.IR "/proc " "contains various files with system statistics."
|
||||
|
||||
.SH AUTHOR
|
||||
Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR "sar" "(1), " "pidstat" "(1), " "iostat" "(1), " "vmstat" "(8)"
|
||||
.PP
|
||||
.I https://github.com/sysstat/sysstat
|
||||
.br
|
||||
.I http://pagesperso-orange.fr/sebastien.godard/
|
|
@ -0,0 +1,450 @@
|
|||
.\" pidstat manual page - (C) 2007-2020 Sebastien Godard (sysstat <at> orange.fr)
|
||||
.TH PIDSTAT 1 "JULY 2020" Linux "Linux User's Manual" -*- nroff -*-
|
||||
.SH NAME
|
||||
pidstat \- Report statistics for Linux tasks.
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B pidstat [ -d ] [ -H ] [ -h ] [ -I ] [ -l ] [ -R ] [ -r ] [ -s ] [ -t ] [ -U [
|
||||
.IB "username " "] ] [ -u ] [ -V ] [ -v ] [ -w ] [ -C " "comm " "] [ -G " "process_name"
|
||||
.BI "] [ --dec={ 0 | 1 | 2 } ] [ --human ] [ -p { " "pid" "[,...]"
|
||||
.B | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ] [
|
||||
.IB "interval " "[ " "count " "] ] [ -e " "program"
|
||||
.IB "args " "]"
|
||||
|
||||
.SH DESCRIPTION
|
||||
.RB "The " "pidstat"
|
||||
command is used for monitoring individual tasks currently being managed
|
||||
by the Linux kernel.
|
||||
It writes to standard output activities for every task selected with option
|
||||
.B -p
|
||||
or for every task managed by the Linux kernel if option
|
||||
.B -p ALL
|
||||
has been used. Not selecting any tasks is equivalent to specifying
|
||||
.B -p ALL
|
||||
but only active tasks (tasks with non-zero statistics values)
|
||||
will appear in the report.
|
||||
.PP
|
||||
.RB "The " "pidstat"
|
||||
command can also be used for monitoring the child processes of selected tasks.
|
||||
Read about option
|
||||
.BR "-T " "below."
|
||||
.PP
|
||||
.RI "The " "interval"
|
||||
parameter specifies the amount of time in seconds between each report.
|
||||
A value of 0 (or no parameters at all) indicates that tasks statistics are
|
||||
to be reported for the time since system startup (boot). The
|
||||
.IR "count " "parameter can be specified in conjunction with the"
|
||||
.IR "interval " "parameter if this one is not set to zero. The value of"
|
||||
.IR "count " "determines the number of reports generated at"
|
||||
.IR "interval " "seconds apart. If the " "interval " "parameter is specified without the " "count"
|
||||
parameter, the
|
||||
.B pidstat
|
||||
command generates reports continuously.
|
||||
.PP
|
||||
You can select information about specific task activities using flags.
|
||||
Not specifying any flags selects only CPU activity.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI "-C " "comm"
|
||||
Display only tasks whose command name includes the string
|
||||
.IR "comm" ". This string can be a regular expression."
|
||||
.TP
|
||||
.B -d
|
||||
Report I/O statistics (kernels 2.6.20 and later only).
|
||||
The following values may be displayed:
|
||||
.RS
|
||||
.IP UID
|
||||
The real user identification number of the task being monitored.
|
||||
.IP USER
|
||||
The name of the real user owning the task being monitored.
|
||||
.IP PID
|
||||
The identification number of the task being monitored.
|
||||
.IP kB_rd/s
|
||||
Number of kilobytes the task has caused to be read from disk per second.
|
||||
.IP kB_wr/s
|
||||
Number of kilobytes the task has caused, or shall cause to be
|
||||
written to disk per second.
|
||||
.IP kB_ccwr/s
|
||||
Number of kilobytes whose writing to disk has been cancelled by
|
||||
the task. This may occur when the task truncates some
|
||||
dirty pagecache. In this case, some IO which another task has
|
||||
been accounted for will not be happening.
|
||||
.IP iodelay
|
||||
Block I/O delay of the task being monitored,
|
||||
measured in clock ticks. This metric includes the delays spent
|
||||
waiting for sync block I/O completion and for swapin block I/O
|
||||
completion.
|
||||
.IP Command
|
||||
The command name of the task.
|
||||
.RE
|
||||
.TP
|
||||
.B --dec={ 0 | 1 | 2 }
|
||||
Specify the number of decimal places to use (0 to 2, default value is 2).
|
||||
.TP
|
||||
.BI "-e " "program args"
|
||||
Execute
|
||||
.I program
|
||||
with given arguments
|
||||
.I args
|
||||
and monitor it with
|
||||
.BR "pidstat" "."
|
||||
.BR "pidstat " "stops when"
|
||||
.IR "program " "terminates."
|
||||
.TP
|
||||
.BI "-G " "process_name"
|
||||
Display only processes whose command name includes the string
|
||||
.IR "process_name" "."
|
||||
This string can be a regular expression. If option
|
||||
.BR "-t " "is used together with option " "-G"
|
||||
then the threads belonging to that process are also displayed
|
||||
(even if their command name doesn't include the string
|
||||
.IR "process_name" ")."
|
||||
.TP
|
||||
.B -H
|
||||
Display timestamp in seconds since the epoch.
|
||||
.TP
|
||||
.B -h
|
||||
Display all activities horizontally on a single line, with no
|
||||
average statistics at the end of the report. This is
|
||||
intended to make it easier to be parsed by other programs.
|
||||
.TP
|
||||
.B --human
|
||||
Print sizes in human readable format (e.g. 1.0k, 1.2M, etc.)
|
||||
The units displayed with this option supersede any other default units (e.g.
|
||||
kilobytes, sectors...) associated with the metrics.
|
||||
.TP
|
||||
.B -I
|
||||
In an SMP environment, indicate that tasks CPU usage
|
||||
.RB "(as displayed by option " "-u" ")"
|
||||
should be divided by the total number of processors.
|
||||
.TP
|
||||
.B -l
|
||||
Display the process command name and all its arguments.
|
||||
.TP
|
||||
.BI "-p { " "pid" "[,...] | SELF | ALL }"
|
||||
Select tasks (processes) for which statistics are to be reported.
|
||||
.I pid
|
||||
is the process identification number. The
|
||||
.B SELF
|
||||
keyword indicates that statistics are to be reported for the
|
||||
.BR "pidstat " "process itself, whereas the " "ALL"
|
||||
keyword indicates that statistics are to be reported for all the
|
||||
tasks managed by the system.
|
||||
.TP
|
||||
.B -R
|
||||
Report realtime priority and scheduling policy information.
|
||||
The following values may be displayed:
|
||||
.RS
|
||||
.IP UID
|
||||
The real user identification number of the task being monitored.
|
||||
.IP USER
|
||||
The name of the real user owning the task being monitored.
|
||||
.IP PID
|
||||
The identification number of the task being monitored.
|
||||
.IP prio
|
||||
The realtime priority of the task being monitored.
|
||||
.IP policy
|
||||
The scheduling policy of the task being monitored.
|
||||
.IP Command
|
||||
The command name of the task.
|
||||
.RE
|
||||
.TP
|
||||
.B -r
|
||||
Report page faults and memory utilization.
|
||||
|
||||
When reporting statistics for individual tasks,
|
||||
the following values may be displayed:
|
||||
.RS
|
||||
.IP UID
|
||||
The real user identification number of the task being monitored.
|
||||
.IP USER
|
||||
The name of the real user owning the task being monitored.
|
||||
.IP PID
|
||||
The identification number of the task being monitored.
|
||||
.IP minflt/s
|
||||
Total number of minor faults the task has made per second, those
|
||||
which have not required loading a memory page from disk.
|
||||
.IP majflt/s
|
||||
Total number of major faults the task has made per second, those
|
||||
which have required loading a memory page from disk.
|
||||
.IP VSZ
|
||||
Virtual Size: The virtual memory usage of entire task in kilobytes.
|
||||
.IP RSS
|
||||
Resident Set Size: The non-swapped physical memory
|
||||
used by the task in kilobytes.
|
||||
.IP %MEM
|
||||
The tasks's currently used share of available physical memory.
|
||||
.IP Command
|
||||
The command name of the task.
|
||||
.RE
|
||||
.IP
|
||||
When reporting global statistics for tasks and all their children,
|
||||
the following values may be displayed:
|
||||
.RS
|
||||
.IP UID
|
||||
The real user identification number of the task which is being monitored
|
||||
together with its children.
|
||||
.IP USER
|
||||
The name of the real user owning the task which is being monitored
|
||||
together with its children.
|
||||
.IP PID
|
||||
The identification number of the task which is being monitored
|
||||
together with its children.
|
||||
.IP minflt-nr
|
||||
Total number of minor faults made by the task and all its children,
|
||||
and collected during the interval of time.
|
||||
.IP majflt-nr
|
||||
Total number of major faults made by the task and all its children,
|
||||
and collected during the interval of time.
|
||||
.IP Command
|
||||
The command name of the task which is being monitored
|
||||
together with its children.
|
||||
.RE
|
||||
.TP
|
||||
.B -s
|
||||
Report stack utilization.
|
||||
The following values may be displayed:
|
||||
.RS
|
||||
.IP UID
|
||||
The real user identification number of the task being monitored.
|
||||
.IP USER
|
||||
The name of the real user owning the task being monitored.
|
||||
.IP PID
|
||||
The identification number of the task being monitored.
|
||||
.IP StkSize
|
||||
The amount of memory in kilobytes reserved for the task as stack,
|
||||
but not necessarily used.
|
||||
.IP StkRef
|
||||
The amount of memory in kilobytes used as stack, referenced by the task.
|
||||
.IP Command
|
||||
The command name of the task.
|
||||
.RE
|
||||
.TP
|
||||
.B -T { TASK | CHILD | ALL }
|
||||
This option specifies what has to be monitored by the
|
||||
.BR "pidstat " "command. The " "TASK"
|
||||
keyword indicates that statistics are to be reported for individual tasks
|
||||
(this is the default option) whereas the
|
||||
.B CHILD
|
||||
keyword indicates that statistics are to be globally reported for the
|
||||
selected tasks and all their children. The
|
||||
.B ALL
|
||||
keyword indicates that statistics are to be reported for
|
||||
individual tasks and globally for the selected
|
||||
tasks and their children.
|
||||
|
||||
Note: Global statistics for tasks and all their children are not available
|
||||
for all options of
|
||||
.B pidstat.
|
||||
Also these statistics are not necessarily relevant to current time interval:
|
||||
The statistics of a child process are collected only when it finishes or
|
||||
it is killed.
|
||||
.TP
|
||||
.B -t
|
||||
Also display statistics for threads associated with selected tasks.
|
||||
|
||||
This option adds the following values to the reports:
|
||||
.RS
|
||||
.IP TGID
|
||||
The identification number of the thread group leader.
|
||||
.IP TID
|
||||
The identification number of the thread being monitored.
|
||||
.RE
|
||||
.TP
|
||||
.BI "-U [ " "username " "]"
|
||||
Display the real user name of the tasks being monitored instead of the UID.
|
||||
.RI "If " "username"
|
||||
is specified, then only tasks belonging to the specified user are displayed.
|
||||
.TP
|
||||
.B -u
|
||||
Report CPU utilization.
|
||||
|
||||
When reporting statistics for individual tasks,
|
||||
the following values may be displayed:
|
||||
.RS
|
||||
.IP UID
|
||||
The real user identification number of the task being monitored.
|
||||
.IP USER
|
||||
The name of the real user owning the task being monitored.
|
||||
.IP PID
|
||||
The identification number of the task being monitored.
|
||||
.IP %usr
|
||||
Percentage of CPU used by the task while executing at the user level
|
||||
(application), with or without nice priority. Note that this field
|
||||
does NOT include time spent running a virtual processor.
|
||||
.IP %system
|
||||
Percentage of CPU used by the task while executing at the system level (kernel).
|
||||
.IP %guest
|
||||
Percentage of CPU spent by the task in virtual machine (running a virtual processor).
|
||||
.IP %wait
|
||||
Percentage of CPU spent by the task while waiting to run.
|
||||
.IP %CPU
|
||||
Total percentage of CPU time used by the task. In an SMP environment,
|
||||
the task's CPU usage will be divided by the total number of CPU's if option
|
||||
.B -I
|
||||
has been entered on the command line.
|
||||
.IP CPU
|
||||
Processor number to which the task is attached.
|
||||
.IP Command
|
||||
The command name of the task.
|
||||
.RE
|
||||
.IP
|
||||
When reporting global statistics for tasks and all their children,
|
||||
the following values may be displayed:
|
||||
.RS
|
||||
.IP UID
|
||||
The real user identification number of the task which is being monitored
|
||||
together with its children.
|
||||
.IP USER
|
||||
The name of the real user owning the task which is being monitored
|
||||
together with its children.
|
||||
.IP PID
|
||||
The identification number of the task which is being monitored
|
||||
together with its children.
|
||||
.IP usr-ms
|
||||
Total number of milliseconds spent
|
||||
by the task and all its children while executing at the
|
||||
user level (application), with or without nice priority, and
|
||||
collected during the interval of time. Note that this field does
|
||||
NOT include time spent running a virtual processor.
|
||||
.IP system-ms
|
||||
Total number of milliseconds spent
|
||||
by the task and all its children while executing at the
|
||||
system level (kernel), and collected during the interval of time.
|
||||
.IP guest-ms
|
||||
Total number of milliseconds spent
|
||||
by the task and all its children in virtual machine (running a virtual processor).
|
||||
.IP Command
|
||||
The command name of the task which is being monitored
|
||||
together with its children.
|
||||
.RE
|
||||
.TP
|
||||
.B -V
|
||||
Print version number then exit.
|
||||
.TP
|
||||
.B -v
|
||||
Report values of some kernel tables. The following values may be displayed:
|
||||
.RS
|
||||
.IP UID
|
||||
The real user identification number of the task being monitored.
|
||||
.IP USER
|
||||
The name of the real user owning the task being monitored.
|
||||
.IP PID
|
||||
The identification number of the task being monitored.
|
||||
.IP threads
|
||||
Number of threads associated with current task.
|
||||
.IP fd-nr
|
||||
Number of file descriptors associated with current task.
|
||||
.IP Command
|
||||
The command name of the task.
|
||||
.RE
|
||||
.TP
|
||||
.B -w
|
||||
Report task switching activity (kernels 2.6.23 and later only).
|
||||
The following values may be displayed:
|
||||
.RS
|
||||
.IP UID
|
||||
The real user identification number of the task being monitored.
|
||||
.IP USER
|
||||
The name of the real user owning the task being monitored.
|
||||
.IP PID
|
||||
The identification number of the task being monitored.
|
||||
.IP cswch/s
|
||||
Total number of voluntary context switches the task made per second.
|
||||
A voluntary context switch occurs when a task blocks because it
|
||||
requires a resource that is unavailable.
|
||||
.IP nvcswch/s
|
||||
Total number of non voluntary context switches the task made per second.
|
||||
An involuntary context switch takes place when a task executes
|
||||
for the duration of its time slice and then is forced to relinquish the
|
||||
processor.
|
||||
.IP Command
|
||||
The command name of the task.
|
||||
.RE
|
||||
|
||||
.SH ENVIRONMENT
|
||||
The
|
||||
.B pidstat
|
||||
command takes into account the following environment variables:
|
||||
.TP
|
||||
.B S_COLORS
|
||||
By default statistics are displayed in color when the output is connected to a terminal.
|
||||
Use this variable to change the settings. Possible values for this variable are
|
||||
.IR "never" ", " "always " "or " "auto"
|
||||
(the latter is equivalent to the default settings).
|
||||
.br
|
||||
Please note that the color (being red, yellow, or some other color) used to display a value
|
||||
is not indicative of any kind of issue simply because of the color. It only indicates different
|
||||
ranges of values.
|
||||
.TP
|
||||
.B S_COLORS_SGR
|
||||
Specify the colors and other attributes used to display statistics on the terminal.
|
||||
Its value is a colon-separated list of capabilities that defaults to
|
||||
.BR "H=31;1:I=32;22:M=35;1:N=34;1:Z=34;22" "."
|
||||
Supported capabilities are:
|
||||
.RS
|
||||
.TP
|
||||
.B H=
|
||||
SGR (Select Graphic Rendition) substring for percentage values greater than or equal to 75%.
|
||||
.TP
|
||||
.B I=
|
||||
SGR substring for item values like PID, UID or CPU number.
|
||||
.TP
|
||||
.B M=
|
||||
SGR substring for percentage values in the range from 50% to 75%.
|
||||
.TP
|
||||
.B N=
|
||||
SGR substring for non-zero statistics values and for tasks names.
|
||||
.TP
|
||||
.B Z=
|
||||
SGR substring for zero values and for threads names.
|
||||
.RE
|
||||
.TP
|
||||
.B S_TIME_FORMAT
|
||||
If this variable exists and its value is
|
||||
.BR ISO
|
||||
then the current locale will be ignored when printing the date in the report header. The
|
||||
.B pidstat
|
||||
command will use the ISO 8601 format (YYYY-MM-DD) instead.
|
||||
The timestamp will also be compliant with ISO 8601 format.
|
||||
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B pidstat 2 5
|
||||
Display five reports of CPU statistics for every active task in the system
|
||||
at two second intervals.
|
||||
.TP
|
||||
.B pidstat -r -p 1643 2 5
|
||||
Display five reports of page faults and memory statistics for
|
||||
PID 1643 at two second intervals.
|
||||
.TP
|
||||
.B pidstat -C """fox|bird"" -r -p ALL
|
||||
Display global page faults and memory statistics for all the
|
||||
processes whose command name includes the string "fox" or "bird".
|
||||
.TP
|
||||
.B pidstat -T CHILD -r 2 5
|
||||
Display five reports of page faults statistics at two second intervals
|
||||
for the child processes of all tasks in the system. Only child processes
|
||||
with non-zero statistics values are displayed.
|
||||
|
||||
.SH BUGS
|
||||
.IR "/proc " "filesystem must be mounted for the"
|
||||
.BR "pidstat " "command to work."
|
||||
.PP
|
||||
.RB "Although " "pidstat"
|
||||
speaks of kilobytes (kB), megabytes (MB)..., it actually uses kibibytes (kiB), mebibytes (MiB)...
|
||||
A kibibyte is equal to 1024 bytes, and a mebibyte is equal to 1024 kibibytes.
|
||||
|
||||
.SH FILES
|
||||
.IR "/proc " "contains various files with system statistics."
|
||||
|
||||
.SH AUTHOR
|
||||
Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR "sar" "(1), " "top" "(1), " "ps" "(1), " "mpstat" "(1), " "iostat" "(1), " "vmstat" "(8)"
|
||||
.PP
|
||||
.I https://github.com/sysstat/sysstat
|
||||
.br
|
||||
.I http://pagesperso-orange.fr/sebastien.godard/
|
|
@ -0,0 +1,91 @@
|
|||
.\" sa1 manual page - (C) 1999-2020 Sebastien Godard (sysstat <at> orange.fr)
|
||||
.TH SA1 8 "NOVEMBER 2020" Linux "Linux User's Manual" -*- nroff -*-
|
||||
.SH NAME
|
||||
sa1 \- Collect and store binary data in the system activity daily data file.
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B @SA_LIB_DIR@/sa1 [ --boot | --rotate [ iso ] | --sleep |
|
||||
.I interval count
|
||||
.B ]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.RB "The " "sa1"
|
||||
.RB "command is a shell procedure variant of the " "sadc"
|
||||
command and handles all of the flags and parameters of that command. The
|
||||
.B sa1
|
||||
command collects and stores binary data in the current standard
|
||||
system activity daily data file.
|
||||
.PP
|
||||
The standard system activity daily data file is named
|
||||
.IR "saDD " "unless"
|
||||
.BR "sadc" "'s option " "-D " "is used, in which case its name is"
|
||||
.IR "saYYYYMMDD" ","
|
||||
.RI "where " "YYYY " "stands for the current year, " "MM " "for the current month and " "DD"
|
||||
for the current day. By default it is located in the
|
||||
.I @SA_DIR@
|
||||
directory.
|
||||
.PP
|
||||
.RI "The " "interval " "and " "count"
|
||||
parameters specify that the record should be written
|
||||
.IR "count " "times at " "interval"
|
||||
seconds. If no arguments are given to
|
||||
.B sa1
|
||||
then a single record is written.
|
||||
|
||||
The
|
||||
.B sa1
|
||||
command is designed to be started automatically by the
|
||||
.BR "cron " "command."
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B --boot
|
||||
This option tells
|
||||
.BR "sa1 " "that the " "sadc"
|
||||
command should be called without specifying the
|
||||
.IR "interval " "and " "count"
|
||||
parameters in order to insert a dummy record, marking the time when the counters
|
||||
restart from 0.
|
||||
.TP
|
||||
.B --rotate [ iso ]
|
||||
.RB "Use this option to tell " "sa1 " "to insert a record of statistics to the standard"
|
||||
.IR "saDD" " system activity daily data file of the previous day."
|
||||
This should be done shortly after midnight (on day DD+1) in order to make sure that the
|
||||
data file covers the whole day, including the last interval of time just before midnight.
|
||||
.RB "Adding the " "iso" " keyword tells " "sa1" " to use
|
||||
.IR "saYYYYMMDD" " instead of " "saDD" " as the standard system activity daily data file name."
|
||||
.TP
|
||||
.B --sleep
|
||||
.RB "This option tells " "sa1 " "that the " "sadc"
|
||||
command should insert a comment indicating that the system is entering or leaving
|
||||
sleep mode (i.e. system suspend or hibernation).
|
||||
|
||||
.SH EXAMPLE
|
||||
To collect data (including those from disks) every 10 minutes,
|
||||
place the following entry in your root crontab file:
|
||||
|
||||
.B 0,10,20,30,40,50 * * * * @SA_LIB_DIR@/sa1 1 1 -S DISK
|
||||
|
||||
To rotate current system activity daily data file, ensuring it is complete,
|
||||
place the following entry in your root crontab file:
|
||||
|
||||
.B 0 0 * * * @SA_LIB_DIR@/sa1 --rotate
|
||||
|
||||
.SH FILES
|
||||
.I @SA_DIR@/saDD
|
||||
.br
|
||||
.I @SA_DIR@/saYYYYMMDD
|
||||
.RS
|
||||
The standard system activity daily data files and their default location.
|
||||
.IR "YYYY " "stands for the current year, " "MM " "for the current month and " "DD"
|
||||
for the current day.
|
||||
|
||||
.SH AUTHOR
|
||||
Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR "sar" "(1), " "sadc" "(8), " "sa2" "(8), " "sadf" "(1), " "sysstat" "(5)"
|
||||
.PP
|
||||
.I https://github.com/sysstat/sysstat
|
||||
.br
|
||||
.I http://pagesperso-orange.fr/sebastien.godard/
|
|
@ -0,0 +1,56 @@
|
|||
.\" sa2 manual page - (C) 1999-2020 Sebastien Godard (sysstat <at> orange.fr)
|
||||
.TH SA2 8 "JULY 2020" Linux "Linux User's Manual" -*- nroff -*-
|
||||
.SH NAME
|
||||
sa2 \- Create a report from the current standard system activity daily data file.
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B @SA_LIB_DIR@/sa2
|
||||
|
||||
.SH DESCRIPTION
|
||||
.RB "The " "sa2 " "command is a shell procedure variant of the " "sar"
|
||||
command which writes a daily report in the
|
||||
.IR "sarDD " "or the " "sarYYYYMMDD " "file, where"
|
||||
.IR "YYYY " "stands for the current year, " "MM " "for the current month and " "DD"
|
||||
for the current day. By default the report is saved in the
|
||||
.I @SA_DIR@
|
||||
directory. The
|
||||
.B sa2
|
||||
command will also remove reports more than one week old by default.
|
||||
You can however keep reports for a longer (or a shorter) period by setting the
|
||||
.B HISTORY
|
||||
environment variable. Read the
|
||||
.BR "sysstat" "(5) manual page for details."
|
||||
.PP
|
||||
.RB "The " "sa2 " "command accepts most of the flags and parameters of the " "sar " "command."
|
||||
.PP
|
||||
.RB "The " "sa2 " "command is designed to be started automatically by the " "cron " "command."
|
||||
|
||||
.SH EXAMPLES
|
||||
.RB "To run the " "sa2"
|
||||
command daily, place the following entry in your root crontab file:
|
||||
|
||||
.B 5 19 * * 1-5 @SA_LIB_DIR@/sa2 -A
|
||||
|
||||
This will generate by default a daily report called
|
||||
.IR "sarDD " "in the"
|
||||
.I @SA_DIR@
|
||||
directory, where the
|
||||
.IR "DD " "parameter is a number representing the day of the month."
|
||||
|
||||
.SH FILES
|
||||
.I @SA_DIR@/sarDD
|
||||
.br
|
||||
.I @SA_DIR@/sarYYYYMMDD
|
||||
.RS
|
||||
The standard system activity daily report files and their default location.
|
||||
.IR "YYYY " "stands for the current year, " "MM " "for the current month and " "DD " "for the current day."
|
||||
|
||||
.SH AUTHOR
|
||||
Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR "sar" "(1), " "sadc" "(8), " "sa1" "(8), " "sadf" "(1), " "sysstat" "(5)"
|
||||
.PP
|
||||
.I https://github.com/sysstat/sysstat
|
||||
.br
|
||||
.I http://pagesperso-orange.fr/sebastien.godard/
|
|
@ -0,0 +1,205 @@
|
|||
.\" sadc manual page - (C) 1999-2020 Sebastien Godard (sysstat <at> orange.fr)
|
||||
.TH SADC 8 "JULY 2020" Linux "Linux User's Manual" -*- nroff -*-
|
||||
.SH NAME
|
||||
sadc \- System activity data collector.
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B @SA_LIB_DIR@/sadc [ -C
|
||||
.I comment
|
||||
.BI "] [ -D ] [ -F ] [ -f ] [ -L ] [ -V ] [ -S { " "keyword" "[,...] | ALL | XALL } ] ["
|
||||
.IB "interval " "[ " "count " "] ] [ " "outfile " "]"
|
||||
|
||||
.SH DESCRIPTION
|
||||
.RB "The " "sadc"
|
||||
command samples system data a specified number of times
|
||||
.RI "(" "count" ") at a specified interval measured in seconds (" "interval" ")."
|
||||
It writes in binary format to the specified
|
||||
.IR "outfile " "or to standard output. If " "outfile"
|
||||
.RB "is set to " "-" ", then " "sadc"
|
||||
uses the standard system activity daily data file (see below).
|
||||
In this case, if the file already exists,
|
||||
.B sadc
|
||||
will overwrite it if it is from a previous month. By default
|
||||
.B sadc
|
||||
collects most of the data available from the kernel.
|
||||
But there are also optional metrics, for which the
|
||||
relevant options must be explicitly passed to
|
||||
.BR "sadc " "to be collected (see option " "-S " "below)."
|
||||
.PP
|
||||
The standard system activity daily data file is named
|
||||
.IR "saDD " "unless option"
|
||||
.B -D
|
||||
is used, in which case its name is
|
||||
.IR "saYYYYMMDD" ", where " "YYYY " "stands for the current year, " "MM " "for the current month and " "DD"
|
||||
for the current day. By default it is located in the
|
||||
.I @SA_DIR@
|
||||
directory. Yet it is possible to specify an alternate location for
|
||||
it: If
|
||||
.I outfile
|
||||
is a directory (instead of a plain file) then it will be considered
|
||||
as the directory where the standard system activity daily data file
|
||||
will be saved.
|
||||
.PP
|
||||
.RI "When the " "count"
|
||||
parameter is not specified,
|
||||
.B sadc
|
||||
writes its data endlessly. When both
|
||||
.IR "interval " "and " "count"
|
||||
are not specified, and option
|
||||
.B -C
|
||||
is not used, a dummy record, which is used at system startup to mark
|
||||
the time when the counter restarts from 0, will be written.
|
||||
For example, one of the system startup script may write the restart mark to
|
||||
the daily data file by the command entry:
|
||||
|
||||
.B @SA_LIB_DIR@/sadc -
|
||||
|
||||
.RB "The " "sadc " "command is intended to be used as a backend to the " "sar " "command."
|
||||
.PP
|
||||
.RB "Note: The " "sadc"
|
||||
command only reports on local activities.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI "-C " "comment"
|
||||
When neither the
|
||||
.IR "interval " "nor the " "count"
|
||||
parameters are specified, this option tells
|
||||
.B sadc
|
||||
to write a dummy record containing the specified
|
||||
.I comment
|
||||
string. This comment can then be displayed with option
|
||||
.BR "-C " "of " "sar" "."
|
||||
.TP
|
||||
.B -D
|
||||
.RI "Use " "saYYYYMMDD " "instead of " "saDD"
|
||||
as the standard system activity daily data file name.
|
||||
.TP
|
||||
.B -F
|
||||
.RI "The creation of " "outfile"
|
||||
will be forced. If the file already exists and has a format unknown to
|
||||
.B sadc
|
||||
then it will be truncated. This may be useful for daily data files
|
||||
created by an older version of
|
||||
.B sadc
|
||||
and whose format is no longer compatible with current one.
|
||||
.TP
|
||||
.B -f
|
||||
fdatasync() will be used to ensure data is written to disk. This differs
|
||||
from the normal operation in that a sudden system reset is less likely to
|
||||
result in the
|
||||
.I saDD
|
||||
datafiles being corrupted. However, this is at the
|
||||
expense of performance within the
|
||||
.B sadc
|
||||
process as forward progress will be
|
||||
blocked while data is written to underlying disk instead of just to cache.
|
||||
.TP
|
||||
.B -L
|
||||
.B sadc
|
||||
will try to get an exclusive lock on the
|
||||
.I outfile
|
||||
before writing to it or truncating it. Failure to get the lock is fatal,
|
||||
except in the case of trying to write a normal (i.e. not a dummy and not
|
||||
a header) record to an existing file, in which case
|
||||
.B sadc
|
||||
will try again at the next interval. Usually, the only reason a lock
|
||||
would fail would be if another
|
||||
.BR "sadc " "process were also writing to the file. This can happen when " "cron"
|
||||
is used to launch
|
||||
.BR "sadc" ". If the system is under heavy load, an old " "sadc"
|
||||
might still be running when
|
||||
.B cron
|
||||
starts a new one. Without locking, this situation can result in a corrupted system
|
||||
activity file.
|
||||
.TP
|
||||
.BI "-S { " "keyword" "[,...] | ALL | XALL }"
|
||||
Possible keywords are
|
||||
.BR "DISK" ", " "INT" ", " "IPV6" ", " "POWER" ", " "SNMP" ", " "XDISK" ", " "ALL " "and " "XALL" "."
|
||||
.br
|
||||
Specify which optional activities should be collected by
|
||||
.BR "sadc" "."
|
||||
Some activities are optional to prevent data files from growing too large. The
|
||||
.BR "DISK " "keyword indicates that " "sadc"
|
||||
should collect data for block devices. The
|
||||
.BR "INT " "keyword indicates that " "sadc"
|
||||
should collect data for system interrupts. The
|
||||
.BR "IPV6 " "keyword indicates that IPv6 statistics should be collected by " "sadc" ". The"
|
||||
.BR "POWER " "keyword indicates that " "sadc"
|
||||
should collect power management statistics. The
|
||||
.BR "SNMP " "keyword indicates that SNMP statistics should be collected by " "sadc" ". The"
|
||||
.BR "ALL " "keyword is equivalent to specifying all the keywords above and therefore"
|
||||
all previous activities are collected.
|
||||
.IP
|
||||
.RB "The " "XDISK " "keyword is an extension to the " "DISK"
|
||||
one and indicates that partitions and filesystems statistics should be collected by
|
||||
.B sadc
|
||||
in addition to disk statistics. This option works only with kernels 2.6.25
|
||||
and later. The
|
||||
.B XALL
|
||||
keyword is equivalent to specifying all the keywords above (including
|
||||
keyword extensions) and therefore all possible activities are collected.
|
||||
.IP
|
||||
Important note: The activities (including optional ones) saved in an existing
|
||||
data file prevail over those selected with option
|
||||
.BR "-S" "."
|
||||
As a consequence, appending data to an existing data file will result in option
|
||||
.B -S
|
||||
being ignored.
|
||||
.TP
|
||||
.B -V
|
||||
Print version number then exit.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
.RB "The " "sadc"
|
||||
command takes into account the following environment variable:
|
||||
.TP
|
||||
.B S_TIME_DEF_TIME
|
||||
If this variable exists and its value is
|
||||
.BR "UTC " "then " "sadc"
|
||||
will save its data in UTC time.
|
||||
.B sadc
|
||||
will also use UTC time instead of local time to determine the current
|
||||
daily data file located in the
|
||||
.IR @SA_DIR@
|
||||
directory.
|
||||
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B @SA_LIB_DIR@/sadc 1 10 /tmp/datafile
|
||||
Write 10 records of one second intervals to the
|
||||
.IR "/tmp/datafile " "binary file."
|
||||
.TP
|
||||
.B @SA_LIB_DIR@/sadc -C """Backup Start"" /tmp/datafile
|
||||
Insert the comment "Backup Start" into the file
|
||||
.IR "/tmp/datafile" "."
|
||||
|
||||
.SH BUGS
|
||||
.RI "The " "/proc"
|
||||
filesystem must be mounted for the
|
||||
.BR "sadc " "command to work."
|
||||
.PP
|
||||
All the statistics are not necessarily available, depending on the kernel version used.
|
||||
.B sadc
|
||||
assumes that you are using at least a 2.6 kernel.
|
||||
|
||||
.SH FILES
|
||||
.I @SA_DIR@/saDD
|
||||
.br
|
||||
.I @SA_DIR@/saYYYYMMDD
|
||||
.RS
|
||||
The standard system activity daily data files and their default location.
|
||||
.IR "YYYY " "stands for the current year, " "MM " "for the current month and " "DD"
|
||||
for the current day.
|
||||
.RE
|
||||
.IR "/proc " "and " "/sys " "contain various files with system statistics."
|
||||
|
||||
.SH AUTHOR
|
||||
Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR "sar" "(1), " "sa1" "(8), " "sa2" "(8), " "sadf" "(1), " "sysstat" "(5)"
|
||||
.PP
|
||||
.I https://github.com/sysstat/sysstat
|
||||
.br
|
||||
.I http://pagesperso-orange.fr/sebastien.godard/
|
|
@ -0,0 +1,384 @@
|
|||
.\" sadf manual page - (C) 1999-2022 Sebastien Godard (sysstat <at> orange.fr)
|
||||
.TH SADF 1 "JANUARY 2022" Linux "Linux User's Manual" -*- nroff -*-
|
||||
.SH NAME
|
||||
sadf \- Display data collected by sar in multiple formats.
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B sadf [ -C ] [ -c | -d | -g | -j | -l | -p | -r | -x ] [ -H ] [ -h ] [ -T | -t | -U ] [ -V ] [ -O
|
||||
.IB "opts " "[,...] ] [ -P { " "cpu_list " "| ALL } ] [ -s ["
|
||||
.IB "hh" ":" "mm" "[:" "ss" "] ] ] [ -e [" "hh" ":" "mm" "[:" "ss" "] ] ]"
|
||||
.BI "[ --dev=" "dev_list " "] [ --fs=" "fs_list " "] [ --iface=" "iface_list" "] [ --int=" "int_list " "] [ --"
|
||||
.IB "sar_options " "] [ " "interval " "[ " "count " "] ] [ " "datafile " "| " "-[0-9]+ " "]"
|
||||
|
||||
.SH DESCRIPTION
|
||||
.RB "The " "sadf"
|
||||
command is used for displaying the contents of data files created by the
|
||||
.BR "sar" "(1) command. But unlike " "sar" ", " "sadf"
|
||||
can write its data in many different formats (CSV, XML, etc.)
|
||||
The default format is one that can
|
||||
easily be handled by pattern processing commands like
|
||||
.BR "awk " "(see option " "-p" "). The " "sadf"
|
||||
command can also be used to draw graphs for the various activities collected by
|
||||
.B sar
|
||||
and display them as SVG (Scalable Vector Graphics) graphics in your web browser
|
||||
(see option
|
||||
.BR "-g" ")."
|
||||
.PP
|
||||
.RB "The " "sadf"
|
||||
command extracts and writes to standard output records saved in the
|
||||
.I datafile
|
||||
file. This file must have been created by a version of
|
||||
.BR "sar " "which is compatible with that of " "sadf" ". If"
|
||||
.I datafile
|
||||
.RB "is omitted, " "sadf"
|
||||
uses the standard system activity daily data file.
|
||||
It is also possible to enter
|
||||
.BR "-1" ", " "-2 " "etc. as an argument to " "sadf"
|
||||
to display data of that days ago. For example,
|
||||
.B -1
|
||||
will point at the standard system activity file of yesterday.
|
||||
.PP
|
||||
The standard system activity daily data file is named
|
||||
.IR "saDD " "or " "saYYYYMMDD" ", where"
|
||||
.IR "YYYY " "stands for the current year, " "MM " "for the current month and " "DD"
|
||||
for the current day.
|
||||
.B sadf
|
||||
will look for the most recent of
|
||||
.IR "saDD " "and " "saYYYYMMDD" ","
|
||||
and use it. By default it is located in the
|
||||
.I @SA_DIR@
|
||||
directory. Yet it is possible to specify an alternate location for it: If
|
||||
.I datafile
|
||||
is a directory (instead of a plain file) then it will be considered as
|
||||
the directory where the standard system activity daily data file is located.
|
||||
.PP
|
||||
.RI "The " "interval " "and " "count " "parameters are used to tell"
|
||||
.BR "sadf " "to select"
|
||||
.IR "count " "records at " "interval " "seconds apart. If the " "count"
|
||||
parameter is not set, then all the records saved in the data file will be displayed.
|
||||
.PP
|
||||
All the activity flags of
|
||||
.B sar
|
||||
may be entered on the command line to indicate which
|
||||
activities are to be reported. Before specifying them, put a pair of dashes
|
||||
.RB "(" "--" ")"
|
||||
on the command line in order not to confuse the flags with those of
|
||||
.B sadf.
|
||||
Not specifying any flags selects only CPU activity.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -C
|
||||
.RB "Tell " "sadf " "to display comments present in file."
|
||||
.TP
|
||||
.B -c
|
||||
Convert an old system activity binary datafile (version 9.1.6 and later)
|
||||
to current up-to-date format. Use the following syntax:
|
||||
|
||||
.BI "sadf -c " "old_datafile " "> " "new_datafile"
|
||||
|
||||
Conversion can be controlled using option
|
||||
.BR "-O " "(see below)."
|
||||
.TP
|
||||
.B -d
|
||||
Print the contents of the data file in a format that can easily
|
||||
be ingested by a relational database system. The output consists
|
||||
of fields separated by a semicolon. Each record contains
|
||||
the hostname of the host where the file was created, the interval value
|
||||
(or -1 if not applicable), the timestamp in a form easily acceptable by
|
||||
most databases, and additional semicolon separated data fields as specified by
|
||||
.IR "sar_options " "command line options."
|
||||
Note that timestamp output can be controlled by options
|
||||
.BR "-T" ", " "-t " "and " "-U" "."
|
||||
.TP
|
||||
.BI "--dev=" "dev_list"
|
||||
Specify the block devices for which statistics are to be displayed by
|
||||
.BR "sadf" "."
|
||||
.I dev_list
|
||||
is a list of comma-separated device names. Useful with option
|
||||
.BR "-d " "from " "sar" "."
|
||||
.TP
|
||||
.BI "-e [ " "hh" ":" "mm" "[:" "ss" "] ]"
|
||||
Set the ending time of the report. The default ending
|
||||
time is 18:00:00. Hours must be given in 24-hour format.
|
||||
.TP
|
||||
.BI "--fs=" "fs_list"
|
||||
Specify the filesystems for which statistics are to be displayed by
|
||||
.BR "sadf" "."
|
||||
.I fs_list
|
||||
is a list of comma-separated filesystem names or mountpoints. Useful with option
|
||||
.BR "-F " "from " "sar" "."
|
||||
.TP
|
||||
.B -g
|
||||
Print the contents of the data file in SVG (Scalable Vector Graphics) format.
|
||||
This option enables you to display some fancy graphs in your web browser.
|
||||
Use the following syntax:
|
||||
|
||||
.BI "sadf -g " "your_datafile " "[ -- " "sar_options " "] > " "output.svg"
|
||||
|
||||
and open the resulting SVG file in your favorite web browser.
|
||||
Output can be controlled using option
|
||||
.BR "-O " "(see below)."
|
||||
.TP
|
||||
.B -H
|
||||
Display only the header of the report (when applicable). If no format has
|
||||
been specified, then the header data (metadata) of the data file are displayed.
|
||||
.TP
|
||||
.B -h
|
||||
When used in conjunction with option
|
||||
.BR "-d" ", all activities will be displayed horizontally on a single line."
|
||||
.TP
|
||||
.BI "--iface=" "iface_list"
|
||||
Specify the network interfaces for which statistics are to be displayed by
|
||||
.BR "sadf" "."
|
||||
.I iface_list
|
||||
is a list of comma-separated interface names. Useful with options
|
||||
.BR "-n DEV " "and " "-n EDEV " "from " "sar" "."
|
||||
.TP
|
||||
.BI "--int=" "int_list"
|
||||
Specify the interrupts names for which statistics are to be displayed by
|
||||
.BR "sadf" "."
|
||||
.I int_list
|
||||
is a list of comma-separated values or range of values (e.g.,
|
||||
.BR "0-16,35,40-" "). Useful with option " "-I " "from " "sar" "."
|
||||
.TP
|
||||
.B -j
|
||||
Print the contents of the data file in JSON (JavaScript Object Notation)
|
||||
format. Timestamps can be controlled by options
|
||||
.BR "-T " "and " "-t" "."
|
||||
.TP
|
||||
.B -l
|
||||
Export the contents of the data file to a PCP (Performance Co-Pilot) archive.
|
||||
The name of the archive can be specified using the keyword
|
||||
.BR "pcparchive= " "with option " "-O" "."
|
||||
.TP
|
||||
.BI "-O " "opts" "[,...]"
|
||||
Use the specified options to control the output of
|
||||
.BR "sadf" "."
|
||||
The following options are used to control SVG output displayed by
|
||||
.BR "sadf -g" ":"
|
||||
.RS
|
||||
.IP autoscale
|
||||
Draw all the graphs of a given view as large as possible based on current
|
||||
view's scale. To do this, a factor (10, 100, 1000...) is used to
|
||||
enlarge the graph drawing.
|
||||
This option may be interesting when several graphs are drawn on the same
|
||||
view, some with only very small values, and others with high ones,
|
||||
the latter making the former hardly visible.
|
||||
.IP bwcol
|
||||
Use a black and white palette to draw the graphs.
|
||||
.IP customcol
|
||||
Use a customizable color palette instead of the default one to draw
|
||||
the graphs. See environment variable
|
||||
.B S_COLORS_PALETTE
|
||||
below to know how to customize that palette.
|
||||
.IP debug
|
||||
Add helpful comments in SVG output file.
|
||||
.TP
|
||||
.RI "height=" "value"
|
||||
Set SVG canvas height to
|
||||
.IR "value" "."
|
||||
.IP oneday
|
||||
Display graphs data over a period of 24 hours. Note that hours are still
|
||||
printed in UTC by default: You should use option
|
||||
.BR "-T " "to print them in local time"
|
||||
and get a time window starting from midnight.
|
||||
.IP packed
|
||||
Group all views from the same activity (and for the same device) on the same row.
|
||||
.IP showidle
|
||||
Also display %idle state in graphs for CPU statistics.
|
||||
.IP showinfo
|
||||
Display additional information (such as the date and the host name) on each view.
|
||||
.IP showtoc
|
||||
Add a table of contents at the beginning of the SVG output, consisting of links
|
||||
pointing at the first graph of each activity.
|
||||
.IP skipempty
|
||||
Do not display views where all graphs have only zero values.
|
||||
.RE
|
||||
.IP
|
||||
The following option may be used when converting an old system activity binary datafile
|
||||
to current up-to-date format:
|
||||
.RS
|
||||
.TP
|
||||
.RI "hz=" "value"
|
||||
Specify the number of ticks per second for the machine where the old datafile has been created.
|
||||
.RE
|
||||
.IP
|
||||
The following option may be used when data are exported to a PCP archive:
|
||||
.RS
|
||||
.TP
|
||||
.RI "pcparchive=" "name"
|
||||
Specify the name of the PCP archive to create.
|
||||
.RE
|
||||
.IP
|
||||
The following option is used to control raw output displayed by
|
||||
.BR "sadf -r" ":"
|
||||
.RS
|
||||
.IP debug
|
||||
Display additional information, mainly useful for debugging purpose.
|
||||
.RE
|
||||
.TP
|
||||
.BI "-P { " "cpu_list " "| ALL }"
|
||||
.RB "Tell " "sadf"
|
||||
that processor dependent statistics are to be reported only for the
|
||||
specified processor or processors.
|
||||
.I cpu_list
|
||||
is a list of comma-separated values or range of values (e.g.,
|
||||
.BR "0,2,4-7,12-" ")."
|
||||
Note that processor 0 is the first processor, and processor
|
||||
.BR "all " "is the global average among all processors. Specifying the " "ALL"
|
||||
keyword reports statistics for each individual processor, and globally for
|
||||
all processors.
|
||||
.TP
|
||||
.B -p
|
||||
Print the contents of the data file in a format that can
|
||||
easily be handled by pattern processing commands like
|
||||
.BR "awk" "."
|
||||
The output consists of fields separated by a tab. Each record contains the
|
||||
hostname of the host where the file was created, the interval value
|
||||
(or -1 if not applicable), the timestamp, the device name (or - if not applicable),
|
||||
the field name and its value.
|
||||
Note that timestamp output can be controlled by options
|
||||
.BR "-T" ", " "-t " "and " "-U" "."
|
||||
.TP
|
||||
.B -r
|
||||
Print the raw contents of the data file. With this format, the values for
|
||||
all the counters are displayed as read from the kernel, which means e.g., that
|
||||
no average values are calculated over the elapsed time interval.
|
||||
Output can be controlled using option
|
||||
.BR "-O " "(see above)."
|
||||
.TP
|
||||
.BI "-s [ " "hh" ":" "mm" "[:" "ss" "] ]"
|
||||
Set the starting time of the data, causing the
|
||||
.B sadf
|
||||
command to extract records time-tagged at, or following, the time
|
||||
specified. The default starting time is 08:00:00.
|
||||
Hours must be given in 24-hour format.
|
||||
.TP
|
||||
.B -T
|
||||
Display timestamp in local time instead of UTC (Coordinated Universal Time).
|
||||
.TP
|
||||
.B -t
|
||||
Display timestamp in the original local time of the data file creator
|
||||
instead of UTC (Coordinated Universal Time).
|
||||
.TP
|
||||
.B -U
|
||||
Display timestamp (UTC - Coordinated Universal Time) in seconds from the epoch.
|
||||
.TP
|
||||
.B -V
|
||||
Print version number then exit.
|
||||
.TP
|
||||
.B -x
|
||||
Print the contents of the data file in XML format.
|
||||
Timestamps can be controlled by options
|
||||
.BR "-T " "and " "-t" "."
|
||||
The corresponding DTD (Document Type Definition) and XML Schema are included
|
||||
in the sysstat source package. They are also available at
|
||||
.IR "http://pagesperso-orange.fr/sebastien.godard/download.html" "."
|
||||
|
||||
.SH ENVIRONMENT
|
||||
.RB "The " "sadf"
|
||||
command takes into account the following environment variables:
|
||||
.TP
|
||||
.B S_COLORS_PALETTE
|
||||
Specify the colors used by
|
||||
.B sadf -g
|
||||
to render the SVG output. This environment variable is taken into account
|
||||
only when the custom color palette has been selected with the option
|
||||
.BR "customcol " "(see option " "-O" ")."
|
||||
Its value is a colon-separated list of capabilities associated
|
||||
with six-digit, three-byte
|
||||
hexadecimal numbers (hex triplets) representing colors that defaults to
|
||||
|
||||
.B 0=000000:1=1a1aff:2=1affb2:3=b21aff:
|
||||
.br
|
||||
.B 4=1ab2ff:5=ff1a1a:6=ffb31a:7=b2ff1a:
|
||||
.br
|
||||
.B 8=efefef:9=000000:A=1a1aff:B=1affb2:
|
||||
.br
|
||||
.B C=b21aff:D=1ab2ff:E=ff1a1a:F=ffb31a:
|
||||
.br
|
||||
.B G=bebebe:H=000000:I=000000:K=ffffff:
|
||||
.br
|
||||
.B L=000000:T=000000:W=000000:X=000000
|
||||
|
||||
Capabilities consisting of a hexadecimal digit
|
||||
.RB "(" "0 " "through " "F" ") are used to specify"
|
||||
the first sixteen colors in the palette (these colors are used to draw the graphs),
|
||||
e.g., 3=ffffff would indicate that the third color in the palette is white (0xffffff).
|
||||
.br
|
||||
Other capabilities are:
|
||||
.RS
|
||||
.TP
|
||||
.B G=
|
||||
Specify the color used to draw the grid lines.
|
||||
.TP
|
||||
.B H=
|
||||
Specify the color used to display the report header.
|
||||
.TP
|
||||
.B I=
|
||||
Specify the color used to display additional information (e.g., date, hostname...)
|
||||
.TP
|
||||
.B K=
|
||||
Specify the color used for the graphs background.
|
||||
.TP
|
||||
.B L=
|
||||
Specify the default color (which is for example used to display the table of contents).
|
||||
.TP
|
||||
.B T=
|
||||
Specify the color used to display the graphs title.
|
||||
.TP
|
||||
.B W=
|
||||
Specify the color used to display warning and error messages.
|
||||
.TP
|
||||
.B X=
|
||||
Specify the color used to draw the axes and display the graduations.
|
||||
.RE
|
||||
.TP
|
||||
.B S_TIME_DEF_TIME
|
||||
If this variable exists and its value is
|
||||
.BR "UTC " "then " "sadf"
|
||||
will use UTC time instead of local time to determine the current daily data
|
||||
file located in the
|
||||
.IR @SA_DIR@
|
||||
directory.
|
||||
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B sadf -d @SA_DIR@/sa21 -- -r -n DEV
|
||||
Extract memory and network statistics from system activity file
|
||||
.IR "sa21" ","
|
||||
and display them in a format that can be ingested by a database.
|
||||
.TP
|
||||
.B sadf -p -P 1
|
||||
Extract CPU statistics for processor 1 (the second processor) from current
|
||||
daily data file, and display them in a format that can easily be handled
|
||||
by a pattern processing command.
|
||||
|
||||
.SH BUGS
|
||||
SVG output (as created by option
|
||||
.BR "-g" ")"
|
||||
is fully compliant with SVG 1.1 standard.
|
||||
Graphics have been successfully displayed in various web browsers, including
|
||||
Firefox, Chrome and Opera. Yet SVG rendering is broken on Microsoft browsers
|
||||
(tested on Internet Explorer 11 and Edge 13.1): So please don't use them.
|
||||
|
||||
.SH FILES
|
||||
.I @SA_DIR@/saDD
|
||||
.br
|
||||
.I @SA_DIR@/saYYYYMMDD
|
||||
.RS
|
||||
The standard system activity daily data files and their default location.
|
||||
.IR "YYYY " "stands for the current year, " "MM " "for the current month and " "DD"
|
||||
for the current day.
|
||||
.RE
|
||||
|
||||
.SH AUTHOR
|
||||
Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR "sar" "(1), " "sadc" "(8), " "sa1" "(8), " "sa2" "(8), " "sysstat" "(5)"
|
||||
.PP
|
||||
.I https://github.com/sysstat/sysstat
|
||||
.br
|
||||
.I http://pagesperso-orange.fr/sebastien.godard/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,161 @@
|
|||
.\" sysstat manual page - (C) 2020 Sebastien Godard (sysstat <at> orange.fr)
|
||||
.TH SYSSTAT 5 "JULY 2020" Linux "Linux User's Manual" -*- nroff -*-
|
||||
.SH NAME
|
||||
sysstat \- sysstat configuration file.
|
||||
|
||||
.SH DESCRIPTION
|
||||
This file is read by
|
||||
.BR "sa1" "(8) and " "sa2" "(8) shell scripts from the sysstat's set of tools."
|
||||
It consists of a sequence of shell variable assignments used to
|
||||
configure sysstat logging.
|
||||
The variables and their meanings are:
|
||||
.TP
|
||||
.B COMPRESSAFTER
|
||||
Number of days after which daily data files are to be compressed.
|
||||
The compression program is given in the
|
||||
.BR "ZIP " "variable."
|
||||
.TP
|
||||
.B DELAY_RANGE
|
||||
.RB "Tell " "sa2"
|
||||
script to wait for a random delay in the indicated range before running.
|
||||
This delay is expressed in seconds, and is aimed at preventing a massive I/O burst
|
||||
at the same time on VM sharing the same storage area.
|
||||
.RB "A value of 0 means that " "sa2"
|
||||
script will generate its reports files immediately.
|
||||
.TP
|
||||
.B HISTORY
|
||||
The number of days during which a daily data file or a report
|
||||
should be kept. Data files or reports older than this number of
|
||||
days will be removed by the
|
||||
.BR "sa2" "(8) shell script."
|
||||
Data files and reports are normally saved in the @SA_DIR@ directory,
|
||||
under the name
|
||||
.IR "saDD " "(for data files) or " "sarDD " "(for reports), where the " "DD"
|
||||
parameter indicates the current day.
|
||||
|
||||
The number of files actually kept in the @SA_DIR@ directory may be
|
||||
slightly higher than the
|
||||
.BR "HISTORY " "value due to the way the " "sa2"
|
||||
script figures out which files are to be removed (see below "How the
|
||||
.BR "sa2" "(8) script applies " "HISTORY"
|
||||
value"). Using a value of 28 keeps a whole month's worth of data. If you set
|
||||
.B HISTORY
|
||||
to a value greater than 28 then you should consider using
|
||||
.BR "sadc" "'s option " "-D"
|
||||
to prevent older data files from being overwritten (see
|
||||
.BR "sadc" "(8)"
|
||||
manual page). In this latter case data files are named
|
||||
.IR "saYYYYMMDD " "and reports " "sarYYYYMMDD" ", where"
|
||||
.IR "YYYY " "stands for the current year, " "MM " "for the current month and " "DD"
|
||||
for the current day.
|
||||
|
||||
How the
|
||||
.BR "sa2" "(8) script applies " "HISTORY " "value"
|
||||
|
||||
.RB "The " "sa2"
|
||||
script uses the
|
||||
.BR "find " "command with the " "-mtime " "option to figure"
|
||||
out which files are to be removed. The
|
||||
.BR "find " "command interprets this value"
|
||||
as "N 24 hour periods", ignoring any fractional part. This means that the
|
||||
last modified time of a given
|
||||
.IR "sa[r]DD " "data or report file, using a"
|
||||
.B HISTORY
|
||||
of 1, has to have been modified at least two days ago before it will be
|
||||
removed. And for a
|
||||
.BR "HISTORY " "of 28 that would mean 29 days ago."
|
||||
|
||||
.RB "To figure out how a " "HISTORY"
|
||||
of 28 is applied in practice, we need to consider that the
|
||||
.BR "sa2 " "script that issues the " "find " "command to remove the"
|
||||
old files typically runs just before midnight on a given system, and since
|
||||
the first record from
|
||||
.B sadc
|
||||
can also be written to the previous day's data file
|
||||
(thereby moving its modification time up a bit), the
|
||||
.B sa2
|
||||
script will leave
|
||||
30 files untouched. So for a setting of 28, and counting the data file of
|
||||
the current day, there will always be 31 files (or 30 files, depending on the
|
||||
number of days in a month) in the @SA_DIR@ directory during the majority
|
||||
of a given day. E.g.:
|
||||
|
||||
April 30th: 31 files (Apr 30th-1st, Mar 31th)
|
||||
.br
|
||||
May 1st: 30 files (May 1st, Apr 30th-2nd)
|
||||
|
||||
Yet we can note the following exceptions (as inspected at Noon of the given day):
|
||||
|
||||
February 28th: 31 files (Feb 28th-1st, Jan 31st, 30th & 29th)
|
||||
.br
|
||||
March 1st: 30 files (Mar 1st, Feb 28th-2nd, Jan 31st & 30th)
|
||||
.br
|
||||
March 2nd: 29 files (Mar 1st & 2nd, Feb 28th-3rd, Jan. 31st)
|
||||
.br
|
||||
March 3rd: 28 files (Mar 1st-3rd, Feb 28th-4th)
|
||||
.br
|
||||
March 4th - March 28th: 28 files
|
||||
.br
|
||||
March 29th: 29 files
|
||||
.br
|
||||
March 30th: 30 files
|
||||
.br
|
||||
March 31st: 31 files
|
||||
|
||||
(Determining the number of files in March on a leap year is left as an
|
||||
exercise for the reader).
|
||||
|
||||
Things are simpler if you use the
|
||||
.IR "sa[r]YYYYMMDD " "name format."
|
||||
Apply the same logic as above in this case and you will find that there
|
||||
are always
|
||||
.BR "HISTORY " "+ 3 files in the"
|
||||
.IR /var/log/sa
|
||||
directory during the majority of a given day.
|
||||
.TP
|
||||
.B REPORTS
|
||||
Set this variable to
|
||||
.BR "false " "to prevent the " "sa2"
|
||||
script from generating reports (the
|
||||
.IR "sarDD " "files)."
|
||||
.TP
|
||||
.B SA_DIR
|
||||
Directory where the standard system activity daily data and report files
|
||||
are saved. Its default value is
|
||||
.IR "@SA_DIR@" "."
|
||||
.TP
|
||||
.B SADC_OPTIONS
|
||||
Options that should be passed to
|
||||
.BR "sadc" "(8)."
|
||||
With these options (see
|
||||
.BR "sadc" "(8)"
|
||||
manual page), you can select some additional data which are going to be saved in
|
||||
daily data files.
|
||||
These options are used only when a new data file is created. They will be
|
||||
ignored with an already existing one.
|
||||
.TP
|
||||
.B YESTERDAY
|
||||
.RB "By default " "sa2"
|
||||
script generates yesterday's summary, since the
|
||||
.BR "cron " "job"
|
||||
usually runs right after midnight. If you want
|
||||
.B sa2
|
||||
to generate the summary of the same day (for example when cron
|
||||
job runs at 23:53) set this variable to
|
||||
.BR "no" "."
|
||||
.TP
|
||||
.B ZIP
|
||||
Program used to compress data and report files.
|
||||
|
||||
.SH FILE
|
||||
.I @SYSCONFIG_DIR@/sysstat
|
||||
|
||||
.SH AUTHOR
|
||||
Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR "sadc" "(8), " "sa1" "(8), " "sa2" "(8)"
|
||||
.PP
|
||||
.I https://github.com/sysstat/sysstat
|
||||
.br
|
||||
.I http://pagesperso-orange.fr/sebastien.godard/
|
|
@ -0,0 +1,233 @@
|
|||
.\" tapestat manual page - (C) 2015 Hewlett-Packard Development Company, L.P.
|
||||
.\" Maintained by Sebastien Godard (sysstat <at> orange.fr)
|
||||
.TH TAPESTAT 1 "JUNE 2020" Linux "Linux User's Manual" -*- nroff -*-
|
||||
.SH NAME
|
||||
tapestat \- Report tape statistics.
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B tapestat [ -k | -m ] [ -t ] [ -V ] [ -y ] [ -z ] [ --human ] [
|
||||
.IB "interval " "[ " "count " "] ]"
|
||||
|
||||
.SH DESCRIPTION
|
||||
.RB "The " "tapestat"
|
||||
command is used for monitoring the activity of tape drives connected to a system.
|
||||
.PP
|
||||
The first report generated by the
|
||||
.BR "tapestat " "command provides statistics"
|
||||
concerning the time since the system was booted, unless the
|
||||
.B -y
|
||||
option is used, when this first report is omitted.
|
||||
Each subsequent report covers the time since the previous report.
|
||||
.PP
|
||||
.RI "The " "interval"
|
||||
parameter specifies the amount of time in seconds between each report. The
|
||||
.I count
|
||||
parameter can be specified in conjunction with the
|
||||
.IR "interval " "parameter. If the " "count " "parameter is specified, the value of " "count"
|
||||
determines the number of reports generated at
|
||||
.IR "interval " "seconds apart. If the " "interval " "parameter is specified without the " "count"
|
||||
.RB "parameter, the " "tapestat"
|
||||
command generates reports continuously.
|
||||
|
||||
.SH REPORT
|
||||
The
|
||||
.B tapestat
|
||||
report provides statistics for each tape drive connected to the system.
|
||||
The following data are displayed:
|
||||
.IP r/s
|
||||
The number of reads issued expressed as the number per second averaged over the interval.
|
||||
.IP w/s
|
||||
The number of writes issued expressed as the number per second averaged over the interval.
|
||||
.IP "kB_read/s | MB_read/s"
|
||||
The amount of data read expressed in kilobytes (by default or if option
|
||||
.BR "-k " "used) or megabytes (if option " "-m"
|
||||
used) per second averaged over the interval.
|
||||
.IP "kB_wrtn/s | MB_wrtn/s"
|
||||
The amount of data written expressed in kilobytes (by default or if option
|
||||
.BR "-k " "used) or megabytes (if option " "-m"
|
||||
used) per second averaged over the interval.
|
||||
.IP %Rd
|
||||
Read percentage wait - The percentage of time over the interval spent waiting for read requests
|
||||
to complete.
|
||||
The time is measured from when the request is dispatched to the SCSI mid-layer until it signals
|
||||
that it completed.
|
||||
.IP %Wr
|
||||
Write percentage wait - The percentage of time over the interval spent waiting for write requests
|
||||
to complete. The time is measured from when the request is dispatched to the SCSI mid-layer until
|
||||
it signals that it completed.
|
||||
.IP %Oa
|
||||
Overall percentage wait - The percentage of time over the interval spent waiting for any
|
||||
I/O request to complete (read, write, and other).
|
||||
.IP Rs/s
|
||||
The number of I/Os, expressed as the number per second averaged over the interval, where
|
||||
a non-zero residual value was encountered.
|
||||
.IP Ot/s
|
||||
The number of I/Os, expressed as the number per second averaged over the interval, that
|
||||
were included as "other". Other I/O includes ioctl calls made to the tape driver and
|
||||
implicit operations performed by the tape driver such as rewind on close
|
||||
(for tape devices that implement rewind on close). It does not include any I/O performed
|
||||
using methods outside of the tape driver (e.g. via sg ioctls).
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B --human
|
||||
Print sizes in human readable format (e.g. 1.0k, 1.2M, etc.)
|
||||
The units displayed with this option supersede any other default units (e.g.
|
||||
kilobytes, sectors...) associated with the metrics.
|
||||
.TP
|
||||
.B -k
|
||||
Show the amount of data written or read in kilobytes per second instead of megabytes.
|
||||
This option is mutually exclusive with
|
||||
.BR "-m" "."
|
||||
.TP
|
||||
.B -m
|
||||
Show the amount of data written or read in megabytes per second instead of kilobytes.
|
||||
This option is mutually exclusive with
|
||||
.BR "-k" "."
|
||||
.TP
|
||||
.B -t
|
||||
Display time stamps. The time stamp format may depend
|
||||
on the value of the
|
||||
.BR "S_TIME_FORMAT " "environment variable (see below)."
|
||||
.TP
|
||||
.B -V
|
||||
Print version and exit.
|
||||
.TP
|
||||
.B -y
|
||||
Omit the initial statistic showing values since boot.
|
||||
.TP
|
||||
.B -z
|
||||
.RB "Tell " "tapestat"
|
||||
to omit output for any tapes for which there was no activity
|
||||
during the sample period.
|
||||
|
||||
.SH CONSIDERATIONS
|
||||
It is possible for a percentage value (read, write, or other) to be greater than 100 percent (the
|
||||
.B tapestat
|
||||
command will never show a percentage value more than 999).
|
||||
If rewinding a tape takes 40 seconds where the interval time is 5 seconds the %Oa value
|
||||
would show as 0 in the intervals before the rewind completed and then show as approximately
|
||||
800 percent when the rewind completes.
|
||||
|
||||
Similar values will be observed for %Rd and %Wr if a tape drive stops reading or writing
|
||||
and then restarts (that is it stopped streaming). In such a case you may see the r/s or w/s drop to zero and the %Rd/%Wr value could be higher than 100 when reading or writing continues
|
||||
(depending on how long it takes to restart writing or reading).
|
||||
This is only an issue if it happens a lot as it may cause tape wear and will impact
|
||||
on the backup times.
|
||||
|
||||
For fast tape drives you may see low percentage wait times.
|
||||
This does not indicate an issue with the tape drive. For a slower tape drive (e.g. an older
|
||||
generation DDS drive) the speed of the tape (and tape drive) is much slower than filesystem I/O,
|
||||
percent wait times are likely to be higher. For faster tape drives (e.g. LTO) the percentage
|
||||
wait times are likely to be lower as program writing to or reading from tape is going
|
||||
to be doing a lot more filesystem I/O because of the higher throughput.
|
||||
|
||||
Although tape statistics are implemented in the kernel using atomic variables they cannot be
|
||||
read atomically as a group. All of the statistics values are read from different files under
|
||||
.IR "/sys" ","
|
||||
because of this there may be I/O completions while reading the different files for the
|
||||
one tape drive. This may result in a set of statistics for a device that contain some values
|
||||
before an I/O completed and some after.
|
||||
|
||||
This command uses rounding down as the rounding method when calculating per second statistics.
|
||||
If, for example, you are using
|
||||
.BR "dd " "to copy one tape to another and running " "tapestat"
|
||||
with an interval of 5 seconds and over the interval there were 3210 writes and 3209 reads
|
||||
then w/s would show 642 and r/s 641 (641.8 rounded down to 641). In such a case if it was
|
||||
a tar archive being copied (with a 10k block size) you would also see a difference between
|
||||
the kB_read/s and kB_wrtn/s of 2 (one I/O 10k in size divided by the interval period of 5
|
||||
seconds). If instead there were 3210 writes and 3211 reads both w/s and r/s would both show
|
||||
642 but you would still see a difference between the kB_read/s and kB_wrtn/s values of 2 kB/s.
|
||||
|
||||
This command is provided with an interval in seconds. However internally the interval is
|
||||
tracked per device and can potentially have an effect on the per second statistics reported.
|
||||
The time each set of statistics is captured is kept with those statistics. The difference
|
||||
between the current and previous time is converted to milliseconds for use in calculations.
|
||||
We can look at how this can impact the statistics reported if we use an example of a tar
|
||||
archive being copied between two tape drives using
|
||||
.BR "dd" "."
|
||||
If both devices reported 28900 kilobytes
|
||||
transferred and the reading tape drive had an interval of 5001 milliseconds and the writing
|
||||
tape drive 5000 milliseconds that would calculate out as 5778 kB_read/s and 5780 kB_wrtn/s.
|
||||
|
||||
The impact of some retrieving statistics during an I/O completion, rounding down, and small differences in the interval period on the statistics calculated should be minimal but may be non-zero.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
.RB "The " "tapestat"
|
||||
command takes into account the following environment variables:
|
||||
.TP
|
||||
.B S_COLORS
|
||||
By default statistics are displayed in color when the output is connected to a terminal.
|
||||
Use this variable to change the settings. Possible values for this variable are
|
||||
.IR "never" ", " "always " "or " "auto"
|
||||
(the latter is equivalent to the default settings).
|
||||
.br
|
||||
Please note that the color (being red, yellow, or some other color) used to display a value
|
||||
is not indicative of any kind of issue simply because of the color. It only indicates different
|
||||
ranges of values.
|
||||
.TP
|
||||
.B S_COLORS_SGR
|
||||
Specify the colors and other attributes used to display statistics on the terminal.
|
||||
Its value is a colon-separated list of capabilities that defaults to
|
||||
.BR "H=31;1:I=32;22:M=35;1:N=34;1:Z=34;22" "."
|
||||
Supported capabilities are:
|
||||
.RS
|
||||
.TP
|
||||
.B H=
|
||||
SGR (Select Graphic Rendition) substring for percentage values greater than or equal to 75%.
|
||||
.TP
|
||||
.B I=
|
||||
SGR substring for tape names.
|
||||
.TP
|
||||
.B M=
|
||||
SGR substring for percentage values in the range from 50% to 75%.
|
||||
.TP
|
||||
.B N=
|
||||
SGR substring for non-zero statistics values.
|
||||
.TP
|
||||
.B Z=
|
||||
SGR substring for zero values.
|
||||
.RE
|
||||
.TP
|
||||
.B S_TIME_FORMAT
|
||||
If this variable exists and its value is
|
||||
.BR ISO
|
||||
then the current locale will be ignored when printing the date in the report
|
||||
header. The
|
||||
.B tapestat
|
||||
command will use the ISO 8601 format (YYYY-MM-DD) instead.
|
||||
The timestamp displayed with option
|
||||
.B -t
|
||||
will also be compliant with ISO 8601 format.
|
||||
|
||||
.SH BUGS
|
||||
.IR "/sys " "filesystem must be mounted for"
|
||||
.B tapestat
|
||||
to work. It will not work on kernels that do not have sysfs support
|
||||
.PP
|
||||
This command requires kernel version 4.2 or later
|
||||
(or tape statistics support backported for an earlier kernel version).
|
||||
.PP
|
||||
.RB "Although " "tapestat"
|
||||
speaks of kilobytes (kB), megabytes (MB)..., it actually uses kibibytes (kiB), mebibytes (MiB)...
|
||||
A kibibyte is equal to 1024 bytes, and a mebibyte is equal to 1024 kibibytes.
|
||||
|
||||
.SH FILES
|
||||
.I /sys/class/scsi_tape/st<num>/stats/*
|
||||
.RS
|
||||
Statistics files for tape devices.
|
||||
.RE
|
||||
.PP
|
||||
.IR "/proc/uptime " "contains system uptime."
|
||||
|
||||
.SH AUTHOR
|
||||
Initial revision by Shane M. SEYMOUR (shane.seymour <at> hpe.com)
|
||||
.br
|
||||
Modified for sysstat by Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR "iostat" "(1), " "mpstat" "(1)"
|
||||
.PP
|
||||
.I https://github.com/sysstat/sysstat
|
||||
.br
|
||||
.I http://pagesperso-orange.fr/sebastien.godard/
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* mpstat: per-processor statistics
|
||||
* (C) 2000-2022 by Sebastien Godard (sysstat <at> orange.fr)
|
||||
*/
|
||||
|
||||
#ifndef _MPSTAT_H
|
||||
#define _MPSTAT_H
|
||||
|
||||
#include "common.h"
|
||||
#include "rd_stats.h"
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* mpstat's specific system files.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#define SOFTIRQS PRE "/proc/softirqs"
|
||||
#define PHYS_PACK_ID "topology/physical_package_id"
|
||||
#define THREAD_SBL_LST "topology/thread_siblings_list"
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Activities definitions.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#define M_D_CPU 0x0001
|
||||
#define M_D_IRQ_SUM 0x0002
|
||||
#define M_D_IRQ_CPU 0x0004
|
||||
#define M_D_SOFTIRQS 0x0008
|
||||
#define M_D_NODE 0x0010
|
||||
|
||||
#define DISPLAY_CPU(m) (((m) & M_D_CPU) == M_D_CPU)
|
||||
#define DISPLAY_IRQ_SUM(m) (((m) & M_D_IRQ_SUM) == M_D_IRQ_SUM)
|
||||
#define DISPLAY_IRQ_CPU(m) (((m) & M_D_IRQ_CPU) == M_D_IRQ_CPU)
|
||||
#define DISPLAY_SOFTIRQS(m) (((m) & M_D_SOFTIRQS) == M_D_SOFTIRQS)
|
||||
#define DISPLAY_NODE(m) (((m) & M_D_NODE) == M_D_NODE)
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Keywords and constants.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/* Indicate that option -P has been used */
|
||||
#define F_OPTION_P 0x01
|
||||
/* Indicate that option -A has been used */
|
||||
#define F_OPTION_A 0x02
|
||||
/* JSON output */
|
||||
#define F_JSON_OUTPUT 0x04
|
||||
/* Indicate that option -N has been used */
|
||||
#define F_OPTION_N 0x08
|
||||
/* Display topology */
|
||||
#define F_TOPOLOGY 0x10
|
||||
|
||||
#define USE_OPTION_P(m) (((m) & F_OPTION_P) == F_OPTION_P)
|
||||
#define USE_OPTION_A(m) (((m) & F_OPTION_A) == F_OPTION_A)
|
||||
#define DISPLAY_JSON_OUTPUT(m) (((m) & F_JSON_OUTPUT) == F_JSON_OUTPUT)
|
||||
#define USE_OPTION_N(m) (((m) & F_OPTION_N) == F_OPTION_N)
|
||||
#define DISPLAY_TOPOLOGY(m) (((m) & F_TOPOLOGY) == F_TOPOLOGY)
|
||||
|
||||
#define K_SUM "SUM"
|
||||
#define K_CPU "CPU"
|
||||
#define K_SCPU "SCPU"
|
||||
|
||||
#define NR_IRQCPU_PREALLOC 3
|
||||
|
||||
#define MAX_IRQ_LEN 16
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Structures used to store statistics.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* stats_irqcpu->irq_name: IRQ#-A
|
||||
* stats_irqcpu->interrupt: number of IRQ#-A for proc 0
|
||||
* stats_irqcpu->irq_name: IRQ#-B
|
||||
* stats_irqcpu->interrupt: number of IRQ#-B for proc 0
|
||||
* ...
|
||||
* stats_irqcpu->irq_name: (undef'd)
|
||||
* stats_irqcpu->interrupt: number of IRQ#-A for proc 1
|
||||
* stats_irqcpu->irq_name: (undef'd)
|
||||
* stats_irqcpu->interrupt: number of IRQ#-B for proc 1
|
||||
* ...
|
||||
*/
|
||||
struct stats_irqcpu {
|
||||
unsigned int interrupt;
|
||||
char irq_name[MAX_IRQ_LEN];
|
||||
};
|
||||
|
||||
#define STATS_IRQCPU_SIZE (sizeof(struct stats_irqcpu))
|
||||
|
||||
struct stats_global_irq {
|
||||
unsigned long long irq_nr;
|
||||
};
|
||||
|
||||
#define STATS_GLOBAL_IRQ_SIZE (sizeof(struct stats_global_irq))
|
||||
|
||||
struct cpu_topology {
|
||||
int phys_package_id;
|
||||
int logical_core_id;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,69 @@
|
|||
WHAT IS NLS?
|
||||
------------
|
||||
NLS stands for National Language Support. It encompasses the features that make
|
||||
a program able to support different languages and cultural habits.
|
||||
This touches the messages displayed on the screen, but also the format used to
|
||||
display the dates or the numbers for example.
|
||||
|
||||
|
||||
HOW I ENABLE NLS WITH SYSSTAT?
|
||||
------------------------------
|
||||
NLS is enabled by default when you configure sysstat (running "./configure").
|
||||
But you can disable it if you want: Use the option "--disable-nls" with
|
||||
./configure or answer 'y' (for 'yes') to the question:
|
||||
"Disable National Language Support (NLS)? (y/n) [--disable-nls]"
|
||||
if you use the interactive configuration script (iconfig).
|
||||
|
||||
|
||||
OK, BUT HOW DO I USE IT NOW?
|
||||
----------------------------
|
||||
To see sysstat's messages in your own language, you have to set your LANG
|
||||
environment variable to the proper value. For example, in France you may
|
||||
want to set it to "fr_FR", although other possibilities exist. If this does
|
||||
not work for your language, see below for how to add a new translation.
|
||||
|
||||
If you use bash and you want to configure your system for a French environment,
|
||||
enter:
|
||||
|
||||
$ export LANG=fr_FR
|
||||
|
||||
('$' is the prompt).
|
||||
If you use the (Tab) C shell, you would have entered:
|
||||
|
||||
% setenv LANG fr_FR
|
||||
|
||||
('%' is the prompt).
|
||||
Here is a complete example with iostat:
|
||||
|
||||
$ export LANG=en_US
|
||||
$ iostat -V
|
||||
sysstat version 5.1.4
|
||||
(C) Sebastien Godard
|
||||
Usage: iostat [ options... ] [ <interval> [ <count> ] ]
|
||||
Options are:
|
||||
[ -c | -d ] [ -k ] [ -m ] [ -t ] [ -V ] [ -x ]
|
||||
[ { <device> [ ... ] | ALL } ] [ -p [ { <device> | ALL } ] ]
|
||||
|
||||
$ export LANG=fr_FR
|
||||
$ iostat -V
|
||||
sysstat version 5.1.4
|
||||
(C) Sebastien Godard
|
||||
Utilisation: iostat [ options... ] [ <intervalle> [ <itérations> ] ]
|
||||
Options possibles:
|
||||
[ -c | -d ] [ -k ] [ -m ] [ -t ] [ -V ] [ -x ]
|
||||
[ { <device> [ ... ] | ALL } ] [ -p [ { <device> | ALL } ] ]
|
||||
|
||||
|
||||
HOW CAN I ADD OR UPDATE A TRANSLATION?
|
||||
--------------------------------------
|
||||
At the present time, sysstat is already translated into several languages.
|
||||
If, however, the translation to your language is incomplete or entirely
|
||||
missing, you can update it or add a new one by contacting the team for
|
||||
your language at the Translation Project -- http://translationproject.org/ .
|
||||
There you can get the latest sysstat PO file for your language, or the
|
||||
latest blank POT file. When you have made the translation complete, send it
|
||||
to your team leader or to the team's mailing list.
|
||||
|
||||
--
|
||||
Sebastien Godard (sysstat <at> orange.fr)
|
||||
|
|
@ -0,0 +1,196 @@
|
|||
# NLS support for the sysstat package.
|
||||
# Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
# Sébastien GODARD <sysstat [at] orange.fr>, 1999.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sysstat 3.0\n"
|
||||
"Report-Msgid-Bugs-To: sysstat <at> orange.fr\n"
|
||||
"POT-Creation-Date: 2007-12-19 14:02+0100\n"
|
||||
"PO-Revision-Date: 2000-01-12 20:17\n"
|
||||
"Last-Translator: Gert Brits <webmaster@linuxhelp.za.net>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"X-Bugs: Report translation errors to the Language-Team address.\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: common.c:57
|
||||
#, c-format
|
||||
msgid "sysstat version %s\n"
|
||||
msgstr "sysstat weergawe %s\n"
|
||||
|
||||
#: common.c:160 common.c:385 ioconf.c:459 mpstat.c:265 sa_common.c:601
|
||||
#: sadc.c:476 sadc.c:485 sadc.c:530 sadc.c:620
|
||||
#, c-format
|
||||
msgid "Cannot open %s: %s\n"
|
||||
msgstr "Probleem met oopmaak van %s: %s\n"
|
||||
|
||||
#: common.c:199
|
||||
#, c-format
|
||||
msgid "Cannot handle so many processors!\n"
|
||||
msgstr "Kan nie soveel proseseerders hanteer nie !\n"
|
||||
|
||||
#: iostat.c:74
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Usage: %s [ options... ] [ <interval> [ <count> ] ]\n"
|
||||
"Options are:\n"
|
||||
"[ -c ] [ -d ] [ -N ] [ -n ] [ -k | -m ] [ -t ] [ -V ] [ -x ]\n"
|
||||
"[ <device> [ ... ] | ALL ] [ -p [ <device> | ALL ] ]\n"
|
||||
msgstr ""
|
||||
"Gebruik: %s [ opsies... ] [ <interval> [ <nommer> ] ]\n"
|
||||
"Opsies moontlik:\n"
|
||||
"[ -c ] [ -d ] [ -N ] [ -n ] [ -k | -m ] [ -t ] [ -V ] [ -x ]\n"
|
||||
"[ <device> [ ... ] | ALL ] [ -p [ <device> | ALL ] ]\n"
|
||||
|
||||
#: iostat.c:1119
|
||||
#, c-format
|
||||
msgid "Time: %s\n"
|
||||
msgstr "Tyd: %s\n"
|
||||
|
||||
#: iostat.c:1435
|
||||
#, c-format
|
||||
msgid "-x and -p options are mutually exclusive\n"
|
||||
msgstr "Opsies -x en -p is beide uitgesluit\n"
|
||||
|
||||
#: mpstat.c:66
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Usage: %s [ options... ] [ <interval> [ <count> ] ]\n"
|
||||
"Options are:\n"
|
||||
"[ -P { <cpu> | ALL } ] [ -V ]\n"
|
||||
msgstr ""
|
||||
"Gebruik: %s [ opsies... ] [ <interval> [ <nommer> ] ]\n"
|
||||
"Opsies moontlik:\n"
|
||||
"[ -P { <cpu> | ALL } ] [ -V ]\n"
|
||||
|
||||
# sar.c:
|
||||
#: mpstat.c:226 pidstat.c:1148 sar.c:740
|
||||
msgid "Average:"
|
||||
msgstr "Gemideld:"
|
||||
|
||||
#: mpstat.c:563 sar.c:157
|
||||
#, c-format
|
||||
msgid "Not that many processors!\n"
|
||||
msgstr "Nie soveel proseseerders nie !\n"
|
||||
|
||||
#: pidstat.c:72
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Usage: %s [ options... ] [ <interval> [ <count> ] ]\n"
|
||||
"Options are:\n"
|
||||
"[ -C <comm> ] [ -d ] [ -I ] [ -r ] [ -t ] [ -u ] [ -V ] [ -w ]\n"
|
||||
"[ -p { <pid> | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ]\n"
|
||||
msgstr ""
|
||||
"Gebruik: %s [ opsies... ] [ <interval> [ <nommer> ] ]\n"
|
||||
"Opsies moontlik:\n"
|
||||
"[ -C <comm> ] [ -d ] [ -I ] [ -r ] [ -t ] [ -u ] [ -V ] [ -w ]\n"
|
||||
"[ -p { <pid> | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ]\n"
|
||||
|
||||
#: pidstat.c:166 sar.c:1419
|
||||
#, c-format
|
||||
msgid "Requested activities not available\n"
|
||||
msgstr "Aangevraagte aktiviteite nie beskikbaar nie\n"
|
||||
|
||||
#: sa_common.c:572
|
||||
#, c-format
|
||||
msgid "Error while reading system activity file: %s\n"
|
||||
msgstr "Probleem gekry met die lees van die sisteem aktiviteit leer: %s\n"
|
||||
|
||||
#: sa_common.c:581
|
||||
#, c-format
|
||||
msgid "End of system activity file unexpected\n"
|
||||
msgstr "Einde van sisteem aktiviteit leer onbeplan geeindig\n"
|
||||
|
||||
#: sa_common.c:608 sadc.c:549
|
||||
#, c-format
|
||||
msgid "Invalid system activity file: %s (%#x)\n"
|
||||
msgstr "Ongemagtige aktiviteit proses: %s (%#x)\n"
|
||||
|
||||
#: sa_common.c:632
|
||||
#, c-format
|
||||
msgid "Requested activities not available in file\n"
|
||||
msgstr "Aangevraagte data is nie beskikbaar in leer nie\n"
|
||||
|
||||
#: sadc.c:83
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Usage: %s [ options... ] [ <interval> [ <count> ] ] [ <outfile> ]\n"
|
||||
"Options are:\n"
|
||||
"[ -C <comment> ] [ -d ] [ -F ] [ -I ] [ -V ]\n"
|
||||
msgstr ""
|
||||
"Gebruik: %s [ opsies... ] [ <interval> [ <nommer> ] ] [ <uitleer> ]\n"
|
||||
"Opsies moontlik:\n"
|
||||
"[ -C <comment> ] [ -d ] [ -F ] [ -I ] [ -V ]\n"
|
||||
|
||||
#: sadc.c:110
|
||||
#, c-format
|
||||
msgid "Cannot write data to system activity file: %s\n"
|
||||
msgstr "Probleem met skryf van sisteem aktiviteit leer: %s\n"
|
||||
|
||||
#: sadc.c:361
|
||||
#, c-format
|
||||
msgid "Cannot write system activity file header: %s\n"
|
||||
msgstr "Probleem met skryf van sisteem aktiviteit hoof: %s\n"
|
||||
|
||||
#: sadc.c:568
|
||||
#, c-format
|
||||
msgid "Cannot append data to that file\n"
|
||||
msgstr "Kan nie data byskryf by die file nie\n"
|
||||
|
||||
#: sadf.c:78
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Usage: %s [ options... ] [ <interval> [ <count> ] ] [ <datafile> ]\n"
|
||||
"Options are:\n"
|
||||
"[ -d | -D | -H | -p | -x ] [ -t ] [ -V ]\n"
|
||||
"[ -P { <cpu> | ALL } ] [ -s [ <hh:mm:ss> ] ] [ -e [ <hh:mm:ss> ] ]\n"
|
||||
"[ -- <sar_options...> ]\n"
|
||||
msgstr ""
|
||||
"Gebruik: %s [ opsies... ] [ <interval> [ <nommer> ] ] [ <leer> ]\n"
|
||||
"Opsies moontlik:\n"
|
||||
"[ -d [ -D | -H | -p | -x ] [ -t ] [ -V ]\n"
|
||||
"[ -P { <cpu> | ALL } ] [ -s [ <hh:mm:ss> ] ] [ -e [ <hh:mm:ss> ] ]\n"
|
||||
"[ -- <sar_opsies...> ]\n"
|
||||
|
||||
#: sar.c:76
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Usage: %s [ options... ] [ <interval> [ <count> ] ]\n"
|
||||
"Options are:\n"
|
||||
"[ -A ] [ -b ] [ -B ] [ -c ] [ -C ] [ -d ] [ -i <interval> ] [ -p ] [ -q ]\n"
|
||||
"[ -r ] [ -R ] [ -t ] [ -u ] [ -v ] [ -V ] [ -w ] [ -W ] [ -y ]\n"
|
||||
"[ -I { <irq> | SUM | ALL | XALL } ] [ -P { <cpu> | ALL } ]\n"
|
||||
"[ -n { DEV | EDEV | NFS | NFSD | SOCK | ALL } ]\n"
|
||||
"[ -o [ <filename> ] | -f [ <filename> ] ]\n"
|
||||
"[ -s [ <hh:mm:ss> ] ] [ -e [ <hh:mm:ss> ] ]\n"
|
||||
msgstr ""
|
||||
"Gebruik: %s [ opsies... ] [ <interval> [ <nommer> ] ]\n"
|
||||
"Opsies moontlik:\n"
|
||||
"[ -A ] [ -b ] [ -B ] [ -c ] [ -C ] [ -d ] [ -i <interval> ] [ -p ] [ -q ]\n"
|
||||
"[ -r ] [ -R ] [ -t ] [ -u ] [ -v ] [ -V ] [ -w ] [ -W ] [ -y ]\n"
|
||||
"[ -I { <irq> | SUM | ALL | XALL } ] [ -P { <cpu> | ALL } ]\n"
|
||||
"[ -n { DEV | EDEV | NFS | NFSD | SOCK | ALL } ]\n"
|
||||
"[ -o [ <leer> ] | -f [ <leer> ] ]\n"
|
||||
"[ -s [ <hh:mm:ss> ] ] [ -e [ <hh:mm:ss> ] ]\n"
|
||||
|
||||
#: sar.c:149
|
||||
#, c-format
|
||||
msgid "Not an SMP machine...\n"
|
||||
msgstr "Nie 'n SMP rekenaar nie...\n"
|
||||
|
||||
#: sar.c:1261
|
||||
#, c-format
|
||||
msgid "Invalid data format\n"
|
||||
msgstr "Verkeerde data formaat\n"
|
||||
|
||||
#: sar.c:1633
|
||||
#, c-format
|
||||
msgid "-f and -o options are mutually exclusive\n"
|
||||
msgstr "Opsies -f en -o is beide uitgesluit\n"
|
||||
|
||||
#: sar.c:1639
|
||||
#, c-format
|
||||
msgid "Not reading from a system activity file (use -f option)\n"
|
||||
msgstr "Kan nie van sisteem aktiviteit leer lees nie (gebruik opsie -f)\n"
|
|
@ -0,0 +1,573 @@
|
|||
# Czech translations for sysstat package.
|
||||
# Copyright (C) 2011 THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the sysstat package.
|
||||
#
|
||||
# Marek Černocký <marek@manet.cz>, 2010, 2011, 2013, 2015, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sysstat 11.5.1\n"
|
||||
"Report-Msgid-Bugs-To: sysstat <at> orange.fr\n"
|
||||
"POT-Creation-Date: 2016-09-23 15:07+0200\n"
|
||||
"PO-Revision-Date: 2016-09-24 00:01+0200\n"
|
||||
"Last-Translator: Marek Černocký <marek@manet.cz>\n"
|
||||
"Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
|
||||
"Language: cs\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Bugs: Report translation errors to the Language-Team address.\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
"X-Generator: Gtranslator 2.91.7\n"
|
||||
|
||||
#: iostat.c:86 cifsiostat.c:70 mpstat.c:98 sar.c:96 pidstat.c:87 tapestat.c:89
|
||||
#, c-format
|
||||
msgid "Usage: %s [ options ] [ <interval> [ <count> ] ]\n"
|
||||
msgstr "Použití: %s [přepínače] [<interval> [<počet>]]\n"
|
||||
|
||||
#: iostat.c:89
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Options are:\n"
|
||||
"[ -c ] [ -d ] [ -h ] [ -k | -m ] [ -N ] [ -t ] [ -V ] [ -x ] [ -y ] [ -z ]\n"
|
||||
"[ -j { ID | LABEL | PATH | UUID | ... } ] [ -o JSON ]\n"
|
||||
"[ [ -H ] -g <group_name> ] [ -p [ <device> [,...] | ALL ] ]\n"
|
||||
"[ <device> [...] | ALL ] [ --debuginfo ]\n"
|
||||
msgstr ""
|
||||
"Přepínače jsou:\n"
|
||||
"[-c] [-d] [-h] [-k|-m] [-N] [-t] [-V] [-x] [-y] [-z]\n"
|
||||
"[-j {ID|LABEL|PATH|UUID|…}] [-o JSON]\n"
|
||||
"[[-H] -g <název_skupiny>] [-p [<zařízení>[,…]|ALL]]\n"
|
||||
"[<zařízení> […]|ALL] [--debuginfo]\n"
|
||||
|
||||
#: iostat.c:95
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Options are:\n"
|
||||
"[ -c ] [ -d ] [ -h ] [ -k | -m ] [ -N ] [ -t ] [ -V ] [ -x ] [ -y ] [ -z ]\n"
|
||||
"[ -j { ID | LABEL | PATH | UUID | ... } ] [ -o JSON ]\n"
|
||||
"[ [ -H ] -g <group_name> ] [ -p [ <device> [,...] | ALL ] ]\n"
|
||||
"[ <device> [...] | ALL ]\n"
|
||||
msgstr ""
|
||||
"Přepínače jsou:\n"
|
||||
"[-c] [-d] [-h] [-k|-m] [-N] [-t] [-V] [-x] [-y] [-z]\n"
|
||||
"[-j {ID|LABEL|PATH|UUID|…}] [-o JSON]\n"
|
||||
"[[-H] -g <název_skupiny>] [-p [<zařízení>[,…]|ALL]]\n"
|
||||
"[<zařízení> […]|ALL]\n"
|
||||
|
||||
#: iostat.c:326
|
||||
#, c-format
|
||||
msgid "Cannot find disk data\n"
|
||||
msgstr "Nelze najít data na disku\n"
|
||||
|
||||
#: iostat.c:1660 sa_common.c:1650
|
||||
#, c-format
|
||||
msgid "Invalid type of persistent device name\n"
|
||||
msgstr "Neplatný typ trvalého názvu zařízení\n"
|
||||
|
||||
#: sadf_misc.c:749
|
||||
#, c-format
|
||||
msgid "System activity data file: %s (%#x)\n"
|
||||
msgstr "Datový soubor se systémovými aktivitami: %s (%#x)\n"
|
||||
|
||||
#: sadf_misc.c:758
|
||||
#, c-format
|
||||
msgid "Genuine sa datafile: %s (%x)\n"
|
||||
msgstr "Skutečný datový soubor se systémovými aktivitami: %s (%x)\n"
|
||||
|
||||
#: sadf_misc.c:759
|
||||
msgid "no"
|
||||
msgstr "ne"
|
||||
|
||||
#: sadf_misc.c:759
|
||||
msgid "yes"
|
||||
msgstr "ano"
|
||||
|
||||
#: sadf_misc.c:762
|
||||
#, c-format
|
||||
msgid "Host: "
|
||||
msgstr "Počítač: "
|
||||
|
||||
#: sadf_misc.c:769
|
||||
#, c-format
|
||||
msgid "Number of CPU for last samples in file: %u\n"
|
||||
msgstr "Počet CPU pro poslední vzorky v souboru: %u\n"
|
||||
|
||||
#: sadf_misc.c:775
|
||||
#, c-format
|
||||
msgid "File date: %s\n"
|
||||
msgstr "Datum souboru: %s\n"
|
||||
|
||||
#: sadf_misc.c:778
|
||||
#, c-format
|
||||
msgid "File time: "
|
||||
msgstr "Čas souboru: "
|
||||
|
||||
#: sadf_misc.c:783
|
||||
#, c-format
|
||||
msgid "Size of a long int: %d\n"
|
||||
msgstr "Velikost „long int“: %d\n"
|
||||
|
||||
#: sadf_misc.c:789
|
||||
#, c-format
|
||||
msgid "List of activities:\n"
|
||||
msgstr "Seznam aktivit:\n"
|
||||
|
||||
#: sadf_misc.c:802
|
||||
#, c-format
|
||||
msgid "\t[Unknown activity format]"
|
||||
msgstr "\t[Neznámý formát aktivity]"
|
||||
|
||||
#: sadc.c:89
|
||||
#, c-format
|
||||
msgid "Usage: %s [ options ] [ <interval> [ <count> ] ] [ <outfile> ]\n"
|
||||
msgstr "Použití: %s [přepínače] [<interval> [<počet>]] [<vstupní_soubor>]\n"
|
||||
|
||||
#: sadc.c:92
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Options are:\n"
|
||||
"[ -C <comment> ] [ -D ] [ -F ] [ -L ] [ -V ]\n"
|
||||
"[ -S { INT | DISK | IPV6 | POWER | SNMP | XDISK | ALL | XALL } ]\n"
|
||||
msgstr ""
|
||||
"Přepínače jsou:\n"
|
||||
"[-C <komentář>] [-D] [-F] [-L] [-V]\n"
|
||||
"[-S {INT|DISK|IPV6|POWER|SNMP|XDISK|ALL|XALL}]\n"
|
||||
|
||||
#: sadc.c:267
|
||||
#, c-format
|
||||
msgid "Cannot write data to system activity file: %s\n"
|
||||
msgstr "Nelze zapsat data do souboru se systémovými aktivitami: %s\n"
|
||||
|
||||
#: sadc.c:563
|
||||
#, c-format
|
||||
msgid "Cannot write system activity file header: %s\n"
|
||||
msgstr "Nelze zapsat hlavičku souboru se systémovými aktivitami: %s\n"
|
||||
|
||||
#: sadc.c:763 sadc.c:772 sadc.c:839 ioconf.c:510 rd_stats.c:69
|
||||
#: sa_common.c:1264 count.c:118
|
||||
#, c-format
|
||||
msgid "Cannot open %s: %s\n"
|
||||
msgstr "Nelze otevřít %s: %s\n"
|
||||
|
||||
#: sadc.c:1019
|
||||
#, c-format
|
||||
msgid "Cannot append data to that file (%s)\n"
|
||||
msgstr "Nelze připojit data do tohoto souboru (%s)\n"
|
||||
|
||||
#: common.c:74
|
||||
#, c-format
|
||||
msgid "sysstat version %s\n"
|
||||
msgstr "sysstat verze %s\n"
|
||||
|
||||
#: cifsiostat.c:74
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Options are:\n"
|
||||
"[ -h ] [ -k | -m ] [ -t ] [ -V ] [ --debuginfo ]\n"
|
||||
msgstr ""
|
||||
"Přepínače jsou:\n"
|
||||
"[-h] [-k|-m] [-t] [-V] [--debuginfo]\n"
|
||||
|
||||
#: cifsiostat.c:77
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Options are:\n"
|
||||
"[ -h ] [ -k | -m ] [ -t ] [ -V ]\n"
|
||||
msgstr ""
|
||||
"Přepínače jsou:\n"
|
||||
"[-h] [-k|-m] [-t] [-V]\n"
|
||||
|
||||
#: mpstat.c:101
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Options are:\n"
|
||||
"[ -A ] [ -u ] [ -V ] [ -I { SUM | CPU | SCPU | ALL } ]\n"
|
||||
"[ -o JSON ] [ -P { <cpu> [,...] | ON | ALL } ]\n"
|
||||
msgstr ""
|
||||
"Přepínače jsou:\n"
|
||||
"[-A] [-u] [-V] [-I {SUM|CPU|SCPU|ALL}]\n"
|
||||
"[-o JSON] [-P {<procesor>[,…]|ON|ALL}]\n"
|
||||
|
||||
#: mpstat.c:1210 sar.c:358 pidstat.c:2303
|
||||
msgid "Average:"
|
||||
msgstr "Průměr:"
|
||||
|
||||
#: mpstat.c:1636
|
||||
#, c-format
|
||||
msgid "Not that many processors!\n"
|
||||
msgstr "Tolik procesorů není!\n"
|
||||
|
||||
#: sadf.c:86
|
||||
#, c-format
|
||||
msgid "Usage: %s [ options ] [ <interval> [ <count> ] ] [ <datafile> | -[0-9]+ ]\n"
|
||||
msgstr "Použití: %s [přepínače] [<interval> [<počet>]] [<datový_soubor>|-[0-9]+]\n"
|
||||
|
||||
#: sadf.c:89
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Options are:\n"
|
||||
"[ -C ] [ -c | -d | -g | -j | -p | -x ] [ -H ] [ -h ] [ -T | -t | -U ] [ -V ]\n"
|
||||
"[ -O <opts> [,...] ] [ -P { <cpu> [,...] | ALL } ]\n"
|
||||
"[ -s [ <hh:mm[:ss]> ] ] [ -e [ <hh:mm[:ss]> ] ]\n"
|
||||
"[ -- <sar_options> ]\n"
|
||||
msgstr ""
|
||||
"Přepínače jsou:\n"
|
||||
"[-C] [-c|-d|-g|-j|-p|-x] [-H] [-h] [-T|-t|-U] [-V]\n"
|
||||
"[-O <volby> [,…] ] [-P {<procesor> [,…]|ALL}]\n"
|
||||
"[-s[ <hh:mm[:ss]>]] [-e[ <hh:mm[:ss]>]]\n"
|
||||
"[-- <přepínače_sar>]\n"
|
||||
|
||||
#: sar.c:111
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Options are:\n"
|
||||
"[ -A ] [ -B ] [ -b ] [ -C ] [ -D ] [ -d ] [ -F [ MOUNT ] ] [ -H ] [ -h ]\n"
|
||||
"[ -p ] [ -q ] [ -R ] [ -r [ ALL ] ] [ -S ] [ -t ] [ -u [ ALL ] ] [ -V ]\n"
|
||||
"[ -v ] [ -W ] [ -w ] [ -y ] [ --sadc ]\n"
|
||||
"[ -I { <int> [,...] | SUM | ALL | XALL } ] [ -P { <cpu> [,...] | ALL } ]\n"
|
||||
"[ -m { <keyword> [,...] | ALL } ] [ -n { <keyword> [,...] | ALL } ]\n"
|
||||
"[ -j { ID | LABEL | PATH | UUID | ... } ]\n"
|
||||
"[ -f [ <filename> ] | -o [ <filename> ] | -[0-9]+ ]\n"
|
||||
"[ -i <interval> ] [ -s [ <hh:mm[:ss]> ] ] [ -e [ <hh:mm[:ss]> ] ]\n"
|
||||
msgstr ""
|
||||
"Přepínače jsou:\n"
|
||||
"[-A] [-B] [-b] [-C] [-D] [-d] [-F [MOUNT]] [-H] [-h]\n"
|
||||
"[-p] [-q] [-R] [-r [ALL]] [-S] [-t] [-u [ALL]] [-V]\n"
|
||||
"[-v] [-W] [-w] [-y] [--sadc]\n"
|
||||
"[-I {<přerušení>[,…]|SUM|ALL|XALL}] [-P {<procesor>[,…]|ALL}]\n"
|
||||
"[-m {<klíčové_slovo>[,…]|ALL}] [-n {<klíčové_slovo>[,…]|ALL}]\n"
|
||||
"[-j {ID|LABEL|PATH|UUID|…}]\n"
|
||||
"[-f [<název_souboru>]|-o [<název_souboru>]|-[0-9]+]\n"
|
||||
"[-i <interval>] [-s[ <hh:mm[:ss]>]] [-e[ <hh:mm[:ss]>]]\n"
|
||||
|
||||
#: sar.c:134
|
||||
#, c-format
|
||||
msgid "Main options and reports:\n"
|
||||
msgstr "Hlavní přepínače a výstupní sestavy:\n"
|
||||
|
||||
#: sar.c:135
|
||||
#, c-format
|
||||
msgid "\t-B\tPaging statistics\n"
|
||||
msgstr "\t-B\tStatistiky stránkování\n"
|
||||
|
||||
#: sar.c:136
|
||||
#, c-format
|
||||
msgid "\t-b\tI/O and transfer rate statistics\n"
|
||||
msgstr "\t-b\tStatistiky přenosové rychlosti V/V\n"
|
||||
|
||||
#: sar.c:137
|
||||
#, c-format
|
||||
msgid "\t-d\tBlock devices statistics\n"
|
||||
msgstr "\t-d\tStatistiky blokových zařízení\n"
|
||||
|
||||
#: sar.c:138
|
||||
#, c-format
|
||||
msgid "\t-F [ MOUNT ]\n"
|
||||
msgstr "\t-F [MOUNT]\n"
|
||||
|
||||
#: sar.c:139
|
||||
#, c-format
|
||||
msgid "\t\tFilesystems statistics\n"
|
||||
msgstr "\t\tStatistiky souborových systémů\n"
|
||||
|
||||
#: sar.c:140
|
||||
#, c-format
|
||||
msgid "\t-H\tHugepages utilization statistics\n"
|
||||
msgstr "\t-H\tStatistiky využití velkých paměťových stránek (hugepages)\n"
|
||||
|
||||
#: sar.c:141
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\t-I { <int> | SUM | ALL | XALL }\n"
|
||||
"\t\tInterrupts statistics\n"
|
||||
msgstr ""
|
||||
"\t-I {<přerušení>|SUM|ALL|XALL}\n"
|
||||
"\t\tStatistiky přerušení\n"
|
||||
|
||||
#: sar.c:143
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\t-m { <keyword> [,...] | ALL }\n"
|
||||
"\t\tPower management statistics\n"
|
||||
"\t\tKeywords are:\n"
|
||||
"\t\tCPU\tCPU instantaneous clock frequency\n"
|
||||
"\t\tFAN\tFans speed\n"
|
||||
"\t\tFREQ\tCPU average clock frequency\n"
|
||||
"\t\tIN\tVoltage inputs\n"
|
||||
"\t\tTEMP\tDevices temperature\n"
|
||||
"\t\tUSB\tUSB devices plugged into the system\n"
|
||||
msgstr ""
|
||||
"\t-m {<klíčové_slovo>[,…]|ALL}\n"
|
||||
"\t\tStatistiky správy napájení\n"
|
||||
"\t\tKlíčová slova jsou:\n"
|
||||
"\t\tCPU\tMomentální frekvence procesoru\n"
|
||||
"\t\tFAN\tRychlost ventilátoru\n"
|
||||
"\t\tFREQ\tPrůměrná frekvence procesoru\n"
|
||||
"\t\tIN\tVstupní napětí\n"
|
||||
"\t\tTEMP\tTeplota zařízení\n"
|
||||
"\t\tUSB\tZařízení USB připojená do systému\n"
|
||||
|
||||
#: sar.c:152
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\t-n { <keyword> [,...] | ALL }\n"
|
||||
"\t\tNetwork statistics\n"
|
||||
"\t\tKeywords are:\n"
|
||||
"\t\tDEV\tNetwork interfaces\n"
|
||||
"\t\tEDEV\tNetwork interfaces (errors)\n"
|
||||
"\t\tNFS\tNFS client\n"
|
||||
"\t\tNFSD\tNFS server\n"
|
||||
"\t\tSOCK\tSockets\t(v4)\n"
|
||||
"\t\tIP\tIP traffic\t(v4)\n"
|
||||
"\t\tEIP\tIP traffic\t(v4) (errors)\n"
|
||||
"\t\tICMP\tICMP traffic\t(v4)\n"
|
||||
"\t\tEICMP\tICMP traffic\t(v4) (errors)\n"
|
||||
"\t\tTCP\tTCP traffic\t(v4)\n"
|
||||
"\t\tETCP\tTCP traffic\t(v4) (errors)\n"
|
||||
"\t\tUDP\tUDP traffic\t(v4)\n"
|
||||
"\t\tSOCK6\tSockets\t(v6)\n"
|
||||
"\t\tIP6\tIP traffic\t(v6)\n"
|
||||
"\t\tEIP6\tIP traffic\t(v6) (errors)\n"
|
||||
"\t\tICMP6\tICMP traffic\t(v6)\n"
|
||||
"\t\tEICMP6\tICMP traffic\t(v6) (errors)\n"
|
||||
"\t\tUDP6\tUDP traffic\t(v6)\n"
|
||||
"\t\tFC\tFibre channel HBAs\n"
|
||||
msgstr ""
|
||||
"\t-n {<klíčové_slovo>[,…]|ALL}\n"
|
||||
"\t\tStatistiky sítě\n"
|
||||
"\t\tKlíčová slova jsou:\n"
|
||||
"\t\tDEV\tSíťové rozhraní\n"
|
||||
"\t\tEDEV\tSíťové rozhraní (chyby)\n"
|
||||
"\t\tNFS\tKlient NFS\n"
|
||||
"\t\tNFSD\tServer NFS\n"
|
||||
"\t\tSOCK\tSokety\t(v4)\n"
|
||||
"\t\tIP\tProvoz IP\t(v4)\n"
|
||||
"\t\tEIP\tProvoz IP\t(v4) (chyby)\n"
|
||||
"\t\tICMP\tProvoz ICMP\t(v4)\n"
|
||||
"\t\tEICMP\tProvoz ICMP\t(v4) (chyby)\n"
|
||||
"\t\tTCP\tProvoz TCP\t(v4)\n"
|
||||
"\t\tETCP\tProvoz TCP\t(v4) (chyby)\n"
|
||||
"\t\tUDP\tProvoz UDP\t(v4)\n"
|
||||
"\t\tSOCK6\tSokety\t(v6)\n"
|
||||
"\t\tIP6\tProvoz IP\t(v6)\n"
|
||||
"\t\tEIP6\tProvoz IP\t(v6) (chyby)\n"
|
||||
"\t\tICMP6\tProvoz ICMP\t(v6)\n"
|
||||
"\t\tEICMP6\tProvoz ICMP\t(v6) (chyby)\n"
|
||||
"\t\tUDP6\tProvoz UDP\t(v6)\n"
|
||||
"\t\tFC\tHBA optických kanálů\n"
|
||||
|
||||
#: sar.c:174
|
||||
#, c-format
|
||||
msgid "\t-q\tQueue length and load average statistics\n"
|
||||
msgstr "\t-q\tStatistiky délky fronty a průměrného vytížení\n"
|
||||
|
||||
#: sar.c:175
|
||||
#, c-format
|
||||
msgid "\t-R\tMemory statistics\n"
|
||||
msgstr "\t-R\tStatistiky paměti\n"
|
||||
|
||||
#: sar.c:176
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\t-r [ ALL ]\n"
|
||||
"\t\tMemory utilization statistics\n"
|
||||
msgstr ""
|
||||
"\t-r [ALL]\n"
|
||||
"\t\tStatistiky využití paměti\n"
|
||||
|
||||
#: sar.c:178
|
||||
#, c-format
|
||||
msgid "\t-S\tSwap space utilization statistics\n"
|
||||
msgstr "\t-S\tStatistiky využití odkládacího prostoru\n"
|
||||
|
||||
#: sar.c:179
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\t-u [ ALL ]\n"
|
||||
"\t\tCPU utilization statistics\n"
|
||||
msgstr ""
|
||||
"\t-u [ALL]\n"
|
||||
"\t\tStatistiky využití procesoru\n"
|
||||
|
||||
#: sar.c:181
|
||||
#, c-format
|
||||
msgid "\t-v\tKernel tables statistics\n"
|
||||
msgstr "\t-v\tStatistiky tabulek jádra\n"
|
||||
|
||||
#: sar.c:182
|
||||
#, c-format
|
||||
msgid "\t-W\tSwapping statistics\n"
|
||||
msgstr "\t-W\tStatistiky odkládání na disk\n"
|
||||
|
||||
#: sar.c:183
|
||||
#, c-format
|
||||
msgid "\t-w\tTask creation and system switching statistics\n"
|
||||
msgstr "\t-w\tStatistiky vytváření úloh a systémového přepínání\n"
|
||||
|
||||
#: sar.c:184
|
||||
#, c-format
|
||||
msgid "\t-y\tTTY devices statistics\n"
|
||||
msgstr "\t-y\tStatistiky zařízení TTY\n"
|
||||
|
||||
#: sar.c:198
|
||||
#, c-format
|
||||
msgid "Data collector will be sought in PATH\n"
|
||||
msgstr "Sběrač dat bude hledán v cestě PATH\n"
|
||||
|
||||
#: sar.c:201
|
||||
#, c-format
|
||||
msgid "Data collector found: %s\n"
|
||||
msgstr "Nalezen sběrač dat: %s\n"
|
||||
|
||||
#: sar.c:260
|
||||
#, c-format
|
||||
msgid "End of data collecting unexpected\n"
|
||||
msgstr "Neočekávaný konec sbírání dat\n"
|
||||
|
||||
#: sar.c:813
|
||||
#, c-format
|
||||
msgid "Using a wrong data collector from a different sysstat version\n"
|
||||
msgstr "Používání nesprávného sběrače dat z jiné verze sysstat\n"
|
||||
|
||||
#: sar.c:865
|
||||
#, c-format
|
||||
msgid "Inconsistent input data\n"
|
||||
msgstr "Nekonzistentní vstupní data\n"
|
||||
|
||||
#: sar.c:1044 pidstat.c:239
|
||||
#, c-format
|
||||
msgid "Requested activities not available\n"
|
||||
msgstr "Požadované aktivity nejsou dostupné\n"
|
||||
|
||||
#: sar.c:1350
|
||||
#, c-format
|
||||
msgid "-f and -o options are mutually exclusive\n"
|
||||
msgstr "Přepínače -f a -o se navzájem vylučují\n"
|
||||
|
||||
#: sar.c:1356
|
||||
#, c-format
|
||||
msgid "Not reading from a system activity file (use -f option)\n"
|
||||
msgstr "Nečte se ze souboru se systémovými aktivitami (použijte přepínač -f)\n"
|
||||
|
||||
#: sar.c:1492
|
||||
#, c-format
|
||||
msgid "Cannot find the data collector (%s)\n"
|
||||
msgstr "Nelze najít sběrač dat (%s)\n"
|
||||
|
||||
#: pr_stats.c:2494 pr_stats.c:2505 pr_stats.c:2606 pr_stats.c:2617
|
||||
msgid "Summary:"
|
||||
msgstr "Souhrn:"
|
||||
|
||||
#: pr_stats.c:2547
|
||||
msgid "Other devices not listed here"
|
||||
msgstr "Ostatní zde neuvedená zařízení"
|
||||
|
||||
#: sa_conv.c:69
|
||||
#, c-format
|
||||
msgid "Cannot convert the format of this file\n"
|
||||
msgstr "Nelze převést formát tohoto souboru\n"
|
||||
|
||||
#: sa_conv.c:562
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\n"
|
||||
"CPU activity not found in file. Aborting...\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"V souboru nebyla nalezena aktivita CPU. Končí se…\n"
|
||||
|
||||
#: sa_conv.c:578
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\n"
|
||||
"Invalid data found. Aborting...\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Byla nalezena neplatná data. Končí se…\n"
|
||||
|
||||
#: sa_conv.c:897
|
||||
#, c-format
|
||||
msgid "Statistics: "
|
||||
msgstr "Statistiky: "
|
||||
|
||||
#: sa_conv.c:1016
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\n"
|
||||
"File successfully converted to sysstat format version %s\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Soubor byl úspěšně převeden do formátu sysstat verze %s\n"
|
||||
|
||||
#: pidstat.c:90
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Options are:\n"
|
||||
"[ -d ] [ -h ] [ -I ] [ -l ] [ -R ] [ -r ] [ -s ] [ -t ] [ -U [ <username> ] ]\n"
|
||||
"[ -u ] [ -V ] [ -v ] [ -w ] [ -C <command> ] [ -G <process_name> ]\n"
|
||||
"[ -p { <pid> [,...] | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ]\n"
|
||||
msgstr ""
|
||||
"Přepínače jsou:\n"
|
||||
"[-d] [-h] [-I] [-l] [-R] [-r] [-s] [-t] [-U [<uživatelské_jméno>]]\n"
|
||||
"[-u] [-V] [-v] [-w] [-C <příkaz>] [-G <název_procesu>]\n"
|
||||
"[-p {<id_procesu>[,…]|SELF|ALL}] [-T {TASK|CHILD|ALL}]\n"
|
||||
|
||||
#: sa_common.c:1060
|
||||
#, c-format
|
||||
msgid "Error while reading system activity file: %s\n"
|
||||
msgstr "Chyba při čtení souboru se systémovými aktivitami: %s\n"
|
||||
|
||||
#: sa_common.c:1070
|
||||
#, c-format
|
||||
msgid "End of system activity file unexpected\n"
|
||||
msgstr "Neočekávaný konec souboru se systémovými aktivitami\n"
|
||||
|
||||
#: sa_common.c:1089
|
||||
#, c-format
|
||||
msgid "File created by sar/sadc from sysstat version %d.%d.%d"
|
||||
msgstr "Soubor vytvořen pomocí sar/sadc z balíku sysstat verze %d.%d.%d"
|
||||
|
||||
#: sa_common.c:1122
|
||||
#, c-format
|
||||
msgid "Invalid system activity file: %s\n"
|
||||
msgstr "Neplatný soubor se systémovými aktivitami: %s\n"
|
||||
|
||||
#: sa_common.c:1134
|
||||
#, c-format
|
||||
msgid "Endian format mismatch\n"
|
||||
msgstr "Formát endian neodpovídá\n"
|
||||
|
||||
#: sa_common.c:1138
|
||||
#, c-format
|
||||
msgid "Current sysstat version cannot read the format of this file (%#x)\n"
|
||||
msgstr "Současná verze sysstat neumí číst formát tohoto souboru (%#x)\n"
|
||||
|
||||
#: sa_common.c:1267
|
||||
#, c-format
|
||||
msgid "Please check if data collecting is enabled\n"
|
||||
msgstr "Zkontrolujte prosím, zda je povolen sběr dat\n"
|
||||
|
||||
#: sa_common.c:1460
|
||||
#, c-format
|
||||
msgid "Requested activities not available in file %s\n"
|
||||
msgstr "Požadované aktivity nejsou v souboru %s dostupné\n"
|
||||
|
||||
#: tapestat.c:91
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Options are:\n"
|
||||
"[ -k | -m ] [ -t ] [ -V ] [ -y ] [ -z ]\n"
|
||||
msgstr ""
|
||||
"Přepínače jsou:\n"
|
||||
"[-k|-m] [-t] [-V] [-y] [-z]\n"
|
||||
|
||||
#: tapestat.c:257
|
||||
#, c-format
|
||||
msgid "No tape drives with statistics found\n"
|
||||
msgstr "Nebyly nalezeny žádné páskové mechaniky se statistikami\n"
|
||||
|
||||
#: count.c:169
|
||||
#, c-format
|
||||
msgid "Cannot handle so many processors!\n"
|
||||
msgstr "Nelze obsloužit tolik procesorů!\n"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue