Logger.pm 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. # ABSTRACT: Scrappy Scraper Event Logging
  2. # Dist::Zilla: +PodWeaver
  3. package Scrappy::Logger;
  4. BEGIN {
  5. $Scrappy::Logger::VERSION = '0.94112090';
  6. }
  7. # load OO System
  8. use Moose;
  9. # load other libraries
  10. use Carp;
  11. use DateTime;
  12. use DateTime::Format::SQLite;
  13. use YAML::Syck;
  14. $YAML::Syck::ImplicitTyping = 1;
  15. has 'auto_save' => (is => 'rw', isa => 'Bool', default => 1);
  16. has file => (is => 'rw', isa => 'Str');
  17. has verbose => (is => 'rw', isa => 'Int', default => 0);
  18. sub load {
  19. my $self = shift;
  20. my $file = shift;
  21. if ($file) {
  22. $self->{file} = $file;
  23. # load event-log file
  24. $self->{stash} = LoadFile($file)
  25. or croak("Log file $file does not exist or is not read/writable");
  26. }
  27. return $self->{stash};
  28. }
  29. sub timestamp {
  30. my $self = shift;
  31. my $date = shift;
  32. if ($date) {
  33. # $date =~ s/\_/ /g;
  34. return DateTime::Format::SQLite->parse_datetime($date)
  35. ; # datetime object
  36. }
  37. else {
  38. $date =
  39. DateTime::Format::SQLite->format_datetime(DateTime->now); # string
  40. # $date =~ s/ /_/g;
  41. return $date;
  42. }
  43. }
  44. sub info {
  45. return shift->event('info', @_);
  46. }
  47. sub warn {
  48. return shift->event('warn', @_);
  49. }
  50. sub error {
  51. return shift->event('error', @_);
  52. }
  53. sub event {
  54. my $self = shift;
  55. my $type = shift;
  56. my $note = shift;
  57. croak("Can't record an event without an event-type and notation")
  58. unless $type && $note;
  59. $self->{stash} = {} unless defined $self->{stash};
  60. $self->{stash}->{$type} = [] unless defined $self->{stash}->{$type};
  61. my $frame = $type eq 'info' || $type eq 'error' || $type eq 'warn' ? 1 : 0;
  62. my @trace = caller($frame);
  63. my $entry = scalar @{$self->{stash}->{$type}};
  64. my $time = $self->timestamp;
  65. my $data = {};
  66. $data = {
  67. '// package' => $trace[0],
  68. '// filename' => $trace[1],
  69. '// line' => $trace[2],
  70. '// occurred' => $time,
  71. '// notation' => $note,
  72. }
  73. if $self->verbose;
  74. $self->{stash}->{$type}->[$entry] = {eventlog => "[$time] [$type] $note"}
  75. unless defined $self->{stash}->{$type}->[$entry];
  76. $self->{stash}->{$type}->[$entry]->{metadata} = $data
  77. if scalar keys %{$data};
  78. if (@_ && $self->verbose) {
  79. my $stash = @_ > 1 ? {@_} : $_[0];
  80. if ($stash) {
  81. if (ref $stash eq 'HASH') {
  82. for (keys %{$stash}) {
  83. $self->{stash}->{$type}->[$entry]->{metadata}->{$_} =
  84. $stash->{$_};
  85. }
  86. }
  87. }
  88. }
  89. $self->write;
  90. return $self->{stash}->{$type}->[$entry];
  91. }
  92. sub write {
  93. my $self = shift;
  94. my $file = shift || $self->{file};
  95. $self->{file} = $file;
  96. if ($file) {
  97. # write event-log file
  98. DumpFile($file, $self->{stash})
  99. or
  100. croak("event-log file $file does not exist or is not read/writable");
  101. }
  102. return $self->{stash};
  103. }
  104. 1;
  105. __END__
  106. =pod
  107. =head1 NAME
  108. Scrappy::Logger - Scrappy Scraper Event Logging
  109. =head1 VERSION
  110. version 0.94112090
  111. =head1 SYNOPSIS
  112. #!/usr/bin/perl
  113. use Scrappy::Logger;
  114. my $logger = Scrappy::Logger->new;
  115. -f 'scraper.log' ?
  116. $logger->load('scraper.log');
  117. $logger->write('scraper.log');
  118. $logger->stash('foo' => 'bar');
  119. $logger->stash('abc' => [('a'..'z')]);
  120. =head1 DESCRIPTION
  121. Scrappy::Logger provides YAML-Based event-log handling for recording events
  122. encountered using the L<Scrappy> framework.
  123. =head2 ATTRIBUTES
  124. The following is a list of object attributes available with every Scrappy::Logger
  125. instance.
  126. =head3 auto_save
  127. The auto_save attribute is a boolean that determines whether event data is
  128. automatically saved to the log file on update.
  129. my $logger = Scrappy::Logger->new;
  130. $logger->load('scraper.log');
  131. # turn auto-saving off
  132. $logger->auto_save(0);
  133. $logger->event('...', 'yada yada yada');
  134. $logger->write; # explicit write
  135. =head3 file
  136. The file attribute gets/sets the filename of the current event-log file.
  137. my $logger = Scrappy::Logger->new;
  138. $logger->load('scraper.log');
  139. $logger->write('scraper.log.bak');
  140. $logger->file('scraper.log');
  141. =head3 verbose
  142. The verbose attribute is a boolean that instructs the logger to write very
  143. detailed logs.
  144. my $logger = Scrappy::Logger->new;
  145. $logger->verbose(1);
  146. =head1 METHODS
  147. =head2 load
  148. The load method is used to read-in an event-log file, it returns its data in the
  149. structure it was saved-in.
  150. my $logger = Scrappy::Logger->new;
  151. my $data = $logger->load('scraper.log');
  152. =head2 timestamp
  153. The timestamp method returns the current date/timestamp in string form. When
  154. supplied a properly formatted date/timestamp this method returns a corresponding
  155. L<DateTime> object.
  156. my $logger = Scrappy::Logger->new;
  157. my $date = $logger->timestamp;
  158. my $dt = $logger->timestamp($date);
  159. =head2 info
  160. The info method is used to capture informational events and returns the event
  161. data.
  162. my $logger = Scrappy::Logger->new;
  163. my %data = (foo => 'bar', baz => 'xyz');
  164. my $event = $logger->info('This is an informational message', %data);
  165. $logger->info('This is an informational message');
  166. =head2 warn
  167. The warn method is used to capture warning events and returns the event
  168. data.
  169. my $logger = Scrappy::Logger->new;
  170. my %data = (foo => 'bar', baz => 'xyz');
  171. my $event = $logger->warn('This is a warning message', %data);
  172. $logger->info('This is an warning message');
  173. =head2 error
  174. The error method is used to capture error events and returns the event
  175. data.
  176. my $logger = Scrappy::Logger->new;
  177. my %data = (foo => 'bar', baz => 'xyz');
  178. my $event = $logger->error('This is a n error message', %data);
  179. $logger->info('This is an error message');
  180. =head2 event
  181. The event method is used to capture custom events and returns the event
  182. data.
  183. my $logger = Scrappy::Logger->new;
  184. my %data = (foo => 'bar', baz => 'xyz');
  185. my $event = $logger->event('myapp', 'This is a user-defined message', %data);
  186. $logger->event('myapp', 'This is a user-defined message');
  187. =head2 write
  188. The write method is used to write-out an event-log file.
  189. my $logger = Scrappy::Logger->new;
  190. $logger->info('This is very cool', 'foo' => 'bar');
  191. $logger->warn('Somethin aint right here');
  192. $logger->error('It broke, I cant believe it broke');
  193. $logger->write('scraper.log');
  194. =head1 AUTHOR
  195. Al Newkirk <awncorp@cpan.org>
  196. =head1 COPYRIGHT AND LICENSE
  197. This software is copyright (c) 2010 by awncorp.
  198. This is free software; you can redistribute it and/or modify it under
  199. the same terms as the Perl 5 programming language system itself.
  200. =cut