1 # This file was automatically generated by SWIG (http://www.swig.org).
4 # Do not make changes to this file unless you know what you are doing--modify
5 # the SWIG interface file instead.
7 package Amanda::Logfile;
9 use base qw(DynaLoader);
10 require Amanda::Cmdline;
11 package Amanda::Logfilec;
12 bootstrap Amanda::Logfile;
13 package Amanda::Logfile;
16 # ---------- BASE METHODS -------------
18 package Amanda::Logfile;
21 my ($classname,$obj) = @_;
22 return bless $obj, $classname;
32 my ($self,$field) = @_;
33 my $member_func = "swig_${field}_get";
34 $self->$member_func();
38 my ($self,$field,$newval) = @_;
39 my $member_func = "swig_${field}_set";
40 $self->$member_func($newval);
49 # ------- FUNCTION WRAPPERS --------
51 package Amanda::Logfile;
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 *match_host = *Amanda::Logfilec::match_host;
65 *match_disk = *Amanda::Logfilec::match_disk;
66 *match_datestamp = *Amanda::Logfilec::match_datestamp;
67 *match_level = *Amanda::Logfilec::match_level;
69 ############# Class : Amanda::Logfile::find_result_t ##############
71 package Amanda::Logfile::find_result_t;
72 use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
73 @ISA = qw( Amanda::Logfile );
77 return unless $_[0]->isa('HASH');
78 my $self = tied(%{$_[0]});
79 return unless defined $self;
80 delete $ITERATORS{$self};
81 if (exists $OWNER{$self}) {
82 Amanda::Logfilec::delete_find_result_t($self);
87 *swig_timestamp_get = *Amanda::Logfilec::find_result_t_timestamp_get;
88 *swig_timestamp_set = *Amanda::Logfilec::find_result_t_timestamp_set;
89 *swig_write_timestamp_get = *Amanda::Logfilec::find_result_t_write_timestamp_get;
90 *swig_write_timestamp_set = *Amanda::Logfilec::find_result_t_write_timestamp_set;
91 *swig_hostname_get = *Amanda::Logfilec::find_result_t_hostname_get;
92 *swig_hostname_set = *Amanda::Logfilec::find_result_t_hostname_set;
93 *swig_diskname_get = *Amanda::Logfilec::find_result_t_diskname_get;
94 *swig_diskname_set = *Amanda::Logfilec::find_result_t_diskname_set;
95 *swig_level_get = *Amanda::Logfilec::find_result_t_level_get;
96 *swig_level_set = *Amanda::Logfilec::find_result_t_level_set;
97 *swig_label_get = *Amanda::Logfilec::find_result_t_label_get;
98 *swig_label_set = *Amanda::Logfilec::find_result_t_label_set;
99 *swig_filenum_get = *Amanda::Logfilec::find_result_t_filenum_get;
100 *swig_filenum_set = *Amanda::Logfilec::find_result_t_filenum_set;
101 *swig_status_get = *Amanda::Logfilec::find_result_t_status_get;
102 *swig_status_set = *Amanda::Logfilec::find_result_t_status_set;
103 *swig_dump_status_get = *Amanda::Logfilec::find_result_t_dump_status_get;
104 *swig_dump_status_set = *Amanda::Logfilec::find_result_t_dump_status_set;
105 *swig_message_get = *Amanda::Logfilec::find_result_t_message_get;
106 *swig_message_set = *Amanda::Logfilec::find_result_t_message_set;
107 *swig_partnum_get = *Amanda::Logfilec::find_result_t_partnum_get;
108 *swig_partnum_set = *Amanda::Logfilec::find_result_t_partnum_set;
109 *swig_totalparts_get = *Amanda::Logfilec::find_result_t_totalparts_get;
110 *swig_totalparts_set = *Amanda::Logfilec::find_result_t_totalparts_set;
111 *swig_sec_get = *Amanda::Logfilec::find_result_t_sec_get;
112 *swig_sec_set = *Amanda::Logfilec::find_result_t_sec_set;
113 *swig_kb_get = *Amanda::Logfilec::find_result_t_kb_get;
114 *swig_kb_set = *Amanda::Logfilec::find_result_t_kb_set;
115 *swig_orig_kb_get = *Amanda::Logfilec::find_result_t_orig_kb_get;
116 *swig_orig_kb_set = *Amanda::Logfilec::find_result_t_orig_kb_set;
119 my $self = Amanda::Logfilec::new_find_result_t(@_);
120 bless $self, $pkg if defined($self);
125 my $ptr = tied(%$self);
131 my $ptr = tied(%$self);
136 # ------- VARIABLE STUBS --------
138 package Amanda::Logfile;
140 *L_BOGUS = *Amanda::Logfilec::L_BOGUS;
141 *L_FATAL = *Amanda::Logfilec::L_FATAL;
142 *L_ERROR = *Amanda::Logfilec::L_ERROR;
143 *L_WARNING = *Amanda::Logfilec::L_WARNING;
144 *L_INFO = *Amanda::Logfilec::L_INFO;
145 *L_SUMMARY = *Amanda::Logfilec::L_SUMMARY;
146 *L_START = *Amanda::Logfilec::L_START;
147 *L_FINISH = *Amanda::Logfilec::L_FINISH;
148 *L_DISK = *Amanda::Logfilec::L_DISK;
149 *L_DONE = *Amanda::Logfilec::L_DONE;
150 *L_PART = *Amanda::Logfilec::L_PART;
151 *L_PARTPARTIAL = *Amanda::Logfilec::L_PARTPARTIAL;
152 *L_SUCCESS = *Amanda::Logfilec::L_SUCCESS;
153 *L_PARTIAL = *Amanda::Logfilec::L_PARTIAL;
154 *L_FAIL = *Amanda::Logfilec::L_FAIL;
155 *L_STRANGE = *Amanda::Logfilec::L_STRANGE;
156 *L_CHUNK = *Amanda::Logfilec::L_CHUNK;
157 *L_CHUNKSUCCESS = *Amanda::Logfilec::L_CHUNKSUCCESS;
158 *L_STATS = *Amanda::Logfilec::L_STATS;
159 *L_MARKER = *Amanda::Logfilec::L_MARKER;
160 *L_CONT = *Amanda::Logfilec::L_CONT;
161 *P_UNKNOWN = *Amanda::Logfilec::P_UNKNOWN;
162 *P_PLANNER = *Amanda::Logfilec::P_PLANNER;
163 *P_DRIVER = *Amanda::Logfilec::P_DRIVER;
164 *P_REPORTER = *Amanda::Logfilec::P_REPORTER;
165 *P_DUMPER = *Amanda::Logfilec::P_DUMPER;
166 *P_CHUNKER = *Amanda::Logfilec::P_CHUNKER;
167 *P_TAPER = *Amanda::Logfilec::P_TAPER;
168 *P_AMFLUSH = *Amanda::Logfilec::P_AMFLUSH;
169 *P_AMDUMP = *Amanda::Logfilec::P_AMDUMP;
170 *P_AMIDXTAPED = *Amanda::Logfilec::P_AMIDXTAPED;
171 *P_AMFETCHDUMP = *Amanda::Logfilec::P_AMFETCHDUMP;
172 *P_AMCHECKDUMP = *Amanda::Logfilec::P_AMCHECKDUMP;
173 *P_AMVAULT = *Amanda::Logfilec::P_AMVAULT;
174 *amanda_log_trace_log = *Amanda::Logfilec::amanda_log_trace_log;
182 Amanda::Logfile - manage Amanda trace logs
186 use Amanda::Logfile qw( :constants );
187 use Amanda::Config qw( :getconf config_dir_relative );
189 for my $logfile (Amanda::Logfile::find_log()) {
190 $logfile = config_dir_relative(getconf($CNF_LOGDIR)) . "/" . $logfile;
192 my $hdl = Amanda::Logfile::open_logfile($logfile);
193 while (my ($type, $prog, $str) = Amanda::Logfile::get_logline($hdl)) {
194 if ($type == $L_INFO) {
195 my $pname = Amanda::Logfile::program_t_to_string($prog);
196 print "Found info line from $pname: $str\n";
199 Amanda::Logfile::close_logfile($hdl);
201 my @dumps = Amanda::Logfile::search_logfile("TapeLabel-001", "19780615", $logfile, 1);
203 my @matching = Amanda::Logfile::dumps_match([@dumps], "myhost", "/usr", undef, undef, 0);
204 for my $dump (@matching) {
205 print "$dump->{'label'}:$dump->{'filenum'} = $dump->{'hostname'}:$dump->{'disk'}\n";
209 =head1 RAW LOGFILE ACCESS
211 This section corresponds to the C C<logfile> module.
213 Raw access to logfiles is accomplished by opening a logfile and
214 fetching log lines one by one via the C<get_logline> function.
216 A log line is represented by a list C<($type, $prog, $string)> where C<$type>
217 is one of the C<L_*> constants (available in export tag C<logtype_t>), C<$prog>
218 is one of the C<P_*> constants (available in export tag C<program_t>), and
219 C<$str> is the remainder of the line. Both sets of constants are also available
220 in the usual C<constants> export tag. Both families of constants can be
221 converted to symbolic names with C<logtype_t_to_string> and
222 C<program_t_to_string>, respectively.
226 Use these functions to read a logfile:
230 =item C<open_logfile($filename)>
232 Opens a logfile for reading, returning an opaque log file
233 handle. Returns C<undef> and sets C<$!> on failure.
235 =item C<close_logfile($handle)>
237 Closes a log file handle.
239 =item C<get_logline($handle)>
241 Returns a list as described above representing the next log line in
242 C<$handle>, or nothing at the end of the logfile.
246 =head3 Writing a "current" Logfile
248 To write a logfile, call C<log_add($logtype, $string)>. On the first call,
249 this function opens and locks C<$logdir/log>; subsequent calls just append to
250 this file. As such, this function is only appropriate for situations where
251 C<log_rename> will be invoked later to rename C<$logdir/log> to
252 C<$logdir/log.$timestamp.$n>.
254 If you need to write a log entry for another program, for example to simulate
255 taper entries, call C<log_add_full($logtype, $pname, $string)>.
257 All of the functions in this section can be imported by name if
262 Many trace log entries have a statistics entry in what used to be the error
263 message slot, of the form C<[sec .. kb .. kps ..]>. The function C<make_stats>
264 will create such an entry for you:
266 make_stats($size, $duration, $orig_kb);
268 Note that C<$orig_kb> can be undefined, in which case it will not appear in
269 the statistics output.
271 =head2 Amanda::Find::find_result_t objects
273 These objects contain information about dumps, as read from logfiles.
274 Instance variables are:
276 To rename the current logfile to a datestamped logfile, call C<log_rename($ts)>
277 where C<$ts> is the write timestamp for this dump. The
278 C<get_current_log_timestamp()> function will calculate this timestamp,
279 returning C<undef> on error.
307 Note that the format for these variables are based on that found in
308 the logfiles. In particular, C<timestamp> is the timestamp for the run
309 in which the client dump took place, and not for the timestamp of the
312 =head1 HIGHER-LEVEL FUNCTIONS
314 Functions in this section extract information from logfiles.
320 Return a list of logfiles for active tapes. The tapelist must be loaded
321 before this function is called (see L<Amanda::Tapelist>). This function uses
322 the C API which indexes logfiles with tapes. If there is no corresponding
323 tape, the logfile will not be found.
325 =item C<find_all_logs([dir])>
327 Return a list of all logs the configuration. An optional directory argument
328 can be specified, if not present, C<find_all_logs> checks C<LOGDIR>.
330 =item C<find_latest_log([dir])>
332 Returns the most recent logfile in the list of logfiles returned by
333 C<find_all_logs>. The optional directory argument is passed to
336 =item C<search_logfile($label, $datestamp, $logfile, $add_missing_disks)>
338 Return all results in C<$logfile> matching C<$label> and
339 C<$datestamp>. If C<$add_missing_disks> is true, then any disks in
340 the logfile not present in the disklist are added to the disklist;
341 otherwise, such dumps are skipped.
343 =item C<search_holding_disk()>
345 Return results for all holding-disk files. Results are similar to those from
348 =item C<dumps_match([@results], $hostname, $diskname, $datestamp, $level, $ok)>
350 Return a filtered version of C<@results> containing only results that
351 match the given expressions. If C<$ok> is true, don't match partial
352 results. Note that C<$level> is given as a string, since it is a
355 =item C<dumps_match_dumpspecs([@results], [@dumpspecs], $ok)>
357 Return a filtered version of C<@results>, containing only results that match
358 one or more of the dumpspecs. C<$ok> is as for C<dumps_match>. Supplying no
359 dumpspecs will result in an empty return value. If multiple dumpspecs match
360 the same result, that result will be returned multiple times.
364 All of these functions can be imported by name.
368 The following functions are available to match strings against patterns using
369 the rules described in amanda(8):
371 match_host($pat, $str);
372 match_disk($pat, $str);
373 match_datestamp($pat, $str);
374 match_level($pat, $str);
376 =head1 DEBUG LOGGING HANDLER
378 This package provides C<$amanda_log_trace_log>, which sends C<die>
379 messages (and any C<g_error> or C<g_critical> calls from C) to the
380 trace log. Use it like this:
382 use Amanda::Logfile qw( $amanda_log_trace_log );
384 Amanda::Debug::add_amanda_log_handler($amanda_log_trace_log);
390 push @EXPORT_OK, qw(open_logfile get_logline close_logfile
391 log_add log_add_full);
393 push @EXPORT_OK, qw(logtype_t_to_string);
394 push @{$EXPORT_TAGS{"logtype_t"}}, qw(logtype_t_to_string);
396 my %_logtype_t_VALUES;
397 #Convert an enum value to a single string
398 sub logtype_t_to_string {
401 for my $k (keys %_logtype_t_VALUES) {
402 my $v = $_logtype_t_VALUES{$k};
404 #is this a matching flag?
405 if ($enumval == $v) {
410 #default, just return the number
414 push @EXPORT_OK, qw($L_BOGUS);
415 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_BOGUS);
417 $_logtype_t_VALUES{"L_BOGUS"} = $L_BOGUS;
419 push @EXPORT_OK, qw($L_FATAL);
420 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_FATAL);
422 $_logtype_t_VALUES{"L_FATAL"} = $L_FATAL;
424 push @EXPORT_OK, qw($L_ERROR);
425 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_ERROR);
427 $_logtype_t_VALUES{"L_ERROR"} = $L_ERROR;
429 push @EXPORT_OK, qw($L_WARNING);
430 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_WARNING);
432 $_logtype_t_VALUES{"L_WARNING"} = $L_WARNING;
434 push @EXPORT_OK, qw($L_INFO);
435 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_INFO);
437 $_logtype_t_VALUES{"L_INFO"} = $L_INFO;
439 push @EXPORT_OK, qw($L_SUMMARY);
440 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_SUMMARY);
442 $_logtype_t_VALUES{"L_SUMMARY"} = $L_SUMMARY;
444 push @EXPORT_OK, qw($L_START);
445 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_START);
447 $_logtype_t_VALUES{"L_START"} = $L_START;
449 push @EXPORT_OK, qw($L_FINISH);
450 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_FINISH);
452 $_logtype_t_VALUES{"L_FINISH"} = $L_FINISH;
454 push @EXPORT_OK, qw($L_DISK);
455 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_DISK);
457 $_logtype_t_VALUES{"L_DISK"} = $L_DISK;
459 push @EXPORT_OK, qw($L_DONE);
460 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_DONE);
462 $_logtype_t_VALUES{"L_DONE"} = $L_DONE;
464 push @EXPORT_OK, qw($L_PART);
465 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_PART);
467 $_logtype_t_VALUES{"L_PART"} = $L_PART;
469 push @EXPORT_OK, qw($L_PARTPARTIAL);
470 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_PARTPARTIAL);
472 $_logtype_t_VALUES{"L_PARTPARTIAL"} = $L_PARTPARTIAL;
474 push @EXPORT_OK, qw($L_SUCCESS);
475 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_SUCCESS);
477 $_logtype_t_VALUES{"L_SUCCESS"} = $L_SUCCESS;
479 push @EXPORT_OK, qw($L_PARTIAL);
480 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_PARTIAL);
482 $_logtype_t_VALUES{"L_PARTIAL"} = $L_PARTIAL;
484 push @EXPORT_OK, qw($L_FAIL);
485 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_FAIL);
487 $_logtype_t_VALUES{"L_FAIL"} = $L_FAIL;
489 push @EXPORT_OK, qw($L_STRANGE);
490 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_STRANGE);
492 $_logtype_t_VALUES{"L_STRANGE"} = $L_STRANGE;
494 push @EXPORT_OK, qw($L_CHUNK);
495 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_CHUNK);
497 $_logtype_t_VALUES{"L_CHUNK"} = $L_CHUNK;
499 push @EXPORT_OK, qw($L_CHUNKSUCCESS);
500 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_CHUNKSUCCESS);
502 $_logtype_t_VALUES{"L_CHUNKSUCCESS"} = $L_CHUNKSUCCESS;
504 push @EXPORT_OK, qw($L_STATS);
505 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_STATS);
507 $_logtype_t_VALUES{"L_STATS"} = $L_STATS;
509 push @EXPORT_OK, qw($L_MARKER);
510 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_MARKER);
512 $_logtype_t_VALUES{"L_MARKER"} = $L_MARKER;
514 push @EXPORT_OK, qw($L_CONT);
515 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_CONT);
517 $_logtype_t_VALUES{"L_CONT"} = $L_CONT;
519 #copy symbols in logtype_t to constants
520 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"logtype_t"}};
522 push @EXPORT_OK, qw(program_t_to_string);
523 push @{$EXPORT_TAGS{"program_t"}}, qw(program_t_to_string);
525 my %_program_t_VALUES;
526 #Convert an enum value to a single string
527 sub program_t_to_string {
530 for my $k (keys %_program_t_VALUES) {
531 my $v = $_program_t_VALUES{$k};
533 #is this a matching flag?
534 if ($enumval == $v) {
539 #default, just return the number
543 push @EXPORT_OK, qw($P_UNKNOWN);
544 push @{$EXPORT_TAGS{"program_t"}}, qw($P_UNKNOWN);
546 $_program_t_VALUES{"P_UNKNOWN"} = $P_UNKNOWN;
548 push @EXPORT_OK, qw($P_PLANNER);
549 push @{$EXPORT_TAGS{"program_t"}}, qw($P_PLANNER);
551 $_program_t_VALUES{"P_PLANNER"} = $P_PLANNER;
553 push @EXPORT_OK, qw($P_DRIVER);
554 push @{$EXPORT_TAGS{"program_t"}}, qw($P_DRIVER);
556 $_program_t_VALUES{"P_DRIVER"} = $P_DRIVER;
558 push @EXPORT_OK, qw($P_REPORTER);
559 push @{$EXPORT_TAGS{"program_t"}}, qw($P_REPORTER);
561 $_program_t_VALUES{"P_REPORTER"} = $P_REPORTER;
563 push @EXPORT_OK, qw($P_DUMPER);
564 push @{$EXPORT_TAGS{"program_t"}}, qw($P_DUMPER);
566 $_program_t_VALUES{"P_DUMPER"} = $P_DUMPER;
568 push @EXPORT_OK, qw($P_CHUNKER);
569 push @{$EXPORT_TAGS{"program_t"}}, qw($P_CHUNKER);
571 $_program_t_VALUES{"P_CHUNKER"} = $P_CHUNKER;
573 push @EXPORT_OK, qw($P_TAPER);
574 push @{$EXPORT_TAGS{"program_t"}}, qw($P_TAPER);
576 $_program_t_VALUES{"P_TAPER"} = $P_TAPER;
578 push @EXPORT_OK, qw($P_AMFLUSH);
579 push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMFLUSH);
581 $_program_t_VALUES{"P_AMFLUSH"} = $P_AMFLUSH;
583 push @EXPORT_OK, qw($P_AMDUMP);
584 push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMDUMP);
586 $_program_t_VALUES{"P_AMDUMP"} = $P_AMDUMP;
588 push @EXPORT_OK, qw($P_AMIDXTAPED);
589 push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMIDXTAPED);
591 $_program_t_VALUES{"P_AMIDXTAPED"} = $P_AMIDXTAPED;
593 push @EXPORT_OK, qw($P_AMFETCHDUMP);
594 push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMFETCHDUMP);
596 $_program_t_VALUES{"P_AMFETCHDUMP"} = $P_AMFETCHDUMP;
598 push @EXPORT_OK, qw($P_AMCHECKDUMP);
599 push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMCHECKDUMP);
601 $_program_t_VALUES{"P_AMCHECKDUMP"} = $P_AMCHECKDUMP;
603 push @EXPORT_OK, qw($P_AMVAULT);
604 push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMVAULT);
606 $_program_t_VALUES{"P_AMVAULT"} = $P_AMVAULT;
608 #copy symbols in program_t to constants
609 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"program_t"}};
611 push @EXPORT_OK, qw(find_log search_logfile dumps_match log_rename
612 match_host match_disk match_datestamp match_level);
614 push @EXPORT_OK, qw($amanda_log_trace_log);
616 push @EXPORT_OK, qw(find_all_logs find_latest_log
617 get_current_log_timestamp
623 my $logdir = shift @_ || config_dir_relative(getconf($CNF_LOGDIR));
625 opendir my $logdh, $logdir or die("can't read $logdir");
626 my @logfiles = sort grep { m{^log\.\d+\.\d+$} } readdir $logdh;
633 my $logdir = shift @_;
634 my @logs = find_all_logs($logdir || ());
641 sub get_current_log_timestamp
643 my $logfile = Amanda::Config::config_dir_relative(
644 Amanda::Config::getconf($Amanda::Config::CNF_LOGDIR)) . "/log";
646 Amanda::Debug::warning("no current logfile '$logfile'");
650 my $logh = open_logfile("$logfile");
652 Amanda::Debug::warning("could not open logfile '$logfile'");
655 while (my ($type, $prog, $str) = get_logline($logh)) {
656 if ($type == $L_START) {
657 my ($ts) = ($str =~ /date (\d+)/);
662 # no timestamp, apparently
663 Amanda::Debug::warning("no current timestamp found in logfile");
668 my ($size, $duration, $orig_kb) = @_;
670 $duration = 0.1 if $duration <= 0; # prevent division by zero
672 my $kps = "$kb.0"/$duration; # Perlish cast from BigInt to float
674 if (defined $orig_kb) {
675 return sprintf("[sec %f kb %d kps %f orig-kb %d]", $duration, $kb, $kps, $orig_kb);
677 return sprintf("[sec %f kb %d kps %f]", $duration, $kb, $kps);