Bio::EnsEMBL::Utils Logger
SummaryPackage variablesSynopsisDescriptionGeneral documentationMethods
Toolbar
WebCvsRaw content
Summary
Bio::EnsEMBL::Utils::ConversionSupport - Utility module for Vega release and
schema conversion scripts
Package variables
Privates (from "my" definitions)
%level_defs = ( 'error' => 1, 'warn' => 2, 'warning' => 2, 'info' => 3, 'debug' => 4, 'verbose' => 4,)
@reverse_level_defs = (undef, qw(error warning info debug))
Included modules
Bio::EnsEMBL::Utils::Argument qw ( rearrange )
Bio::EnsEMBL::Utils::Exception qw ( throw )
Bio::EnsEMBL::Utils::ScriptUtils qw ( parse_bytes )
FindBin qw ( $Bin $Script )
POSIX qw ( strftime )
Synopsis
  my $serverroot = '/path/to/ensembl';
my $suport = new Bio::EnsEMBL::Utils::ConversionSupport($serverroot);
# parse common options $support->parse_common_options; # parse extra options for your script $support->parse_extra_options( 'string_opt=s', 'numeric_opt=n' ); # ask user if he wants to run script with these parameters $support->confirm_params; # see individual method documentation for more stuff
Description
This module is a collection of common methods and provides helper
functions for the Vega release and schema conversion scripts. Amongst
others, it reads options from a config file, parses commandline options
and does logging.
Methods
create_auto_logfile
No description
Code
dateDescriptionCode
date_and_memDescriptionCode
debugDescriptionCode
errorDescriptionCode
extract_log_identifier
No description
Code
finish_logDescriptionCode
info
No description
Code
init_logDescriptionCode
init_progress
No description
Code
is_component
No description
Code
log
No description
Code
log_auto_id
No description
Code
log_error
No description
Code
log_filehandleDescriptionCode
log_genericDescriptionCode
log_progress
No description
Code
log_progressbar
No description
Code
log_stamped
No description
Code
log_verbose
No description
Code
log_warning
No description
Code
logappend
No description
Code
logauto
No description
Code
logfile
No description
Code
loglevel
No description
Code
logpath
No description
Code
memDescriptionCode
newDescriptionCode
runtime
No description
Code
time_and_mem
No description
Code
warningDescriptionCode
warning_countDescriptionCode
Methods description
datecode    nextTop
  Example     : print "Date: " . $support->date . "\n";
Description : Prints a nicely formatted timestamp (YYYY-DD-MM hh:mm:ss)
Return type : String - the timestamp
Exceptions : none
Caller : general
date_and_memcodeprevnextTop
  Example     : print LOG "Time, memory usage: ".$support->date_and_mem."\n";
Description : Prints a timestamp and the memory usage of your script.
Return type : String - timestamp and memory usage
Exceptions : none
Caller : general
debugcodeprevnextTop
  Arg[1]      : String $txt - the warning text to log
Arg[2] : Int $indent - indentation level for log message
Example : my $log = $support->log_filehandle;
$support->log_verbose('Log this verbose message.\n', 1);
Description : Logs a message via $self->log if --verbose option was used
Return type : TRUE on success, FALSE if not verbose
Exceptions : none
Caller : general
errorcodeprevnextTop
  Arg[1]      : String $txt - the error text to log
Arg[2] : Int $indent - indentation level for log message
Example : my $log = $support->log_filehandle;
$support->log_error('Log foo.\n', 1);
Description : Logs a message via $self->log and exits the script.
Return type : none
Exceptions : none
Caller : general
finish_logcodeprevnextTop
  Example     : $support->finish_log;
Description : Writes footer information to a logfile. This includes the
number of logged warnings, timestamp and memory footprint.
Return type : TRUE on success
Exceptions : none
Caller : general
init_logcodeprevnextTop
  Example     : $support->init_log;
Description : Opens a filehandle to the logfile and prints some header
information to this file. This includes script name, date, user
running the script and parameters the script will be running
with.
Return type : Filehandle - the log filehandle
Exceptions : none
Caller : general
log_filehandlecodeprevnextTop
  Arg[1]      : (optional) String $mode - file access mode
Example : my $log = $support->log_filehandle;
# print to the filehandle
print $log 'Lets start logging...\n';
# log via the wrapper $self->log()
$support->log('Another log message.\n');
Description : Returns a filehandle for logging (STDERR by default, logfile if
set from config or commandline). You can use the filehandle
directly to print to, or use the smart wrapper $self->log().
Logging mode (truncate or append) can be set by passing the
mode as an argument to log_filehandle(), or with the
--logappend commandline option (default: truncate)
Return type : Filehandle - the filehandle to log to
Exceptions : thrown if logfile can't be opened
Caller : general
log_genericcodeprevnextTop
  Arg[1]      : String $txt - the text to log
Arg[2] : Int $indent - indentation level for log message
Example : my $log = $support->log_filehandle;
$support->log('Log foo.\n', 1);
Description : Logs a message to the filehandle initialised by calling
$self->log_filehandle(). You can supply an indentation level
to get nice hierarchical log messages.
Return type : true on success
Exceptions : thrown when no filehandle can be obtained
Caller : general
memcodeprevnextTop
  Example     : print "Memory usage: " . $support->mem . "\n";
Description : Prints the memory used by your script. Not sure about platform
dependence of this call ...
Return type : String - memory usage
Exceptions : none
Caller : general
newcodeprevnextTop
  Arg[1]      : String $serverroot - root directory of your ensembl sandbox
Example : my $support = new Bio::EnsEMBL::Utils::ConversionSupport(
'/path/to/ensembl');
Description : constructor
Return type : Bio::EnsEMBL::Utils::ConversionSupport object
Exceptions : thrown on invalid loglevel
Caller : general
warningcodeprevnextTop
  Arg[1]      : String $txt - the warning text to log
Arg[2] : Int $indent - indentation level for log message
Example : my $log = $support->log_filehandle;
$support->log_warning('Log foo.\n', 1);
Description : Logs a message via $self->log and increases the warning counter.
Return type : true on success
Exceptions : none
Caller : general
warning_countcodeprevnextTop
  Example     : print LOG "There were ".$support->warnings." warnings.\n";
Description : Returns the number of warnings encountered while running the
script (the warning counter is increased by $self->log_warning).
Return type : Int - number of warnings
Exceptions : none
Caller : general
Methods code
create_auto_logfiledescriptionprevnextTop
sub create_auto_logfile {
  my $self = shift;
  my $logautobase = shift;

  # do nothing if automatic logfile generation isn't set
return unless ($self->logauto); # an explicit logfile name overrides LOGAUTO
return if ($self->logfile); # argument check
unless ($logautobase) { throw('Need a base logfile name for auto-generating logfile.'); } # create a logfile name
$self->logfile("${logautobase}_".$self->log_auto_id.".log");
}
datedescriptionprevnextTop
sub date {
  return strftime "%Y-%m-%d %T", localtime;
}
date_and_memdescriptionprevnextTop
sub date_and_mem {
  my $date = strftime "%Y-%m-%d %T", localtime;
  my $mem = `ps -p $$ -o vsz |tail -1`;
  chomp $mem;
  $mem = parse_bytes($mem*1000);
  return "[$date, mem $mem]";
}
debugdescriptionprevnextTop
sub debug {
  my ($self, $txt, $indent, $stamped) = @_;

  return(0) unless ($self->{'loglevel'} >= 4);

  $self->log_generic($txt, $indent, $stamped);
  return(1);
}
errordescriptionprevnextTop
sub error {
  my ($self, $txt, $indent, $stamped) = @_;

  return(0) unless ($self->{'loglevel'} >= 1);
  
  $txt = "ERROR: ".$txt;
  $self->log_generic($txt, $indent, $stamped);
  
  $self->log_generic("\nExiting prematurely.\n\n");
  $self->log_generic("Runtime: ".$self->runtime." ".$self->date_and_mem."\n\n");
  
  exit(1);
}
extract_log_identifierdescriptionprevnextTop
sub extract_log_identifier {
  my $self = shift;

  if (my $logfile = $self->logfile) {
    $logfile =~ /.+\.([^\.]+)\.log/;
    return $1;
  } else {
    return undef;
  }
}
finish_logdescriptionprevnextTop
sub finish_log {
  my $self = shift;
  
  $self->info("\nAll done for $Script.\n");
  $self->info($self->warning_count." warnings. ");
  $self->info("Runtime: ".$self->runtime." ".$self->date_and_mem."\n\n");
  
  return(1);
}
infodescriptionprevnextTop
sub info {
  my ($self, $txt, $indent, $stamped) = @_;

  return(0) unless ($self->{'loglevel'} >= 3);

  $self->log_generic($txt, $indent, $stamped);
  return(1);
}
init_logdescriptionprevnextTop
sub init_log {
  my $self = shift;
  my $params = shift;

  # get a log filehandle
my $log = $self->log_filehandle; # remember start time
$self->{'_start_time'} = time; # don't log parameters if this script is run by another one
if ($self->logauto or ! $self->is_component) { # print script name, date, user who is running it
my $hostname = `hostname`; chomp $hostname; my $script = "$hostname:$Bin/$Script"; my $user = `whoami`; chomp $user; $self->info("Script: $script\nDate: ".$self->date."\nUser: $user\n"); # print parameters the script is running with
if ($params) { $self->info("Parameters:\n\n"); $self->info($params); } } return $log;
}
init_progressdescriptionprevnextTop
sub init_progress {
  my $self = shift;
  my $max = shift;
  my $num_bins = shift || 50;

  throw("You must provide the maximum value for your progress bar")
    unless (defined($max));

  # auto-generate a unique name for your progressbar
my $name = time . '_' . int(rand(1000)); # calculate bin size; we will use 50 bins (2% increments)
my $binsize = $max/$num_bins;
$self->{'_progress'}->{$name}->{'max_val'} = $max; $self->{'_progress'}->{$name}->{'binsize'} = $binsize; $self->{'_progress'}->{$name}->{'numbins'} = $num_bins; $self->{'_progress'}->{$name}->{'next'} = 0; $self->{'_progress'}->{$name}->{'index'} = 0; return $name;
}
is_componentdescriptionprevnextTop
sub is_component {
  my $self = shift;
  $self->{'_is_component'} = shift if (@_);
  return $self->{'_is_component'};
}
logdescriptionprevnextTop
sub log {
  return $_[0]->info(@_);
}
log_auto_iddescriptionprevnextTop
sub log_auto_id {
  my $self = shift;
  $self->{'_log_auto_id'} = shift if (@_);
  return $self->{'_log_auto_id'};
}
log_errordescriptionprevnextTop
sub log_error {
  return $_[0]->error(@_);
}
log_filehandledescriptionprevnextTop
sub log_filehandle {
  my ($self, $mode) = @_;
  
  unless ($self->{'_log_filehandle'}) {
    $mode ||= '>';
    $mode = '>>' if ($self->logappend);
    
    my $fh =\* STDERR;
    
    if (my $logfile = $self->logfile) {
      if (my $logpath = $self->logpath) {
        unless (-e $logpath) {
          system("mkdir -p $logpath") == 0 or
            throw("Can't create log dir $logpath: $!\n");
        }
        
        $logfile = "$logpath/".$self->logfile;
      }
      
      open($fh, "$mode", $logfile) or
        throw("Unable to open $logfile for writing: $!");
    }

    $self->{'_log_filehandle'} = $fh;
  }

  return $self->{'_log_filehandle'};
}
log_genericdescriptionprevnextTop
sub log_generic {
  my ($self, $txt, $indent, $stamped) = @_;

  $indent ||= 0;
  my $fh = $self->log_filehandle;

  # append timestamp and memory usage to log text if requested
if ($stamped) { $txt =~ s/^(\n*)(.*)(\n*)$/$2/; $txt = sprintf("%-60s%20s", $txt, $self->time_and_mem); $txt = $1.$txt.$3; } # strip off leading linebreaks so that indenting doesn't break
$txt =~ s/^(\n*)//; # indent
$txt = $1." "x$indent . $txt; print $fh "$txt"; return(1);
}
log_progressdescriptionprevnextTop
sub log_progress {
  my $self = shift;
  my $name = shift;
  my $curr = shift;
  my $indent = shift;
  
  throw("You must provide a name and the current value for your progress bar")
    unless ($name and $curr);

  # return if we haven't reached the next increment
return if ($curr < int($self->{'_progress'}->{$name}->{'next'})); my $index = $self->{'_progress'}->{$name}->{'index'}; my $num_bins = $self->{'_progress'}->{$name}->{'numbins'}; my $percent = $index/$num_bins*100;
my $log_str; $log_str .= ' 'x$indent if ($index == 0); $log_str .= "\b"x4; $log_str .= sprintf("%3s%%", $percent); $log_str .= "\n" if ($curr == $self->{'_progress'}->{$name}->{'max_val'}); $self->info($log_str); # increment counters
$self->{'_progress'}->{$name}->{'index'}++; $self->{'_progress'}->{$name}->{'next'} += $self->{'_progress'}->{$name}->{'binsize'};
}
log_progressbardescriptionprevnextTop
sub log_progressbar {
  my $self = shift;
  my $name = shift;
  my $curr = shift;
  my $indent = shift;
  
  throw("You must provide a name and the current value for your progress bar")
    unless ($name and $curr);

  # return if we haven't reached the next increment
return if ($curr < int($self->{'_progress'}->{$name}->{'next'})); my $index = $self->{'_progress'}->{$name}->{'index'}; my $num_bins = $self->{'_progress'}->{$name}->{'numbins'}; my $percent = $index/$num_bins*100;
my $log_str = "\r".(' 'x$indent)."[".('='x$index).(' 'x($num_bins-$index))."] ${percent}\%"; $log_str .= "\n" if ($curr == $self->{'_progress'}->{$name}->{'max_val'}); $self->info($log_str); # increment counters
$self->{'_progress'}->{$name}->{'index'}++; $self->{'_progress'}->{$name}->{'next'} += $self->{'_progress'}->{$name}->{'binsize'};
}
log_stampeddescriptionprevnextTop
sub log_stamped {
  return $_[0]->log(@_, 1);
}



1;
}
log_verbosedescriptionprevnextTop
sub log_verbose {
  return $_[0]->debug(@_);
}
log_warningdescriptionprevnextTop
sub log_warning {
  return $_[0]->warning(@_);
}
logappenddescriptionprevnextTop
sub logappend {
  my $self = shift;
  $self->{'_logappend'} = shift if (@_);
  return $self->{'_logappend'};
}
logautodescriptionprevnextTop
sub logauto {
  my $self = shift;
  $self->{'_log_auto'} = shift if (@_);
  return $self->{'_log_auto'};
}
logfiledescriptionprevnextTop
sub logfile {
  my $self = shift;
  $self->{'_logfile'} = shift if (@_);
  return $self->{'_logfile'};
}
logleveldescriptionprevnextTop
sub loglevel {
  my $self = shift;
  return $reverse_level_defs[$self->{'loglevel'}];
}


#
# deprecated methods (left here for backwards compatibility
#
}
logpathdescriptionprevnextTop
sub logpath {
  my $self = shift;
  $self->{'_logpath'} = shift if (@_);
  return $self->{'_logpath'};
}
memdescriptionprevnextTop
sub mem {
  my $mem = `ps -p $$ -o vsz |tail -1`;
  chomp $mem;
  return $mem;
}
newdescriptionprevnextTop
sub new {
  my $caller = shift;
  my $class = ref($caller) || $caller;

  my ($logfile, $logauto, $logautobase, $logautoid, $logpath, $logappend,
    $loglevel, $is_component) = rearrange(
      ['LOGFILE', 'LOGAUTO', 'LOGAUTOBASE', 'LOGAUTOID', 'LOGPATH', 'LOGAPPEND',
      'LOGLEVEL', 'IS_COMPONENT'], @_);
  
  my $self = { '_warnings'     => 0, };
  bless ($self, $class);

  # initialise
$self->logfile($logfile); $self->logpath($logpath); $self->logappend($logappend); $self->is_component($is_component); # automatic logfile creation
$self->logauto($logauto); $logautoid ||= strftime("%Y%m%d-%H%M%S", localtime); $self->log_auto_id($logautoid); $self->create_auto_logfile($logautobase); $loglevel ||= 'info'; if ($loglevel =~ /^\d+$/ and $loglevel > 0 and $loglevel < 5) { $self->{'loglevel'} = $loglevel; } elsif ($level_defs{lc($loglevel)}) { $self->{'loglevel'} = $level_defs{lc($loglevel)}; } else { throw('Unknown loglevel: $loglevel.'); } return $self;
}
runtimedescriptionprevnextTop
sub runtime {
  my $self = shift;

  my $runtime = "n/a";

  if ($self->{'_start_time'}) {
    my $diff = time - $self->{'_start_time'};
    my $sec = $diff % 60;
    $diff = ($diff - $sec) / 60;
my $min = $diff % 60; my $hours = ($diff - $min) / 60;
$runtime = "${hours}h ${min}min ${sec}sec"; } return $runtime;
}
time_and_memdescriptionprevnextTop
sub time_and_mem {
  my $date = strftime "%T", localtime;
  my $mem = `ps -p $$ -o vsz |tail -1`;
  chomp $mem;
  $mem = parse_bytes($mem*1000);
  $mem =~ s/ //;
  return "[$date|$mem]";
}
warningdescriptionprevnextTop
sub warning {
  my ($self, $txt, $indent, $stamped) = @_;
  
  return(0) unless ($self->{'loglevel'} >= 2);
  
  $txt = "WARNING: " . $txt;
  $self->log_generic($txt, $indent, $stamped);
  
  $self->{'_warnings'}++;
  
  return(1);
}
warning_countdescriptionprevnextTop
sub warning_count {
  my $self = shift;
  return $self->{'_warnings'};
}
General documentation
LICENSETop
  Copyright (c) 1999-2009 The European Bioinformatics Institute and
Genome Research Limited. All rights reserved.
This software is distributed under a modified Apache license. For license details, please see /info/about/code_licence.html
CONTACTTop
  Please email comments or questions to the public Ensembl
developers list at <ensembl-dev@ebi.ac.uk>.
Questions may also be sent to the Ensembl help desk at <helpdesk@ensembl.org>.
Top
  Arg[1]      : 
Example :
Description :
Return type :
Exceptions :
Caller :
Status :
Top
  Arg[1]      : 
Example :
Description :
Return type :
Exceptions :
Caller :
Status :
Top
  Arg[1]      : 
Example :
Description :
Return type :
Exceptions :
Caller :
Status :
Top
  Arg[1]      : 
Example :
Description :
Return type :
Exceptions :
Caller :
Status : At Risk
: under development
Top
  Arg[1]      : 
Example :
Description :
Return type :
Exceptions :
Caller :
Status :
Top
  Arg[1]      : 
Example :
Description :
Return type :
Exceptions :
Caller :
Status :
Top
  Arg[1]      : 
Example :
Description :
Return type :
Exceptions :
Caller :
Status :