ubuntu@ip-172-31-23-227:~$ accton --help
Usage: accton [OPTION] on|off|ACCOUNTING_FILE
Turns process accounting on or off, or changes the file where this
info is saved.
OPTIONS:
-h, --help Show help and exit
-V, --version Show version and exit
ARGUMENTS:
on Activate process accounting and use default file
off Deactivate process accounting
ACCOUNTING_FILE Activate (if not active) and save information in
this file
The system's default process accounting file is '/var/log/account/pacct'.
Report bugs to <bug-acct@gnu.org>
shell:
ubuntu@ip-172-31-23-227:~$ sudo accton ./own_acct
Turning on process accounting, file set to './own_acct'.
ubuntu@ip-172-31-23-227:~$ ls -lrt own_acct
-rw-rw-r-- 1 ubuntu ubuntu 128 Sep 27 19:27 own_acct
2. Process Accounting Data Structure
ubuntu@ip-172-31-23-227:~$ less /usr/include/x86_64-linux-gnu/sys/acct.h
......
/*
comp_t is a 16-bit "floating" point number with a 3-bit base 8
exponent and a 13-bit fraction. See linux/kernel/acct.c for the
specific encoding system used.
*/
typedef u_int16_t comp_t;
struct acct
{
char ac_flag; /* Flags. */
u_int16_t ac_uid; /* Real user ID. */
u_int16_t ac_gid; /* Real group ID. */
u_int16_t ac_tty; /* Controlling terminal. */
u_int32_t ac_btime; /* Beginning time. */
comp_t ac_utime; /* User time. */
comp_t ac_stime; /* System time. */
comp_t ac_etime; /* Elapsed time. */
comp_t ac_mem; /* Average memory usage. */
comp_t ac_io; /* Chars transferred. */
comp_t ac_rw; /* Blocks read or written. */
comp_t ac_minflt; /* Minor pagefaults. */
comp_t ac_majflt; /* Major pagefaults. */
comp_t ac_swaps; /* Number of swaps. */
u_int32_t ac_exitcode; /* Process exitcode. */
char ac_comm[ACCT_COMM+1]; /* Command name. */
char ac_pad[10]; /* Padding bytes. */
};
......
Macro used to parse "ac_flag" field:
ubuntu@ip-172-31-23-227:~$ less /usr/include/x86_64-linux-gnu/sys/acct.h
......
enum
{
AFORK = 0x01, /* Has executed fork, but no exec. */
ASU = 0x02, /* Used super-user privileges. */
ACORE = 0x08, /* Dumped core. */
AXSIG = 0x10 /* Killed by a signal. */
};
......
Notes:
1) ac_btime: beginning time records when the process starts, but the time only end up with accuracy of second level, ac_etime: elapsed time records how many clock ticks the process uses. Based on ac_btime, ac_etime and ending order of process accounting record, we can't get the starting order of each process, if each process starts at the same second.
2) If Program A runs exec to launch program B which then run exec to launch program C, "A B C" happens at the same process, so only one process accounting record is written to describe 3 programs.
3. Example:
Process.c will create several processes, each process will be terminated in different ways.
And then we can use accounting.c to read the process accounting file
process.c:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
int main(int argc, char* argv[])
{
pid_t pid;
if((pid = fork()) < 0) {
printf("fork error!\n");
exit(1);
}
else if(pid != 0) { // parent process
sleep(2);
exit(2);
}
// First Child Process
if((pid = fork()) < 0) {
printf("fork error!\n");
exit(1);
}
else if(pid != 0) {
sleep(4);
abort();
}
// Second Child Process
if((pid = fork()) < 0) {
printf("fork error!\n");
exit(1);
}
else if(pid != 0) {
execl("/usr/bin/date", "date", (char*)0);
exit(7);
}
// Third Child Process
if((pid = fork()) < 0) {
printf("fork error!\n");
exit(1);
}
else if(pid != 0) {
sleep(8);
exit(0);
}
// Fourth Child Process
sleep(6);
kill(getpid(), SIGKILL); // the process will be terminated immediately
}
accounting.c:
#include<stdio.h>
#include<stdlib.h>
#include<sys/acct.h>
#include<unistd.h>
#ifdef HAS_SA_STAT
#define FMT "%s e = %6ld, chars = %7ld, stat = %3u: %c %c %c %c\n"
#else
#define FMT "%s e = %6ld, chars = %7ld, %c %c %c %c\n"
#endif
#ifndef HAS_ACORE
#define ACORE 0
#endif
#ifndef HAS_AXSIG
#define AXSIG 0
#endif
static unsigned long compt2ulong(comp_t comptime)
{
unsigned long val;
int exp;
val = comptime & 0x1fff; // val stores lower 13 bits of comptime
exp = (comptime >> 13) & 7; // exp stores lower position 16 15 14, 3 bits of value
while(exp-- > 0)
val *= 8;
return (val);
}
int main(int argc, char* argv[])
{
struct acct acdata;
FILE *fp;
if(argc != 2) {
printf("usage: pracct filename\n");
exit(1);
}
if((fp = fopen(argv[1], "r")) == NULL) {
printf("fopen error!\n");
exit(2);
}
// Read the accounting record, and output to shell
while(fread(&acdata, sizeof(acdata), 1, fp) == 1) {
printf(FMT, acdata.ac_comm, compt2ulong(acdata.ac_etime), compt2ulong(acdata.ac_io),
#ifdef HAS_SA_STAT
(unsigned char) acdata.ac_stat,
#endif
acdata.ac_flag & ACORE ? 'D' : ' ',
acdata.ac_flag & AXSIG ? 'X' : ' ',
acdata.ac_flag & AFORK ? 'F' : ' ',
acdata.ac_flag & ASU ? 'S' : ' ');
}
if(ferror(fp)) {
printf("read error!\n");
exit(3);
}
exit(0);
}
shell:
ubuntu@ip-172-31-23-227:~$ sudo accton ./own_acct
Turning on process accounting, file set to './own_acct'.
ubuntu@ip-172-31-23-227:~$ ./process.out
ubuntu@ip-172-31-23-227:~$ ./pracct.out ./own_acct
No comments:
Post a Comment