Imported Upstream version 3.2.0
[debian/amanda] / perl / Amanda / Logfile.pm
index 8f03f2472c9298ef7c93f73bcf29464117f76b05..8a18a8e4778c4def2cea99d44666890c9e57ff68 100644 (file)
@@ -1,16 +1,17 @@
 # This file was automatically generated by SWIG (http://www.swig.org).
-# Version 1.3.33
+# Version 1.3.39
 #
-# Don't modify this file, modify the SWIG interface instead.
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
 
 package Amanda::Logfile;
-require Exporter;
-require DynaLoader;
-@ISA = qw(Exporter DynaLoader);
+use base qw(Exporter);
+use base qw(DynaLoader);
+require Amanda::Cmdline;
 package Amanda::Logfilec;
 bootstrap Amanda::Logfile;
 package Amanda::Logfile;
-@EXPORT = qw( );
+@EXPORT = qw();
 
 # ---------- BASE METHODS -------------
 
@@ -52,9 +53,18 @@ package Amanda::Logfile;
 *open_logfile = *Amanda::Logfilec::open_logfile;
 *close_logfile = *Amanda::Logfilec::close_logfile;
 *get_logline = *Amanda::Logfilec::get_logline;
+*log_add = *Amanda::Logfilec::log_add;
+*log_add_full = *Amanda::Logfilec::log_add_full;
+*log_rename = *Amanda::Logfilec::log_rename;
 *find_log = *Amanda::Logfilec::find_log;
 *search_logfile = *Amanda::Logfilec::search_logfile;
+*search_holding_disk = *Amanda::Logfilec::search_holding_disk;
 *dumps_match = *Amanda::Logfilec::dumps_match;
+*dumps_match_dumpspecs = *Amanda::Logfilec::dumps_match_dumpspecs;
+*match_host = *Amanda::Logfilec::match_host;
+*match_disk = *Amanda::Logfilec::match_disk;
+*match_datestamp = *Amanda::Logfilec::match_datestamp;
+*match_level = *Amanda::Logfilec::match_level;
 
 ############# Class : Amanda::Logfile::find_result_t ##############
 
@@ -76,6 +86,8 @@ sub DESTROY {
 
 *swig_timestamp_get = *Amanda::Logfilec::find_result_t_timestamp_get;
 *swig_timestamp_set = *Amanda::Logfilec::find_result_t_timestamp_set;
+*swig_write_timestamp_get = *Amanda::Logfilec::find_result_t_write_timestamp_get;
+*swig_write_timestamp_set = *Amanda::Logfilec::find_result_t_write_timestamp_set;
 *swig_hostname_get = *Amanda::Logfilec::find_result_t_hostname_get;
 *swig_hostname_set = *Amanda::Logfilec::find_result_t_hostname_set;
 *swig_diskname_get = *Amanda::Logfilec::find_result_t_diskname_get;
@@ -88,8 +100,20 @@ sub DESTROY {
 *swig_filenum_set = *Amanda::Logfilec::find_result_t_filenum_set;
 *swig_status_get = *Amanda::Logfilec::find_result_t_status_get;
 *swig_status_set = *Amanda::Logfilec::find_result_t_status_set;
+*swig_dump_status_get = *Amanda::Logfilec::find_result_t_dump_status_get;
+*swig_dump_status_set = *Amanda::Logfilec::find_result_t_dump_status_set;
+*swig_message_get = *Amanda::Logfilec::find_result_t_message_get;
+*swig_message_set = *Amanda::Logfilec::find_result_t_message_set;
 *swig_partnum_get = *Amanda::Logfilec::find_result_t_partnum_get;
 *swig_partnum_set = *Amanda::Logfilec::find_result_t_partnum_set;
+*swig_totalparts_get = *Amanda::Logfilec::find_result_t_totalparts_get;
+*swig_totalparts_set = *Amanda::Logfilec::find_result_t_totalparts_set;
+*swig_sec_get = *Amanda::Logfilec::find_result_t_sec_get;
+*swig_sec_set = *Amanda::Logfilec::find_result_t_sec_set;
+*swig_kb_get = *Amanda::Logfilec::find_result_t_kb_get;
+*swig_kb_set = *Amanda::Logfilec::find_result_t_kb_set;
+*swig_orig_kb_get = *Amanda::Logfilec::find_result_t_orig_kb_get;
+*swig_orig_kb_set = *Amanda::Logfilec::find_result_t_orig_kb_set;
 sub new {
     my $pkg = shift;
     my $self = Amanda::Logfilec::new_find_result_t(@_);
@@ -142,17 +166,24 @@ package Amanda::Logfile;
 *P_CHUNKER = *Amanda::Logfilec::P_CHUNKER;
 *P_TAPER = *Amanda::Logfilec::P_TAPER;
 *P_AMFLUSH = *Amanda::Logfilec::P_AMFLUSH;
+*P_AMDUMP = *Amanda::Logfilec::P_AMDUMP;
+*P_AMIDXTAPED = *Amanda::Logfilec::P_AMIDXTAPED;
+*P_AMFETCHDUMP = *Amanda::Logfilec::P_AMFETCHDUMP;
+*P_AMCHECKDUMP = *Amanda::Logfilec::P_AMCHECKDUMP;
+*P_AMVAULT = *Amanda::Logfilec::P_AMVAULT;
+*amanda_log_trace_log = *Amanda::Logfilec::amanda_log_trace_log;
 
 @EXPORT_OK = ();
 %EXPORT_TAGS = ();
 
+
 =head1 NAME
 
 Amanda::Logfile - manage Amanda trace logs
 
 =head1 SYNOPSIS
 
-  use Amanda::Logfile qw(:logtype_t); # XXX change
+  use Amanda::Logfile qw( :constants );
   use Amanda::Config qw( :getconf config_dir_relative );
 
   for my $logfile (Amanda::Logfile::find_log()) {
@@ -165,9 +196,9 @@ Amanda::Logfile - manage Amanda trace logs
         print "Found info line from $pname: $str\n";
       }
     }
-    Amanda::Logfile::close_logfile($log);
+    Amanda::Logfile::close_logfile($hdl);
 
-    my @dumps = Amanda::Logfile::search_logfile("TapeLabel-001", "19780615", $logfile);
+    my @dumps = Amanda::Logfile::search_logfile("TapeLabel-001", "19780615", $logfile, 1);
 
     my @matching = Amanda::Logfile::dumps_match([@dumps], "myhost", "/usr", undef, undef, 0);
     for my $dump (@matching) {
@@ -175,32 +206,31 @@ Amanda::Logfile - manage Amanda trace logs
     }
   }
 
-=head1 API STATUS
-
-Stabilizing
-
 =head1 RAW LOGFILE ACCESS
 
-This section corresponds to the C C<logfile> module. 
+This section corresponds to the C C<logfile> module.
 
 Raw access to logfiles is accomplished by opening a logfile and
 fetching log lines one by one via the C<get_logline> function.
 
-A log line is represented by a list C<($type, $prog, $string)>
-where C<$type> is one of the C<L_*> constants (available in export
-tag C<logtype_t>), C<$prog> is one of the C<P_*> constants (available
-in export tag C<program_t>), and C<$str> is the remainder of the line.
-
-Both families of constants can be converted to symbolic names with
-C<logtype_t_to_string> and C<program_t_to_string>, respectively.
+A log line is represented by a list C<($type, $prog, $string)> where C<$type>
+is one of the C<L_*> constants (available in export tag C<logtype_t>), C<$prog>
+is one of the C<P_*> constants (available in export tag C<program_t>), and
+C<$str> is the remainder of the line. Both sets of constants are also available
+in the usual C<constants> export tag.  Both families of constants can be
+converted to symbolic names with C<logtype_t_to_string> and
+C<program_t_to_string>, respectively.
 
 =head2 FUNCTIONS
 
+Use these functions to read a logfile:
+
 =over
 
 =item C<open_logfile($filename)>
 
-Opens a logfile for reading, returning an opaque log file handle.
+Opens a logfile for reading, returning an opaque log file
+handle. Returns C<undef> and sets C<$!> on failure.
 
 =item C<close_logfile($handle)>
 
@@ -208,38 +238,77 @@ Closes a log file handle.
 
 =item C<get_logline($handle)>
 
-Return a list as described above representing the next log line in
-C<$handle>, or nothing at the end of the logfile. 
+Returns a list as described above representing the next log line in
+C<$handle>, or nothing at the end of the logfile.
 
 =back
 
-All of these functions can be imported by name if desired.
+=head3 Writing a "current" Logfile
+
+To write a logfile, call C<log_add($logtype, $string)>.  On the first call,
+this function opens and locks C<$logdir/log>; subsequent calls just append to
+this file.  As such, this function is only appropriate for situations where
+C<log_rename> will be invoked later to rename C<$logdir/log> to
+C<$logdir/log.$timestamp.$n>.
+
+If you need to write a log entry for another program, for example to simulate
+taper entries, call C<log_add_full($logtype, $pname, $string)>.
+
+All of the functions in this section can be imported by name if
+desired.
+
+=head3 Utilities
 
-=head1 Amanda::Find::find_result_t objects
+Many trace log entries have a statistics entry in what used to be the error
+message slot, of the form C<[sec .. kb .. kps ..]>.  The function C<make_stats>
+will create such an entry for you:
+
+    make_stats($size, $duration, $orig_kb);
+
+Note that C<$orig_kb> can be undefined, in which case it will not appear in
+the statistics output.
+
+=head2 Amanda::Find::find_result_t objects
 
 These objects contain information about dumps, as read from logfiles.
 Instance variables are:
 
+To rename the current logfile to a datestamped logfile, call C<log_rename($ts)>
+where C<$ts> is the write timestamp for this dump.  The
+C<get_current_log_timestamp()> function will calculate this timestamp,
+returning C<undef> on error.
+
 =over
 
-=item C<$timestamp>
+=item C<timestamp>
+
+=item C<hostname>
 
-=item C<$hostname>
+=item C<diskname>
 
-=item C<$diskname>
+=item C<level>
 
-=item C<$level>
+=item C<label>
 
-=item C<$label>
+=item C<filenum>
 
-=item C<$filenum>
+=item C<status>
 
-=item C<$status>
+=item C<partnum>
 
-=item C<$partnum>
+=item C<totalparts>
+
+=item C<sec>
+
+=item C<kb>
 
 =back
 
+Note that the format for these variables are based on that found in
+the logfiles.  In particular, C<timestamp> is the timestamp for the run
+in which the client dump took place, and not for the timestamp of the
+logfile.
+
 =head1 HIGHER-LEVEL FUNCTIONS
 
 Functions in this section extract information from logfiles.
@@ -248,27 +317,78 @@ Functions in this section extract information from logfiles.
 
 =item C<find_log()>
 
-Return a list of logfiles for active tapes.  The tapelist must be loaded before
-this function is called (see L<Amanda::Tapelist>).
+Return a list of logfiles for active tapes.  The tapelist must be loaded
+before this function is called (see L<Amanda::Tapelist>).  This function uses
+the C API which indexes logfiles with tapes.  If there is no corresponding
+tape, the logfile will not be found.
+
+=item C<find_all_logs([dir])>
+
+Return a list of all logs the configuration.  An optional directory argument
+can be specified, if not present, C<find_all_logs> checks C<LOGDIR>.
+
+=item C<find_latest_log([dir])>
+
+Returns the most recent logfile in the list of logfiles returned by
+C<find_all_logs>.  The optional directory argument is passed to
+C<find_all_logs>.
 
 =item C<search_logfile($label, $datestamp, $logfile, $add_missing_disks)>
 
-Return all results in C<$logfile> matching C<$label> and C<$datestamp>.
-If C<$add_missing_disks> is true, then any disks in the logfile
-not present in the disklist are added to the disklist; otherwise,
-such dumps are skipped.
+Return all results in C<$logfile> matching C<$label> and
+C<$datestamp>.  If C<$add_missing_disks> is true, then any disks in
+the logfile not present in the disklist are added to the disklist;
+otherwise, such dumps are skipped.
+
+=item C<search_holding_disk()>
+
+Return results for all holding-disk files.  Results are similar to those from
+search_logfile.
 
 =item C<dumps_match([@results], $hostname, $diskname, $datestamp, $level, $ok)>
 
-Return a filtered version of C<@results> containing only results that match the 
-given expressions.  If C<$ok> is true, don't match partial results.  Note that
-C<$level> is given as a string, since it is a match expression.
+Return a filtered version of C<@results> containing only results that
+match the given expressions.  If C<$ok> is true, don't match partial
+results.  Note that C<$level> is given as a string, since it is a
+match expression.
+
+=item C<dumps_match_dumpspecs([@results], [@dumpspecs], $ok)>
+
+Return a filtered version of C<@results>, containing only results that match
+one or more of the dumpspecs.  C<$ok> is as for C<dumps_match>.  Supplying no
+dumpspecs will result in an empty return value.  If multiple dumpspecs match
+the same result, that result will be returned multiple times.
+
+=back
 
 All of these functions can be imported by name.
 
+=head1 MATCHING
+
+The following functions are available to match strings against patterns using
+the rules described in amanda(8):
+
+  match_host($pat, $str);
+  match_disk($pat, $str);
+  match_datestamp($pat, $str);
+  match_level($pat, $str);
+
+=head1 DEBUG LOGGING HANDLER
+
+This package provides C<$amanda_log_trace_log>, which sends C<die>
+messages (and any C<g_error> or C<g_critical> calls from C) to the
+trace log.  Use it like this:
+
+  use Amanda::Logfile qw( $amanda_log_trace_log );
+  # ...
+  Amanda::Debug::add_amanda_log_handler($amanda_log_trace_log);
+
 =cut
 
-push @EXPORT_OK, qw(open_logfile get_logline close_logfile);
+
+
+push @EXPORT_OK, qw(open_logfile get_logline close_logfile
+    log_add log_add_full);
 
 push @EXPORT_OK, qw(logtype_t_to_string);
 push @{$EXPORT_TAGS{"logtype_t"}}, qw(logtype_t_to_string);
@@ -396,6 +516,9 @@ push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_CONT);
 
 $_logtype_t_VALUES{"L_CONT"} = $L_CONT;
 
+#copy symbols in logtype_t to constants
+push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"logtype_t"}};
+
 push @EXPORT_OK, qw(program_t_to_string);
 push @{$EXPORT_TAGS{"program_t"}}, qw(program_t_to_string);
 
@@ -457,5 +580,102 @@ push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMFLUSH);
 
 $_program_t_VALUES{"P_AMFLUSH"} = $P_AMFLUSH;
 
-push @EXPORT_OK, qw(find_log search_logfile dumps_match);
+push @EXPORT_OK, qw($P_AMDUMP);
+push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMDUMP);
+
+$_program_t_VALUES{"P_AMDUMP"} = $P_AMDUMP;
+
+push @EXPORT_OK, qw($P_AMIDXTAPED);
+push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMIDXTAPED);
+
+$_program_t_VALUES{"P_AMIDXTAPED"} = $P_AMIDXTAPED;
+
+push @EXPORT_OK, qw($P_AMFETCHDUMP);
+push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMFETCHDUMP);
+
+$_program_t_VALUES{"P_AMFETCHDUMP"} = $P_AMFETCHDUMP;
+
+push @EXPORT_OK, qw($P_AMCHECKDUMP);
+push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMCHECKDUMP);
+
+$_program_t_VALUES{"P_AMCHECKDUMP"} = $P_AMCHECKDUMP;
+
+push @EXPORT_OK, qw($P_AMVAULT);
+push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMVAULT);
+
+$_program_t_VALUES{"P_AMVAULT"} = $P_AMVAULT;
+
+#copy symbols in program_t to constants
+push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"program_t"}};
+
+push @EXPORT_OK, qw(find_log search_logfile dumps_match log_rename
+    match_host match_disk match_datestamp match_level);
+
+push @EXPORT_OK, qw($amanda_log_trace_log);
+
+push @EXPORT_OK, qw(find_all_logs find_latest_log
+    get_current_log_timestamp
+    make_stats);
+
+
+sub find_all_logs
+{
+    my $logdir = shift @_ || config_dir_relative(getconf($CNF_LOGDIR));
+
+    opendir my $logdh, $logdir or die("can't read $logdir");
+    my @logfiles = sort grep { m{^log\.\d+\.\d+$} } readdir $logdh;
+
+    return @logfiles;
+}
+
+sub find_latest_log
+{
+    my $logdir = shift @_;
+    my @logs = find_all_logs($logdir || ());
+    return $logs[-1];
+}
+
+use Amanda::Config;
+use Amanda::Debug;
+
+sub get_current_log_timestamp
+{
+    my $logfile = Amanda::Config::config_dir_relative(
+               Amanda::Config::getconf($Amanda::Config::CNF_LOGDIR)) . "/log";
+    if (! -f $logfile) {
+       Amanda::Debug::warning("no current logfile '$logfile'");
+       return undef;
+    }
+
+    my $logh = open_logfile("$logfile");
+    if (!$logh) {
+       Amanda::Debug::warning("could not open logfile '$logfile'");
+       return undef;
+    }
+    while (my ($type, $prog, $str) = get_logline($logh)) {
+       if ($type == $L_START) {
+           my ($ts) = ($str =~ /date (\d+)/);
+           return $ts if $ts;
+       }
+    }
+
+    # no timestamp, apparently
+    Amanda::Debug::warning("no current timestamp found in logfile");
+    return undef;
+}
+
+sub make_stats {
+    my ($size, $duration, $orig_kb) = @_;
+
+    $duration = 0.1 if $duration <= 0;  # prevent division by zero
+    my $kb = $size/1024;
+    my $kps = "$kb.0"/$duration; # Perlish cast from BigInt to float
+
+    if (defined $orig_kb) {
+       return sprintf("[sec %f kb %d kps %f orig-kb %d]", $duration, $kb, $kps, $orig_kb);
+    } else {
+       return sprintf("[sec %f kb %d kps %f]", $duration, $kb, $kps);
+    }
+}
+
 1;