# on Windows: perl .\geo_stream.pl [--static|s OR --live|l] <log_file_name>
# on linux: carmel exec perl ./geo_stream.pl [--static|s OR --live|l] <log_file_name>
# options for static:
# --deduct-time|-d <seconds> time in seconds to fast-forward log timestamps
# --test|-t output all lines of log.txt (for testing)
# --sql_trace|-q output SQL queries (not currently using MySQL db)
# options for live:
# --interval|-i <seconds> time gap between monitoring log file for size change (default: 0.5)
=begin
monitor memory useage in powershell:
# Get the Perl process ID
$proc = Get-Process perl
# Monitor it
while ($true) {
$proc.Refresh()
"{0:HH:mm:ss} | {1} MB" -f (Get-Date), ([math]::Round($proc.WorkingSet64 / 1MB, 2))
Start-Sleep 2
}
=cut
use 5.34.0;
use lib '.';
use GeoStream;
use Getopt::Long;
use Time::HiRes qw(sleep);
use autodie qw(open close seek);
use utf8;
use open ':std', ':utf8';
binmode STDOUT, ':encoding(UTF-8)';
binmode STDERR, ':encoding(UTF-8)';
STDOUT->autoflush(1);
STDERR->autoflush(1);
# Handle interrupt gracefully
$SIG{INT} = sub {
say STDERR "\nShutting down...";
exit 0;
};
# Command line options
my %opts;
GetOptions(
# static file opts:
'static|s=s' => \$opts{static},
'test|t' => \$opts{test},
'sql_trace|q' => \$opts{sql_trace},
'deduct-time|d=i' => \$opts{deduct_time},
# live stream opts:
'live|l=s' => \$opts{live},
'interval|i=f' => \$opts{interval},
);
if (my $file = $opts{static}) {
read_log($file);
}
elsif ($file = $opts{live}) {
monitor_log($file);
}
else {
# pod2usage("Error: Must specify either --static or --live mode\n");
say 'Error: must specify either --static|s or --live|l mode + filename';
}
sub read_log {
my $file = shift;
my $geo = GeoStream->new(
deduct_time => $opts{deduct_time},
test_output => $opts{test},
sql_trace => $opts{sql_trace},
);
open my $fh, '<', $file or die "Can't open $file: $!"; # warn $file;
while (<$fh>) { # say $_;
$geo->decode_line($_);
}
exit 0;
}
sub monitor_log {
my $log_file = shift;
my $interval = $opts{interval} // 0.5;
my $last_size = -s $log_file // die "Cannot access $log_file: $!\n"; # say $last_size;
my $geo = GeoStream->new();
=begin # maybe unnecessary?
# if script opened after x-plane started, will die unless simulation start time set:
unless ( $geo->sim_start_time ) {
open my $fh, '<', $log_file;
while (<$fh>) { # say $_;
next unless $_ =~ m/X-Plane Started on (.*)/i;
$geo->set_sim_start_time($_);
}
close $fh;
}
=cut
while (1) {
eval {
my $size = -s $log_file; # say $size;
if ($size > $last_size) { # warn 'here';
open my $fh, '<', $log_file;
seek($fh, $last_size, 0);
while (my $line = <$fh>) {
$geo->decode_line($line);
}
close $fh;
$last_size = $size;
}
};
warn "Error reading $log_file: $@" if $@;
sleep $interval;
}
}
__END__
=head1 NAME
geo_stream_live.pl - Monitor X-Plane log file for geographic data
=head1 SYNOPSIS
geo_stream_live.pl -f <logfile> [-i <interval>]
Options:
-f, --file Log file to monitor (required)
-i, --interval Check interval in seconds (default: 0.5)
-h, --help Show this help
=head1 DESCRIPTION
Monitors an X-Plane log file in real-time and processes geographic data.
Handles Windows file streaming limitations.
=cut