#!/usr/bin/perl -w use strict; sub clear_hash($) { my $hash = shift; for my $key (keys %${hash}) { delete $hash->{$key} } } sub clear_state($$$) { my $sessions = shift; my $lok_starting = shift; my $lok_running = shift; my @names = keys %{$sessions}; print "Leaked sessions:\n\t" . join(',', @names) . "\n" if (@names > 0); @names = keys %{$lok_starting}; print "Sessions starting:\n\t" . join(',', @names) . "\n" if (@names > 0); @names = keys %{$lok_running}; print "Sessions running:\n\t" . join(',', @names) . "\n" if (@names > 0); clear_hash($sessions); clear_hash($lok_starting); clear_hash($lok_running); } my @input = ; my $total_blocks = 0; # live state: my $inodes = 0; my $blocks = 0; my $running = 0; my $mem_used = 0; my $load_avg = 0; my $cpu_user = 0; my $cpu_sys = 0; my %sessions; my %lok_starting; my %lok_running; my $printed_header = 0; while (my $line = shift @input) { my ($pevent, $pdetail); $line =~ s/\r*\n*//g; # df -i /dev/sda1 | logger # df /dev/sda1 | logger # root: /dev/sda1 655360 77457 577903 12% / if ($line =~ /root: \S+\s+(\d+)\s+(\d+)/) { my ($total, $used) = ($1, $2); $total_blocks = $total if ($total_blocks < $total); if ($total == $total_blocks) { $blocks = $used; } else { $inodes = $used; } } # top -b -n1 | head -4 | logger # root: top - 15:38:01 up 5 days, 1:56, 1 user, load average: 0.00, 0.05, 0.06 # root: Tasks: 82 total, 1 running, 81 sleeping, 0 stopped, 0 zombie # root: %Cpu(s): 0.2 us, 0.1 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st # root: KiB Mem: 7870968 total, 3202484 used, 4668484 free, 181104 buffers $load_avg = $1 if ($line =~ m/top.*load average: (\d+\.\d+)/); $mem_used = $1 if ($line =~ m/KiB Mem:.*\s(\d+)\s+used,/); if ($line =~ m/%Cpu(s):\s+(\d+\.\d+) us,\s+(\d+\.\d+) sy,/) { $cpu_user = $1; $cpu_sys = $2; } $running = $1 if ($line =~ m/Tasks:.*\s+(\d+) running,/); $mem_used = $1 if ($line =~ m/KiB Mem:.*\s(\d+)\s+used,/); $mem_used = $1 if ($line =~ m/KiB Mem:.*\s(\d+)\s+used,/); # Session 000d is loading. 0 views loaded. # Session 000e is unloading. 0 views will remain. if ($line =~ m/Session (\S+) is (\S*)loading. (\d+) views/) { my ($skey, $type, $count) = ($1, $2, $3); if ($type eq 'un') { $pevent = "unload\t\"$skey\""; if (defined $sessions{$skey}) { $pdetail = $sessions{$skey}; } else { # setup - somewhere earlier in the logs. $pdetail = 'pre-existing'; } delete $sessions{$skey}; } else { $sessions{$skey} = 1; } } # systemd[1]: loolwsd.service: main process exited, code=killed, status=11/SEGV if ($line =~m/loolwsd.service: main process exited.*status=(.*)$/) { print "loolwsd exit: $1\n"; } if ($line =~m/Initializing wsd/) { print "Re-started\n"; clear_state(\%sessions, \%lok_starting, \%lok_running); } # different PIDs: ... # [loolbroker ] Spawned kit [1689]. # [loolkit ] loolkit [1689] is ready. # [loolbroker ] Child 1536 terminated. # [loolbroker ] Child process [1689] exited with code: 0. if ($line =~ m/loolbroker.*Forked kit \[(\d+)\]./) { my $pid = $1; $lok_starting{$pid} = 1; $pevent = "newkit\t\"$pid\""; $pdetail = ''; } if ($line =~ m/loolkit \[(\d+)\] is ready./) { my $pid = $1; delete $lok_starting{$pid}; $lok_running{$pid} = 1; $pevent = "livekit\t\"$pid\""; $pdetail = ''; } # [loolbroker ] Child process [1689] exited with code: 0. if ($line =~ m/loolbroker.*Child process \[(\d+)\]\s+(\S+)\s+.*with /) { my $pid = $1; my $code = $2; $code = 'exit' if ($code eq 'exited'); delete $lok_running{$pid}; $pevent = $code . "kit\t\"$pid\""; $pdetail = ''; } # loolwsd: if ($line =~ m/Loading new document from URI: \[([^\]]+)\].*for session \[([^\]]+)\]/) { my ($doc_uri, $session) = ($1, $2); $sessions{$session} = $doc_uri; $pevent = "load\t\"$session\""; $pdetail = $doc_uri; } if (defined $pevent) { my $session_count = keys %sessions; my $start_count = keys %lok_starting; my $running_count = keys %lok_running; if ($printed_header++ == 0) { print "event\tkey\tinodes\tfs_blk\t"; print "mem/Kb\trun\t"; print "loadavg\tsess\t"; print "start\tlive\t"; print "file\n"; } print "$pevent\t$inodes\t$blocks\t"; print "$mem_used\t$running\t"; print "$load_avg\t$session_count\t"; print "$start_count\t$running_count\t"; print "$pdetail\n"; } } clear_state(\%sessions, \%lok_starting, \%lok_running);