perlquestion
wazoox
Dear brethren,
<p>I'm looking for an elegant way of reading data from a file on one hand, and serve it (preferably through a websocket) on the other hand. So far I managed to solve elegantly the problem of reading the output from several programs simultaneously by using on of the big powers of Unix : named pipes. However now I'm stuck on the next part: serving data. As reading from a pipe is blocking, and so is listening to a socket, I don't know how to get out of this.
</p>
<p>
So here's the code:
</p>
<code>
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use Net::WebSocket::Server;
use JSON;
my %data;
my $json;
# Net::WebSocket::Server->new(
# listen => 8080,
# on_connect => sub {
# my ($serv, $conn) = @_;
# $conn->on(
# handshake => sub {
# my ($conn, $handshake) = @_;
# },
# utf8 => sub {
# my ($conn) = @_;
# $_->send_utf8($json) for $conn->server->connections;
# },
# );
# },
# )->start;
open my $fh, '<', 'toto1' or die "can't open fifo toto1: $?";
while ( my $line = <$fh> ) {
my @list = ( split /\s+/, $line );
# skip empty lines
next if $#list <= 1;
shift @list if $list[0] eq '';
# test for iostat header
next if $list[0] eq 'avg-cpu:';
next if $list[0] eq 'Device:';
# test for vmstat header
next if $list[0] eq 'procs';
if ( $#list == 11 ) {
(
undef,
$data{io}{ $list[0] }{rrqms},
$data{io}{ $list[0] }{wrqms},
$data{io}{ $list[0] }{reads},
$data{io}{ $list[0] }{writes},
$data{io}{ $list[0] }{rsecs},
$data{io}{ $list[0] }{wsecs},
$data{io}{ $list[0] }{avgrqsz},
$data{io}{ $list[0] }{avgqusz},
$data{io}{ $list[0] }{await},
$data{io}{ $list[0] }{svctm},
$data{io}{ $list[0] }{util}
) = @list;
} elsif ( $#list == 15 ) {
(
$data{vm}{r}, $data{vm}{b}, $data{vm}{swpd},
$data{vm}{free}, $data{vm}{buff}, $data{vm}{cache},
$data{vm}{swapin}, $data{vm}{swapout}, $data{vm}{ioin},
$data{vm}{ioout}, $data{vm}{sysin}, $data{vm}{syscs},
$data{vm}{user}, $data{vm}{sys}, $data{vm}{idle},
$data{vm}{wait}
) = @list;
} elsif ( $#list == 5 ) {
$data{vm}{nice} = $list[1];
}
$json = encode_json( \%data);
sleep 1;
}
</code>
<p>Of course the script work by commenting out one of the two loops, either the websocket one, or the file reading one. To use this script, create a named pipe </p><c>mkfifo toto1</c><p> run continuously vmstat and/or iostat and redirect their output to the pipe: </p><c>vmstat 3 |tee toto1</c> <p>and </p> <c>iostat -x 3 | tee toto1</c>.
<p>
I don't know how to get any further from there... maybe golang? :)</p>