App-RecordStream

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

lib/App/RecordStream/Stream/Sub.pm
lib/App/RecordStream/Test/Aggregator/ArrayHelper.pm
lib/App/RecordStream/Test/DistinctCountHelper.pm
lib/App/RecordStream/Test/LastHelper.pm
lib/App/RecordStream/Test/OperationHelper.pm
lib/App/RecordStream/Test/Tester.pm
lib/App/RecordStream/Test/UniqConcatHelper.pm
logos/logo-small.svg
logos/logo.eps
logos/logo.pdf
logos/logo.png
logos/logo.svg
src/fast-recs-collate/LICENSE
src/fast-recs-collate/Makefile
src/fast-recs-collate/aggregators.c
src/fast-recs-collate/aggregators.h
src/fast-recs-collate/hash.c
src/fast-recs-collate/hash.h
src/fast-recs-collate/json.h
src/fast-recs-collate/lookup3.c
src/fast-recs-collate/lookup3.h

doc/recs-togdgraph.pod  view on Meta::CPAN

 Args:
    --key|-k|--key <keyspec>     Specify keys that correlate to keys in JSON data
    --option|-o option=val       Specify custom command for GD::Graph
    --label-x <val>              Specify X-axis label
    --label-y <val>              Specify Y-axis label
    --width <val>                Specify width
    --height <val>               Specify height
    --graph-title <val>          Specify graph title
    --type <val>                 Specify different graph type other than scatter
                                 (supported: line, bar)
    --png-file <val>             Specify output PNG filename
    --dump-use-spec <val>        Dump GD usage (used mainly for testing)
    --filename-key|fk <keyspec>  Add a key with the source filename (if no
                                 filename is applicable will put NONE)
 
   Help Options:
       --help-all        Output all help for this script
       --help            This help screen
       --help-keygroups  Help on keygroups, a way of specifying multiple keys
       --help-keys       Help on keygroups and keyspecs
       --help-keyspecs   Help on keyspecs, a way to index deeply and with regexes
 
 Examples:
   for a plain point graph:
 
   recs-togdgraph --keys uid,ct --png-file login-graph.png --graph-title '# of logins' --label-x user --label-y logins
 
   togdgraph also accepts any GD::Graph options with the --option command...
   for a pink background with yellow label text if that really is your thing:
 
   recs-togdgraph --keys uid,ct --option boxclr=pink --label-y 'logins' --label-x 'user' --option labelclr=yellow
 
   however, for a different graph type such as line or bar, specify with --type:
 
   recs-togdgraph --keys uid,ct --type line
 

doc/recs-tognuplot.pod  view on Meta::CPAN

    --plot <plot spec>           May be specified multiple times, may be comma
                                 separated. A directive passed directly to plot,
                                 e.g. --plot '5 title "threshold"'
    --precommand <gnuplot spec>  May be specified multiple times, may be comma
                                 separated. A command executed by gnuplot
                                 before executing plot, e.g. --precommand 'set
                                 xlabel "foo"'
    --title <title>              Specify a title for the entire graph
    --label <label>              Labels each --using line with the indicated
                                 label
    --file <filename>            Name of output png file. Will append .png if not
                                 present Defaults to tognuplot.png
    --lines                      Draw lines between points, may specify more than
                                 2 key, each field is a line
    --bargraph                   Draw a bar graph, each field is a bar, may
                                 specify than 2 key, each field is a bar
    --gnuplot-command            Location of gnuplot binary if not on path
    --dump-to-screen             Instead of making a graph, dump the generated
                                 gnuplot script to STDOUT
    --filename-key|fk <keyspec>  Add a key with the source filename (if no
                                 filename is applicable will put NONE)
 

lib/App/RecordStream.pm  view on Meta::CPAN

    max_depth   => 4,
  )->plugins
}

=encoding utf-8

=for markdown
<img src="https://cdn.rawgit.com/benbernard/RecordStream/master/logos/logo-small.svg" align="right">

=for markdown
[![CPAN version](https://badge.fury.io/pl/App-RecordStream.png)](https://metacpan.org/release/App-RecordStream)
[![Build Status](https://travis-ci.org/benbernard/RecordStream.svg?branch=master)](https://travis-ci.org/benbernard/RecordStream)

=head1 NAME

App::RecordStream - recs - A system for command-line analysis of data

=head1 SYNOPSIS

A set of programs for creating, manipulating, and outputting a stream of
Records, or JSON hashes.  Inspired by Monad.

lib/App/RecordStream/Operation/togdgraph.pm  view on Meta::CPAN

my $GD_TYPES = {
  'line'    => 'lines',
  'scatter' => 'points',
  'bar'     => 'bars'
};

sub init {
  my $this = shift;
  my $args = shift;

  my $png_file = 'togdgraph.png';
  my $title;
  my $label_x;
  my $label_y;
  my @additional_options;
  my $graph_type = 'scatter';
  my $width = 600;
  my $height = 300;

  my $dump_use_spec;

  my $key_groups = App::RecordStream::KeyGroups->new();

  my $cmdspec = {
    'key|k|fields|f=s'   => sub { $key_groups->add_groups($_[1]); },
    'option|o=s'         => sub { push @additional_options, [split(/=/, $_[1])]; },
    'label-x=s'          => \$label_x,
    'label-y=s'          => \$label_y,
    'graph-title=s'      => \$title,
    'png-file=s'         => \$png_file,
    'type=s'             => \$graph_type,
    'width=i'            => \$width,
    'height=i'           => \$height,
    'dump-use-spec'      => \$dump_use_spec
  };
  $this->parse_options($args, $cmdspec);

  if ( ! $GD_TYPES->{$graph_type} ) {
    die "Unsupported graph type: $graph_type\n";
  }

lib/App/RecordStream/Operation/togdgraph.pm  view on Meta::CPAN

  $this->{'LABEL_Y'}          = $label_y;
  $this->{'TITLE'}            = $title unless !$this->{'TITLE'};

  $this->{'GDGRAPH_OPTIONS'}  = \@additional_options;
  $this->{'KEYGROUPS'}        = $key_groups;
  $this->{'FIRST_RECORD'}     = 1;

  $this->{'GRAPH_TYPE'}       = $graph_type;
  $this->{'WIDTH'}            = $width;
  $this->{'HEIGHT'}           = $height;
  $this->{'PNG_FILE'}         = $png_file;

  if ( $dump_use_spec ) {
    $this->push_line('x label: '.$title) unless !$this->{'LABEL_X'};
    $this->push_line('y label: '.$title) unless !$this->{'LABEL_Y'};
    $this->push_line('title: '.$title) unless !$this->{'TITLE'};
    $this->push_line('type: '.$graph_type);
    $this->push_line('width: '.$width);
    $this->push_line('height: '.$height);
    $this->push_line('output file: '.$png_file);
  }
}

sub init_fields {
  my ($this, $record) = @_;

  my $specs = $this->{'KEYGROUPS'}->get_keyspecs($record);
  if ( $this->{'DUMP_USE_SPEC'} ) {
    foreach my $sfield (@{$specs}) {
      $this->push_line('field: '.$sfield);

lib/App/RecordStream/Operation/togdgraph.pm  view on Meta::CPAN

      push @data, $this->{'PLOTDATA'}->{$field};
    }
  }
  my $gd = $gdhnd->plot(\@data);
  if ( !$gd ) {
    print "could not plot data\n";
    exit;
  }
  open(IMG, '>', $this->{'PNG_FILE'}) or die "Could not open file for writing $this->{PNG_FILE}: $!";
  binmode IMG;
  print IMG $gd->png;
  close IMG;

}

sub add_help_types {
  my $this = shift;
  $this->use_help_type('keyspecs');
  $this->use_help_type('keygroups');
  $this->use_help_type('keys');
}

lib/App/RecordStream/Operation/togdgraph.pm  view on Meta::CPAN


  my $options = [
    ['key|-k|--key <keyspec>', 'Specify keys that correlate to keys in JSON data'],
    ['option|-o option=val', 'Specify custom command for GD::Graph'],
    ['label-x <val>', 'Specify X-axis label'],
    ['label-y <val>', 'Specify Y-axis label'],
    ['width <val>', 'Specify width'],
    ['height <val>', 'Specify height'],
    ['graph-title <val>', 'Specify graph title'],
    ['type <val>', 'Specify different graph type other than scatter (supported: line, bar)'],
    ['png-file <val>', 'Specify output PNG filename'],
    ['dump-use-spec <val>', 'Dump GD usage (used mainly for testing)']
  ];

  my $args_string = $this->options_string($options);

  return <<USAGE;
Usage: recs-togdgraph <args> [<files>]
  __FORMAT_TEXT__
  Create a bar, scatter, or line graph using GD::Graph.
  __FORMAT_TEXT__

Args:
$args_string

Examples:
  for a plain point graph:

  recs-togdgraph --keys uid,ct --png-file login-graph.png --graph-title '# of logins' --label-x user --label-y logins

  togdgraph also accepts any GD::Graph options with the --option command...
  for a pink background with yellow label text if that really is your thing:

  recs-togdgraph --keys uid,ct --option boxclr=pink --label-y 'logins' --label-x 'user' --option labelclr=yellow

  however, for a different graph type such as line or bar, specify with --type:

  recs-togdgraph --keys uid,ct --type line
USAGE

lib/App/RecordStream/Operation/tognuplot.pm  view on Meta::CPAN

use File::Temp qw(tempfile);

sub init {
  my $this = shift;
  my $args = shift;

  my $bar_graph;
  my $dump_to_screen = 0;
  my $gnuplot_command = 'gnuplot';
  my $lines;
  my $png_file = 'tognuplot.png';
  my $title;
  my @labels;
  my @plots;
  my @precommands;
  my @using;

  my $key_groups = App::RecordStream::KeyGroups->new();

  my $spec = {
    "file=s"            => \$png_file,
    "key|k|fields|f=s"  => sub { $key_groups->add_groups($_[1]); },
    "label=s"           => sub { push @labels, split(/,/, $_[1]); },
    "plot=s"            => sub { push @plots, split(/,/, $_[1]); },
    "precommand=s"      => sub { push @precommands, split(/,/, $_[1]); },
    "title=s"           => \$title,
    "using=s"           => sub { push @using,  $_[1]; },
    'bargraph'          => \$bar_graph,
    'dump-to-screen'    => \$dump_to_screen,
    'gnuplot-command=s' => \$gnuplot_command,
    'lines'             => \$lines,

lib/App/RecordStream/Operation/tognuplot.pm  view on Meta::CPAN

  };

  $this->parse_options($args, $spec);

  die 'Must specify at least one field' unless ( $key_groups->has_any_group() );

  if ( $bar_graph && $lines ) {
    die 'Must specify one of --bargraph or --lines';
  }

  $png_file .= '.png' unless ( $png_file =~ m/\.png$/ );

  if ( ! $dump_to_screen ) {
    if ( open(my $fh, '|-', $gnuplot_command) ) {
      close $fh;
    }
    else {
      warn "Could not run gnuplot command: $gnuplot_command: $!\n";
      warn "May want to specify a binary with --gnuplot-command\n";
      exit 0;
    }

lib/App/RecordStream/Operation/tognuplot.pm  view on Meta::CPAN

  my ($tempfh, $tempfile) = tempfile();

  $this->{'BAR_GRAPH'}       = $bar_graph;
  $this->{'DUMP_TO_SCREEN'}  = $dump_to_screen;
  $this->{'FIRST_RECORD'}    = 1;
  $this->{'GNUPLOT_COMMAND'} = $gnuplot_command;
  $this->{'KEY_GROUPS'}      = $key_groups;
  $this->{'LABELS'}          = \@labels;
  $this->{'LINES'}           = $lines;
  $this->{'PLOTS'}           = \@plots;
  $this->{'PNG_FILE'}        = $png_file;
  $this->{'PRECOMMANDS'}     = \@precommands;
  $this->{'TEMPFH'}          = $tempfh;
  $this->{'TEMPFILE'}        = $tempfile;
  $this->{'TITLE'}           = $title;
  $this->{'USING'}           = \@using;
}

sub init_fields {
  my $this   = shift;
  my $record = shift;

lib/App/RecordStream/Operation/tognuplot.pm  view on Meta::CPAN


  return 1;
}

sub stream_done {
  my ($this) = @_;

  close $this->{'TEMPFH'};

  my $plot_script = '';
  $plot_script .= "set terminal png\n";
  $plot_script .= "set output '" . $this->{'PNG_FILE'} . "'\n";
  $plot_script .= "set title '" . $this->{'TITLE'} . "'\n";

  if ( $this->{'BAR_GRAPH'} ) {
    $plot_script .= <<CMDS;
set style data histogram
set style histogram cluster gap 1
set style fill solid border -1
CMDS
  }

lib/App/RecordStream/Operation/tognuplot.pm  view on Meta::CPAN

sub usage {
  my $this = shift;

  my $options = [
    ['key|-k <keys>', 'May be specified multiple times, may be comma separated.  These are the keys to graph.  If you have more than 2 keys, you must specify a --using statement or use --bargraph or --lines May be a keyspec or keygroup, see \'--help-...
    ['using <using spec>', 'A \'using\' string passed directly to gnuplot, you can use keys specified with --key in the order specified.  For instance --key count,date,avg with --using \'3:2\' would plot avg vs. date.  May be specified multiple times...
    ['plot <plot spec>', 'May be specified multiple times, may be comma separated.  A directive passed directly to plot, e.g. --plot \'5 title "threshold"\''],
    ['precommand <gnuplot spec>', 'May be specified multiple times, may be comma separated.  A command executed by gnuplot before executing plot, e.g. --precommand \'set xlabel "foo"\''],
    ['title <title>', 'Specify a title for the entire graph'],
    ['label <label>', 'Labels each --using line with the indicated label'],
    ['file <filename>', 'Name of output png file.  Will append .png if not present Defaults to tognuplot.png'],
    ['lines', 'Draw lines between points, may specify more than 2 key, each field is a line'],
    ['bargraph', 'Draw a bar graph, each field is a bar, may specify than 2 key, each field is a bar'],
    ['gnuplot-command', 'Location of gnuplot binary if not on path'],
    ['dump-to-screen', 'Instead of making a graph, dump the generated gnuplot script to STDOUT'],
  ];

  my $args_string = $this->options_string($options);

  return <<USAGE;
Usage: recs-tognuplot <args> [<files>]

logos/logo-small.svg  view on Meta::CPAN

         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
     id="defs6" /><g
     transform="matrix(1.25,0,0,-1.25,0,562.8)"
     id="g10"><g
       transform="scale(0.1,0.1)"
       id="g12"><g
         transform="scale(4682.4,4502.4)"
         id="g14"><image
           id="image16"
           xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB58AAAdUCAYAAABwqM6aAAAABHNCSVQICAgIfAhkiAAAIABJREFUeJzs3enPZOeZ3/fvfZZan61XNimqKQ01oqCZ0YwRDGADiT0IkEQvjMR5GwTJ3+A/YBIBCeIEhpEJECAGnCAxEscxJh54RjOGI2k00mijdlGkhhqKokh2k713P2stZ7nvv...
           transform="matrix(1,0,0,-1,0,1)"
           preserveAspectRatio="none"
           height="1"
           width="1" /></g></g></g></svg>

logos/logo.svg  view on Meta::CPAN

         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
     id="defs6" /><g
     transform="matrix(1.25,0,0,-1.25,0,562.8)"
     id="g10"><g
       transform="scale(0.1,0.1)"
       id="g12"><g
         transform="scale(4682.4,4502.4)"
         id="g14"><image
           id="image16"
           xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB58AAAdUCAYAAABwqM6aAAAABHNCSVQICAgIfAhkiAAAIABJREFUeJzs3enPZOeZ3/fvfZZan61XNimqKQ01oqCZ0YwRDGADiT0IkEQvjMR5GwTJ3+A/YBIBCeIEhpEJECAGnCAxEscxJh54RjOGI2k00mijdlGkhhqKokh2k713P2stZ7nvv...
           transform="matrix(1,0,0,-1,0,1)"
           preserveAspectRatio="none"
           height="1"
           width="1" /></g></g></g></svg>

tests/RecordStream/Operation/togdgraph.t  view on Meta::CPAN

{"uid":"rtkit","ct":1}
{"uid":"haldaemon","ct":2}
{"uid":"root","ct":75}
{"uid":"bernard","ct":58}
STREAM

my $solution = <<SOLUTION;
type: scatter
width: 600
height: 300
output file: TEMP-gd.png
field: uid
field: ct
syslog 1
messagebus 1
avahi 2
daemon 1
gdm 1
rtkit 1
haldaemon 2
root 75
bernard 58
SOLUTION

App::RecordStream::Test::OperationHelper->test_output(
  'togdgraph',
  ['--key', 'uid,ct', '--png-file', 'TEMP-gd.png', '--dump-use-spec'],
  $stream,
  $solution,
);

unlink 'TEMP-gd.png';

tests/RecordStream/Operation/tognuplot.t  view on Meta::CPAN

my $solution = <<SOLUTION;
1
1
2
1
1
1
2
75
58
set terminal png
set output 'TEMP_TEST_OUTPUT.png'
set title 'ct'
set style data linespoints
plot 'screen' using 1 title "ct" 
Wrote graph file: TEMP_TEST_OUTPUT.png
SOLUTION

App::RecordStream::Test::OperationHelper->test_output(
  'tognuplot',
  ['--dump-to-screen', '--key', 'ct', '--lines', '--file', 'TEMP_TEST_OUTPUT.png'],
  $stream,
  $solution,
);

unlink 'TEMP_TEST_OUTPUT.png'



( run in 1.673 second using v1.01-cache-2.11-cpan-df04353d9ac )