lots of misc work
This commit is contained in:
parent
15265a8fc5
commit
dc16056ead
|
@ -22,6 +22,7 @@ my %WriteMakefileArgs = (
|
|||
'Error::Helper' => '1.0.0',
|
||||
'Search::Elasticsearch' => '6.00',
|
||||
'Template' => '2.29',
|
||||
'Template::Plugin::JSON' => '0.08',
|
||||
},
|
||||
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
|
||||
clean => { FILES => 'Search-ESsearcher-*' },
|
||||
|
|
|
@ -1,2 +1,43 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Search::ESsearcher;
|
||||
use Getopt::Long qw(:config pass_through);
|
||||
|
||||
# set all the templates the servers use to to fault
|
||||
my $search;
|
||||
my $options;
|
||||
my $output;
|
||||
my $elastic;
|
||||
|
||||
GetOptions(
|
||||
's=s' => \$search,
|
||||
'g=s' => \$options,
|
||||
'o=s' => \$output,
|
||||
'e=s' => \$elastic,
|
||||
);
|
||||
|
||||
my $ess = Search::ESsearcher->new();
|
||||
|
||||
# reels in the options
|
||||
$ess->options_set( $options );
|
||||
$ess->load_options;
|
||||
$ess->get_options;
|
||||
|
||||
# reels in the search template
|
||||
$ess->search_set( $search );
|
||||
$ess->load_search;
|
||||
$ess->search_fill_in;
|
||||
|
||||
# reels in the elastic config
|
||||
$ess->elastic_set( $elastic );
|
||||
$ess->load_elastic;
|
||||
|
||||
my $results=$ess->search_run;
|
||||
|
||||
|
||||
|
||||
use Data::Dumper;
|
||||
print Dumper( $results );
|
||||
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
package Search::ESsearcher;
|
||||
|
||||
use 5.006;
|
||||
use base Error::Helper;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
use JSON;
|
||||
use Template;
|
||||
use Search::Elasticsearch;
|
||||
use Term::ANSIColor;
|
||||
use Time::ParseDate;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
@ -10,11 +17,11 @@ Search::ESsearcher - The great new Search::ESsearcher!
|
|||
|
||||
=head1 VERSION
|
||||
|
||||
Version 0.01
|
||||
Version 0.0.0
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = '0.01';
|
||||
our $VERSION = '0.0.0';
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
@ -25,28 +32,658 @@ Perhaps a little code snippet.
|
|||
|
||||
use Search::ESsearcher;
|
||||
|
||||
my $foo = Search::ESsearcher->new();
|
||||
...
|
||||
my $ess = Search::ESsearcher->new();
|
||||
|
||||
=head1 EXPORT
|
||||
|
||||
A list of functions that can be exported. You can delete this section
|
||||
if you don't export anything, such as for a purely object-oriented module.
|
||||
|
||||
=head1 SUBROUTINES/METHODS
|
||||
=head1 METHODS
|
||||
|
||||
=head2 function1
|
||||
=head2 new
|
||||
|
||||
This initiates the object.
|
||||
|
||||
my $ss=Search::ESsearcher->new;
|
||||
|
||||
=cut
|
||||
|
||||
sub function1 {
|
||||
sub new{
|
||||
|
||||
my $self = {
|
||||
perror=>undef,
|
||||
error=>undef,
|
||||
errorString=>"",
|
||||
base=>undef,
|
||||
search=>'syslog',
|
||||
search_template=>undef,
|
||||
search_filled_in=>undef,
|
||||
search_usable=>undef,
|
||||
output=>'syslog',
|
||||
output_template=>undef,
|
||||
options=>'syslog',
|
||||
options_array=>undef,
|
||||
elastic=>'default',
|
||||
elastic_hash=>{
|
||||
nodes => [
|
||||
'127.0.0.1:9200'
|
||||
]
|
||||
},
|
||||
errorExtra=>{
|
||||
flags=>{
|
||||
'1'=>'IOerror',
|
||||
'2'=>'NOfile',
|
||||
'3'=>'nameInvalid',
|
||||
'4'=>'searchNotUsable',
|
||||
'5'=>'elasticNotLoadable',
|
||||
}
|
||||
},
|
||||
};
|
||||
bless $self;
|
||||
|
||||
# finds the etc base to use
|
||||
if ( -d '/usr/local/etc/essearch/' ) {
|
||||
$self->{base}='/usr/local/etc/essearch/';
|
||||
} elsif ( -d '/etc/essearch/' ) {
|
||||
$self->{base}='/etc/essearch/';
|
||||
} elsif ( $0 =~ /bin\/essearcher$/ ) {
|
||||
$self->{base}=$0;
|
||||
$self->{base}=~s/\/bin\/essearcher$/\/etc\/essearch\//;
|
||||
}
|
||||
|
||||
# inits Template
|
||||
$self->{t}=Template->new({
|
||||
EVAL_PERL=>1,
|
||||
INTERPOLATE=>1,
|
||||
POST_CHOMP=>1,
|
||||
});
|
||||
|
||||
# inits JSON
|
||||
$self->{j}=JSON->new;
|
||||
$self->{j}->pretty(1); # make the output sanely human readable
|
||||
$self->{j}->relaxed(1); # make writing search templates a bit easier
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 function2
|
||||
=head elastic_get
|
||||
|
||||
This returns what Elasticsearch config will be used.
|
||||
|
||||
my $elastic=$ess->elastic_get;
|
||||
|
||||
=cut
|
||||
|
||||
sub function2 {
|
||||
sub elastic_get{
|
||||
my $self=$_[0];
|
||||
my $name=$_[1];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
return $self->{elastic};
|
||||
}
|
||||
|
||||
=head elastic_set
|
||||
|
||||
This sets the name of the config file to use.
|
||||
|
||||
One option is taken and name of the config file to load.
|
||||
|
||||
Undef sets it back to the default, "default".
|
||||
|
||||
$ess->elastic_set('foo');
|
||||
|
||||
$ess->elastic_set(undef);
|
||||
|
||||
=cut
|
||||
|
||||
sub elastic_set{
|
||||
my $self=$_[0];
|
||||
my $name=$_[1];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
if (! $self->name_validate( $name ) ){
|
||||
$self->{error}=3;
|
||||
$self->{errorString}='"'.$name.'" is not a valid name';
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
|
||||
if( !defined( $name ) ){
|
||||
$name='default';
|
||||
}
|
||||
|
||||
$self->{elastic}=$name;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
=head2 get_options
|
||||
|
||||
This fetches the options.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_options{
|
||||
my $self=$_[0];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
my %parsed_options;
|
||||
|
||||
GetOptions( \%parsed_options, @{ $self->{options_array} } );
|
||||
|
||||
|
||||
$self->{parsed_options}=\%parsed_options;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 load_options
|
||||
|
||||
=cut
|
||||
|
||||
sub load_options{
|
||||
my $self=$_[0];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $file;
|
||||
my $data;
|
||||
|
||||
# ~/ -> etc -> module -> error
|
||||
if (
|
||||
( defined( $ENV{'HOME'} ) ) &&
|
||||
( -f $ENV{'HOME'}.'/.config/essearcher/options/'.$self->{options} )
|
||||
) {
|
||||
$file=$ENV{'HOME'}.'/.config/essearcher/options/'.$self->{options};
|
||||
} elsif (
|
||||
( defined( $self->{base} ) ) &&
|
||||
( -f $self->{base}.'/etc/essearcher/options/'.$self->{options} )
|
||||
) {
|
||||
$file=$self->{base}.'/etc/essearcher/options/'.$self->{options};
|
||||
} else {
|
||||
# do a quick check of making sure we have a valid name before trying a module...
|
||||
# not all valid names are perl module name valid, but it will prevent arbitrary code execution
|
||||
if ( $self->name_validate( $self->{options} ) ){
|
||||
my $to_eval='use Search::ESsearcher::Templates::'.$self->{options}.
|
||||
'; $data=Search::ESsearcher::Templates::'.$self->{options}.'->options;';
|
||||
eval( $to_eval );
|
||||
}
|
||||
# if undefined, it means the eval failed
|
||||
if ( ! defined( $data ) ){
|
||||
$self->{error}=2;
|
||||
$self->{errorString}='No options file or module with the name "'.$self->{options}.'" was found';
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
if ( defined( $file ) ) {
|
||||
my $fh;
|
||||
if (! open($fh, '<', $file ) ) {
|
||||
$self->{error}=1;
|
||||
$self->{errorString}='Failed to open "'.$file.'"',
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
# if it is larger than 2M bytes, something is wrong as the options
|
||||
# it takes is literally longer than all HHGTTG books combined
|
||||
if (! read($fh, $data, 200000000 )) {
|
||||
$self->{error}=1;
|
||||
$self->{errorString}='Failed to read "'.$file.'"',
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
close($fh);
|
||||
}
|
||||
|
||||
# split it appart and remove comments and blank lines
|
||||
my @options=split(/\n/,$data);
|
||||
@options=grep(!/^#/, @options);
|
||||
@options=grep(!/^$/, @options);
|
||||
|
||||
# we have now completed with out error, so save it
|
||||
$self->{options_array}=\@options;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 load_output
|
||||
|
||||
=cut
|
||||
|
||||
sub load_elastic{
|
||||
my $self=$_[0];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $file=undef;
|
||||
|
||||
# ~/ -> etc -> error
|
||||
if (
|
||||
( defined( $ENV{'HOME'} ) ) &&
|
||||
( -f $ENV{'HOME'}.'/.config/essearcher/elastic/'.$self->{elastic} )
|
||||
) {
|
||||
$file=$ENV{'HOME'}.'/.config/essearcher/elastic/'.$self->{elastic};
|
||||
} elsif (
|
||||
( defined( $self->{base} ) ) &&
|
||||
( -f $self->{base}.'/etc/essearcher/elastic/'.$self->{elastic} )
|
||||
) {
|
||||
$file=$self->{base}.'/etc/essearcher/elastic/'.$self->{elastic};
|
||||
} else {
|
||||
$self->{elastic_hash}={
|
||||
nodes => [
|
||||
'127.0.0.1:9200'
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
if (defined( $file )) {
|
||||
my $fh;
|
||||
if (! open($fh, '<', $file ) ) {
|
||||
$self->{error}=1;
|
||||
$self->{errorString}='Failed to open "'.$file.'"',
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
my $data;
|
||||
# if it is larger than 2M bytes, something is wrong as the template
|
||||
# it takes is literally longer than all HHGTTG books combined
|
||||
if (! read($fh, $data, 200000000 )) {
|
||||
$self->{error}=1;
|
||||
$self->{errorString}='Failed to read "'.$file.'"',
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
close($fh);
|
||||
|
||||
eval {
|
||||
my $decoded=$self->{j}->decode( $data );
|
||||
$self->{elastic_hash}=$decoded;
|
||||
};
|
||||
if ( $@ ){
|
||||
$self->{error}=5;
|
||||
$self->{errorString}=$@;
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval{
|
||||
$self->{es}=Search::Elasticsearch->new( $self->{elastic_hash} );
|
||||
};
|
||||
if ( $@ ){
|
||||
$self->{error}=5;
|
||||
$self->{errorString}=$@;
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 load_output
|
||||
|
||||
=cut
|
||||
|
||||
sub load_output{
|
||||
my $self=$_[0];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $file=undef;
|
||||
|
||||
# ~/ -> etc -> error
|
||||
if (
|
||||
( defined( $ENV{'HOME'} ) ) &&
|
||||
( -f $ENV{'HOME'}.'/.config/essearcher/output/'.$self->{output} )
|
||||
) {
|
||||
$file=$ENV{'HOME'}.'/.config/essearcher/output/'.$self->{output};
|
||||
} elsif (
|
||||
( defined( $self->{base} ) ) &&
|
||||
( -f $self->{base}.'/etc/essearcher/output/'.$self->{output} )
|
||||
) {
|
||||
$file=$self->{base}.'/etc/essearcher/outpot/'.$self->{output};
|
||||
} else {
|
||||
$self->{error}=2;
|
||||
$self->{errorString}='No options file with the name "'.$self->{output}.'" was found';
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $fh;
|
||||
if (! open($fh, '<', $file ) ) {
|
||||
$self->{error}=1;
|
||||
$self->{errorString}='Failed to open "'.$file.'"',
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
my $data;
|
||||
# if it is larger than 2M bytes, something is wrong as the template
|
||||
# it takes is literally longer than all HHGTTG books combined
|
||||
if (! read($fh, $data, 200000000 )) {
|
||||
$self->{error}=1;
|
||||
$self->{errorString}='Failed to read "'.$file.'"',
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
close($fh);
|
||||
|
||||
# we have now completed with out error, so save it
|
||||
$self->{output_template}=$data;
|
||||
|
||||
}
|
||||
|
||||
=head2 load_search
|
||||
|
||||
=cut
|
||||
|
||||
sub load_search{
|
||||
my $self=$_[0];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $file=undef;
|
||||
my $data;
|
||||
|
||||
# ~/ -> etc -> module -> error
|
||||
if (
|
||||
( defined( $ENV{'HOME'} ) ) &&
|
||||
( -f $ENV{'HOME'}.'/.config/essearcher/search/'.$self->{search} )
|
||||
) {
|
||||
$file=$ENV{'HOME'}.'/.config/essearcher/search/'.$self->{search};
|
||||
} elsif (
|
||||
( defined( $self->{base} ) ) &&
|
||||
( -f $self->{base}.'/etc/essearcher/search/'.$self->{search} )
|
||||
) {
|
||||
$file=$self->{base}.'/etc/essearcher/search/'.$self->{search};
|
||||
} else {
|
||||
# do a quick check of making sure we have a valid name before trying a module...
|
||||
# not all valid names are perl module name valid, but it will prevent arbitrary code execution
|
||||
if ( $self->name_validate( $self->{options} ) ){
|
||||
my $to_eval='use Search::ESsearcher::Templates::'.$self->{options}.
|
||||
'; $data=Search::ESsearcher::Templates::'.$self->{options}.'->search;';
|
||||
eval( $to_eval );
|
||||
}
|
||||
# if undefined, it means the eval failed
|
||||
if ( ! defined( $data ) ){
|
||||
$self->{error}=2;
|
||||
$self->{errorString}='No template file with the name "'.$self->{search}.'" was found';
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! defined( $data ) ) {
|
||||
my $fh;
|
||||
if (! open($fh, '<', $file ) ) {
|
||||
$self->{error}=1;
|
||||
$self->{errorString}='Failed to open "'.$file.'"',
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
# if it is larger than 2M bytes, something is wrong as the template
|
||||
# it takes is literally longer than all HHGTTG books combined
|
||||
if (! read($fh, $data, 200000000 )) {
|
||||
$self->{error}=1;
|
||||
$self->{errorString}='Failed to read "'.$file.'"',
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
close($fh);
|
||||
}
|
||||
|
||||
# we have now completed with out error, so save it
|
||||
$self->{search_template}=$data;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 name_valide
|
||||
|
||||
=cut
|
||||
|
||||
sub name_validate{
|
||||
my $self=$_[0];
|
||||
my $name=$_[1];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
if (! defined( $name ) ){
|
||||
return 1;
|
||||
}
|
||||
|
||||
$name=~s/[A-Za-z\:\-\=\_+\ ]+//;
|
||||
|
||||
if ( $name !~ /^$/ ){
|
||||
return undef;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head options_get
|
||||
|
||||
=cut
|
||||
|
||||
sub options_get{
|
||||
my $self=$_[0];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
return $self->{options};
|
||||
}
|
||||
|
||||
=head options_set
|
||||
|
||||
=cut
|
||||
|
||||
sub options_set{
|
||||
my $self=$_[0];
|
||||
my $name=$_[1];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
if (! $self->name_validate( $name ) ){
|
||||
$self->{error}=3;
|
||||
$self->{errorString}='"'.$name.'" is not a valid name';
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
|
||||
if( !defined( $name ) ){
|
||||
$name='syslog';
|
||||
}
|
||||
|
||||
$self->{options}=$name;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head output_get
|
||||
|
||||
=cut
|
||||
|
||||
sub output_get{
|
||||
my $self=$_[0];
|
||||
my $name=$_[1];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
return $self->{output};
|
||||
}
|
||||
|
||||
=head output_set
|
||||
|
||||
=cut
|
||||
|
||||
sub output_set{
|
||||
my $self=$_[0];
|
||||
my $name=$_[1];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
if (! $self->name_validate( $name ) ){
|
||||
$self->{error}=3;
|
||||
$self->{errorString}='"'.$name.'" is not a valid name';
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
|
||||
if( !defined( $name ) ){
|
||||
$name='syslog';
|
||||
}
|
||||
|
||||
$self->{output}=$name;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head search_get
|
||||
|
||||
=cut
|
||||
|
||||
sub search_get{
|
||||
my $self=$_[0];
|
||||
my $name=$_[1];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
return $self->{search};
|
||||
}
|
||||
|
||||
=head2 search_fill_in
|
||||
|
||||
=cut
|
||||
|
||||
sub search_fill_in{
|
||||
my $self=$_[0];
|
||||
my $name=$_[1];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $vars={
|
||||
o=>$self->{parsed_options},
|
||||
pd=>sub{
|
||||
if( $_[0] =~ /^raw\:/ ){
|
||||
$_[0] =~ s/^raw\://;
|
||||
return $_[0];
|
||||
}
|
||||
$_[0]=~s/m$/minutes/;
|
||||
$_[0]=~s/M$/months/;
|
||||
$_[0]=~s/d$/days/;
|
||||
$_[0]=~s/h$/hours/;
|
||||
$_[0]=~s/h$/weeks/;
|
||||
$_[0]=~s/y$/years/;
|
||||
$_[0]=~s/([0123456789])$/$1seconds/;
|
||||
$_[0]=~s/([0123456789])s$/$1seconds/;
|
||||
my $secs="";
|
||||
eval{ $secs=parsedate( $_[0] ); };
|
||||
return $secs;
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
my $processed;
|
||||
$self->{t}->process( \$self->{search_template}, $vars , \$processed );
|
||||
|
||||
$self->{search_filled_in}=$processed;
|
||||
print $processed;
|
||||
$self->{search_usable}=undef;
|
||||
|
||||
eval {
|
||||
my $decoded=$self->{j}->decode( $processed );
|
||||
$self->{search_hash}=$decoded;
|
||||
};
|
||||
if ( $@ ){
|
||||
$self->{error}=4;
|
||||
$self->{errorString}='The returned filled in search template does not parse as JSON... '.$@;
|
||||
$self->warn;
|
||||
return $processed;
|
||||
}
|
||||
|
||||
return $processed;
|
||||
}
|
||||
|
||||
=head2 search_run
|
||||
|
||||
=cut
|
||||
|
||||
sub search_run{
|
||||
my $self=$_[0];
|
||||
my $name=$_[1];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $results;
|
||||
eval{
|
||||
$results=$self->{es}->search( $self->{search_hash} );
|
||||
};
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
=head search_set
|
||||
|
||||
=cut
|
||||
|
||||
sub search_set{
|
||||
my $self=$_[0];
|
||||
my $name=$_[1];
|
||||
|
||||
if ( ! $self->errorblank ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
if (! $self->name_validate( $name ) ){
|
||||
$self->{error}=3;
|
||||
$self->{errorString}='"'.$name.'" is not a valid name';
|
||||
$self->warn;
|
||||
return undef;
|
||||
}
|
||||
|
||||
if( !defined( $name ) ){
|
||||
$name='syslog';
|
||||
}
|
||||
|
||||
$self->{search}=$name;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
@ -106,4 +743,4 @@ This is free software, licensed under:
|
|||
|
||||
=cut
|
||||
|
||||
1; # End of Search::ESsearcher
|
||||
1; # End of Search::ESsearcher
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
package Search::ESsearcher::Templates::syslog;
|
||||
|
||||
use 5.006;
|
||||
use base Error::Helper;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Search::ESsearcher::Templates::syslog - Provides a basic syslog template
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
Version 0.0.0
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = '0.0.0';
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Search::ESsearcher::Templates::syslog;
|
||||
|
||||
my $options = Search::ESsearcher::Templates::syslog->options;
|
||||
my $search = Search::ESsearcher::Templates::syslog->search;
|
||||
my $output = Search::ESsearcher::Templates::syslog->output;
|
||||
|
||||
=head1 LOGSTASH
|
||||
|
||||
This uses a logstash configuration below.
|
||||
|
||||
input {
|
||||
syslog {
|
||||
host => "10.10.10.10"
|
||||
port => 11514
|
||||
type => "syslog"
|
||||
}
|
||||
}
|
||||
|
||||
filter { }
|
||||
|
||||
output {
|
||||
if [type] == "syslog" {
|
||||
elasticsearch {
|
||||
hosts => [ "127.0.0.1:9200" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
sub search{
|
||||
return '
|
||||
[% USE JSON ( pretty => 1 ) %]
|
||||
[% DEFAULT o.host = "*" %]
|
||||
[% DEFAULT o.src = "*" %]
|
||||
[% DEFAULT o.program = "*" %]
|
||||
[% DEFAULT o.facility = "*" %]
|
||||
[% DEFAULT o.severity = "*" %]
|
||||
[% DEFAULT o.pid = "*" %]
|
||||
[% DEFAULT o.size = "50" %]
|
||||
{
|
||||
"index": "logstash-*",
|
||||
"body": {
|
||||
"size": [% o.size.json %],
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{
|
||||
"term": { "type": "syslog" } },
|
||||
{"query_string": {
|
||||
"default_field": "host",
|
||||
"query": [% o.host.json %]
|
||||
}
|
||||
},
|
||||
{"query_string": {
|
||||
"default_field": "logsource",
|
||||
"query": [% o.src.json %]
|
||||
}
|
||||
},
|
||||
{"query_string": {
|
||||
"default_field": "program",
|
||||
"query": [% o.program.json %]
|
||||
}
|
||||
},
|
||||
{"query_string": {
|
||||
"default_field": "facility_label",
|
||||
"query": [% o.facility.json %]
|
||||
}
|
||||
},
|
||||
{"query_string": {
|
||||
"default_field": "severity_label",
|
||||
"query": [% o.severity.json %]
|
||||
}
|
||||
},
|
||||
{"query_string": {
|
||||
"default_field": "pid",
|
||||
"query": [% o.pid.json %]
|
||||
}
|
||||
},
|
||||
[% IF o.dgt %]
|
||||
{"range": {
|
||||
"@timestamp": {
|
||||
"gt": [% pd( o.dgt ).json %]
|
||||
}
|
||||
}
|
||||
},
|
||||
[% END %]
|
||||
[% IF o.dgte %]
|
||||
{"range": {
|
||||
"@timestamp": {
|
||||
"gte": [% pd( o.dgte ).json %]
|
||||
}
|
||||
}
|
||||
},
|
||||
[% END %]
|
||||
[% IF o.dlt %]
|
||||
{"range": {
|
||||
"@timestamp": {
|
||||
"lt": [% pd( o.dlt ).json %]
|
||||
}
|
||||
}
|
||||
},
|
||||
[% END %]
|
||||
[% IF o.dlte %]
|
||||
{"range": {
|
||||
"@timestamp": {
|
||||
"lte": [% pd( o.dlte ).json %]
|
||||
}
|
||||
}
|
||||
},
|
||||
[% END %]
|
||||
]
|
||||
}
|
||||
},
|
||||
"sort": [
|
||||
{
|
||||
"@timestamp": {"order" : "desc"}}
|
||||
]
|
||||
}
|
||||
}
|
||||
';
|
||||
}
|
||||
|
||||
sub options{
|
||||
return '
|
||||
log=s
|
||||
host=s
|
||||
src=s
|
||||
program=s
|
||||
size=s
|
||||
facility=s
|
||||
severity=s
|
||||
pid=s
|
||||
dgt=s
|
||||
dgte=s
|
||||
dlt=s
|
||||
dlte=s
|
||||
';
|
||||
}
|
||||
|
||||
# [% IF o.dgt %]
|
||||
# {"range": {
|
||||
#
|
||||
# }
|
||||
# },
|
||||
# [% END %]
|
Loading…
Reference in New Issue