3 See the NOTICE file distributed with
this work
for additional information
4 regarding copyright ownership.
6 Licensed under the Apache License, Version 2.0 (the
"License");
7 you may not use
this file except in compliance with the License.
8 You may obtain a copy of the License at
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an
"AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License
for the specific language governing permissions and
16 limitations under the License.
23 Please email comments or questions to the
public Ensembl
24 developers list at <http:
26 Questions may also be sent to the Ensembl help desk at
34 schema conversion scripts
38 my $serverroot =
'/path/to/ensembl';
41 # parse common options
42 $support->parse_common_options;
44 # parse extra options for your script
45 $support->parse_extra_options(
'string_opt=s',
'numeric_opt=n' );
47 # ask user if he wants to run script with these parameters
48 $support->confirm_params;
50 # see individual method documentation for more stuff
54 This module is a collection of common methods and provides helper
55 functions
for the Vega release and schema conversion scripts. Amongst
56 others, it reads options from a config file, parses commandline options
63 package Bio::EnsEMBL::Utils::Logger;
67 no warnings
'uninitialized';
69 use FindBin qw($Bin $Script);
70 use POSIX qw(strftime);
85 my @reverse_level_defs = (undef, qw(error warning
info debug));
89 Arg[1] : String $serverroot - root directory of your ensembl sandbox
92 Description : constructor
94 Exceptions : thrown on invalid loglevel
101 my $class = ref($caller) || $caller;
103 my ($logfile, $logauto, $logautobase, $logautoid, $logpath, $logappend,
104 $loglevel, $is_component) = rearrange(
105 [
'LOGFILE',
'LOGAUTO',
'LOGAUTOBASE',
'LOGAUTOID',
'LOGPATH',
'LOGAPPEND',
106 'LOGLEVEL',
'IS_COMPONENT'], @_);
108 my $self = {
'_warnings' => 0, };
109 bless ($self, $class);
112 $self->logfile($logfile);
113 $self->logpath($logpath);
114 $self->logappend($logappend);
115 $self->is_component($is_component);
117 # automatic logfile creation
118 $self->logauto($logauto);
119 $logautoid ||= strftime(
"%Y%m%d-%H%M%S", localtime);
120 $self->log_auto_id($logautoid);
121 $self->create_auto_logfile($logautobase);
123 $loglevel ||=
'info';
124 if ($loglevel =~ /^\d+$/ and $loglevel > 0 and $loglevel < 5) {
125 $self->{
'loglevel'} = $loglevel;
126 } elsif ($level_defs{lc($loglevel)}) {
127 $self->{
'loglevel'} = $level_defs{lc($loglevel)};
129 throw(
'Unknown loglevel: $loglevel.');
138 Arg[1] : String $txt - the text to log
139 Arg[2] : Int $indent - indentation level
for log message
140 Example : my $log = $support->log_filehandle;
141 $support->log(
'Log foo.\n', 1);
142 Description : Logs a message to the filehandle initialised by calling
143 $self->log_filehandle(). You can supply an indentation level
144 to get nice hierarchical log messages.
145 Return type :
true on success
146 Exceptions : thrown when no filehandle can be obtained
152 my ($self, $txt, $indent, $stamped) = @_;
155 my $fh = $self->log_filehandle;
157 # append timestamp and memory usage to log text if requested
159 $txt =~ s/^(\n*)(.*)(\n*)$/$2/;
160 $txt = sprintf(
"%-60s%20s", $txt, $self->time_and_mem);
164 # strip off leading linebreaks so that indenting doesn't break
168 $txt = $1.
" "x$indent . $txt;
178 Arg[1] : String $txt - the error text to log
179 Arg[2] : Int $indent - indentation level
for log message
180 Example : my $log = $support->log_filehandle;
181 $support->log_error(
'Log foo.\n', 1);
182 Description : Logs a message via $self->log and exits the script.
190 my ($self, $txt, $indent, $stamped) = @_;
192 return(0) unless ($self->{
'loglevel'} >= 1);
194 $txt =
"ERROR: ".$txt;
195 $self->log_generic($txt, $indent, $stamped);
197 $self->log_generic(
"\nExiting prematurely.\n\n");
198 $self->log_generic(
"Runtime: ".$self->runtime.
" ".$self->date_and_mem.
"\n\n");
206 Arg[1] : String $txt - the warning text to log
207 Arg[2] : Int $indent - indentation level
for log message
208 Example : my $log = $support->log_filehandle;
209 $support->log_warning(
'Log foo.\n', 1);
210 Description : Logs a message via $self->log and increases the warning counter.
211 Return type :
true on success
218 my ($self, $txt, $indent, $stamped) = @_;
220 return(0) unless ($self->{
'loglevel'} >= 2);
222 $txt =
"WARNING: " . $txt;
223 $self->log_generic($txt, $indent, $stamped);
225 $self->{
'_warnings'}++;
232 my ($self, $txt, $indent, $stamped) = @_;
234 return(0) unless ($self->{
'loglevel'} >= 3);
236 $self->log_generic($txt, $indent, $stamped);
243 Arg[1] : String $txt - the warning text to log
244 Arg[2] : Int $indent - indentation level
for log message
245 Example : my $log = $support->log_filehandle;
246 $support->log_verbose(
'Log this verbose message.\n', 1);
247 Description : Logs a message via $self->log
if --verbose option was used
248 Return type : TRUE on success, FALSE
if not verbose
255 my ($self, $txt, $indent, $stamped) = @_;
257 return(0) unless ($self->{
'loglevel'} >= 4);
259 $self->log_generic($txt, $indent, $stamped);
270 throw(
"You must provide a name and the current value for your progress bar")
271 unless ($name and $curr);
273 # return if we haven't reached the next increment
274 return if ($curr <
int($self->{
'_progress'}->{$name}->{
'next'}));
276 my $index = $self->{
'_progress'}->{$name}->{
'index'};
277 my $num_bins = $self->{
'_progress'}->{$name}->{
'numbins'};
278 my $percent = $index/$num_bins*100;
281 $log_str .=
' 'x$indent
if ($index == 0);
283 $log_str .= sprintf(
"%3s%%", $percent);
284 $log_str .=
"\n" if ($curr == $self->{
'_progress'}->{$name}->{
'max_val'});
286 $self->info($log_str);
289 $self->{
'_progress'}->{$name}->{
'index'}++;
290 $self->{
'_progress'}->{$name}->{
'next'} += $self->{
'_progress'}->{$name}->{
'binsize'};
294 sub log_progressbar {
300 throw(
"You must provide a name and the current value for your progress bar")
301 unless ($name and $curr);
303 # return if we haven't reached the next increment
304 return if ($curr <
int($self->{
'_progress'}->{$name}->{
'next'}));
306 my $index = $self->{
'_progress'}->{$name}->{
'index'};
307 my $num_bins = $self->{
'_progress'}->{$name}->{
'numbins'};
308 my $percent = $index/$num_bins*100;
310 my $log_str =
"\r".(
' 'x$indent).
"[".(
'='x$index).(
' 'x($num_bins-$index)).
"] ${percent}\%";
311 $log_str .=
"\n" if ($curr == $self->{
'_progress'}->{$name}->{
'max_val'});
313 $self->info($log_str);
316 $self->{
'_progress'}->{$name}->{
'index'}++;
317 $self->{
'_progress'}->{$name}->{
'next'} += $self->{
'_progress'}->{$name}->{
'binsize'};
324 my $num_bins = shift || 50;
326 throw(
"You must provide the maximum value for your progress bar")
327 unless (defined($max));
329 # auto-generate a unique name for your progressbar
330 my $name = time .
'_' . int(rand(1000));
332 # calculate bin size; we will use 50 bins (2% increments)
333 my $binsize = $max/$num_bins;
335 $self->{
'_progress'}->{$name}->{
'max_val'} = $max;
336 $self->{
'_progress'}->{$name}->{
'binsize'} = $binsize;
337 $self->{
'_progress'}->{$name}->{
'numbins'} = $num_bins;
338 $self->{
'_progress'}->{$name}->{
'next'} = 0;
339 $self->{
'_progress'}->{$name}->{
'index'} = 0;
345 =head2 log_filehandle
347 Arg[1] : (optional) String $mode - file access mode
348 Example : my $log = $support->log_filehandle;
349 # print to the filehandle
350 print $log
'Lets start logging...\n';
351 # log via the wrapper $self->log()
352 $support->log(
'Another log message.\n');
353 Description : Returns a filehandle
for logging (STDERR by
default, logfile
if
354 set from config or commandline). You can use the filehandle
355 directly to print to, or use the smart wrapper $self->log().
356 Logging mode (truncate or append) can be set by passing the
357 mode as an argument to log_filehandle(), or with the
358 --logappend commandline option (
default: truncate)
359 Return type : Filehandle - the filehandle to log to
360 Exceptions : thrown
if logfile can
't be opened
366 my ($self, $mode) = @_;
368 unless ($self->{'_log_filehandle
'}) {
370 $mode = '>>
' if ($self->logappend);
374 if (my $logfile = $self->logfile) {
375 if (my $logpath = $self->logpath) {
376 unless (-e $logpath) {
377 system("mkdir -p $logpath") == 0 or
378 throw("Can't create log dir $logpath: $!\n
");
381 $logfile = "$logpath/
".$self->logfile;
384 open($fh, "$mode
", $logfile) or
385 throw("Unable to open $logfile
for writing: $!
");
388 $self->{'_log_filehandle'} = $fh;
391 return $self->{'_log_filehandle'};
395 =head2 extract_log_identifier
407 sub extract_log_identifier {
410 if (my $logfile = $self->logfile) {
411 $logfile =~ /.+\.([^\.]+)\.log/;
421 Example : $support->init_log;
422 Description : Opens a filehandle to the logfile and prints some header
423 information to this file. This includes script name, date, user
424 running the script and parameters the script will be running
426 Return type : Filehandle - the log filehandle
436 # get a log filehandle
437 my $log = $self->log_filehandle;
439 # remember start time
440 $self->{'_start_time'} = time;
442 # don't log parameters if this script is run by another one
443 if ($self->logauto or ! $self->is_component) {
444 # print script name, date, user who is running it
445 my $hostname = `hostname`;
447 my $script = "$hostname:$Bin/$Script
";
450 $self->info("Script: $script\nDate:
".$self->date."\nUser: $user\n
");
452 # print parameters the script is running with
454 $self->info("Parameters:\n\n
");
455 $self->info($params);
465 Example : $support->finish_log;
466 Description : Writes footer information to a logfile. This includes the
467 number of logged warnings, timestamp and memory footprint.
468 Return type : TRUE on success
477 $self->info("\nAll done
for $Script.\n
");
478 $self->info($self->warning_count." warnings.
");
479 $self->info("Runtime:
".$self->runtime." ".$self->date_and_mem."\n\n
");
490 if ($self->{'_start_time'}) {
491 my $diff = time - $self->{'_start_time'};
492 my $sec = $diff % 60;
493 $diff = ($diff - $sec) / 60;
494 my $min = $diff % 60;
495 my $hours = ($diff - $min) / 60;
497 $runtime = "${hours}h ${min}min ${sec}sec
";
506 Example : print LOG "Time, memory
usage:
".$support->date_and_mem."\n
";
507 Description : Prints a timestamp and the memory usage of your script.
508 Return type : String - timestamp and memory usage
515 my $date = strftime "%Y-%m-%d %T
", localtime;
516 my $mem = `ps -p $$ -o vsz |tail -1`;
518 $mem = parse_bytes($mem*1000);
519 return "[$date, mem $mem]
";
524 my $date = strftime "%T
", localtime;
525 my $mem = `ps -p $$ -o vsz |tail -1`;
527 $mem = parse_bytes($mem*1000);
529 return "[$date|$mem]
";
535 Example : print "Date:
" . $support->date . "\n
";
536 Description : Prints a nicely formatted timestamp (YYYY-DD-MM hh:mm:ss)
537 Return type : String - the timestamp
544 return strftime "%Y-%m-%d %T
", localtime;
550 Example : print "Memory
usage:
" . $support->mem . "\n
";
551 Description : Prints the memory used by your script. Not sure about platform
552 dependence of this call ...
553 Return type : String - memory usage
560 my $mem = `ps -p $$ -o vsz |tail -1`;
568 Example : print LOG "There were
".$support->warnings." warnings.\n
";
569 Description : Returns the number of warnings encountered while running the
570 script (the warning counter is increased by $self->log_warning).
571 Return type : Int - number of warnings
579 return $self->{'_warnings'};
587 Description : Getter and setter for the logfile
597 $self->{'_logfile'} = shift if (@_);
598 return $self->{'_logfile'};
616 $self->{'_log_auto_id'} = shift if (@_);
617 return $self->{'_log_auto_id'};
623 $self->{'_log_auto'} = shift if (@_);
624 return $self->{'_log_auto'};
628 =head2 create_auto_logfile
641 sub create_auto_logfile {
643 my $logautobase = shift;
645 # do nothing if automatic logfile generation isn't set
646 return unless ($self->logauto);
648 # an explicit logfile name overrides LOGAUTO
649 return if ($self->logfile);
652 unless ($logautobase) {
653 throw('Need a base logfile name for auto-generating logfile.');
656 # create a logfile name
657 $self->logfile("${logautobase}_
".$self->log_auto_id.".log
");
675 $self->{'_logpath'} = shift if (@_);
676 return $self->{'_logpath'};
694 $self->{'_logappend'} = shift if (@_);
695 return $self->{'_logappend'};
713 $self->{'_is_component'} = shift if (@_);
714 return $self->{'_is_component'};
720 return $reverse_level_defs[$self->{'loglevel'}];
725 # deprecated methods (left here for backwards compatibility
728 return $_[0]->error(@_);
732 return $_[0]->warning(@_);
736 return $_[0]->info(@_);
740 return $_[0]->debug(@_);
744 return $_[0]->log(@_, 1);