1# This file was automatically generated by SWIG (http://www.swig.org). 2# Version 3.0.7 3# 4# Do not make changes to this file unless you know what you are doing--modify 5# the SWIG interface file instead. 6 7package Amanda::Logfile; 8use base qw(Exporter); 9use base qw(DynaLoader); 10require Amanda::Cmdline; 11package Amanda::Logfilec; 12bootstrap Amanda::Logfile; 13package Amanda::Logfile; 14@EXPORT = qw(); 15 16# ---------- BASE METHODS ------------- 17 18package Amanda::Logfile; 19 20sub TIEHASH { 21 my ($classname,$obj) = @_; 22 return bless $obj, $classname; 23} 24 25sub CLEAR { } 26 27sub FIRSTKEY { } 28 29sub NEXTKEY { } 30 31sub FETCH { 32 my ($self,$field) = @_; 33 my $member_func = "swig_${field}_get"; 34 $self->$member_func(); 35} 36 37sub STORE { 38 my ($self,$field,$newval) = @_; 39 my $member_func = "swig_${field}_set"; 40 $self->$member_func($newval); 41} 42 43sub this { 44 my $ptr = shift; 45 return tied(%$ptr); 46} 47 48 49# ------- FUNCTION WRAPPERS -------- 50 51package Amanda::Logfile; 52 53*open_logfile = *Amanda::Logfilec::open_logfile; 54*close_logfile = *Amanda::Logfilec::close_logfile; 55*get_logline = *Amanda::Logfilec::get_logline; 56*log_add = *Amanda::Logfilec::log_add; 57*log_add_full = *Amanda::Logfilec::log_add_full; 58*log_rename = *Amanda::Logfilec::log_rename; 59*find_log = *Amanda::Logfilec::find_log; 60*search_logfile = *Amanda::Logfilec::search_logfile; 61*search_holding_disk = *Amanda::Logfilec::search_holding_disk; 62*dumps_match = *Amanda::Logfilec::dumps_match; 63*dumps_match_dumpspecs = *Amanda::Logfilec::dumps_match_dumpspecs; 64 65############# Class : Amanda::Logfile::find_result_t ############## 66 67package Amanda::Logfile::find_result_t; 68use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS); 69@ISA = qw( Amanda::Logfile ); 70%OWNER = (); 71%ITERATORS = (); 72sub DESTROY { 73 return unless $_[0]->isa('HASH'); 74 my $self = tied(%{$_[0]}); 75 return unless defined $self; 76 delete $ITERATORS{$self}; 77 if (exists $OWNER{$self}) { 78 Amanda::Logfilec::delete_find_result_t($self); 79 delete $OWNER{$self}; 80 } 81} 82 83*swig_timestamp_get = *Amanda::Logfilec::find_result_t_timestamp_get; 84*swig_timestamp_set = *Amanda::Logfilec::find_result_t_timestamp_set; 85*swig_write_timestamp_get = *Amanda::Logfilec::find_result_t_write_timestamp_get; 86*swig_write_timestamp_set = *Amanda::Logfilec::find_result_t_write_timestamp_set; 87*swig_hostname_get = *Amanda::Logfilec::find_result_t_hostname_get; 88*swig_hostname_set = *Amanda::Logfilec::find_result_t_hostname_set; 89*swig_diskname_get = *Amanda::Logfilec::find_result_t_diskname_get; 90*swig_diskname_set = *Amanda::Logfilec::find_result_t_diskname_set; 91*swig_level_get = *Amanda::Logfilec::find_result_t_level_get; 92*swig_level_set = *Amanda::Logfilec::find_result_t_level_set; 93*swig_label_get = *Amanda::Logfilec::find_result_t_label_get; 94*swig_label_set = *Amanda::Logfilec::find_result_t_label_set; 95*swig_filenum_get = *Amanda::Logfilec::find_result_t_filenum_get; 96*swig_filenum_set = *Amanda::Logfilec::find_result_t_filenum_set; 97*swig_status_get = *Amanda::Logfilec::find_result_t_status_get; 98*swig_status_set = *Amanda::Logfilec::find_result_t_status_set; 99*swig_dump_status_get = *Amanda::Logfilec::find_result_t_dump_status_get; 100*swig_dump_status_set = *Amanda::Logfilec::find_result_t_dump_status_set; 101*swig_message_get = *Amanda::Logfilec::find_result_t_message_get; 102*swig_message_set = *Amanda::Logfilec::find_result_t_message_set; 103*swig_partnum_get = *Amanda::Logfilec::find_result_t_partnum_get; 104*swig_partnum_set = *Amanda::Logfilec::find_result_t_partnum_set; 105*swig_totalparts_get = *Amanda::Logfilec::find_result_t_totalparts_get; 106*swig_totalparts_set = *Amanda::Logfilec::find_result_t_totalparts_set; 107*swig_sec_get = *Amanda::Logfilec::find_result_t_sec_get; 108*swig_sec_set = *Amanda::Logfilec::find_result_t_sec_set; 109*swig_bytes_get = *Amanda::Logfilec::find_result_t_bytes_get; 110*swig_bytes_set = *Amanda::Logfilec::find_result_t_bytes_set; 111*swig_kb_get = *Amanda::Logfilec::find_result_t_kb_get; 112*swig_kb_set = *Amanda::Logfilec::find_result_t_kb_set; 113*swig_orig_kb_get = *Amanda::Logfilec::find_result_t_orig_kb_get; 114*swig_orig_kb_set = *Amanda::Logfilec::find_result_t_orig_kb_set; 115sub new { 116 my $pkg = shift; 117 my $self = Amanda::Logfilec::new_find_result_t(@_); 118 bless $self, $pkg if defined($self); 119} 120 121sub DISOWN { 122 my $self = shift; 123 my $ptr = tied(%$self); 124 delete $OWNER{$ptr}; 125} 126 127sub ACQUIRE { 128 my $self = shift; 129 my $ptr = tied(%$self); 130 $OWNER{$ptr} = 1; 131} 132 133 134# ------- VARIABLE STUBS -------- 135 136package Amanda::Logfile; 137 138*L_BOGUS = *Amanda::Logfilec::L_BOGUS; 139*L_FATAL = *Amanda::Logfilec::L_FATAL; 140*L_ERROR = *Amanda::Logfilec::L_ERROR; 141*L_WARNING = *Amanda::Logfilec::L_WARNING; 142*L_INFO = *Amanda::Logfilec::L_INFO; 143*L_SUMMARY = *Amanda::Logfilec::L_SUMMARY; 144*L_START = *Amanda::Logfilec::L_START; 145*L_FINISH = *Amanda::Logfilec::L_FINISH; 146*L_DISK = *Amanda::Logfilec::L_DISK; 147*L_DONE = *Amanda::Logfilec::L_DONE; 148*L_PART = *Amanda::Logfilec::L_PART; 149*L_PARTPARTIAL = *Amanda::Logfilec::L_PARTPARTIAL; 150*L_SUCCESS = *Amanda::Logfilec::L_SUCCESS; 151*L_PARTIAL = *Amanda::Logfilec::L_PARTIAL; 152*L_FAIL = *Amanda::Logfilec::L_FAIL; 153*L_STRANGE = *Amanda::Logfilec::L_STRANGE; 154*L_CHUNK = *Amanda::Logfilec::L_CHUNK; 155*L_CHUNKSUCCESS = *Amanda::Logfilec::L_CHUNKSUCCESS; 156*L_STATS = *Amanda::Logfilec::L_STATS; 157*L_MARKER = *Amanda::Logfilec::L_MARKER; 158*L_CONT = *Amanda::Logfilec::L_CONT; 159*P_UNKNOWN = *Amanda::Logfilec::P_UNKNOWN; 160*P_PLANNER = *Amanda::Logfilec::P_PLANNER; 161*P_DRIVER = *Amanda::Logfilec::P_DRIVER; 162*P_REPORTER = *Amanda::Logfilec::P_REPORTER; 163*P_DUMPER = *Amanda::Logfilec::P_DUMPER; 164*P_CHUNKER = *Amanda::Logfilec::P_CHUNKER; 165*P_TAPER = *Amanda::Logfilec::P_TAPER; 166*P_AMFLUSH = *Amanda::Logfilec::P_AMFLUSH; 167*P_AMDUMP = *Amanda::Logfilec::P_AMDUMP; 168*P_AMIDXTAPED = *Amanda::Logfilec::P_AMIDXTAPED; 169*P_AMFETCHDUMP = *Amanda::Logfilec::P_AMFETCHDUMP; 170*P_AMCHECKDUMP = *Amanda::Logfilec::P_AMCHECKDUMP; 171*P_AMVAULT = *Amanda::Logfilec::P_AMVAULT; 172*amanda_log_trace_log = *Amanda::Logfilec::amanda_log_trace_log; 173 174@EXPORT_OK = (); 175%EXPORT_TAGS = (); 176 177 178=head1 NAME 179 180Amanda::Logfile - manage Amanda trace logs 181 182=head1 SYNOPSIS 183 184 use Amanda::Logfile qw( :constants ); 185 use Amanda::Config qw( :getconf config_dir_relative ); 186 187 for my $logfile (Amanda::Logfile::find_log()) { 188 $logfile = config_dir_relative(getconf($CNF_LOGDIR)) . "/" . $logfile; 189 190 my $hdl = Amanda::Logfile::open_logfile($logfile); 191 while (my ($type, $prog, $str) = Amanda::Logfile::get_logline($hdl)) { 192 if ($type == $L_INFO) { 193 my $pname = Amanda::Logfile::program_t_to_string($prog); 194 print "Found info line from $pname: $str\n"; 195 } 196 } 197 Amanda::Logfile::close_logfile($hdl); 198 199 my @dumps = Amanda::Logfile::search_logfile("TapeLabel-001", "19780615", $logfile, 1); 200 201 my @matching = Amanda::Logfile::dumps_match([@dumps], "myhost", "/usr", undef, undef, 0); 202 for my $dump (@matching) { 203 print "$dump->{'label'}:$dump->{'filenum'} = $dump->{'hostname'}:$dump->{'disk'}\n"; 204 } 205 } 206 207=head1 RAW LOGFILE ACCESS 208 209This section corresponds to the C C<logfile> module. 210 211Raw access to logfiles is accomplished by opening a logfile and 212fetching log lines one by one via the C<get_logline> function. 213 214A log line is represented by a list C<($type, $prog, $string)> where C<$type> 215is one of the C<L_*> constants (available in export tag C<logtype_t>), C<$prog> 216is one of the C<P_*> constants (available in export tag C<program_t>), and 217C<$str> is the remainder of the line. Both sets of constants are also available 218in the usual C<constants> export tag. Both families of constants can be 219converted to symbolic names with C<logtype_t_to_string> and 220C<program_t_to_string>, respectively. 221 222=head2 FUNCTIONS 223 224Use these functions to read a logfile: 225 226=over 227 228=item C<open_logfile($filename)> 229 230Opens a logfile for reading, returning an opaque log file 231handle. Returns C<undef> and sets C<$!> on failure. 232 233=item C<close_logfile($handle)> 234 235Closes a log file handle. 236 237=item C<get_logline($handle)> 238 239Returns a list as described above representing the next log line in 240C<$handle>, or nothing at the end of the logfile. 241 242=back 243 244=head3 Writing a "current" Logfile 245 246To write a logfile, call C<log_add($logtype, $string)>. On the first call, 247this function opens and locks C<$logdir/log>; subsequent calls just append to 248this file. As such, this function is only appropriate for situations where 249C<log_rename> will be invoked later to rename C<$logdir/log> to 250C<$logdir/log.$timestamp.$n>. 251 252If you need to write a log entry for another program, for example to simulate 253taper entries, call C<log_add_full($logtype, $pname, $string)>. 254 255All of the functions in this section can be imported by name if 256desired. 257 258=head3 Utilities 259 260Many trace log entries have a statistics entry in what used to be the error 261message slot, of the form C<[sec .. kb .. kps ..]>. The function C<make_stats> 262will create such an entry for you: 263 264 make_stats($size, $duration, $orig_kb); 265 266Note that C<$orig_kb> can be undefined, in which case it will not appear in 267the statistics output. 268 269=head2 Amanda::Find::find_result_t objects 270 271These objects contain information about dumps, as read from logfiles. 272Instance variables are: 273 274To rename the current logfile to a datestamped logfile, call C<log_rename($ts)> 275where C<$ts> is the write timestamp for this dump. The 276C<get_current_log_timestamp()> function will calculate this timestamp, 277returning C<undef> on error. 278 279=over 280 281=item C<timestamp> 282 283=item C<hostname> 284 285=item C<diskname> 286 287=item C<level> 288 289=item C<label> 290 291=item C<filenum> 292 293=item C<status> 294 295=item C<partnum> 296 297=item C<totalparts> 298 299=item C<sec> 300 301=item C<kb> 302 303=back 304 305Note that the format for these variables are based on that found in 306the logfiles. In particular, C<timestamp> is the timestamp for the run 307in which the client dump took place, and not for the timestamp of the 308logfile. 309 310=head1 HIGHER-LEVEL FUNCTIONS 311 312Functions in this section extract information from logfiles. 313 314=over 315 316=item C<find_log()> 317 318Return a list of logfiles for active tapes. The tapelist must be loaded 319before this function is called (see L<Amanda::Tapelist>). This function uses 320the C API which indexes logfiles with tapes. If there is no corresponding 321tape, the logfile will not be found. 322 323=item C<find_all_logs([dir])> 324 325Return a list of all logs the configuration. An optional directory argument 326can be specified, if not present, C<find_all_logs> checks C<LOGDIR>. 327 328=item C<find_latest_log([dir])> 329 330Returns the most recent logfile in the list of logfiles returned by 331C<find_all_logs>. The optional directory argument is passed to 332C<find_all_logs>. 333 334=item C<search_logfile($label, $datestamp, $logfile, $add_missing_disks)> 335 336Return all results in C<$logfile> matching C<$label> and 337C<$datestamp>. If C<$add_missing_disks> is true, then any disks in 338the logfile not present in the disklist are added to the disklist; 339otherwise, such dumps are skipped. 340 341=item C<search_holding_disk()> 342 343Return results for all holding-disk files. Results are similar to those from 344search_logfile. 345 346=item C<dumps_match([@results], $hostname, $diskname, $datestamp, $level, $ok)> 347 348Return a filtered version of C<@results> containing only results that 349match the given expressions. If C<$ok> is true, don't match partial 350results. Note that C<$level> is given as a string, since it is a 351match expression. 352 353=item C<dumps_match_dumpspecs([@results], [@dumpspecs], $ok)> 354 355Return a filtered version of C<@results>, containing only results that match 356one or more of the dumpspecs. C<$ok> is as for C<dumps_match>. Supplying no 357dumpspecs will result in an empty return value. If multiple dumpspecs match 358the same result, that result will be returned multiple times. 359 360=back 361 362All of these functions can be imported by name. 363 364=head1 DEBUG LOGGING HANDLER 365 366This package provides C<$amanda_log_trace_log>, which sends C<die> 367messages (and any C<g_error> or C<g_critical> calls from C) to the 368trace log. Use it like this: 369 370 use Amanda::Logfile qw( $amanda_log_trace_log ); 371 # ... 372 Amanda::Debug::add_amanda_log_handler($amanda_log_trace_log); 373 374=cut 375 376 377 378push @EXPORT_OK, qw(open_logfile get_logline close_logfile 379 log_add log_add_full); 380 381push @EXPORT_OK, qw(logtype_t_to_string); 382push @{$EXPORT_TAGS{"logtype_t"}}, qw(logtype_t_to_string); 383 384my %_logtype_t_VALUES; 385#Convert an enum value to a single string 386sub logtype_t_to_string { 387 my ($enumval) = @_; 388 389 for my $k (keys %_logtype_t_VALUES) { 390 my $v = $_logtype_t_VALUES{$k}; 391 392 #is this a matching flag? 393 if ($enumval == $v) { 394 return $k; 395 } 396 } 397 398#default, just return the number 399 return $enumval; 400} 401 402push @EXPORT_OK, qw($L_BOGUS); 403push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_BOGUS); 404 405$_logtype_t_VALUES{"L_BOGUS"} = $L_BOGUS; 406 407push @EXPORT_OK, qw($L_FATAL); 408push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_FATAL); 409 410$_logtype_t_VALUES{"L_FATAL"} = $L_FATAL; 411 412push @EXPORT_OK, qw($L_ERROR); 413push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_ERROR); 414 415$_logtype_t_VALUES{"L_ERROR"} = $L_ERROR; 416 417push @EXPORT_OK, qw($L_WARNING); 418push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_WARNING); 419 420$_logtype_t_VALUES{"L_WARNING"} = $L_WARNING; 421 422push @EXPORT_OK, qw($L_INFO); 423push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_INFO); 424 425$_logtype_t_VALUES{"L_INFO"} = $L_INFO; 426 427push @EXPORT_OK, qw($L_SUMMARY); 428push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_SUMMARY); 429 430$_logtype_t_VALUES{"L_SUMMARY"} = $L_SUMMARY; 431 432push @EXPORT_OK, qw($L_START); 433push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_START); 434 435$_logtype_t_VALUES{"L_START"} = $L_START; 436 437push @EXPORT_OK, qw($L_FINISH); 438push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_FINISH); 439 440$_logtype_t_VALUES{"L_FINISH"} = $L_FINISH; 441 442push @EXPORT_OK, qw($L_DISK); 443push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_DISK); 444 445$_logtype_t_VALUES{"L_DISK"} = $L_DISK; 446 447push @EXPORT_OK, qw($L_DONE); 448push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_DONE); 449 450$_logtype_t_VALUES{"L_DONE"} = $L_DONE; 451 452push @EXPORT_OK, qw($L_PART); 453push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_PART); 454 455$_logtype_t_VALUES{"L_PART"} = $L_PART; 456 457push @EXPORT_OK, qw($L_PARTPARTIAL); 458push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_PARTPARTIAL); 459 460$_logtype_t_VALUES{"L_PARTPARTIAL"} = $L_PARTPARTIAL; 461 462push @EXPORT_OK, qw($L_SUCCESS); 463push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_SUCCESS); 464 465$_logtype_t_VALUES{"L_SUCCESS"} = $L_SUCCESS; 466 467push @EXPORT_OK, qw($L_PARTIAL); 468push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_PARTIAL); 469 470$_logtype_t_VALUES{"L_PARTIAL"} = $L_PARTIAL; 471 472push @EXPORT_OK, qw($L_FAIL); 473push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_FAIL); 474 475$_logtype_t_VALUES{"L_FAIL"} = $L_FAIL; 476 477push @EXPORT_OK, qw($L_STRANGE); 478push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_STRANGE); 479 480$_logtype_t_VALUES{"L_STRANGE"} = $L_STRANGE; 481 482push @EXPORT_OK, qw($L_CHUNK); 483push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_CHUNK); 484 485$_logtype_t_VALUES{"L_CHUNK"} = $L_CHUNK; 486 487push @EXPORT_OK, qw($L_CHUNKSUCCESS); 488push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_CHUNKSUCCESS); 489 490$_logtype_t_VALUES{"L_CHUNKSUCCESS"} = $L_CHUNKSUCCESS; 491 492push @EXPORT_OK, qw($L_STATS); 493push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_STATS); 494 495$_logtype_t_VALUES{"L_STATS"} = $L_STATS; 496 497push @EXPORT_OK, qw($L_MARKER); 498push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_MARKER); 499 500$_logtype_t_VALUES{"L_MARKER"} = $L_MARKER; 501 502push @EXPORT_OK, qw($L_CONT); 503push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_CONT); 504 505$_logtype_t_VALUES{"L_CONT"} = $L_CONT; 506 507#copy symbols in logtype_t to constants 508push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"logtype_t"}}; 509 510push @EXPORT_OK, qw(program_t_to_string); 511push @{$EXPORT_TAGS{"program_t"}}, qw(program_t_to_string); 512 513my %_program_t_VALUES; 514#Convert an enum value to a single string 515sub program_t_to_string { 516 my ($enumval) = @_; 517 518 for my $k (keys %_program_t_VALUES) { 519 my $v = $_program_t_VALUES{$k}; 520 521 #is this a matching flag? 522 if ($enumval == $v) { 523 return $k; 524 } 525 } 526 527#default, just return the number 528 return $enumval; 529} 530 531push @EXPORT_OK, qw($P_UNKNOWN); 532push @{$EXPORT_TAGS{"program_t"}}, qw($P_UNKNOWN); 533 534$_program_t_VALUES{"P_UNKNOWN"} = $P_UNKNOWN; 535 536push @EXPORT_OK, qw($P_PLANNER); 537push @{$EXPORT_TAGS{"program_t"}}, qw($P_PLANNER); 538 539$_program_t_VALUES{"P_PLANNER"} = $P_PLANNER; 540 541push @EXPORT_OK, qw($P_DRIVER); 542push @{$EXPORT_TAGS{"program_t"}}, qw($P_DRIVER); 543 544$_program_t_VALUES{"P_DRIVER"} = $P_DRIVER; 545 546push @EXPORT_OK, qw($P_REPORTER); 547push @{$EXPORT_TAGS{"program_t"}}, qw($P_REPORTER); 548 549$_program_t_VALUES{"P_REPORTER"} = $P_REPORTER; 550 551push @EXPORT_OK, qw($P_DUMPER); 552push @{$EXPORT_TAGS{"program_t"}}, qw($P_DUMPER); 553 554$_program_t_VALUES{"P_DUMPER"} = $P_DUMPER; 555 556push @EXPORT_OK, qw($P_CHUNKER); 557push @{$EXPORT_TAGS{"program_t"}}, qw($P_CHUNKER); 558 559$_program_t_VALUES{"P_CHUNKER"} = $P_CHUNKER; 560 561push @EXPORT_OK, qw($P_TAPER); 562push @{$EXPORT_TAGS{"program_t"}}, qw($P_TAPER); 563 564$_program_t_VALUES{"P_TAPER"} = $P_TAPER; 565 566push @EXPORT_OK, qw($P_AMFLUSH); 567push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMFLUSH); 568 569$_program_t_VALUES{"P_AMFLUSH"} = $P_AMFLUSH; 570 571push @EXPORT_OK, qw($P_AMDUMP); 572push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMDUMP); 573 574$_program_t_VALUES{"P_AMDUMP"} = $P_AMDUMP; 575 576push @EXPORT_OK, qw($P_AMIDXTAPED); 577push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMIDXTAPED); 578 579$_program_t_VALUES{"P_AMIDXTAPED"} = $P_AMIDXTAPED; 580 581push @EXPORT_OK, qw($P_AMFETCHDUMP); 582push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMFETCHDUMP); 583 584$_program_t_VALUES{"P_AMFETCHDUMP"} = $P_AMFETCHDUMP; 585 586push @EXPORT_OK, qw($P_AMCHECKDUMP); 587push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMCHECKDUMP); 588 589$_program_t_VALUES{"P_AMCHECKDUMP"} = $P_AMCHECKDUMP; 590 591push @EXPORT_OK, qw($P_AMVAULT); 592push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMVAULT); 593 594$_program_t_VALUES{"P_AMVAULT"} = $P_AMVAULT; 595 596#copy symbols in program_t to constants 597push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"program_t"}}; 598 599push @EXPORT_OK, qw(find_log search_logfile dumps_match log_rename); 600 601push @EXPORT_OK, qw($amanda_log_trace_log); 602 603push @EXPORT_OK, qw(find_all_logs find_latest_log 604 get_current_log_timestamp 605 make_stats); 606 607 608use Amanda::Config qw ( :init :getconf config_dir_relative ); 609use Amanda::Debug; 610 611sub find_all_logs 612{ 613 my $logdir = shift @_ || config_dir_relative(getconf($CNF_LOGDIR)); 614 615 opendir my $logdh, $logdir or die("can't read $logdir"); 616 my @logfiles = sort grep { m{^log\.\d+\.\d+$} } readdir $logdh; 617 618 return @logfiles; 619} 620 621sub find_latest_log 622{ 623 my $logdir = shift @_; 624 my @logs = find_all_logs($logdir || ()); 625 return $logs[-1]; 626} 627 628sub get_current_log_timestamp 629{ 630 my $logfile = config_dir_relative(getconf($CNF_LOGDIR)) . "/log"; 631 if (! -f $logfile) { 632 Amanda::Debug::warning("no current logfile '$logfile'"); 633 return undef; 634 } 635 636 my $logh = open_logfile("$logfile"); 637 if (!$logh) { 638 Amanda::Debug::warning("could not open logfile '$logfile'"); 639 return undef; 640 } 641 while (my ($type, $prog, $str) = get_logline($logh)) { 642 if ($type == $L_START) { 643 my ($ts) = ($str =~ /date (\d+)/); 644 return $ts if $ts; 645 } 646 } 647 648 # no timestamp, apparently 649 Amanda::Debug::warning("no current timestamp found in logfile"); 650 return undef; 651} 652 653sub make_stats { 654 my ($size, $duration, $orig_kb) = @_; 655 656 $duration = 0.1 if $duration <= 0; # prevent division by zero 657 my $kb = $size/1024; 658 my $kps = "$kb.0"/$duration; # Perlish cast from BigInt to float 659 660 if (defined $orig_kb) { 661 return sprintf("[sec %f bytes %s kps %f orig-kb %s]", $duration, $size, $kps, $orig_kb); 662 } else { 663 return sprintf("[sec %f bytes %s kps %f]", $duration, $size, $kps); 664 } 665} 666 6671; 668