#!/usr/bin/perl ## ExAcctly: Extended Accounting proc Dumper ## ## benr@cuddletech.com - 10/18/09 use strict; use warnings; use Sun::Solaris::Exacct qw(:EXACCT_ALL); die("Usage is $0 \n") unless (@ARGV == 1); # Open the exact file and display the header information. my $ef = ea_new_file($ARGV[0], &O_RDONLY) || die(error_str()); printf("Creator: %s\n", $ef->creator()); printf("Hostname: %s\n\n", $ef->hostname()); ## Print Header: printf("%10s %6s %6s %6s %20s | %6s %6s %10s | %24s | %10s %10s %10s %10s \n", "ZONE", "UID", "GID", "PID", "CMD", "Real", "User", "Sys", "Start Date", "RSS AVG", "RSS MAX", "SysCalls", "Swaps"); print(" ----------------------------------------------------+--------------------------+--------------------------+--------------------------------------------------\n"); my $idxCounter = 1; # Dump the file contents while (my $obj = $ef->get()) { ## Get an object from the EA File and reposition to next. $idxCounter++; ## Count records. my $objectType = $obj->type(); ## Return the object type (group or item) my $objectCatalogObj = $obj->catalog(); ## Return a catalog object for this object my ($a, $b, $c) = $objectCatalogObj->value(); ## Breakout the catalog triplet #printf("Object is: %s - Catalog: %s %s %s\n", $objectType, $a, $b, $c ); ## Output the catalog and object type for the object at hand. if ( $objectType == EO_GROUP) { my $REC_TYPE = ""; if ( $c == EXD_GROUP_PROC ) { $REC_TYPE = "FULL"; } elsif ( $c == EXD_GROUP_PROC_PARTIAL ) { $REC_TYPE = "PART"; } else { next; } my @objectList = $obj->value(); ## Return the sub-group which will contain actual items. my ($__PID, $__CMD, $__UID, $__GID, $__ZONE, $__RSS_AVG, $__RSS_MAX, $__SYSCALLS, $__SWAPS) = ""; my ($__START_S, $__START_NS, $__END_S, $__END_NS) = ""; my ($__USER_S, $__USER_NS, $__SYS_S, $__SYS_NS) = ""; foreach my $item (@objectList) { my $itemsType = $item->type(); ## Get type for new object.. is it a EO_ITEM or EO_GROUP? if ($itemsType == EO_ITEM){ my $itemCatalog = $item->catalog(); ## Return the "Catalog Object" for this object. my ($itemType, $itemGroup, $itemId) = $itemCatalog->value(); ## Breakout the catalog triple my $itemValue = $item->value(); ## Get the item value itself. #print("\t\tId: $itemId \tValue: $itemValue\n"); ## Now print just the catalog item id and item value. $__PID = $itemValue if ( $itemId == EXD_PROC_PID ); $__UID = $itemValue if ( $itemId == EXD_PROC_UID ); $__GID = $itemValue if ( $itemId == EXD_PROC_GID ); $__CMD = $itemValue if ( $itemId == EXD_PROC_COMMAND ); $__ZONE = $itemValue if ( $itemId == EXD_PROC_ZONENAME ); $__RSS_AVG = $itemValue if ( $itemId == EXD_PROC_MEM_RSS_AVG_K ); $__RSS_MAX = $itemValue if ( $itemId == EXD_PROC_MEM_RSS_MAX_K ); $__SYSCALLS = $itemValue if ( $itemId == EXD_PROC_SYSCALLS ); $__SWAPS = $itemValue if ( $itemId == EXD_PROC_SWAPS ); $__START_S = $itemValue if ( $itemId == EXD_PROC_START_SEC ); $__START_NS = $itemValue if ( $itemId == EXD_PROC_START_NSEC ); $__END_S = $itemValue if ( $itemId == EXD_PROC_FINISH_SEC ); $__END_NS = $itemValue if ( $itemId == EXD_PROC_FINISH_NSEC ); $__USER_S = $itemValue if ( $itemId == EXD_PROC_CPU_USER_SEC ); $__USER_NS = $itemValue if ( $itemId == EXD_PROC_CPU_USER_NSEC ); $__SYS_S = $itemValue if ( $itemId == EXD_PROC_CPU_SYS_SEC ); $__SYS_NS = $itemValue if ( $itemId == EXD_PROC_CPU_SYS_NSEC ); } else { #print("\t\tERROR: Expected Item, got a group instead.\n"); } } ## Now output pretty formated data: #printf("%10d %4d %4d %5d %30s\n", $idxCounter, $__UID, $__GID, $__PID, $__CMD); ## Convert ns to seconds ${__START_NS} = ${__START_NS} * .0000000010; ${__END_NS} = ${__END_NS} * .0000000010; ${__USER_NS} = ${__USER_NS} * .0000000010; ${__SYS_NS} = ${__SYS_NS} * .0000000010; my $_START = ${__START_S} + ${__START_NS}; my $_END = ${__END_S} + ${__END_NS}; my $_REAL = $_END - $_START; my $_USER = ${__USER_S} + ${__USER_NS}; my $_SYS = ${__SYS_S} + ${__SYS_NS}; my $_START_DATE = localtime($__START_S); #print("$__ZONE $__UID $__GID $__PID $__CMD | $_REAL $_USER $_SYS | $_START_DATE | $__RSS_AVG $__RSS_MAX $__SYSCALLS $__SWAPS \n"); printf("%10s %6d %6d %6d %20s | %6.2f %6.2f %10.2f | %24s | %10d K %10d K %10d %10d | %4s\n", $__ZONE, $__UID, $__GID, $__PID, $__CMD, $_REAL, $_USER, $_SYS, $_START_DATE, $__RSS_AVG, $__RSS_MAX, $__SYSCALLS, $__SWAPS, $REC_TYPE); } } # Report any errors if (ea_error() != EXR_OK && ea_error() != EXR_EOF) { printf("\nERROR: %s\n", ea_error_str()); exit(1); }