portslogger 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #!/usr/bin/perl
  2. # $OpenBSD: portslogger,v 1.1 2010/08/30 19:02:33 steven Exp $
  3. # Copyright (c) 2001 Marc Espie. All rights reserved.
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions
  6. # are met:
  7. # 1. Redistributions of code must retain the above copyright
  8. # notice, this list of conditions and the following disclaimer.
  9. # 2. Neither the name of OpenBSD nor the names of its contributors
  10. # may be used to endorse or promote products derived from this software
  11. # without specific prior written permission.
  12. #
  13. # THIS SOFTWARE IS PROVIDED BY ITS AUTHOR AND THE OpenBSD project ``AS IS'' AND
  14. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16. # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  17. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  19. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  20. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  23. # SUCH DAMAGE.
  24. # This critter recognizes context switch changes in the ports tree
  25. # and logs its output accordingly, as a kind of `super-tee'
  26. {
  27. package Logger;
  28. @ISA=qw(IO::File);
  29. use File::Path;
  30. use IO::File;
  31. use File::Temp qw/tempfile/;
  32. our $directory;
  33. our %temps;
  34. sub setdir
  35. {
  36. $directory = shift;
  37. mkpath $directory;
  38. die "No logging directory" unless -d $directory;
  39. }
  40. sub new
  41. {
  42. my $class = shift;
  43. my $name = shift;
  44. $name = "$directory/$name.log";
  45. my $self = IO::File::new($class, $name, '>>');
  46. if (!$self) {
  47. if (defined $temps{$name}) {
  48. $self = IO::File::new($class, $temps{$name}, '>>');
  49. } else {
  50. ($self, $temps{$name}) = tempfile(SUFFIX => '.log') or
  51. die "Can't create any logfile";
  52. print STDERR "*** Couldn't open $name, \n";
  53. print STDERR "*** using ".$temps{$name}." instead\n";
  54. bless $self, $class;
  55. }
  56. }
  57. $self->print("+++ ", `date`);
  58. $self->autoflush(1);
  59. return $self;
  60. }
  61. sub close
  62. {
  63. my $self = shift;
  64. print $self "--- ", `date`;
  65. $self->SUPER::close();
  66. }
  67. sub DESTROY
  68. {
  69. my $self = shift;
  70. $self->close();
  71. }
  72. }
  73. use Getopt::Std;
  74. our $opt_s;
  75. getopts('s');
  76. if (@ARGV < 1) {
  77. print STDERR "Usage: $0 directory\n";
  78. exit 1;
  79. }
  80. Logger::setdir(shift);
  81. my $logfile = undef;
  82. my $ncontext = undef;
  83. my $context;
  84. while (<>) {
  85. print unless $opt_s;
  86. s/\cM+$//;
  87. # zap fetch & pkg_add progress bar
  88. s/^.*\cM//;
  89. if (m/^\=\=\=\>\s+
  90. (?:
  91. (?: Extracting|
  92. Applying\ distribution\ patches|
  93. Patching|
  94. Configuring|
  95. Building|
  96. Faking\ installation|
  97. Building\ package|
  98. Deinstalling|
  99. Cleaning|
  100. Dist\ cleaning|
  101. Checking\ files|
  102. Regression\ check|
  103. Updating\ plist|
  104. Updating|
  105. Registering\ installation)\s+for\s+(.*)|
  106. Returning\ to\ build\ of\s+(.*)|
  107. Installing\s+(.*?)\s+from)
  108. /ox) {
  109. $ncontext = "$1$2$3"; # XXX only one alternative matches
  110. chomp $ncontext;
  111. # register to `master' context.
  112. $ncontext=$1 if $ncontext =~ m/^.*\[(.*?)\]$/;
  113. if ($ncontext ne $context) {
  114. $context = $ncontext;
  115. $logfile = new Logger $context;
  116. }
  117. } elsif (m/^\=\=\=\> Exiting\s+(.*)\s+with an error$/) {
  118. undef $context;
  119. }
  120. unless (defined $context) {
  121. $context = default;
  122. $logfile = new Logger 'default';
  123. }
  124. $logfile->print($_);
  125. }