[comp.protocols.appletalk] Application accounting log parser

koreth@ssyx.ucsc.edu (Steven Grimm) (04/04/89)

As promised, here is a shell script to make useful reports from the application
accounting logfile, created using the diffs I posted last week.  It reports
simultaneous usage of programs.  The output looks like this:

% simul /usr/adm/aufs.log /usr/adm/aufs.acct
Times	Users	Program
-----	-----	-------
1	1	DIAS Demo 1.01
4	1	Display
2	2	Display
1	1	FreeTerm 3.0B2
8	1	Microsoft Excel
11	1	NCSA Telnet 2.2
2	1	Wallpaper
1	1	Word 3.01

This means that there was one instance of one user running "DIAS Demo 1.01,"
four instances of one user using "Display," and two instances of two users
using "Display" at the same time.

Hope people find this useful.

---
Steven Grimm				koreth@ssyx.ucsc.edu
Division of Social Sciences		uunet!ucbvax!ucscc!ssyx!koreth
University of California, Santa Cruz	"A waist is a terrible thing to mind."


#!/bin/sh

# usage: simul logfile acctfile

if [ $# -ne 2 ]; then
	echo Usage: $0 logfile acctfile
	exit 1
fi

# output some column headers for the script's eventual result.

echo "Times	Users	Program"
echo "-----	-----	-------"

# this is better than a c program, anyway.
# it produces output like
#
# 00321 xx/yy/zz xx:yy:zz O 3		for pid 321 opening as session 3
# 00456 xx/yy/zz xx:yy:zz A MacWrite	for pid 456's client running MacWrite
# 12341 xx/yy/zz xx:yy:zz C		for pid 12341 closing
#
# these are sorted by date then time.
# we are going to use tabs internally later, so change them to spaces here.

(
awk '\
	/starting for/ \
		{ printf("%05d %s %s O %s\n", $5, $2, $3, $9); } \
	/session .* terminated/ \
		{ printf("%05d %s %s C\n", \
		substr($5,1,length($5)-1), $2, $3); } \
	' < $1 ;
awk '{ printf("%s %s %s A %s\n", substr($1, 1, 5), $2, $3, \
	substr($0, 26, length($0)-25)); }' < $2
) |
sort -n +2.6 +2 +2.3 +1d +0 |
cut -c1-5,24- |
tr '	' ' ' |

# then it pipes here, which cooks the output a little and produces (with tabs)
# A	3	MacWrite	for session 3 running MacWrite
# C	1			for session 1 closing

awk '\
	/^..... O/ \
		{ session[$1]=$3 } \
	/^..... C/ \
		{ printf("C\t%d\n", session[$1]); } \
	/^..... A/ \
		{ printf("A\t%d\t%s\n",session[$1],substr($0,9,length($0)-8));\
}' |

# now take this and produce a long simultaneous usage list.  when a program is
# used, if the session was using something else before, reduce the previous
# program's usage count by one.  increment the new usage count by one, and
# output it:
#
# 5	Foolish Quest		for 5 simultaneous Foolish Quest users
#
# when a session closes, decrement it's current program's usage count and
# clear the session's current program.
#
# this can probably be incorporated into the awk above, but it's clearer (for
# me, anyway) this way.

# (that's -F\<tab> even though it looks like a space)
awk -F\	 '\
	/^C/ { \
		users[program[$2]]--; \
		program[$2]=""; \
	} \
	/^A/ { \
		if (program[$2] != "") \
			users[program[$2]]--; \
		if (length(users[$3]) == 0) \
			users[$3] = 0; \
		program[$2] = $3; \
		users[$3]++; \
		printf("%d\t%s\n", users[$3], $3); \
	}' |

# now sort that based on program name and simultaneous users.
sort -t'	' +1 +0n |

# produce a count of each number of times a specific count of simultaneous
# users occurred for each program.
uniq -c |

# unfortunately, this produces screwy spacing, so make it look good.
sed 's/^ *//' |
sed 's/ /	/'