From: mbeckman@mbeckman.mbeckman.com (Mel Beckman) Newsgroups: comp.dcom.isdn Subject: New Ascend P50 log analysis utility! Date: Sun, 29 Jan 95 08:01:09 PST Organization: Beckman Software Engineering Reply-To: mbeckman@mbeckman.com There must be a lot of P50's out there, because I've had over 100 people download my Pipeline-50 log analyzer. The analyzer consists of a shell script and an ANSI C program. It reports length and cost of calls, but doesn't accomodate changing day rates (default is set up for .04 for the first minute, .01 per minute thereafter). To avoid having quite so many hits on my ISDN-connected anonymous FTP server (deliberately not named here ) I'm posting the whole utility to this group -- it's pretty short anyway. I've also received several revisions, all doing about the same thing: cleaning up the code and fixing some bugs. Dave Yost caught everything the others did (Thank you John Borney, David E. Smith, and Doug Lakin), plus made some very nice improvements to the code, so I'm folding his changes into the latest version, version 1.1. To use this, you must enable SYSLOG logging in your P50. Remember NOT to log a remote P50 to a local host, unless you want your ISDN line to be up all the time fielding log entries! Things I wish somebody would do (because I don't have time): 1. Build in configurable constants for message unit costs 2. Allow for different costs based on incoming/outgoing and time (e.g. to allow for outgoing Home ISDN calls, billed only 8-5) 3. Provide some kind of alarm threshold to call out high conntimes 4. Parameterize the shell script to pass in path to logfile ----------------BEGIN INCLUDED MESSAGE-------------- From: Dave@Yost.com To: mbeckman@mbeckman.com Subject: isdnlog, isdnhist Cc: Dave@Yost.com Reply-To: Dave@Yost.com Date: Sun, 29 Jan 1995 00:27:00 -0800 Thanks! I've been waiting for something like this to show up on the net. Couldn't help hacking it a bit. See enclosed files. This should really be in Perl (which I haven't learned yet)... Dave ======== isdnlog V1.1 #!/bin/sh # Parse /var/console.log to cull just call initiations and terminations case "$1" in "") log=/var/adm/SYSLOG ;; *) log=$1 esac grep 'port.*Call' $log \ | tr -s " " \ | cut -d" " -f1-3,6-22 \ | isdnhist ======== isdnhist.c V1.1 /*******************************************************/ /* Program Name : isdnhist.c */ /* Print ISDN call history */ /* Date 11/04/94 */ /* Written by : Mel Beckman */ /* Prime Contractor: Beckman Software Engineering */ /* */ /* Input: STDIN- Digested console log */ /* Output: STDOUT- Call history w/elapsed times */ /* */ /* */ /* */ /* Modification Log : */ /* 1/29/95 Dave Yost */ /* tightened up code; deal with dangling */ /* disconnects without corresponding */ /* connect log entry */ /*******************************************************/ #include #include enum direction { OUTGOING, INCOMING, UNKNOWN }; /****************************************************************************** * Input is a digested form of the console log file containing Ascend * Pipeline-50 call start and end messages. The call start messages are * of the form: * * Nov 4 16:54:55 slot 2 port 1, Outgoing Call, 6580801 * or * Oct 28 06:51:13 slot 0 port 0, line 1, channel 1, Incoming Call, MBID 118 * * Call end messages are of the form: * * Oct 28 09:58:09 slot 2 port 1, Call Terminated * * The keywords for validating each message are "Outgoing", "line", and * "Terminated", respectively. All other messages will be bypassed. * * An ISDN line can have either one or two calls, indicated by a channel * number for "incoming" messages or a port number of "outgoing" and "call * terminated" messages. We keep track of each call appearance separately. */ main() { /* working variables */ time_t right_now, temptime, begtime, endtime; time_t start[2]; struct tm timestring; struct tm *mytime; int callnumber; char buffer[255]; char monthstring[4]; char testa[32], testb[32], testc[32], testd[32], teste[32], testf[32], testg[32], testh[32]; enum direction direction, dir[2]; int port; int channel; int z; double totcost, totincost, totoutcost; double elapsed, elapsedm, totelapsed, totelapsedm; static const char *const months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; /* * Read each record and extract ident info and total due, then cvt to money & print */ right_now = time(NULL); mytime = localtime(&right_now); timestring.tm_year = mytime->tm_year; printf ("\nisdnhist v1.1 ISDN Call History %s\n", ctime(&right_now)); printf ("\nCall# -----Beg Time---- Day -----End Time---- -Secs- -Mins- -Cost- I/O\n"); totelapsed = 0; totelapsedm = 0; totcost = 0; totincost = 0; totoutcost = 0; while ( fgets (buffer, 254, stdin) != NULL) { /* printf ("%s", buffer); */ sscanf (buffer, " %3s %2d %2d:%2d:%2d %s %s %s %1d %s %s %s %s %1d", monthstring, ×tring.tm_mday, ×tring.tm_hour, ×tring.tm_min, ×tring.tm_sec, testa, testb, testc, &port, testd, teste, testf, testg, &channel ); #if 0 printf ("month=%s, day=%d, hh=%d, mm=%d, ss=%d, port=%d, a=%s, b=%s, c=%s, d=%s, e=%s, f=%s, g=%s, chan=%d\n", monthstring, timestring.tm_mday, timestring.tm_hour, timestring.tm_min, timestring.tm_sec, port, testa, testb, testc, testd, teste, testf, testg, channel ); #endif for ( z=0; z<12; z+=1) { if (strcmp(months[z], monthstring) == 0) break; } timestring.tm_mon = z; right_now = time(NULL); mytime = localtime(&right_now); timestring.tm_year = mytime->tm_year; temptime = mktime(×tring); port--; /* so we're 0-based */ port %= 2; /* Cast odd ports to 0, even to 1 */ if (strcmp(teste, "Outgoing") == 0) { /* Outgoing Call */ start[port] = temptime; dir [port] = OUTGOING; } if ( (strcmp(teste, "line") == 0) && (port == -1) ) { /* ? -1 ? DY */ /* line m, channel n, Call Disconnected (?) DY */ channel--; /* so we're 0-based */ start[channel] = temptime; dir [channel] = INCOMING; } if (strcmp(teste, "Call") == 0) { char begstring[32], endstring[32]; double cost; /* Call Terminated */ endtime = temptime; begtime = start[port] != 0 ? start[port] : endtime + 1; direction = dir [port]; start[port] = 0; dir [port] = UNKNOWN; #if 0 printf ("begtime=%d, endtime=%d\n", begtime, endtime); #endif callnumber += 1; elapsed = difftime(endtime, begtime); elapsedm = (elapsed / 60) + 1; strftime(endstring, 31, "%m/%d/%y %H:%M:%S", localtime(&endtime)); if ( elapsed >= 0 ) { cost = ( elapsedm / 100 ) + .03; totcost += cost; if (direction == OUTGOING) { totoutcost += cost; }else{ totincost += cost; } totelapsed += elapsed; totelapsedm += elapsedm; strftime(begstring, 31, "%m/%d/%y %H:%M:%S %a", localtime(&begtime)); printf ("%4d. %s %s %6d %6d %.2f %s\n", callnumber, begstring, endstring, (int)elapsed, (int)elapsedm, cost, direction == OUTGOING ? "O" : direction == INCOMING ? "I" : "?" ); }else{ strftime(begstring, 31, "**/**/** **:**:** %a", localtime(&endtime)); printf ("%4d. %s %s %6s %6s %4s %s\n", callnumber, begstring, endstring, "???", "???", "????", direction == OUTGOING ? "O" : direction == INCOMING ? "I" : "?" ); } } } printf ("\nTotal Calls=%d Elapsed secs=%d Elapsed mins=%d $%.2f\n", callnumber, (int)totelapsed, (int)totelapsedm, totcost ); printf ("\n Incoming=$%.2f Outgoing=$%.2f\n", totincost, totoutcost ); exit(0); } ========