Import Upstream version 12.6.1

This commit is contained in:
denghao 2023-02-28 13:51:48 +08:00
commit 1b5eb75187
4009 changed files with 218692 additions and 0 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
custom: "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=45U6F9R73ESFQ"

58
.gitignore vendored Normal file
View File

@ -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

3
.lgtm.yml Normal file
View File

@ -0,0 +1,3 @@
path_classifiers:
library:
- contrib

2
.travis.yml Normal file
View File

@ -0,0 +1,2 @@
language: c
script: ./do_test

20
BUG_REPORT Normal file
View File

@ -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.

2934
CHANGES Normal file

File diff suppressed because it is too large Load Diff

339
COPYING Normal file
View File

@ -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.

263
CREDITS Normal file
View File

@ -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.

774
FAQ.md Normal file
View File

@ -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.

229
INSTALL Normal file
View File

@ -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.

884
Makefile.in Normal file
View File

@ -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]

193
README.md Normal file
View File

@ -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

2082
activity.c Normal file

File diff suppressed because it is too large Load Diff

20
build/Ask.sh Normal file
View File

@ -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

11
build/clean-sa-dir Normal file
View File

@ -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".

8
build/collect-all Normal file
View 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.

6
build/compress-manpg Normal file
View File

@ -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).

8
build/compressafter Normal file
View File

@ -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.

6
build/conf_dir Normal file
View 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.

5
build/conf_file Normal file
View File

@ -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".

15
build/copy-only Normal file
View File

@ -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).

7
build/cron_interval Normal file
View File

@ -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.

7
build/cron_owner Normal file
View File

@ -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.

4
build/debuginfo Normal file
View File

@ -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.

6
build/delay_range Normal file
View File

@ -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.

11
build/history Normal file
View File

@ -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.

9
build/ignore-file-attr Normal file
View 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.

9
build/install-cron Normal file
View File

@ -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.

6
build/install-doc Normal file
View File

@ -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).

7
build/lto Normal file
View File

@ -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).

6
build/man_group Normal file
View File

@ -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.

9
build/nls Normal file
View File

@ -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.

4
build/pcp Normal file
View File

@ -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.

7
build/prefix Normal file
View File

@ -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.

7
build/rcdir Normal file
View File

@ -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.

7
build/sa_dir Normal file
View File

@ -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.

6
build/sa_lib_dir Normal file
View File

@ -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.

10
build/sadc_options Normal file
View File

@ -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.

7
build/sensors Normal file
View File

@ -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.)

6
build/stripping Normal file
View File

@ -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).

6
build/use-crond Normal file
View File

@ -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).

626
cifsiostat.c Normal file
View File

@ -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;
}

52
cifsiostat.h Normal file
View File

@ -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 */

1688
common.c Normal file

File diff suppressed because it is too large Load Diff

320
common.h Normal file
View File

@ -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 */

7136
configure vendored Executable file

File diff suppressed because it is too large Load Diff

807
configure.in Normal file
View File

@ -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
"

8
contrib/README-contrib Normal file
View File

@ -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)

22
contrib/irqstat/LICENSE Normal file
View File

@ -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.

View File

@ -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>

396
contrib/irqstat/irqstat Executable file
View File

@ -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))

10
contrib/irqstat/pylint.rc Normal file
View File

@ -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

411
contrib/irqtop/irqtop Executable file
View File

@ -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);
}

18
contrib/isag/README-isag Normal file
View File

@ -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)

1581
contrib/isag/isag Executable file

File diff suppressed because it is too large Load Diff

201
contrib/isag/isag.1 Normal file
View File

@ -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).

529
contrib/sargraph/sargraph Executable file
View File

@ -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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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:

294
contrib/sargraph/sargraph2 Executable file
View File

@ -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:

537
count.c Normal file
View File

@ -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 */

39
count.h Normal file
View File

@ -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 */

BIN
cron/.toto.swp Normal file

Binary file not shown.

19
cron/crontab.sample Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,3 @@
#!/bin/sh
# Run system activity accounting tool every @CRON_INTERVAL@ minutes
@SA_LIB_DIR@/sa1 @CRON_INTERVAL_SEC@ @CRON_COUNT@

6
cron/sysstat.crond.in Normal file
View File

@ -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

7
cron/sysstat.sleep.in Normal file
View File

@ -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 $*

20
do_test Executable file
View File

@ -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

199
format.c Normal file
View File

@ -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

253
iconfig Executable file
View File

@ -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}

BIN
images/color_output.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
images/cpugraph.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
images/iostat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
images/loadavg-svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
images/tcgraph.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

507
ioconf.c Normal file
View File

@ -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;
}

92
ioconf.h Normal file
View File

@ -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

2406
iostat.c Normal file

File diff suppressed because it is too large Load Diff

162
iostat.h Normal file
View File

@ -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 */

2612
json_stats.c Normal file

File diff suppressed because it is too large Load Diff

103
json_stats.h Normal file
View File

@ -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 */

154
man/cifsiostat.in Normal file
View File

@ -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/

477
man/iostat.in Normal file
View File

@ -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/

241
man/mpstat.1 Normal file
View File

@ -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/

450
man/pidstat.1 Normal file
View File

@ -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/

91
man/sa1.in Normal file
View File

@ -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/

56
man/sa2.in Normal file
View File

@ -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/

205
man/sadc.in Normal file
View File

@ -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/

384
man/sadf.in Normal file
View File

@ -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/

1691
man/sar.in Normal file

File diff suppressed because it is too large Load Diff

161
man/sysstat.in Normal file
View File

@ -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/

233
man/tapestat.1 Normal file
View File

@ -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/

2404
mpstat.c Normal file

File diff suppressed because it is too large Load Diff

107
mpstat.h Normal file
View File

@ -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

69
nls/README-nls Normal file
View File

@ -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)

196
nls/af.po Normal file
View File

@ -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"

573
nls/cs.po Normal file
View File

@ -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