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;
65 ############# Class : Amanda::Logfile::find_result_t ##############
67 package Amanda::Logfile::find_result_t;
68 use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
69 @ISA = qw( Amanda::Logfile );
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);
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;
117 my $self = Amanda::Logfilec::new_find_result_t(@_);
118 bless $self, $pkg if defined($self);
123 my $ptr = tied(%$self);
129 my $ptr = tied(%$self);
134 # ------- VARIABLE STUBS --------
136 package Amanda::Logfile;
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;
180 Amanda::Logfile - manage Amanda trace logs
184 use Amanda::Logfile qw( :constants );
185 use Amanda::Config qw( :getconf config_dir_relative );
187 for my $logfile (Amanda::Logfile::find_log()) {
188 $logfile = config_dir_relative(getconf($CNF_LOGDIR)) . "/" . $logfile;
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";
197 Amanda::Logfile::close_logfile($hdl);
199 my @dumps = Amanda::Logfile::search_logfile("TapeLabel-001", "19780615", $logfile, 1);
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";
207 =head1 RAW LOGFILE ACCESS
209 This section corresponds to the C C<logfile> module.
211 Raw access to logfiles is accomplished by opening a logfile and
212 fetching log lines one by one via the C<get_logline> function.
214 A log line is represented by a list C<($type, $prog, $string)> where C<$type>
215 is one of the C<L_*> constants (available in export tag C<logtype_t>), C<$prog>
216 is one of the C<P_*> constants (available in export tag C<program_t>), and
217 C<$str> is the remainder of the line. Both sets of constants are also available
218 in the usual C<constants> export tag. Both families of constants can be
219 converted to symbolic names with C<logtype_t_to_string> and
220 C<program_t_to_string>, respectively.
224 Use these functions to read a logfile:
228 =item C<open_logfile($filename)>
230 Opens a logfile for reading, returning an opaque log file
231 handle. Returns C<undef> and sets C<$!> on failure.
233 =item C<close_logfile($handle)>
235 Closes a log file handle.
237 =item C<get_logline($handle)>
239 Returns a list as described above representing the next log line in
240 C<$handle>, or nothing at the end of the logfile.
244 =head3 Writing a "current" Logfile
246 To write a logfile, call C<log_add($logtype, $string)>. On the first call,
247 this function opens and locks C<$logdir/log>; subsequent calls just append to
248 this file. As such, this function is only appropriate for situations where
249 C<log_rename> will be invoked later to rename C<$logdir/log> to
250 C<$logdir/log.$timestamp.$n>.
252 If you need to write a log entry for another program, for example to simulate
253 taper entries, call C<log_add_full($logtype, $pname, $string)>.
255 All of the functions in this section can be imported by name if
260 Many trace log entries have a statistics entry in what used to be the error
261 message slot, of the form C<[sec .. kb .. kps ..]>. The function C<make_stats>
262 will create such an entry for you:
264 make_stats($size, $duration, $orig_kb);
266 Note that C<$orig_kb> can be undefined, in which case it will not appear in
267 the statistics output.
269 =head2 Amanda::Find::find_result_t objects
271 These objects contain information about dumps, as read from logfiles.
272 Instance variables are:
274 To rename the current logfile to a datestamped logfile, call C<log_rename($ts)>
275 where C<$ts> is the write timestamp for this dump. The
276 C<get_current_log_timestamp()> function will calculate this timestamp,
277 returning C<undef> on error.
305 Note that the format for these variables are based on that found in
306 the logfiles. In particular, C<timestamp> is the timestamp for the run
307 in which the client dump took place, and not for the timestamp of the
310 =head1 HIGHER-LEVEL FUNCTIONS
312 Functions in this section extract information from logfiles.
318 Return a list of logfiles for active tapes. The tapelist must be loaded
319 before this function is called (see L<Amanda::Tapelist>). This function uses
320 the C API which indexes logfiles with tapes. If there is no corresponding
321 tape, the logfile will not be found.
323 =item C<find_all_logs([dir])>
325 Return a list of all logs the configuration. An optional directory argument
326 can be specified, if not present, C<find_all_logs> checks C<LOGDIR>.
328 =item C<find_latest_log([dir])>
330 Returns the most recent logfile in the list of logfiles returned by
331 C<find_all_logs>. The optional directory argument is passed to
334 =item C<search_logfile($label, $datestamp, $logfile, $add_missing_disks)>
336 Return all results in C<$logfile> matching C<$label> and
337 C<$datestamp>. If C<$add_missing_disks> is true, then any disks in
338 the logfile not present in the disklist are added to the disklist;
339 otherwise, such dumps are skipped.
341 =item C<search_holding_disk()>
343 Return results for all holding-disk files. Results are similar to those from
346 =item C<dumps_match([@results], $hostname, $diskname, $datestamp, $level, $ok)>
348 Return a filtered version of C<@results> containing only results that
349 match the given expressions. If C<$ok> is true, don't match partial
350 results. Note that C<$level> is given as a string, since it is a
353 =item C<dumps_match_dumpspecs([@results], [@dumpspecs], $ok)>
355 Return a filtered version of C<@results>, containing only results that match
356 one or more of the dumpspecs. C<$ok> is as for C<dumps_match>. Supplying no
357 dumpspecs will result in an empty return value. If multiple dumpspecs match
358 the same result, that result will be returned multiple times.
362 All of these functions can be imported by name.
364 =head1 DEBUG LOGGING HANDLER
366 This package provides C<$amanda_log_trace_log>, which sends C<die>
367 messages (and any C<g_error> or C<g_critical> calls from C) to the
368 trace log. Use it like this:
370 use Amanda::Logfile qw( $amanda_log_trace_log );
372 Amanda::Debug::add_amanda_log_handler($amanda_log_trace_log);
378 push @EXPORT_OK, qw(open_logfile get_logline close_logfile
379 log_add log_add_full);
381 push @EXPORT_OK, qw(logtype_t_to_string);
382 push @{$EXPORT_TAGS{"logtype_t"}}, qw(logtype_t_to_string);
384 my %_logtype_t_VALUES;
385 #Convert an enum value to a single string
386 sub logtype_t_to_string {
389 for my $k (keys %_logtype_t_VALUES) {
390 my $v = $_logtype_t_VALUES{$k};
392 #is this a matching flag?
393 if ($enumval == $v) {
398 #default, just return the number
402 push @EXPORT_OK, qw($L_BOGUS);
403 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_BOGUS);
405 $_logtype_t_VALUES{"L_BOGUS"} = $L_BOGUS;
407 push @EXPORT_OK, qw($L_FATAL);
408 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_FATAL);
410 $_logtype_t_VALUES{"L_FATAL"} = $L_FATAL;
412 push @EXPORT_OK, qw($L_ERROR);
413 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_ERROR);
415 $_logtype_t_VALUES{"L_ERROR"} = $L_ERROR;
417 push @EXPORT_OK, qw($L_WARNING);
418 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_WARNING);
420 $_logtype_t_VALUES{"L_WARNING"} = $L_WARNING;
422 push @EXPORT_OK, qw($L_INFO);
423 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_INFO);
425 $_logtype_t_VALUES{"L_INFO"} = $L_INFO;
427 push @EXPORT_OK, qw($L_SUMMARY);
428 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_SUMMARY);
430 $_logtype_t_VALUES{"L_SUMMARY"} = $L_SUMMARY;
432 push @EXPORT_OK, qw($L_START);
433 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_START);
435 $_logtype_t_VALUES{"L_START"} = $L_START;
437 push @EXPORT_OK, qw($L_FINISH);
438 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_FINISH);
440 $_logtype_t_VALUES{"L_FINISH"} = $L_FINISH;
442 push @EXPORT_OK, qw($L_DISK);
443 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_DISK);
445 $_logtype_t_VALUES{"L_DISK"} = $L_DISK;
447 push @EXPORT_OK, qw($L_DONE);
448 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_DONE);
450 $_logtype_t_VALUES{"L_DONE"} = $L_DONE;
452 push @EXPORT_OK, qw($L_PART);
453 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_PART);
455 $_logtype_t_VALUES{"L_PART"} = $L_PART;
457 push @EXPORT_OK, qw($L_PARTPARTIAL);
458 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_PARTPARTIAL);
460 $_logtype_t_VALUES{"L_PARTPARTIAL"} = $L_PARTPARTIAL;
462 push @EXPORT_OK, qw($L_SUCCESS);
463 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_SUCCESS);
465 $_logtype_t_VALUES{"L_SUCCESS"} = $L_SUCCESS;
467 push @EXPORT_OK, qw($L_PARTIAL);
468 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_PARTIAL);
470 $_logtype_t_VALUES{"L_PARTIAL"} = $L_PARTIAL;
472 push @EXPORT_OK, qw($L_FAIL);
473 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_FAIL);
475 $_logtype_t_VALUES{"L_FAIL"} = $L_FAIL;
477 push @EXPORT_OK, qw($L_STRANGE);
478 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_STRANGE);
480 $_logtype_t_VALUES{"L_STRANGE"} = $L_STRANGE;
482 push @EXPORT_OK, qw($L_CHUNK);
483 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_CHUNK);
485 $_logtype_t_VALUES{"L_CHUNK"} = $L_CHUNK;
487 push @EXPORT_OK, qw($L_CHUNKSUCCESS);
488 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_CHUNKSUCCESS);
490 $_logtype_t_VALUES{"L_CHUNKSUCCESS"} = $L_CHUNKSUCCESS;
492 push @EXPORT_OK, qw($L_STATS);
493 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_STATS);
495 $_logtype_t_VALUES{"L_STATS"} = $L_STATS;
497 push @EXPORT_OK, qw($L_MARKER);
498 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_MARKER);
500 $_logtype_t_VALUES{"L_MARKER"} = $L_MARKER;
502 push @EXPORT_OK, qw($L_CONT);
503 push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_CONT);
505 $_logtype_t_VALUES{"L_CONT"} = $L_CONT;
507 #copy symbols in logtype_t to constants
508 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"logtype_t"}};
510 push @EXPORT_OK, qw(program_t_to_string);
511 push @{$EXPORT_TAGS{"program_t"}}, qw(program_t_to_string);
513 my %_program_t_VALUES;
514 #Convert an enum value to a single string
515 sub program_t_to_string {
518 for my $k (keys %_program_t_VALUES) {
519 my $v = $_program_t_VALUES{$k};
521 #is this a matching flag?
522 if ($enumval == $v) {
527 #default, just return the number
531 push @EXPORT_OK, qw($P_UNKNOWN);
532 push @{$EXPORT_TAGS{"program_t"}}, qw($P_UNKNOWN);
534 $_program_t_VALUES{"P_UNKNOWN"} = $P_UNKNOWN;
536 push @EXPORT_OK, qw($P_PLANNER);
537 push @{$EXPORT_TAGS{"program_t"}}, qw($P_PLANNER);
539 $_program_t_VALUES{"P_PLANNER"} = $P_PLANNER;
541 push @EXPORT_OK, qw($P_DRIVER);
542 push @{$EXPORT_TAGS{"program_t"}}, qw($P_DRIVER);
544 $_program_t_VALUES{"P_DRIVER"} = $P_DRIVER;
546 push @EXPORT_OK, qw($P_REPORTER);
547 push @{$EXPORT_TAGS{"program_t"}}, qw($P_REPORTER);
549 $_program_t_VALUES{"P_REPORTER"} = $P_REPORTER;
551 push @EXPORT_OK, qw($P_DUMPER);
552 push @{$EXPORT_TAGS{"program_t"}}, qw($P_DUMPER);
554 $_program_t_VALUES{"P_DUMPER"} = $P_DUMPER;
556 push @EXPORT_OK, qw($P_CHUNKER);
557 push @{$EXPORT_TAGS{"program_t"}}, qw($P_CHUNKER);
559 $_program_t_VALUES{"P_CHUNKER"} = $P_CHUNKER;
561 push @EXPORT_OK, qw($P_TAPER);
562 push @{$EXPORT_TAGS{"program_t"}}, qw($P_TAPER);
564 $_program_t_VALUES{"P_TAPER"} = $P_TAPER;
566 push @EXPORT_OK, qw($P_AMFLUSH);
567 push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMFLUSH);
569 $_program_t_VALUES{"P_AMFLUSH"} = $P_AMFLUSH;
571 push @EXPORT_OK, qw($P_AMDUMP);
572 push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMDUMP);
574 $_program_t_VALUES{"P_AMDUMP"} = $P_AMDUMP;
576 push @EXPORT_OK, qw($P_AMIDXTAPED);
577 push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMIDXTAPED);
579 $_program_t_VALUES{"P_AMIDXTAPED"} = $P_AMIDXTAPED;
581 push @EXPORT_OK, qw($P_AMFETCHDUMP);
582 push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMFETCHDUMP);
584 $_program_t_VALUES{"P_AMFETCHDUMP"} = $P_AMFETCHDUMP;
586 push @EXPORT_OK, qw($P_AMCHECKDUMP);
587 push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMCHECKDUMP);
589 $_program_t_VALUES{"P_AMCHECKDUMP"} = $P_AMCHECKDUMP;
591 push @EXPORT_OK, qw($P_AMVAULT);
592 push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMVAULT);
594 $_program_t_VALUES{"P_AMVAULT"} = $P_AMVAULT;
596 #copy symbols in program_t to constants
597 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"program_t"}};
599 push @EXPORT_OK, qw(find_log search_logfile dumps_match log_rename);
601 push @EXPORT_OK, qw($amanda_log_trace_log);
603 push @EXPORT_OK, qw(find_all_logs find_latest_log
604 get_current_log_timestamp
610 my $logdir = shift @_ || config_dir_relative(getconf($CNF_LOGDIR));
612 opendir my $logdh, $logdir or die("can't read $logdir");
613 my @logfiles = sort grep { m{^log\.\d+\.\d+$} } readdir $logdh;
620 my $logdir = shift @_;
621 my @logs = find_all_logs($logdir || ());
628 sub get_current_log_timestamp
630 my $logfile = Amanda::Config::config_dir_relative(
631 Amanda::Config::getconf($Amanda::Config::CNF_LOGDIR)) . "/log";
633 Amanda::Debug::warning("no current logfile '$logfile'");
637 my $logh = open_logfile("$logfile");
639 Amanda::Debug::warning("could not open logfile '$logfile'");
642 while (my ($type, $prog, $str) = get_logline($logh)) {
643 if ($type == $L_START) {
644 my ($ts) = ($str =~ /date (\d+)/);
649 # no timestamp, apparently
650 Amanda::Debug::warning("no current timestamp found in logfile");
655 my ($size, $duration, $orig_kb) = @_;
657 $duration = 0.1 if $duration <= 0; # prevent division by zero
659 my $kps = "$kb.0"/$duration; # Perlish cast from BigInt to float
661 if (defined $orig_kb) {
662 return sprintf("[sec %f bytes %s kps %f orig-kb %s]", $duration, $size, $kps, $orig_kb);
664 return sprintf("[sec %f bytes %s kps %f]", $duration, $size, $kps);