File Coverage

blib/script/logfile-tail
Criterion Covered Total %
statement 47 47 100.0
branch 16 16 100.0
condition 2 2 100.0
subroutine 8 8 100.0
pod n/a
total 73 73 100.0


line stmt bran cond sub pod time code
1             #!/usr/local/bin/perl
2              
3             =head1 NAME
4              
5             logfile-tail - output (cat) file from the last saved position
6              
7             =cut
8              
9 9     9   55 use strict;
  9         15  
  9         523  
10 9     9   55 use warnings FATAL => 'all';
  9         19  
  9         838  
11              
12 9     9   7249 use Getopt::Long ();
  9         171269  
  9         402  
13 9     9   4887 use Logfile::Tail ();
  9         32  
  9         18585  
14              
15             =head1 SYNOPSIS
16              
17             logfile-tail [ --status=status-directory | --status=status-file ] logfile
18             logfile-tail --help
19              
20             =cut
21              
22             sub usage {
23 2   100 2   12 my $exit = shift // 0;
24 2         12 my $usage = "Usage: $0 [--status=DIR | --status=FILE] logfile | --help\n";
25 2 100       7 if ($exit) {
26 1         37 print STDERR $usage;
27             } else {
28 1         6 print $usage;
29             }
30 2           exit $exit;
31             }
32              
33 9         1647401 my $status_path;
34 9 100   1   126 Getopt::Long::GetOptions('status=s' => \$status_path, 'help' => sub { usage() }) or exit 1;
  1         931  
35 7 100       5749 if (@ARGV != 1) {
36 1         5 usage(2);
37             }
38              
39 6         22 my %attr = ();
40 6 100       23 if (defined $status_path) {
41 3 100       186 if (-f $status_path) {
42 2         9 $attr{status_file} = $status_path;
43 2 100       10 if ($status_path =~ m!^/!) {
44 1         5 $attr{status_dir} = '/';
45             } else {
46 1         3 $attr{status_dir} = '.';
47             }
48             } else {
49 1         6 $attr{status_dir} = $status_path;
50             }
51             }
52              
53 6         17 my $logfile_name = shift;
54 6         12 my @the_warning;
55             $SIG{'__WARN__'} = sub {
56 1     1   6 push @the_warning, @_;
57 6         64 };
58              
59             my $logfile = new Logfile::Tail(
60             $logfile_name,
61             'r',
62             \%attr,
63 6 100       80 ) or do {
64 2 100       7 if (@the_warning) {
65 1         5 s/\n(.)/$1/g for @the_warning;
66 1         5 s/\n// for @the_warning;
67 1         37 print STDERR "Error while reading [$logfile_name]: @the_warning: $!\n";
68             } else {
69 1         37 print STDERR "Error reading [$logfile_name]: $!\n";
70             }
71 2         0 exit 3;
72             };
73              
74 4         28 while (defined(my $line = $logfile->getline())) {
75 12         93 print $line;
76             }
77              
78             1;
79              
80             =head1 DESCRIPTION
81              
82             When processing log files, you want to continue reading where you
83             left out the last time. The B program uses the
84             B module internally to store the position last
85             seen for the log file and retrieve it upon the subsequent
86             invocation.
87              
88             The program also handles rotated files -- if the log file was
89             rotated since the last read, it is detected and the rest of the
90             rotated file is read first, before proceeding to the newer
91             rotate file or to the current log file.
92              
93             The content is printed to the standard output.
94              
95             =head1 OPTIONS
96              
97             =over 4
98              
99             =item --status=STATUS DIRECTORY | --status=STATUS FILE
100              
101             The parameter specifies either the status file which is used
102             to store the position, or directory which will hold the status file.
103             The file has to already exist (albeit empty) for the path to be
104             recognized as status file, otherwise it is considered to be
105             a status directory path.
106              
107             =item --help
108              
109             Short usage is printed.
110              
111             =back
112              
113             =head1 EXAMPLES
114              
115             # output data from Apache's access_log
116             logfile-tail /var/log/httpd/access_log
117              
118             logfile-tail --status /var/run/apache/logfile-tail error_log
119              
120             =head1 AUTHOR
121              
122             Copyright (C) 2011--2024 by Jan Pazdziora
123              
124             =head1 LICENSE
125              
126             This module is free software. You can redistribute it and/or
127             modify it under the terms of the Artistic License 2.0.
128              
129             This program is distributed in the hope that it will be useful,
130             but without any warranty; without even the implied warranty of
131             merchantability or fitness for a particular purpose.
132              
133             =cut
134