# on Windows: perl .\geo_stream.pl [--static|s OR --live|l] # on linux: carmel exec perl ./geo_stream.pl [--static|s OR --live|l] # options for static: # --deduct-time|-d 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 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 [-i ] 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