File: //lib64/perl5/vendor_perl/Amanda/Logfile.pm
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 2.0.4
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.
package Amanda::Logfile;
use base qw(Exporter);
use base qw(DynaLoader);
require Amanda::Cmdline;
package Amanda::Logfilec;
bootstrap Amanda::Logfile;
package Amanda::Logfile;
@EXPORT = qw();
# ---------- BASE METHODS -------------
package Amanda::Logfile;
sub TIEHASH {
my ($classname,$obj) = @_;
return bless $obj, $classname;
}
sub CLEAR { }
sub FIRSTKEY { }
sub NEXTKEY { }
sub FETCH {
my ($self,$field) = @_;
my $member_func = "swig_${field}_get";
$self->$member_func();
}
sub STORE {
my ($self,$field,$newval) = @_;
my $member_func = "swig_${field}_set";
$self->$member_func($newval);
}
sub this {
my $ptr = shift;
return tied(%$ptr);
}
# ------- FUNCTION WRAPPERS --------
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;
############# Class : Amanda::Logfile::find_result_t ##############
package Amanda::Logfile::find_result_t;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( Amanda::Logfile );
%OWNER = ();
%ITERATORS = ();
sub DESTROY {
return unless $_[0]->isa('HASH');
my $self = tied(%{$_[0]});
return unless defined $self;
delete $ITERATORS{$self};
if (exists $OWNER{$self}) {
Amanda::Logfilec::delete_find_result_t($self);
delete $OWNER{$self};
}
}
*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;
*swig_diskname_set = *Amanda::Logfilec::find_result_t_diskname_set;
*swig_level_get = *Amanda::Logfilec::find_result_t_level_get;
*swig_level_set = *Amanda::Logfilec::find_result_t_level_set;
*swig_label_get = *Amanda::Logfilec::find_result_t_label_get;
*swig_label_set = *Amanda::Logfilec::find_result_t_label_set;
*swig_filenum_get = *Amanda::Logfilec::find_result_t_filenum_get;
*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_bytes_get = *Amanda::Logfilec::find_result_t_bytes_get;
*swig_bytes_set = *Amanda::Logfilec::find_result_t_bytes_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(@_);
bless $self, $pkg if defined($self);
}
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
# ------- VARIABLE STUBS --------
package Amanda::Logfile;
*L_BOGUS = *Amanda::Logfilec::L_BOGUS;
*L_FATAL = *Amanda::Logfilec::L_FATAL;
*L_ERROR = *Amanda::Logfilec::L_ERROR;
*L_WARNING = *Amanda::Logfilec::L_WARNING;
*L_INFO = *Amanda::Logfilec::L_INFO;
*L_SUMMARY = *Amanda::Logfilec::L_SUMMARY;
*L_START = *Amanda::Logfilec::L_START;
*L_FINISH = *Amanda::Logfilec::L_FINISH;
*L_DISK = *Amanda::Logfilec::L_DISK;
*L_DONE = *Amanda::Logfilec::L_DONE;
*L_PART = *Amanda::Logfilec::L_PART;
*L_PARTPARTIAL = *Amanda::Logfilec::L_PARTPARTIAL;
*L_SUCCESS = *Amanda::Logfilec::L_SUCCESS;
*L_PARTIAL = *Amanda::Logfilec::L_PARTIAL;
*L_FAIL = *Amanda::Logfilec::L_FAIL;
*L_STRANGE = *Amanda::Logfilec::L_STRANGE;
*L_CHUNK = *Amanda::Logfilec::L_CHUNK;
*L_CHUNKSUCCESS = *Amanda::Logfilec::L_CHUNKSUCCESS;
*L_STATS = *Amanda::Logfilec::L_STATS;
*L_MARKER = *Amanda::Logfilec::L_MARKER;
*L_CONT = *Amanda::Logfilec::L_CONT;
*P_UNKNOWN = *Amanda::Logfilec::P_UNKNOWN;
*P_PLANNER = *Amanda::Logfilec::P_PLANNER;
*P_DRIVER = *Amanda::Logfilec::P_DRIVER;
*P_REPORTER = *Amanda::Logfilec::P_REPORTER;
*P_DUMPER = *Amanda::Logfilec::P_DUMPER;
*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( :constants );
use Amanda::Config qw( :getconf config_dir_relative );
for my $logfile (Amanda::Logfile::find_log()) {
$logfile = config_dir_relative(getconf($CNF_LOGDIR)) . "/" . $logfile;
my $hdl = Amanda::Logfile::open_logfile($logfile);
while (my ($type, $prog, $str) = Amanda::Logfile::get_logline($hdl)) {
if ($type == $L_INFO) {
my $pname = Amanda::Logfile::program_t_to_string($prog);
print "Found info line from $pname: $str\n";
}
}
Amanda::Logfile::close_logfile($hdl);
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) {
print "$dump->{'label'}:$dump->{'filenum'} = $dump->{'hostname'}:$dump->{'disk'}\n";
}
}
=head1 RAW LOGFILE ACCESS
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 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. Returns C<undef> and sets C<$!> on failure.
=item C<close_logfile($handle)>
Closes a log file handle.
=item C<get_logline($handle)>
Returns a list as described above representing the next log line in
C<$handle>, or nothing at the end of the logfile.
=back
=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
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<hostname>
=item C<diskname>
=item C<level>
=item C<label>
=item C<filenum>
=item C<status>
=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.
=over
=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>). 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.
=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.
=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 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
log_add log_add_full);
push @EXPORT_OK, qw(logtype_t_to_string);
push @{$EXPORT_TAGS{"logtype_t"}}, qw(logtype_t_to_string);
my %_logtype_t_VALUES;
#Convert an enum value to a single string
sub logtype_t_to_string {
my ($enumval) = @_;
for my $k (keys %_logtype_t_VALUES) {
my $v = $_logtype_t_VALUES{$k};
#is this a matching flag?
if ($enumval == $v) {
return $k;
}
}
#default, just return the number
return $enumval;
}
push @EXPORT_OK, qw($L_BOGUS);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_BOGUS);
$_logtype_t_VALUES{"L_BOGUS"} = $L_BOGUS;
push @EXPORT_OK, qw($L_FATAL);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_FATAL);
$_logtype_t_VALUES{"L_FATAL"} = $L_FATAL;
push @EXPORT_OK, qw($L_ERROR);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_ERROR);
$_logtype_t_VALUES{"L_ERROR"} = $L_ERROR;
push @EXPORT_OK, qw($L_WARNING);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_WARNING);
$_logtype_t_VALUES{"L_WARNING"} = $L_WARNING;
push @EXPORT_OK, qw($L_INFO);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_INFO);
$_logtype_t_VALUES{"L_INFO"} = $L_INFO;
push @EXPORT_OK, qw($L_SUMMARY);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_SUMMARY);
$_logtype_t_VALUES{"L_SUMMARY"} = $L_SUMMARY;
push @EXPORT_OK, qw($L_START);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_START);
$_logtype_t_VALUES{"L_START"} = $L_START;
push @EXPORT_OK, qw($L_FINISH);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_FINISH);
$_logtype_t_VALUES{"L_FINISH"} = $L_FINISH;
push @EXPORT_OK, qw($L_DISK);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_DISK);
$_logtype_t_VALUES{"L_DISK"} = $L_DISK;
push @EXPORT_OK, qw($L_DONE);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_DONE);
$_logtype_t_VALUES{"L_DONE"} = $L_DONE;
push @EXPORT_OK, qw($L_PART);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_PART);
$_logtype_t_VALUES{"L_PART"} = $L_PART;
push @EXPORT_OK, qw($L_PARTPARTIAL);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_PARTPARTIAL);
$_logtype_t_VALUES{"L_PARTPARTIAL"} = $L_PARTPARTIAL;
push @EXPORT_OK, qw($L_SUCCESS);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_SUCCESS);
$_logtype_t_VALUES{"L_SUCCESS"} = $L_SUCCESS;
push @EXPORT_OK, qw($L_PARTIAL);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_PARTIAL);
$_logtype_t_VALUES{"L_PARTIAL"} = $L_PARTIAL;
push @EXPORT_OK, qw($L_FAIL);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_FAIL);
$_logtype_t_VALUES{"L_FAIL"} = $L_FAIL;
push @EXPORT_OK, qw($L_STRANGE);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_STRANGE);
$_logtype_t_VALUES{"L_STRANGE"} = $L_STRANGE;
push @EXPORT_OK, qw($L_CHUNK);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_CHUNK);
$_logtype_t_VALUES{"L_CHUNK"} = $L_CHUNK;
push @EXPORT_OK, qw($L_CHUNKSUCCESS);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_CHUNKSUCCESS);
$_logtype_t_VALUES{"L_CHUNKSUCCESS"} = $L_CHUNKSUCCESS;
push @EXPORT_OK, qw($L_STATS);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_STATS);
$_logtype_t_VALUES{"L_STATS"} = $L_STATS;
push @EXPORT_OK, qw($L_MARKER);
push @{$EXPORT_TAGS{"logtype_t"}}, qw($L_MARKER);
$_logtype_t_VALUES{"L_MARKER"} = $L_MARKER;
push @EXPORT_OK, qw($L_CONT);
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);
my %_program_t_VALUES;
#Convert an enum value to a single string
sub program_t_to_string {
my ($enumval) = @_;
for my $k (keys %_program_t_VALUES) {
my $v = $_program_t_VALUES{$k};
#is this a matching flag?
if ($enumval == $v) {
return $k;
}
}
#default, just return the number
return $enumval;
}
push @EXPORT_OK, qw($P_UNKNOWN);
push @{$EXPORT_TAGS{"program_t"}}, qw($P_UNKNOWN);
$_program_t_VALUES{"P_UNKNOWN"} = $P_UNKNOWN;
push @EXPORT_OK, qw($P_PLANNER);
push @{$EXPORT_TAGS{"program_t"}}, qw($P_PLANNER);
$_program_t_VALUES{"P_PLANNER"} = $P_PLANNER;
push @EXPORT_OK, qw($P_DRIVER);
push @{$EXPORT_TAGS{"program_t"}}, qw($P_DRIVER);
$_program_t_VALUES{"P_DRIVER"} = $P_DRIVER;
push @EXPORT_OK, qw($P_REPORTER);
push @{$EXPORT_TAGS{"program_t"}}, qw($P_REPORTER);
$_program_t_VALUES{"P_REPORTER"} = $P_REPORTER;
push @EXPORT_OK, qw($P_DUMPER);
push @{$EXPORT_TAGS{"program_t"}}, qw($P_DUMPER);
$_program_t_VALUES{"P_DUMPER"} = $P_DUMPER;
push @EXPORT_OK, qw($P_CHUNKER);
push @{$EXPORT_TAGS{"program_t"}}, qw($P_CHUNKER);
$_program_t_VALUES{"P_CHUNKER"} = $P_CHUNKER;
push @EXPORT_OK, qw($P_TAPER);
push @{$EXPORT_TAGS{"program_t"}}, qw($P_TAPER);
$_program_t_VALUES{"P_TAPER"} = $P_TAPER;
push @EXPORT_OK, qw($P_AMFLUSH);
push @{$EXPORT_TAGS{"program_t"}}, qw($P_AMFLUSH);
$_program_t_VALUES{"P_AMFLUSH"} = $P_AMFLUSH;
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);
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 bytes %s kps %f orig-kb %s]", $duration, $size, $kps, $orig_kb);
} else {
return sprintf("[sec %f bytes %s kps %f]", $duration, $size, $kps);
}
}
1;