Skip to content

Instantly share code, notes, and snippets.

@dreness
Created December 3, 2016 00:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dreness/8fc259ad45db0a190addcc73e50dc5ac to your computer and use it in GitHub Desktop.
Save dreness/8fc259ad45db0a190addcc73e50dc5ac to your computer and use it in GitHub Desktop.
Properly sort the sa(8) accounting records by time stamp
#!/usr/bin/python
from __future__ import print_function
from datetime import datetime
'''
Display the account records gathered by the sa(8) facility.
from /usr/include/sys/acct.h
or on macOS, /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/sys/acct.h
/*
* Accounting structures; these use a comp_t type which is a 3 bits base 8
* exponent, 13 bit fraction ``floating point'' number. Units are 1/AHZ
* seconds.
*/
typedef u_int16_t comp_t;
struct acct {
char ac_comm[10]; /* command name */
comp_t ac_utime; /* user time */
comp_t ac_stime; /* system time */
comp_t ac_etime; /* elapsed time */
u_int32_t ac_btime; /* starting time */
uid_t ac_uid; /* user id */
gid_t ac_gid; /* group id */
u_int16_t ac_mem; /* average memory usage */
comp_t ac_io; /* count of IO blocks */
dev_t ac_tty; /* controlling tty */
#define AFORK 0x01 /* fork'd but not exec'd */
#define ASU 0x02 /* used super-user permissions */
#define ACOMPAT 0x04 /* used compatibility mode */
#define ACORE 0x08 /* dumped core */
#define AXSIG 0x10 /* killed by a signal */
u_int8_t ac_flag; /* accounting flags */
};
'''
def chunks(l, n):
"""Yield successive n-sized chunks from l."""
for i in xrange(0, len(l), n):
yield l[i:i + n]
def flipHex(i):
return int("".join(i)[::-1].encode("hex"), 16)
fh = open("/var/account/acct", 'r')
sa = fh.read()
tfmt = "%Y-%m-%d %H:%M:%S"
pfmt = "{: <20} {: <5} {: <5} {}"
print(pfmt.format("Start Time", "uid", "gid", "command"))
records = []
# entries from the acct file are each 40 chars long
for rec in chunks(sa, 40):
r = {}
r['cmd'] = rec[:9]
r['start_time'] = flipHex(rec[16:20])
r['uid'] = flipHex(rec[20:24])
r['gid'] = flipHex(rec[24:28])
records.append(r)
sorted_records = sorted(records, key=lambda k: k['start_time'])
for r in sorted_records:
print(pfmt.format(str(datetime.fromtimestamp(r['start_time'])), r['uid'], r['gid'], r['cmd']))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment