Measuring Login Durations for Statistics

Do you use perl to massage your server data?

  • No

    Votes: 0 0.0%
  • What's perl?

    Votes: 0 0.0%
  • Linux is for hippies who like free software that doesn't work

    Votes: 0 0.0%

  • Total voters
    4

systemv

New Member
Jul 29, 2019
94
0
0
I wrote this simple perl script to measure the duration of logins of players (to find issues of aborted logins or what not)
Save the code as a file called "parse".


It's simple:

From the shell run:

perl parse -X < server.log > results.txt
This measures logins that last LESS than X seconds

perl parse Y < server.log > results.txt

This measures logins lasting Y or more seconds.
Just a tool to put data behind your analysis of user action in the server.
Edit to suit.

If you want the results SORTED by login time, then send the output of the script through sort(1)
perl parse -X < server.log | sort > results.txt
(or)
perl parse Y < server.log | sort > results.txt

to reverse the sort
perl parse -X < server.log | sort -r > results.txt

etc..

The only bug it has is it doesn't handle a user who logins or logs out recorded on a different file. It assumes the ingress/egress is in the same log. For practical use it doesn't really matter that those are missed. I don't rotate logs often, and if I really need to split them up I just parse them with other scripts as needed.

The point is: I want to know how long people are on. Oh I just thought of another issue (heh) if a user logins more than once in a log it won't care about the logins after the first. Maybe I'll fix that later. I primarily use this to measure aborted logins (users who pop in out).



Njoy.

Code:
#!/usr/bin/perl
# Copyleft 2013 systemv
# GPL'd, etc..
# Use/reuse/hack/edit to suit.
 
#usage:
# users on LESS than X seconds
#  perl parse -X < server.log
# users on MORE than Y seconds
#  perl parse Y < server.log
 
use Time::Local;
 
my  $pWho;
my  $pDelta;
my  $pDatOn;
my  $pTimOn;
my  $pDatOff;
my  $pTimOff;
my  $pSortKey;
 
format STDOUT=
@################  @<<<<<<<<<<<<<<<<<<<<<< @#######      @<<<<<<<<<<  @<<<<<<<<<<    @<<<<<<<<<<  @<<<<<<<<<<
$pSortKey, $pWho,  $pDelta , $pDatOn, $pTimOn, $pDatOff, $pTimOff
.
 
 
my $offset = shift;
 
#default is user logins lasting less than 10 seconds
$offset = -10 unless $offset;
 
 
sub makeTimeInSeconds {
  my ($d, $t) = @_;
  my $time1 = 0;
  if ( $d =~ /(\d\d\d\d)\-(\d\d)\-(\d\d)/) {
      my ($year1, $month1, $day1 ) = ($1, $2, $3);
      $month1 -= 1;
      if ( $t =~ /(\d\d):(\d\d):(\d\d)/) {
        my ($hour1, $min1, $sec1) = ($1, $2, $3);
        $time1 = timelocal($sec1, $min1, $hour1 , $day1, $month1, $year1-1900);
      }
    }
    return $time1;
}
 
 
 
 
while ($x = <STDIN>) {
  chomp $x;
 
  if ($x =~ /\[Server\] ([^\s]+) has just joined/) {
    my $nam = $1;
    if (!exists($dat{$nam})) {
      if ($x =~ /^(\d\d\d\d\-\d\d\-\d\d)\s(\d\d:\d\d:\d\d)\s\[INFO\]/) {
        $dat{$nam} = $1;
        $tim{$nam} = $2;
        $sortedtime{$nam} = &makeTimeInSeconds($dat{$nam}, $tim{$nam});
      }
      next;
    }
  }
 
  if ($x =~ /\[INFO\]\s([^\s]+) lost connection/) {
      my $who = $1;
      next if (exists($datoff{$who}));
      if (exists( $dat{$who})) {
          if ($x =~ /^(\d\d\d\d\-\d\d\-\d\d)\s(\d\d:\d\d:\d\d)\s\[INFO\]/) {
          $datoff{$who} = $1;
          $timoff{$who} = $2;
          }
          next;
      }
  }
}
 
foreach $k (keys %dat) {
  $dat{$k} =~ /(\d\d\d\d)\-(\d\d)\-(\d\d)/;
  $tim{$k} =~ /(\d\d):(\d\d):(\d\d)/;
  $datoff{$k} =~ /(\d\d\d\d)\-(\d\d)\-(\d\d)/;
  $timoff{$k} =~ /(\d\d):(\d\d):(\d\d)/;
  my $time1=makeTimeInSeconds($dat{$k}, $tim{$k});
  my $time2=makeTimeInSeconds($datoff{$k}, $timoff{$k});
  my $time3=$time2-$time1;
  $pDelta = $time3;
 
  if ($offset < 0) {
    if ($pDelta < -$offset) {
      $pSortKey =  $sortedtime{$k};
      ($pWho, $pDatOn, $pTimOn, $pDatOff, $pTimOff) =  ($k, $dat{$k}, $tim{$k}, $datoff{$k}, $timoff{$k});
      write;
    }
  } elsif ($offset > 0) {
    if ($pDelta >= $offset) {
      $pSortKey =  $sortedtime{$k};
      ($pWho, $pDatOn, $pTimOn, $pDatOff, $pTimOff) =  ($k, $dat{$k}, $tim{$k}, $datoff{$k}, $timoff{$k});
      write;
    }
  }
}
 

systemv

New Member
Jul 29, 2019
94
0
0
Damnit.

I press send and forget the code counts new users.

I'll post a replacement for new or veteran users found in log.
 

Francis Baster

New Member
Jul 29, 2019
295
0
0
Nice, sounds like a useful script. Would be really neat to have some PHP that could display online graphs of total accrued login time.
 

Francis Baster

New Member
Jul 29, 2019
295
0
0
Tweaked log on string pattern to parse servers such as mine (1.5.2 MCPC+) which use the format:
Code:
2013-11-10 02:28:53 [INFO] PlayerName[/IP:Port] logged in with entity id 379270 at ([world] 391.6636055768481, 63.0, -8426.992445585516)

Code:
#!/usr/bin/perl
# Copyleft 2013 systemv
# GPL'd, etc..
# Use/reuse/hack/edit to suit.

#usage:
# users on LESS than X seconds
#  perl parse -X < server.log
# users on MORE than Y seconds
#  perl parse Y < server.log

use Time::Local;
my  $pWho;
my  $pDelta;
my  $pDatOn;
my  $pTimOn;
my  $pDatOff;
my  $pTimOff;
my  $pSortKey;

format STDOUT=
@################  @<<<<<<<<<<<<<<<<<<<<<< @#######      @<<<<<<<<<<  @<<<<<<<<<<    @<<<<<<<<<<  @<<<<<<<<<<
$pSortKey, $pWho,  $pDelta , $pDatOn, $pTimOn, $pDatOff, $pTimOff
.

my $offset = shift;
#default is user logins lasting less than 10 seconds
$offset = -10 unless $offset;
sub makeTimeInSeconds {
  my ($d, $t) = @_;
  my $time1 = 0;
  if ( $d =~ /(\d\d\d\d)\-(\d\d)\-(\d\d)/) {
      my ($year1, $month1, $day1 ) = ($1, $2, $3);
      $month1 -= 1;
      if ( $t =~ /(\d\d):(\d\d):(\d\d)/) {
        my ($hour1, $min1, $sec1) = ($1, $2, $3);
        $time1 = timelocal($sec1, $min1, $hour1 , $day1, $month1, $year1-1900);
      }
    }
    return $time1;
}
while ($x = <STDIN>) {
  chomp $x;
  if ($x =~ /\[INFO\] ([^\s]+)\[.+\] logged in with entity id/) {
    my $nam = $1;
    if (!exists($dat{$nam})) {
      if ($x =~ /^(\d\d\d\d\-\d\d\-\d\d)\s(\d\d:\d\d:\d\d)\s\[INFO\]/) {
        $dat{$nam} = $1;
        $tim{$nam} = $2;
        $sortedtime{$nam} = &makeTimeInSeconds($dat{$nam}, $tim{$nam});
      }
      next;
    }
  }
  if ($x =~ /\[INFO\]\s([^\s]+) lost connection/) {
      my $who = $1;
      next if (exists($datoff{$who}));
      if (exists( $dat{$who})) {
          if ($x =~ /^(\d\d\d\d\-\d\d\-\d\d)\s(\d\d:\d\d:\d\d)\s\[INFO\]/) {
          $datoff{$who} = $1;
          $timoff{$who} = $2;
          }
          next;
      }
  }
}
foreach $k (keys %dat) {
  $dat{$k} =~ /(\d\d\d\d)\-(\d\d)\-(\d\d)/;
  $tim{$k} =~ /(\d\d):(\d\d):(\d\d)/;
  $datoff{$k} =~ /(\d\d\d\d)\-(\d\d)\-(\d\d)/;
  $timoff{$k} =~ /(\d\d):(\d\d):(\d\d)/;
  my $time1=makeTimeInSeconds($dat{$k}, $tim{$k});
  my $time2=makeTimeInSeconds($datoff{$k}, $timoff{$k});
  my $time3=$time2-$time1;
  $pDelta = $time3;
  if ($offset < 0) {
    if ($pDelta < -$offset) {
      $pSortKey =  $sortedtime{$k};
      ($pWho, $pDatOn, $pTimOn, $pDatOff, $pTimOff) =  ($k, $dat{$k}, $tim{$k}, $datoff{$k}, $timoff{$k});
      write;
    }
  } elsif ($offset > 0) {
    if ($pDelta >= $offset) {
      $pSortKey =  $sortedtime{$k};
      ($pWho, $pDatOn, $pTimOn, $pDatOff, $pTimOff) =  ($k, $dat{$k}, $tim{$k}, $datoff{$k}, $timoff{$k});
      write;
    }
  }
}
 
Last edited:

Francis Baster

New Member
Jul 29, 2019
295
0
0
Here's a variation designed to measure who has spent the most time online.
http://pastebin.com/qdga2TMY

Usage:
perl scriptName < server.log > results.txt

Or to sort results:
perl scriptName < server.log | sort -r -n -k2 > results.txt

Edit: Added ability to parse "Unloading Player: PlayerName" which catches when players are kicked during server shutdown.
 
Last edited: