Click to See Complete Forum and Search --> : shell script problem ( checking who is logged on ! )


Dave2001
06-06-2003, 11:07 AM
Hi Guys !

I am having a little problem with a script iam busy with . This script is to determine who is logged onto 4 servers .

While i can collect all the logon messages from the servers and as well the logoff messages - i havent been able to find a way to compare these 2 against each other .
the problem basically is that some users will appear more then once in both logs .
So it would be something like this :

Logged On Logged Off

A B
B C
B D
C A
D
E
A

And comparing these files should result in a file containing B , E, A .

I tried it with forst sorting it with sort and then doing a comm -3 but no go ....

Can anyone help ?

Thanks !!

bwkaz
06-06-2003, 06:43 PM
who?

w?

Neither of these premade programs will work for you?

Dave2001
06-07-2003, 05:09 AM
I wish it was so easy - the logs iam looking at are appliccation logs . So these people are not normally logged on - they are just connected to this application .


Dave

terribleRobbo
06-07-2003, 07:03 AM
Umm...

I'd keep the names in two arrays (one for Logged On, other for... you get the point).

I'll use pseudo-C++. I'd do it in PERL, but I'm just beginning. :-S


// List of those logged on at the moment.
String[] loggedOn = new String[onLog.length];
int arrCounter = 0;

for (int ii, ii < onLog.length, ii++)
{
for (int jj, jj < offLog.length, jj++)
{
if (onLog[ii].equals(offLog[jj].length)
{
loggedOn[arrCounter] = onLog[ii];
arrCounter++;
}
}
}


A little inefficient with the loggedOn array size, and it assumes that the logs are sane (as in, number of people logged off <= logged on).

Sorry if this is all terribly basic, or I've missed the point. :(

DragonHead
06-07-2003, 07:42 AM
When I read this, I thought double array. I see terribleRobbo already explained the theory, so I shall not.

I'd use perl as well. That way you don't have to worry about your array being big enough to handle all the values (all perl values (including arrays) are dynamic in size).

I'd probably use a perl hash, with the keyword being the username and the value being a list of "on and offs".

Dave2001
06-07-2003, 08:18 AM
I suppose i have to look into perl then ... never did anything with it .... :(


Dave

terribleRobbo
06-07-2003, 08:56 AM
Uh oh... Bug!

The REAL DEAL this time. Maybe:


// List of those logged on at the moment.
String[] loggedOn = new String[onLog.length];
int arrCounter = 0;
int foundMatch = -1;

for (int ii, ii < onLog.length, ii++)
{
for (int jj, jj < offLog.length, jj++)
{
if (onLog[ii].equals(offLog[jj].length))
{
foundMatch = ii;
}
if (foundMatch < 0)
{
loggedOn[arrCounter] = onLog[ii];
arrCounter++;
}
}
}


(Apologies... My Pseudo-C++ has turned into Java. *Sigh* :rolleyes: )

terribleRobbo
06-07-2003, 09:01 AM
*Sigh*

I apologise. I have made big booboo AGAIN! NO PORKRINDS FOR YOU, etc.

Umm, the nature of the problem is this: if a user logs in, logs out, then logs back in, then the user is still counted as logged out (because foundMatch > -1).

Damn... Erm...

Aha! Idea!

Maybe a counter could be set up to check if each log-on has a corresponding log-off. If not corresponding, then the user is still logged in.

Or maybe using uniq somehow...

Hmm... I'll mull over this one for a while. :D

bwkaz
06-07-2003, 09:34 AM
terribleRobbo -- you'll also want to initialize your loop indices. ;)

As it is, they'll start at some unspecified value (when you say "int ii", that means "create ii on the stack, and don't initialize it to anything special", which means it'll get whatever value happened to be on the stack at the time). You want to say "int ii=0", and the same for jj.

As for the rest of it... I'm not really sure. You could do something very much like terribleRobbo said in his last post, and set up an array of counters (one counter for each person), then run through the logon array, counting the number of logons for each person (again, a Perl hash would probably be the most efficient for this -- you'd index by logon name, and the value would be the count of logons). Then, run through the logoff array, decrementing the count for each person on each entry you see.

After you've done this, run through each person's count. If the count is >0, they're still logged on (the number of current logons will be equal to their count). If the count is <0, there's a bug in the application's logging, because someone was able to log off more times than they logged on. :D

I haven't done hardly any Perl myself, so while I'd think this is very possible, I haven't the slightest clue how to do it.

terribleRobbo
06-07-2003, 10:08 AM
Originally posted by bwkaz
terribleRobbo -- you'll also want to initialize your loop indices. ;)

*Smacks forehead*

Thanks. :(


As for your solution: good stuff. Me likes it. :D

Dave2001
06-07-2003, 12:12 PM
Is there no way to do it without perl ?
I think i might have come up with a solution ...

Ok i got 2 files : on ( logged on users ) off ( logged off users )

sort on
sort off
comm -3 on off >> result

I think actually that result will contain all logged on users . am i right ?
I know it is less elegant then the perl solution - but i need to come up with that script pretty soon ( to impress some people on my work ) and dont have enough time to learn perl .

Dave

DragonHead
06-07-2003, 01:39 PM
Of course you can do it without perl. You can do it in any language you want to. It is after all, your project ;)

There is nothing wrong with doing it in C/C++. Some ways may be better than others, but as long as it works, hey..what they heck...

dchidelf
06-08-2003, 09:23 AM
Originally posted by Dave2001
Ok i got 2 files : on ( logged on users ) off ( logged off users )

sort on
sort off
comm -3 on off >> result

I think actually that result will contain all logged on users . am i right ?

I'm assuming you are capturing the output of the sort commands in another file, as sort doesn't sort in place.

comm -3 will give you the names that are uniq to on or off, so it would be users who logged on more than they logged off, or logged off more than they logged on. If the logs are hourly or daily, it would list a user who logged on in the previous log, but did not log off until the current log.

Is it possible for a user to not log out? Perhaps if it is a web app they just time out and log in later?

Dave2001
06-08-2003, 12:32 PM
Yes you are right - the output of sort is saved in another file ( my mistake not mentioning that ) .

The users just stay logged on till

1. they log off
2. their session crashes ( log off message in the log )

They cant be logged in twice at the same time .
the logs itself are updated every minute ....

So is this actually the solution ?

terribleRobbo
06-08-2003, 11:22 PM
Are there different logs for different days (as in, on_20030906, and on_20030907, and so on), or is it one big continuous file?

Dave2001
06-09-2003, 12:36 AM
Yep - there are different logs for different days .


Just wanted to say thanks for all the time you people spend helping me !!

Dave