#!/usr/bin/env perl

use strict;
use warnings;

our $VERSION = '0.10';

use Beekeeper::Service::LogTail;
use Beekeeper::Logger ':log_levels';
use Getopt::Long;

my ($opt_count, $opt_level, $opt_host, $opt_pool, $opt_service,  
    $opt_message, $opt_follow, $opt_verbose, $opt_help);

GetOptions(
    "number=i"  => \$opt_count,    # --number
    "level=i"   => \$opt_level,    # --level
    "host=s"    => \$opt_host,     # --host
    "pool=s"    => \$opt_pool,     # --pool
    "service=s" => \$opt_service,  # --service
    "message=s" => \$opt_message,  # --message
    "follow"    => \$opt_follow,   # --follow
    "verbose"   => \$opt_verbose,  # --verbose
    "help"      => \$opt_help,     # --help    
) or exit;

my $Help = "
Usage: bkpr-log [OPTIONS]
Display log entries generated by worker pools.

  -n, --number N    output the last N lines, instead of the last 10
  -l, --level N     show only messages of severity N or above
  -h, --host re     show only messages generated at matching hosts (regex)
  -p, --pool re     show only messages generated at matching pools (regex)
  -s, --service re  show only messages generated by matching services (regex)
  -m, --message re  show only messages matching given regex
  -f, --follow      keep receiving messages in real time (press Ctrl-C to stop)
  -v, --verbose     display also host:pool:pid of each entry
  -h, --help        display this help and exit

All filters can be combined.

";

if ($opt_help) {
    print $Help;
    exit;
}

my $last;

MAIN: {

    my $l = Beekeeper::Service::LogTail->tail(
        count   => $opt_count,
        level   => $opt_level,
        host    => $opt_host, 
        pool    => $opt_pool, 
        service => $opt_service,
        message => $opt_message,
        after   => $last,
    );

    foreach my $msg (@$l) {

        my $ts = $msg->{tstamp};
        my $ms = int(($ts * 1000) % 1000);
        my @t = reverse((localtime($ts))[0..5]); $t[0] += 1900; $t[1]++;

        my $str = sprintf("[%4d-%02d-%02d %02d:%02d:%02d.%03d]", @t, $ms);

        if ($opt_verbose) {
            $str .= "[$msg->{host}:$msg->{pool}:$msg->{pid}]";
        }
        else {
            # Timestamp without the date part
            $str = "[". substr( $str, 12 );
        }

        my $level = $msg->{level};
        my $label = $LOG_LABEL{$level};

        $label = ( $level == LOG_FATAL ) ? "\033[41m${label}\033[0m"   :
                 ( $level <= LOG_ERROR ) ? "\033[31;1m${label}\033[0m" :
                 ( $level <= LOG_WARN  ) ? "\033[33;1m${label}\033[0m" :
                 ( $level <= LOG_INFO  ) ? "\033[36m${label}\033[0m"   : $label;

        $str .= "[$msg->{service}]";
        $str .= "[$label] ";
        $str .= $msg->{message};

        $str =~ s/\n+\s*$//s;

        print $str . "\n";
        
        $last = $ts;
    }

    sleep 1 && redo if $opt_follow;
}


__END__

=pod

=encoding utf8

=head1 NAME

bkpr-log - Display log entries generated by worker pools

=head1 VERSION

Version 0.09

=head1 SYNOPSIS

  Usage: bkpr-log [OPTIONS]
  Display log entries generated by worker pools.
  
    -n, --number N    output the last N lines, instead of the last 10
    -l, --level N     show only messages of severity N or above
    -h, --host re     show only messages generated at matching hosts (regex)
    -p, --pool re     show only messages generated at matching pools (regex)
    -s, --service re  show only messages generated by matching services (regex)
    -m, --message re  show only messages matching given regex
    -f, --follow      keep receiving messages in real time (press Ctrl-C to stop)
    -v, --verbose     display also host:pool:pid of each entry
    -h, --help        display this help and exit
  
  All filters can be combined.

=head1 DESCRIPTION

Display log entries generated by worker pools in a C<tail> fashion.

=head1 SEE ALSO

L<Beekeeper::Service::LogTail>, L<Beekeeper::Logger>.

=head1 AUTHOR

José Micó, C<jose.mico@gmail.com>

=head1 COPYRIGHT AND LICENSE

Copyright 2015-2023 José Micó.

This is free software; you can redistribute it and/or modify it under the same 
terms as the Perl 5 programming language itself.

This software is distributed in the hope that it will be useful, but it is 
provided “as is” and without any express or implied warranties. For details, 
see the full text of the license in the file LICENSE.

=cut
