Dear brethren,
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.
So here's the 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;
}
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
mkfifo toto1 run continuously vmstat and/or iostat and redirect their output to the pipe:
vmstat 3 |tee toto1 and
iostat -x 3 | tee toto1.
I don't know how to get any further from there... maybe golang? :)
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.